diff --git a/PlexRequests.Core/IRequestService.cs b/PlexRequests.Core/IRequestService.cs index 342e83d05..20fe5e071 100644 --- a/PlexRequests.Core/IRequestService.cs +++ b/PlexRequests.Core/IRequestService.cs @@ -26,6 +26,8 @@ #endregion using System.Collections.Generic; +using System.Threading.Tasks; + using PlexRequests.Store; namespace PlexRequests.Core @@ -33,13 +35,21 @@ namespace PlexRequests.Core public interface IRequestService { long AddRequest(RequestedModel model); + Task AddRequestAsync(RequestedModel model); RequestedModel CheckRequest(int providerId); + Task CheckRequestAsync(int providerId); RequestedModel CheckRequest(string musicId); + Task CheckRequestAsync(string musicId); void DeleteRequest(RequestedModel request); + Task DeleteRequestAsync(RequestedModel request); bool UpdateRequest(RequestedModel model); + Task UpdateRequestAsync(RequestedModel model); RequestedModel Get(int id); + Task GetAsync(int id); IEnumerable GetAll(); + Task> GetAllAsync(); bool BatchUpdate(List model); + bool BatchDelete(List model); } } \ No newline at end of file diff --git a/PlexRequests.Core/ISettingsService.cs b/PlexRequests.Core/ISettingsService.cs index 9687d920e..a1ef1341e 100644 --- a/PlexRequests.Core/ISettingsService.cs +++ b/PlexRequests.Core/ISettingsService.cs @@ -24,12 +24,18 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ************************************************************************/ #endregion + +using System.Threading.Tasks; + namespace PlexRequests.Core { public interface ISettingsService { T GetSettings(); + Task GetSettingsAsync(); bool SaveSettings(T model); + Task SaveSettingsAsync(T model); bool Delete(T model); + Task DeleteAsync(T model); } } \ No newline at end of file diff --git a/PlexRequests.Core/JsonRequestService.cs b/PlexRequests.Core/JsonRequestService.cs index deefdfccd..d44069271 100644 --- a/PlexRequests.Core/JsonRequestService.cs +++ b/PlexRequests.Core/JsonRequestService.cs @@ -27,6 +27,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using Newtonsoft.Json; @@ -57,6 +58,19 @@ namespace PlexRequests.Core return result ? id : -1; } + public async Task AddRequestAsync(RequestedModel model) + { + var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId }; + var id = await Repo.InsertAsync(entity); + + model.Id = id; + + entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = id, MusicId = model.MusicBrainzId }; + var result = await Repo.UpdateAsync(entity); + + return result ? id : -1; + } + public RequestedModel CheckRequest(int providerId) { var blobs = Repo.GetAll(); @@ -64,6 +78,13 @@ namespace PlexRequests.Core return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; } + public async Task CheckRequestAsync(int providerId) + { + var blobs = await Repo.GetAllAsync(); + var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId); + return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; + } + public RequestedModel CheckRequest(string musicId) { var blobs = Repo.GetAll(); @@ -71,18 +92,37 @@ namespace PlexRequests.Core return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; } + public async Task CheckRequestAsync(string musicId) + { + var blobs = await Repo.GetAllAsync(); + var blob = blobs.FirstOrDefault(x => x.MusicId == musicId); + return blob != null ? ByteConverterHelper.ReturnObject(blob.Content) : null; + } + public void DeleteRequest(RequestedModel request) { var blob = Repo.Get(request.Id); Repo.Delete(blob); } + public async Task DeleteRequestAsync(RequestedModel request) + { + var blob = await Repo.GetAsync(request.Id); + await Repo.DeleteAsync(blob); + } + public bool UpdateRequest(RequestedModel model) { var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id }; return Repo.Update(entity); } + public async Task UpdateRequestAsync(RequestedModel model) + { + var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id }; + return await Repo.UpdateAsync(entity); + } + public RequestedModel Get(int id) { var blob = Repo.Get(id); @@ -94,6 +134,17 @@ namespace PlexRequests.Core return model; } + public async Task GetAsync(int id) + { + var blob = await Repo.GetAsync(id); + if (blob == null) + { + return new RequestedModel(); + } + var model = ByteConverterHelper.ReturnObject(blob.Content); + return model; + } + public IEnumerable GetAll() { var blobs = Repo.GetAll(); @@ -102,10 +153,24 @@ namespace PlexRequests.Core .ToList(); } + public async Task> GetAllAsync() + { + var blobs = await Repo.GetAllAsync(); + return blobs.Select(b => Encoding.UTF8.GetString(b.Content)) + .Select(JsonConvert.DeserializeObject) + .ToList(); + } + public bool BatchUpdate(List model) { var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList(); return Repo.UpdateAll(entities); } + + public bool BatchDelete(List model) + { + var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList(); + return Repo.DeleteAll(entities); + } } } \ No newline at end of file diff --git a/PlexRequests.Core/SettingsServiceV2.cs b/PlexRequests.Core/SettingsServiceV2.cs index 3fb53cd35..5705544d0 100644 --- a/PlexRequests.Core/SettingsServiceV2.cs +++ b/PlexRequests.Core/SettingsServiceV2.cs @@ -24,6 +24,8 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ************************************************************************/ #endregion + +using System.Threading.Tasks; using Newtonsoft.Json; using PlexRequests.Core.SettingModels; @@ -62,6 +64,21 @@ namespace PlexRequests.Core return model; } + public async Task GetSettingsAsync() + { + var result = await Repo.GetAsync(EntityName); + if (result == null) + { + return new T(); + } + result.Content = DecryptSettings(result); + var obj = string.IsNullOrEmpty(result.Content) ? null : JsonConvert.DeserializeObject(result.Content, SerializerSettings.Settings); + + var model = obj; + + return model; + } + public bool SaveSettings(T model) { var entity = Repo.Get(EntityName); @@ -88,6 +105,31 @@ namespace PlexRequests.Core return result; } + public async Task SaveSettingsAsync(T model) + { + var entity = await Repo.GetAsync(EntityName); + + if (entity == null) + { + var newEntity = model; + + var settings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(newEntity, SerializerSettings.Settings) }; + settings.Content = EncryptSettings(settings); + var insertResult = await Repo.InsertAsync(settings); + + return insertResult != int.MinValue; + } + + var modified = model; + modified.Id = entity.Id; + + var globalSettings = new GlobalSettings { SettingsName = EntityName, Content = JsonConvert.SerializeObject(modified, SerializerSettings.Settings), Id = entity.Id }; + globalSettings.Content = EncryptSettings(globalSettings); + var result = await Repo.UpdateAsync(globalSettings); + + return result; + } + public bool Delete(T model) { var entity = Repo.Get(EntityName); @@ -100,6 +142,17 @@ namespace PlexRequests.Core return true; } + public async Task DeleteAsync(T model) + { + var entity = Repo.Get(EntityName); + if (entity != null) + { + return await Repo.DeleteAsync(entity); + } + + return true; + } + private string EncryptSettings(GlobalSettings settings) { return StringCipher.Encrypt(settings.Content, settings.SettingsName); diff --git a/PlexRequests.Core/Setup.cs b/PlexRequests.Core/Setup.cs index 8bdf2faa6..87e16118e 100644 --- a/PlexRequests.Core/Setup.cs +++ b/PlexRequests.Core/Setup.cs @@ -53,7 +53,7 @@ namespace PlexRequests.Core { CreateDefaultSettingsPage(urlBase); } - + var version = CheckSchema(); if (version > 0) { @@ -61,6 +61,10 @@ namespace PlexRequests.Core { MigrateToVersion1700(); } + if (version > 1800 && version <= 1899) + { + MigrateToVersion1800(); + } } return Db.DbConnection().ConnectionString; @@ -73,7 +77,7 @@ namespace PlexRequests.Core { var productVersion = AssemblyHelper.GetProductVersion(); var trimStatus = new Regex("[^0-9]", RegexOptions.Compiled).Replace(productVersion, string.Empty).PadRight(4, '0'); - var version = int.Parse(trimStatus); + var version = int.Parse(trimStatus); var connection = Db.DbConnection(); var schema = connection.GetSchemaVersion(); @@ -173,5 +177,50 @@ namespace PlexRequests.Core TableCreation.DropTable(Db.DbConnection(), "User"); TableCreation.DropTable(Db.DbConnection(), "Log"); } + + /// + /// Migrates to version 1.8. + /// This includes updating the admin account to have all roles. + /// Set the log level to info + /// + private void MigrateToVersion1800() + { + try + { + var userMapper = new UserMapper(new UserRepository(Db, new MemoryCacheProvider())); + var users = userMapper.GetUsers(); + + foreach (var u in users) + { + var claims = new[] { UserClaims.User, UserClaims.Admin, UserClaims.PowerUser }; + u.Claims = ByteConverterHelper.ReturnBytes(claims); + + userMapper.EditUser(u); + } + } + catch (Exception e) + { + Log.Error(e); + throw; + } + + try + { + var settingsService = new SettingsServiceV2(new SettingsJsonRepository(Db, new MemoryCacheProvider())); + var logSettings = settingsService.GetSettings(); + logSettings.Level = LogLevel.Info.Ordinal; + settingsService.SaveSettings(logSettings); + + LoggingHelper.ReconfigureLogLevel(LogLevel.FromOrdinal(logSettings.Level)); + + } + catch (Exception e) + { + Log.Error(e); + throw; + } + + + } } } diff --git a/PlexRequests.Core/UserMapper.cs b/PlexRequests.Core/UserMapper.cs index eb66cbea3..909c3a34c 100644 --- a/PlexRequests.Core/UserMapper.cs +++ b/PlexRequests.Core/UserMapper.cs @@ -81,6 +81,16 @@ namespace PlexRequests.Core return null; } + public UsersModel EditUser(UsersModel user) + { + var existingUser = Repo.Get(user.UserGuid); + + user.Id = existingUser.Id; + user.UserGuid = existingUser.UserGuid; + Repo.Update(user); + return user; + } + public bool DoUsersExist() { var users = Repo.GetAll(); @@ -88,7 +98,7 @@ namespace PlexRequests.Core return users.Any(); } - public Guid? CreateUser(string username, string password, string[] claims = default(string[])) + private Guid? CreateUser(string username, string password, string[] claims = default(string[])) { var salt = PasswordHasher.GenerateSalt(); @@ -108,6 +118,21 @@ namespace PlexRequests.Core return new Guid(userRecord.UserGuid); } + public Guid? CreateAdmin(string username, string password) + { + return CreateUser(username, password, new[] { UserClaims.User, UserClaims.PowerUser, UserClaims.Admin }); + } + + public Guid? CreatePowerUser(string username, string password) + { + return CreateUser(username, password, new[] { UserClaims.User, UserClaims.PowerUser }); + } + + public Guid? CreateRegularUser(string username, string password) + { + return CreateUser(username, password, new[] { UserClaims.User }); + } + public bool UpdatePassword(string username, string oldPassword, string newPassword) { var users = Repo.GetAll(); @@ -134,15 +159,25 @@ namespace PlexRequests.Core { return Repo.GetAll(); } + + public UsersModel GetUser(Guid userId) + { + var user = Repo.Get(userId.ToString()); + return user; + } } public interface ICustomUserMapper { IEnumerable GetUsers(); - Guid? CreateUser(string username, string password, string[] claims = default(string[])); + UsersModel GetUser(Guid userId); + UsersModel EditUser(UsersModel user); bool DoUsersExist(); Guid? ValidateUser(string username, string password); bool UpdatePassword(string username, string oldPassword, string newPassword); + Guid? CreateAdmin(string username, string password); + Guid? CreatePowerUser(string username, string password); + Guid? CreateRegularUser(string username, string password); } } diff --git a/PlexRequests.Helpers.Tests/PasswordHasherTests.cs b/PlexRequests.Helpers.Tests/PasswordHasherTests.cs index 500d07534..2ac54a547 100644 --- a/PlexRequests.Helpers.Tests/PasswordHasherTests.cs +++ b/PlexRequests.Helpers.Tests/PasswordHasherTests.cs @@ -24,7 +24,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ************************************************************************/ #endregion -using System.Diagnostics; using NUnit.Framework; @@ -41,7 +40,7 @@ namespace PlexRequests.Helpers.Tests var hash = PasswordHasher.ComputeHash(password, salt); Assert.That(hash, Is.Not.EqualTo(password)); - + var match = PasswordHasher.VerifyPassword(password, salt, hash); Assert.That(match, Is.True); diff --git a/PlexRequests.Helpers.Tests/PlexRequests.Helpers.Tests.csproj b/PlexRequests.Helpers.Tests/PlexRequests.Helpers.Tests.csproj index bb9e7143b..9f3adbd0d 100644 --- a/PlexRequests.Helpers.Tests/PlexRequests.Helpers.Tests.csproj +++ b/PlexRequests.Helpers.Tests/PlexRequests.Helpers.Tests.csproj @@ -8,7 +8,7 @@ Properties PlexRequests.Helpers.Tests PlexRequests.Helpers.Tests - v4.6 + v4.5 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10.0 @@ -16,6 +16,7 @@ $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages False UnitTest + true diff --git a/PlexRequests.Helpers.Tests/UriHelperTests.cs b/PlexRequests.Helpers.Tests/UriHelperTests.cs index 93fb32997..cc748f95c 100644 --- a/PlexRequests.Helpers.Tests/UriHelperTests.cs +++ b/PlexRequests.Helpers.Tests/UriHelperTests.cs @@ -26,7 +26,8 @@ #endregion using System; -using System.Linq.Expressions; +using System.Collections.Generic; + using NUnit.Framework; namespace PlexRequests.Helpers.Tests @@ -35,11 +36,9 @@ namespace PlexRequests.Helpers.Tests public class UriHelperTests { [TestCaseSource(nameof(UriData))] - public void CreateUri1(string uri, Uri expected) + public Uri CreateUri1(string uri) { - var result = uri.ReturnUri(); - - Assert.That(result, Is.EqualTo(expected)); + return uri.ReturnUri(); } [Test] @@ -52,54 +51,58 @@ namespace PlexRequests.Helpers.Tests } [TestCaseSource(nameof(UriDataWithPort))] - public void CreateUri2(string uri, int port, Uri expected) + public Uri CreateUri2(string uri, int port) { - var result = uri.ReturnUri(port); - - Assert.That(result, Is.EqualTo(expected)); + return uri.ReturnUri(port); } [TestCaseSource(nameof(UriDataWithSubDir))] - public void CreateUriWithSubDir(string uri, int port, bool ssl, string subDir, Uri expected) + public Uri CreateUriWithSubDir(string uri, int port, bool ssl, string subDir) { - var result = uri.ReturnUriWithSubDir(port, ssl, subDir); - - Assert.That(result, Is.EqualTo(expected)); + return uri.ReturnUriWithSubDir(port, ssl, subDir); } - static readonly object[] UriData = + private static IEnumerable UriData { - new object[] { "google.com", new Uri("http://google.com/"), }, - new object[] { "http://google.com", new Uri("http://google.com/"), }, - new object[] { "https://google.com", new Uri("https://google.com/"), }, - new object[] { "192.168.1.1", new Uri("http://192.168.1.1")}, - new object[] { "0.0.0.0:5533", new Uri("http://0.0.0.0:5533")}, - new object[] {"www.google.com", new Uri("http://www.google.com/")}, - new object[] {"http://www.google.com/", new Uri("http://www.google.com/") }, - new object[] {"https://www.google.com", new Uri("https://www.google.com/") }, - new object[] {"www.google.com:443", new Uri("http://www.google.com:443/") }, - new object[] {"https://www.google.com:443", new Uri("https://www.google.com:443/") }, - new object[] {"http://www.google.com:443/id=2", new Uri("http://www.google.com:443/id=2") }, - new object[] {"www.google.com:4438/id=22", new Uri("http://www.google.com:4438/id=22") } - }; + get + { + yield return new TestCaseData("google.com").Returns(new Uri("http://google.com/")); + yield return new TestCaseData("http://google.com").Returns(new Uri("http://google.com/")); + yield return new TestCaseData("https://google.com").Returns(new Uri("https://google.com/")); + yield return new TestCaseData("192.168.1.1").Returns(new Uri("http://192.168.1.1")); + yield return new TestCaseData("0.0.0.0:5533").Returns(new Uri("http://0.0.0.0:5533")); + yield return new TestCaseData("www.google.com").Returns(new Uri("http://www.google.com/")); + yield return new TestCaseData("http://www.google.com/").Returns(new Uri("http://www.google.com/")); + yield return new TestCaseData("https://www.google.com").Returns(new Uri("https://www.google.com/")); + yield return new TestCaseData("www.google.com:443").Returns(new Uri("http://www.google.com:443/")); + yield return new TestCaseData("https://www.google.com:443").Returns(new Uri("https://www.google.com/")); + yield return new TestCaseData("http://www.google.com:443/id=2").Returns(new Uri("http://www.google.com:443/id=2")); + yield return new TestCaseData("www.google.com:4438/id=22").Returns(new Uri("http://www.google.com:4438/id=22")); + } + } - static readonly object[] UriDataWithPort = + private static IEnumerable UriDataWithPort { - new object[] {"www.google.com", 80, new Uri("http://www.google.com:80/"), }, - new object[] {"www.google.com", 443, new Uri("http://www.google.com:443/") }, - new object[] {"http://www.google.com", 443, new Uri("http://www.google.com:443/") }, - new object[] {"https://www.google.com", 443, new Uri("https://www.google.com:443/") }, - new object[] {"http://www.google.com/id=2", 443, new Uri("http://www.google.com:443/id=2") }, - new object[] {"http://www.google.com/id=2", 443, new Uri("http://www.google.com:443/id=2") }, - new object[] {"https://www.google.com/id=2", 443, new Uri("https://www.google.com:443/id=2") }, - }; + get + { + yield return new TestCaseData("www.google.com", 80).Returns(new Uri("http://www.google.com:80/")); + yield return new TestCaseData("www.google.com", 443).Returns(new Uri("http://www.google.com:443/")); + yield return new TestCaseData("http://www.google.com", 443).Returns(new Uri("http://www.google.com:443/")); + yield return new TestCaseData("https://www.google.com", 443).Returns(new Uri("https://www.google.com:443/")); + yield return new TestCaseData("http://www.google.com/id=2", 443).Returns(new Uri("http://www.google.com:443/id=2")); + yield return new TestCaseData("https://www.google.com/id=2", 443).Returns(new Uri("https://www.google.com:443/id=2")); + } + } - static readonly object[] UriDataWithSubDir = -{ - new object[] {"www.google.com", 80, false,"test", new Uri("http://www.google.com:80/test"), }, - new object[] {"www.google.com", 443, false,"test", new Uri("http://www.google.com:443/test") }, - new object[] {"http://www.google.com", 443, true,"test", new Uri("https://www.google.com:443/test") }, - new object[] {"https://www.google.com", 443,true,"test", new Uri("https://www.google.com:443/test") }, - }; + private static IEnumerable UriDataWithSubDir + { + get + { + yield return new TestCaseData("www.google.com", 80, false, "test").Returns(new Uri("http://www.google.com:80/test")); + yield return new TestCaseData("www.google.com", 443, false, "test").Returns(new Uri("http://www.google.com:443/test")); + yield return new TestCaseData("http://www.google.com", 443, true, "test").Returns(new Uri("https://www.google.com:443/test")); + yield return new TestCaseData("https://www.google.com", 443, true, "test").Returns(new Uri("https://www.google.com:443/test")); + } + } } } \ No newline at end of file diff --git a/PlexRequests.Helpers.Tests/app.config b/PlexRequests.Helpers.Tests/app.config index 6a9f5188b..1911601e2 100644 --- a/PlexRequests.Helpers.Tests/app.config +++ b/PlexRequests.Helpers.Tests/app.config @@ -1,15 +1,15 @@ - + - - + + - - + + - \ No newline at end of file + diff --git a/PlexRequests.Helpers/ICacheProvider.cs b/PlexRequests.Helpers/ICacheProvider.cs index fa957315d..00fde411b 100644 --- a/PlexRequests.Helpers/ICacheProvider.cs +++ b/PlexRequests.Helpers/ICacheProvider.cs @@ -25,6 +25,7 @@ // ************************************************************************/ #endregion using System; +using System.Threading.Tasks; namespace PlexRequests.Helpers { @@ -40,6 +41,7 @@ namespace PlexRequests.Helpers /// The amount of time we want to cache the object /// T GetOrSet(string key, Func itemCallback, int cacheTime = 20) where T : class; + Task GetOrSetAsync(string key, Func> itemCallback, int cacheTime = 20) where T : class; /// /// Gets the specified item from the cache. diff --git a/PlexRequests.Helpers/MemoryCacheProvider.cs b/PlexRequests.Helpers/MemoryCacheProvider.cs index fdb78f291..c85ef40f0 100644 --- a/PlexRequests.Helpers/MemoryCacheProvider.cs +++ b/PlexRequests.Helpers/MemoryCacheProvider.cs @@ -27,6 +27,7 @@ using System; using System.Linq; using System.Runtime.Caching; +using System.Threading.Tasks; namespace PlexRequests.Helpers { @@ -65,6 +66,23 @@ namespace PlexRequests.Helpers return item.CloneJson(); } + public async Task GetOrSetAsync(string key, Func> itemCallback, int cacheTime = 20) where T : class + { + var item = Get(key); + if (item == null) + { + item = await itemCallback(); + if (item != null) + { + Set(key, item, cacheTime); + } + } + + // Return a copy, not the stored cache reference + // The cached object will not change + return item.CloneJson(); + } + /// /// Gets the specified item from the cache. /// diff --git a/PlexRequests.Services/Jobs/CouchPotatoCacher.cs b/PlexRequests.Services/Jobs/CouchPotatoCacher.cs index 6b905a9b3..3fb831b12 100644 --- a/PlexRequests.Services/Jobs/CouchPotatoCacher.cs +++ b/PlexRequests.Services/Jobs/CouchPotatoCacher.cs @@ -87,7 +87,7 @@ namespace PlexRequests.Services.Jobs public int[] QueuedIds() { var movies = Cache.Get(CacheKeys.CouchPotatoQueued); - return movies?.movies.Select(x => x.info.tmdb_id).ToArray() ?? new int[] { }; + return movies?.movies?.Select(x => x.info.tmdb_id).ToArray() ?? new int[] { }; } public void Execute(IJobExecutionContext context) diff --git a/PlexRequests.Services/Jobs/JobNames.cs b/PlexRequests.Services/Jobs/JobNames.cs index d996ac01e..ff6791d92 100644 --- a/PlexRequests.Services/Jobs/JobNames.cs +++ b/PlexRequests.Services/Jobs/JobNames.cs @@ -24,7 +24,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ************************************************************************/ #endregion -namespace PlexRequests.Services +namespace PlexRequests.Services.Jobs { public static class JobNames { @@ -33,5 +33,6 @@ namespace PlexRequests.Services public const string SonarrCacher = "Sonarr Cacher"; public const string SrCacher = "SickRage Cacher"; public const string PlexChecker = "Plex Availability Cacher"; + public const string StoreCleanup = "Database Cleanup"; } } \ No newline at end of file diff --git a/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs b/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs index d6bd244ca..b22961317 100644 --- a/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs +++ b/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs @@ -326,33 +326,36 @@ namespace PlexRequests.Services.Jobs try { var plexUser = PlexApi.GetUsers(apiKey); - if (plexUser?.User == null || plexUser.User.Length == 0) - { - return; - } + var userAccount = PlexApi.GetAccount(apiKey); + + var adminUsername = userAccount.Username ?? string.Empty; var users = UserNotifyRepo.GetAll().ToList(); + Log.Debug("Notifying Users Count {0}", users.Count); foreach (var model in modelChanged) { var selectedUsers = users.Select(x => x.Username).Intersect(model.RequestedUsers); + Log.Debug("Selected Users {0}", selectedUsers.DumpJson()); foreach (var user in selectedUsers) { + Log.Info("Notifying user {0}", user); + if (user == adminUsername) + { + Log.Info("This user is the Plex server owner"); + PublishUserNotification(userAccount.Username, userAccount.Email, model.Title); + return; + } + var email = plexUser.User.FirstOrDefault(x => x.Username == user); if (email == null) { + Log.Info("There is no email address for this Plex user, cannot send notification"); // We do not have a plex user that requested this! continue; } - var notificationModel = new NotificationModel - { - User = email.Username, - UserEmail = email.Email, - NotificationType = NotificationType.RequestAvailable, - Title = model.Title - }; - - // Send the notification to the user. - Notification.Publish(notificationModel); + + Log.Info("Sending notification to: {0} at: {1}, for title: {2}", email.Username, email.Email, model.Title); + PublishUserNotification(email.Username, email.Email, model.Title); } } } @@ -362,6 +365,20 @@ namespace PlexRequests.Services.Jobs } } + private void PublishUserNotification(string username, string email, string title) + { + var notificationModel = new NotificationModel + { + User = username, + UserEmail = email, + NotificationType = NotificationType.RequestAvailable, + Title = title + }; + + // Send the notification to the user. + Notification.Publish(notificationModel); + } + public void Execute(IJobExecutionContext context) { CheckAndUpdateAll(); diff --git a/PlexRequests.Services/Jobs/SickRageCacher.cs b/PlexRequests.Services/Jobs/SickRageCacher.cs index 69b50b358..cece5100d 100644 --- a/PlexRequests.Services/Jobs/SickRageCacher.cs +++ b/PlexRequests.Services/Jobs/SickRageCacher.cs @@ -87,7 +87,7 @@ namespace PlexRequests.Services.Jobs public int[] QueuedIds() { var tv = Cache.Get(CacheKeys.SickRageQueued); - return tv?.data.Values.Select(x => x.tvdbid).ToArray() ?? new int[] { }; + return tv?.data?.Values.Select(x => x.tvdbid).ToArray() ?? new int[] { }; } public void Execute(IJobExecutionContext context) diff --git a/PlexRequests.Services/Jobs/StoreBackup.cs b/PlexRequests.Services/Jobs/StoreBackup.cs index 1009e0daf..e36f73eb4 100644 --- a/PlexRequests.Services/Jobs/StoreBackup.cs +++ b/PlexRequests.Services/Jobs/StoreBackup.cs @@ -26,15 +26,11 @@ #endregion using System; using System.IO; -using System.Linq; -using System.Globalization; using NLog; using PlexRequests.Services.Interfaces; using PlexRequests.Store; -using PlexRequests.Store.Models; -using PlexRequests.Store.Repository; using Quartz; @@ -57,7 +53,7 @@ namespace PlexRequests.Services.Jobs public void Execute(IJobExecutionContext context) { TakeBackup(); - Cleanup (); + Cleanup(); } private void TakeBackup() @@ -81,11 +77,11 @@ namespace PlexRequests.Services.Jobs try { - if(DoWeNeedToBackup(backupDir.FullName)) - { - File.Copy(dbPath, Path.Combine(backupDir.FullName, $"PlexRequests.sqlite_{DateTime.Now.ToString("yyyy-MM-dd hh.mm.ss")}.bak")); - } - } + if (DoWeNeedToBackup(backupDir.FullName)) + { + File.Copy(dbPath, Path.Combine(backupDir.FullName, $"PlexRequests.sqlite_{DateTime.Now.ToString("yyyy-MM-dd hh.mm.ss")}.bak")); + } + } catch (Exception e) { Log.Warn(e); @@ -98,53 +94,58 @@ namespace PlexRequests.Services.Jobs } - private void Cleanup() - { - Log.Trace("Starting DB Cleanup"); - var dbPath = Sql.CurrentPath; - var dir = Path.GetDirectoryName(dbPath); - if (dir == null) - { - Log.Warn("We couldn't find the DB path. We cannot backup."); - return; - } - var backupDir = Directory.CreateDirectory(Path.Combine(dir, "Backup")); - - var files = backupDir.GetFiles(); - - foreach (var file in files) { - var dt = ParseName(file.Name); - if(dt < DateTime.Now.AddDays(-7)){ - try { - - File.Delete(file.FullName); - } catch (Exception ex) { - Log.Error(ex); - } - } - } - - } - - private bool DoWeNeedToBackup(string backupPath) - { - var files = Directory.GetFiles(backupPath); - //TODO Get the latest file and if it's within an hour of DateTime.Now then don't bother backing up. - return true; - } - - private DateTime ParseName(string fileName) - { - var names = fileName.Split(new []{'_','.',' '}, StringSplitOptions.RemoveEmptyEntries); - if(names.Count() > 1) - { - DateTime parsed; - //DateTime.TryParseExcat(names[1], "yyyy-MM-dd hh.mm.ss",CultureInfo.CurrentUICulture, DateTimeStyles.None, out parsed); - DateTime.TryParse(names[2], out parsed); - return parsed; - - } - return DateTime.MinValue; - } + private void Cleanup() + { + Log.Trace("Starting DB Cleanup"); + var dbPath = Sql.CurrentPath; + var dir = Path.GetDirectoryName(dbPath); + if (dir == null) + { + Log.Warn("We couldn't find the DB path. We cannot backup."); + return; + } + var backupDir = Directory.CreateDirectory(Path.Combine(dir, "Backup")); + + var files = backupDir.GetFiles(); + + foreach (var file in files) + { + var dt = ParseName(file.Name); + if (dt < DateTime.Now.AddDays(-7)) + { + try + { + + File.Delete(file.FullName); + } + catch (Exception ex) + { + Log.Error(ex); + } + } + } + + } + + private bool DoWeNeedToBackup(string backupPath) + { + var files = Directory.GetFiles(backupPath); + //TODO Get the latest file and if it's within an hour of DateTime.Now then don't bother backing up. + return true; + } + + private DateTime ParseName(string fileName) + { + var names = fileName.Split(new[] { '_', '.', ' ' }, StringSplitOptions.RemoveEmptyEntries); + if (names.Length > 1) + { + DateTime parsed; + //DateTime.TryParseExcat(names[1], "yyyy-MM-dd hh.mm.ss",CultureInfo.CurrentUICulture, DateTimeStyles.None, out parsed); + DateTime.TryParse(names[2], out parsed); + return parsed; + + } + return DateTime.MinValue; + } } } \ No newline at end of file diff --git a/PlexRequests.Services/Jobs/StoreCleanup.cs b/PlexRequests.Services/Jobs/StoreCleanup.cs new file mode 100644 index 000000000..a394211f5 --- /dev/null +++ b/PlexRequests.Services/Jobs/StoreCleanup.cs @@ -0,0 +1,82 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: StoreCleanup.cs +// Created By: Jamie Rees +// +// 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. +// ************************************************************************/ +#endregion +using System; +using System.Linq; + +using NLog; + +using PlexRequests.Services.Interfaces; +using PlexRequests.Store.Models; +using PlexRequests.Store.Repository; + +using Quartz; + +namespace PlexRequests.Services.Jobs +{ + public class StoreCleanup : IJob + { + private static readonly Logger Log = LogManager.GetCurrentClassLogger(); + + public StoreCleanup(IRepository repo, IJobRecord rec) + { + Repo = repo; + JobRecord = rec; + } + + private IJobRecord JobRecord { get; } + + private IRepository Repo { get; } + + private void Cleanup() + { + try + { + var items = Repo.GetAll(); + var orderedItems = items.Where(x => x.Date < DateTime.Now.AddDays(-7)); + + foreach (var o in orderedItems) + { + Repo.Delete(o); + } + } + catch (Exception e) + { + Log.Error(e); + } + finally + { + JobRecord.Record(JobNames.StoreCleanup); + } + + } + + public void Execute(IJobExecutionContext context) + { + Cleanup(); + } + } +} \ No newline at end of file diff --git a/PlexRequests.Services/Notification/EmailMessageNotification.cs b/PlexRequests.Services/Notification/EmailMessageNotification.cs index f2217dc7e..20ef3f612 100644 --- a/PlexRequests.Services/Notification/EmailMessageNotification.cs +++ b/PlexRequests.Services/Notification/EmailMessageNotification.cs @@ -62,7 +62,10 @@ namespace PlexRequests.Services.Notification var emailSettings = (EmailNotificationSettings)settings; - if (!ValidateConfiguration(emailSettings)) return; + if (!ValidateConfiguration(emailSettings)) + { + return; + } switch (model.NotificationType) { @@ -96,13 +99,17 @@ namespace PlexRequests.Services.Notification private bool ValidateConfiguration(EmailNotificationSettings settings) { - if (!settings.Enabled) + if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString())) { return false; } - if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString())) + + if (!settings.EnableUserEmailNotifications) { - return false; + if (!settings.Enabled) + { + return false; + } } return true; diff --git a/PlexRequests.Services/Notification/NotificationService.cs b/PlexRequests.Services/Notification/NotificationService.cs index 3e52e43fa..79e5dcb51 100644 --- a/PlexRequests.Services/Notification/NotificationService.cs +++ b/PlexRequests.Services/Notification/NotificationService.cs @@ -76,7 +76,7 @@ namespace PlexRequests.Services.Notification Observers.TryRemove(notification.NotificationName, out notification); } - private static async Task NotifyAsync(INotification notification, NotificationModel model) + private async Task NotifyAsync(INotification notification, NotificationModel model) { try { @@ -89,7 +89,7 @@ namespace PlexRequests.Services.Notification } - private static async Task NotifyAsync(INotification notification, NotificationModel model, Settings settings) + private async Task NotifyAsync(INotification notification, NotificationModel model, Settings settings) { try { diff --git a/PlexRequests.Services/PlexRequests.Services.csproj b/PlexRequests.Services/PlexRequests.Services.csproj index 257fc5b7e..caafe8d77 100644 --- a/PlexRequests.Services/PlexRequests.Services.csproj +++ b/PlexRequests.Services/PlexRequests.Services.csproj @@ -73,6 +73,7 @@ + diff --git a/PlexRequests.Store/PlexRequests.Store.csproj b/PlexRequests.Store/PlexRequests.Store.csproj index 19578aee5..c5dd29053 100644 --- a/PlexRequests.Store/PlexRequests.Store.csproj +++ b/PlexRequests.Store/PlexRequests.Store.csproj @@ -31,11 +31,20 @@ 4 + + ..\packages\Dapper.1.50.0-beta8\lib\net45\Dapper.dll + True + + + ..\packages\Dapper.Contrib.1.50.0-beta8\lib\net45\Dapper.Contrib.dll + True + ..\Assemblies\Mono.Data.Sqlite.dll + @@ -43,12 +52,6 @@ - - ..\packages\Dapper.1.42\lib\net45\Dapper.dll - - - ..\packages\Dapper.Contrib.1.43\lib\net45\Dapper.Contrib.dll - ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll @@ -61,6 +64,7 @@ + diff --git a/PlexRequests.Store/Repository/BaseGenericRepository.cs b/PlexRequests.Store/Repository/BaseGenericRepository.cs new file mode 100644 index 000000000..ac8c45203 --- /dev/null +++ b/PlexRequests.Store/Repository/BaseGenericRepository.cs @@ -0,0 +1,179 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: BaseGenericRepository.cs +// Created By: Jamie Rees +// +// 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. +// ************************************************************************/ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Dapper.Contrib.Extensions; +using NLog; +using PlexRequests.Helpers; + +namespace PlexRequests.Store.Repository +{ + public abstract class BaseGenericRepository where T : class + { + protected BaseGenericRepository(ISqliteConfiguration config, ICacheProvider cache) + { + Config = config; + Cache = cache; + } + protected ICacheProvider Cache { get; } + protected ISqliteConfiguration Config { get; } + private static readonly Logger Log = LogManager.GetCurrentClassLogger(); + public abstract T Get(string id); + public abstract Task GetAsync(int id); + public abstract T Get(int id); + public abstract Task GetAsync(string id); + + public long Insert(T entity) + { + ResetCache(); + using (var cnn = Config.DbConnection()) + { + cnn.Open(); + return cnn.Insert(entity); + } + } + + public void Delete(T entity) + { + ResetCache(); + using (var db = Config.DbConnection()) + { + db.Open(); + db.Delete(entity); + } + } + + public async Task DeleteAsync(T entity) + { + ResetCache(); + using (var db = Config.DbConnection()) + { + db.Open(); + await db.DeleteAsync(entity); + } + } + + public bool Update(T entity) + { + ResetCache(); + Log.Trace("Updating entity"); + Log.Trace(entity.DumpJson()); + using (var db = Config.DbConnection()) + { + db.Open(); + return db.Update(entity); + } + } + + public async Task UpdateAsync(T entity) + { + ResetCache(); + Log.Trace("Updating entity"); + Log.Trace(entity.DumpJson()); + using (var db = Config.DbConnection()) + { + db.Open(); + return await db.UpdateAsync(entity); + } + } + + public bool UpdateAll(IEnumerable entity) + { + ResetCache(); + Log.Trace("Updating all entities"); + var result = new HashSet(); + + using (var db = Config.DbConnection()) + { + db.Open(); + foreach (var e in entity) + { + result.Add(db.Update(e)); + } + } + return result.All(x => true); + } + + public async Task UpdateAllAsync(IEnumerable entity) + { + ResetCache(); + Log.Trace("Updating all entities"); + var result = new HashSet(); + + using (var db = Config.DbConnection()) + { + db.Open(); + foreach (var e in entity) + { + result.Add(await db.UpdateAsync(e)); + } + } + return result.All(x => true); + } + + public async Task InsertAsync(T entity) + { + ResetCache(); + using (var cnn = Config.DbConnection()) + { + cnn.Open(); + return await cnn.InsertAsync(entity); + } + } + + private void ResetCache() + { + Cache.Remove("Get"); + Cache.Remove("GetAll"); + } + public IEnumerable GetAll() + { + + using (var db = Config.DbConnection()) + { + db.Open(); + var result = db.GetAll(); + return result; + } + + } + public async Task> GetAllAsync() + { + + using (var db = Config.DbConnection()) + { + db.Open(); + var result = await db.GetAllAsync(); + return result; + } + + } + } +} \ No newline at end of file diff --git a/PlexRequests.Store/Repository/GenericRepository.cs b/PlexRequests.Store/Repository/GenericRepository.cs index 17e7b9c0f..6fb1e8216 100644 --- a/PlexRequests.Store/Repository/GenericRepository.cs +++ b/PlexRequests.Store/Repository/GenericRepository.cs @@ -1,4 +1,5 @@ #region Copyright + // /************************************************************************ // Copyright (c) 2016 Jamie Rees // File: GenericRepository.cs @@ -23,59 +24,38 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ************************************************************************/ + #endregion + using System; using System.Collections.Generic; using System.Linq; - +using System.Threading.Tasks; using Dapper.Contrib.Extensions; - using NLog; - using PlexRequests.Helpers; namespace PlexRequests.Store.Repository { - public class GenericRepository : IRepository where T : Entity + public class GenericRepository : BaseGenericRepository, IRepository where T : Entity { - private ICacheProvider Cache { get; } - public GenericRepository(ISqliteConfiguration config, ICacheProvider cache) - { - Config = config; - Cache = cache; - } - - private static Logger Log = LogManager.GetCurrentClassLogger(); - - private ISqliteConfiguration Config { get; } - public long Insert(T entity) + + public GenericRepository(ISqliteConfiguration config, ICacheProvider cache) : base(config, cache) { - ResetCache(); - using (var cnn = Config.DbConnection()) - { - cnn.Open(); - return cnn.Insert(entity); - } + } - - public IEnumerable GetAll() + + public override T Get(string id) { - - using (var db = Config.DbConnection()) - { - db.Open(); - var result = db.GetAll(); - return result; - } - + throw new NotSupportedException("Get(string) is not supported. Use Get(int)"); } - public T Get(string id) + public override Task GetAsync(string id) { - throw new NotSupportedException("Get(string) is not supported. Use Get(int)"); + throw new NotSupportedException("GetAsync(string) is not supported. Use GetAsync(int)"); } - public T Get(int id) + public override T Get(int id) { var key = "Get" + id; var item = Cache.GetOrSet( @@ -91,49 +71,22 @@ namespace PlexRequests.Store.Repository return item; } - public void Delete(T entity) - { - ResetCache(); - using (var db = Config.DbConnection()) - { - db.Open(); - db.Delete(entity); - } - } - - public bool Update(T entity) - { - ResetCache(); - Log.Trace("Updating entity"); - Log.Trace(entity.DumpJson()); - using (var db = Config.DbConnection()) - { - db.Open(); - return db.Update(entity); - } - } - - public bool UpdateAll(IEnumerable entity) + public override async Task GetAsync(int id) { - ResetCache(); - Log.Trace("Updating all entities"); - var result = new HashSet(); - - using (var db = Config.DbConnection()) - { - db.Open(); - foreach (var e in entity) + var key = "Get" + id; + var item = await Cache.GetOrSetAsync( + key, + async () => { - result.Add(db.Update(e)); - } - } - return result.All(x => true); + using (var db = Config.DbConnection()) + { + db.Open(); + return await db.GetAsync(id); + } + }); + return item; } - private void ResetCache() - { - Cache.Remove("Get"); - Cache.Remove("GetAll"); - } + } -} +} \ No newline at end of file diff --git a/PlexRequests.Store/Repository/IRepository.cs b/PlexRequests.Store/Repository/IRepository.cs index 4d301047c..15cf2a2c5 100644 --- a/PlexRequests.Store/Repository/IRepository.cs +++ b/PlexRequests.Store/Repository/IRepository.cs @@ -25,6 +25,7 @@ // ************************************************************************/ #endregion using System.Collections.Generic; +using System.Threading.Tasks; namespace PlexRequests.Store.Repository { @@ -35,12 +36,15 @@ namespace PlexRequests.Store.Repository /// /// The entity. long Insert(T entity); + Task InsertAsync(T entity); /// /// Gets all. /// /// IEnumerable GetAll(); + Task> GetAllAsync(); + /// /// Gets the specified identifier. @@ -48,12 +52,15 @@ namespace PlexRequests.Store.Repository /// The identifier. /// T Get(string id); + Task GetAsync(string id); T Get(int id); + Task GetAsync(int id); /// /// Deletes the specified entity. /// /// The entity. void Delete(T entity); + Task DeleteAsync(T entity); /// /// Updates the specified entity. @@ -61,6 +68,7 @@ namespace PlexRequests.Store.Repository /// The entity. /// bool Update(T entity); + Task UpdateAsync(T entity); /// /// Updates all. @@ -68,5 +76,6 @@ namespace PlexRequests.Store.Repository /// The entity. /// bool UpdateAll(IEnumerable entity); + Task UpdateAllAsync(IEnumerable entity); } } diff --git a/PlexRequests.Store/Repository/IRequestRepository.cs b/PlexRequests.Store/Repository/IRequestRepository.cs index 809628c51..440fe715e 100644 --- a/PlexRequests.Store/Repository/IRequestRepository.cs +++ b/PlexRequests.Store/Repository/IRequestRepository.cs @@ -25,6 +25,7 @@ // ************************************************************************/ #endregion using System.Collections.Generic; +using System.Threading.Tasks; using PlexRequests.Store.Models; @@ -38,13 +39,18 @@ namespace PlexRequests.Store.Repository /// The entity. long Insert(RequestBlobs entity); + Task InsertAsync(RequestBlobs entity); + /// /// Gets all. /// /// IEnumerable GetAll(); + Task> GetAllAsync(); + RequestBlobs Get(int id); + Task GetAsync(int id); /// /// Deletes the specified entity. @@ -52,6 +58,10 @@ namespace PlexRequests.Store.Repository /// The entity. /// bool Delete(RequestBlobs entity); + Task DeleteAsync(RequestBlobs entity); + + bool DeleteAll(IEnumerable entity); + Task DeleteAllAsync(IEnumerable entity); /// /// Updates the specified entity. @@ -59,7 +69,9 @@ namespace PlexRequests.Store.Repository /// The entity. /// bool Update(RequestBlobs entity); + Task UpdateAsync(RequestBlobs entity); bool UpdateAll(IEnumerable entity); + Task UpdateAllAsync(IEnumerable entity); } } \ No newline at end of file diff --git a/PlexRequests.Store/Repository/ISettingsRepository.cs b/PlexRequests.Store/Repository/ISettingsRepository.cs index 393da6ef7..3f6761c66 100644 --- a/PlexRequests.Store/Repository/ISettingsRepository.cs +++ b/PlexRequests.Store/Repository/ISettingsRepository.cs @@ -25,7 +25,7 @@ // ************************************************************************/ #endregion using System.Collections.Generic; - +using System.Threading.Tasks; using PlexRequests.Store.Models; namespace PlexRequests.Store.Repository @@ -37,12 +37,14 @@ namespace PlexRequests.Store.Repository /// /// The entity. long Insert(GlobalSettings entity); + Task InsertAsync(GlobalSettings entity); /// /// Gets all. /// /// IEnumerable GetAll(); + Task> GetAllAsync(); /// /// Gets the specified identifier. @@ -50,12 +52,14 @@ namespace PlexRequests.Store.Repository /// Name of the settings. /// GlobalSettings Get(string settingsName); + Task GetAsync(string settingsName); /// /// Deletes the specified entity. /// /// The entity. /// + Task DeleteAsync(GlobalSettings entity); bool Delete(GlobalSettings entity); /// @@ -63,6 +67,7 @@ namespace PlexRequests.Store.Repository /// /// The entity. /// + Task UpdateAsync(GlobalSettings entity); bool Update(GlobalSettings entity); diff --git a/PlexRequests.Store/Repository/RequestJsonRepository.cs b/PlexRequests.Store/Repository/RequestJsonRepository.cs index 872e07745..07ac3c0bd 100644 --- a/PlexRequests.Store/Repository/RequestJsonRepository.cs +++ b/PlexRequests.Store/Repository/RequestJsonRepository.cs @@ -26,6 +26,7 @@ #endregion using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Dapper.Contrib.Extensions; @@ -56,6 +57,16 @@ namespace PlexRequests.Store.Repository } } + public async Task InsertAsync(RequestBlobs entity) + { + ResetCache(); + using (var con = Db.DbConnection()) + { + var id = await con.InsertAsync(entity); + return id; + } + } + public IEnumerable GetAll() { var key = "GetAll"; @@ -70,6 +81,20 @@ namespace PlexRequests.Store.Repository return item; } + public async Task> GetAllAsync() + { + var key = "GetAll"; + var item = await Cache.GetOrSetAsync(key, async() => + { + using (var con = Db.DbConnection()) + { + var page = await con.GetAllAsync(); + return page; + } + }, 5); + return item; + } + public RequestBlobs Get(int id) { var key = "Get" + id; @@ -84,6 +109,20 @@ namespace PlexRequests.Store.Repository return item; } + public async Task GetAsync(int id) + { + var key = "Get" + id; + var item = await Cache.GetOrSetAsync(key, async () => + { + using (var con = Db.DbConnection()) + { + var page = await con.GetAsync(id); + return page; + } + }, 5); + return item; + } + public bool Delete(RequestBlobs entity) { ResetCache(); @@ -93,6 +132,30 @@ namespace PlexRequests.Store.Repository } } + public async Task DeleteAsync(RequestBlobs entity) + { + ResetCache(); + using (var con = Db.DbConnection()) + { + return await con.DeleteAsync(entity); + } + } + + public async Task DeleteAllAsync(IEnumerable entity) + { + ResetCache(); + var result = new HashSet(); + using (var db = Db.DbConnection()) + { + db.Open(); + foreach (var e in entity) + { + result.Add(await db.DeleteAsync(e)); + } + } + return result.All(x => true); + } + public bool Update(RequestBlobs entity) { ResetCache(); @@ -102,6 +165,15 @@ namespace PlexRequests.Store.Repository } } + public async Task UpdateAsync(RequestBlobs entity) + { + ResetCache(); + using (var con = Db.DbConnection()) + { + return await con.UpdateAsync(entity); + } + } + private void ResetCache() { Cache.Remove("Get"); @@ -122,5 +194,35 @@ namespace PlexRequests.Store.Repository } return result.All(x => true); } + + public async Task UpdateAllAsync(IEnumerable entity) + { + ResetCache(); + var result = new HashSet(); + using (var db = Db.DbConnection()) + { + db.Open(); + foreach (var e in entity) + { + result.Add(await db.UpdateAsync(e)); + } + } + return result.All(x => true); + } + + public bool DeleteAll(IEnumerable entity) + { + ResetCache(); + var result = new HashSet(); + using (var db = Db.DbConnection()) + { + db.Open(); + foreach (var e in entity) + { + result.Add(db.Delete(e)); + } + } + return result.All(x => true); + } } } diff --git a/PlexRequests.Store/Repository/SettingsJsonRepository.cs b/PlexRequests.Store/Repository/SettingsJsonRepository.cs index 64d98f78a..50a59a6af 100644 --- a/PlexRequests.Store/Repository/SettingsJsonRepository.cs +++ b/PlexRequests.Store/Repository/SettingsJsonRepository.cs @@ -26,7 +26,7 @@ #endregion using System.Collections.Generic; using System.Linq; - +using System.Threading.Tasks; using Dapper.Contrib.Extensions; using PlexRequests.Helpers; @@ -57,6 +57,15 @@ namespace PlexRequests.Store.Repository } } + public async Task InsertAsync(GlobalSettings entity) + { + ResetCache(); + using (var con = Db.DbConnection()) + { + return await con.InsertAsync(entity); + } + } + public IEnumerable GetAll() { var key = TypeName + "GetAll"; @@ -71,6 +80,20 @@ namespace PlexRequests.Store.Repository return item; } + public async Task> GetAllAsync() + { + var key = TypeName + "GetAll"; + var item = await Cache.GetOrSetAsync(key, async() => + { + using (var con = Db.DbConnection()) + { + var page = await con.GetAllAsync(); + return page; + } + }, 5); + return item; + } + public GlobalSettings Get(string pageName) { var key = pageName + "Get"; @@ -85,6 +108,38 @@ namespace PlexRequests.Store.Repository return item; } + public async Task GetAsync(string settingsName) + { + var key = settingsName + "Get"; + var item = await Cache.GetOrSetAsync(key, async() => + { + using (var con = Db.DbConnection()) + { + var page = await con.GetAllAsync(); + return page.SingleOrDefault(x => x.SettingsName == settingsName); + } + }, 5); + return item; + } + + public async Task DeleteAsync(GlobalSettings entity) + { + ResetCache(); + using (var con = Db.DbConnection()) + { + return await con.DeleteAsync(entity); + } + } + + public async Task UpdateAsync(GlobalSettings entity) + { + ResetCache(); + using (var con = Db.DbConnection()) + { + return await con.UpdateAsync(entity); + } + } + public bool Delete(GlobalSettings entity) { ResetCache(); diff --git a/PlexRequests.Store/UserRepository.cs b/PlexRequests.Store/UserRepository.cs index 467e0487c..0a938e49f 100644 --- a/PlexRequests.Store/UserRepository.cs +++ b/PlexRequests.Store/UserRepository.cs @@ -27,41 +27,31 @@ using System; using System.Collections.Generic; using System.Linq; - +using System.Threading.Tasks; using Dapper.Contrib.Extensions; - +using PlexRequests.Helpers; using PlexRequests.Store.Repository; namespace PlexRequests.Store { - public class UserRepository : IRepository where T : UserEntity + public class UserRepository : BaseGenericRepository, IRepository where T : UserEntity { - public UserRepository(ISqliteConfiguration config) + public UserRepository(ISqliteConfiguration config, ICacheProvider cache) : base(config, cache) { - Config = config; + } - private ISqliteConfiguration Config { get; } - public long Insert(T entity) + public override T Get(int id) { - using (var cnn = Config.DbConnection()) - { - cnn.Open(); - return cnn.Insert(entity); - } + throw new NotSupportedException("Get(int) is not supported. Use Get(string)"); } - public IEnumerable GetAll() + public override Task GetAsync(int id) { - using (var db = Config.DbConnection()) - { - db.Open(); - var result = db.GetAll(); - return result; - } + throw new NotSupportedException("GetAsync(int) is not supported. Use GetAsync(string)"); } - public T Get(string id) + public override T Get(string id) { using (var db = Config.DbConnection()) { @@ -72,33 +62,18 @@ namespace PlexRequests.Store } } - public T Get(int id) - { - throw new NotSupportedException("Get(int) is not supported. Use Get(string)"); - } - - public void Delete(T entity) + public override async Task GetAsync(string id) { using (var db = Config.DbConnection()) { db.Open(); - db.Delete(entity); + var result = await db.GetAllAsync(); + var selected = result.FirstOrDefault(x => x.UserGuid == id); + return selected; } } - public bool Update(T entity) - { - using (var db = Config.DbConnection()) - { - db.Open(); - return db.Update(entity); - } - } - public bool UpdateAll(IEnumerable entity) - { - throw new NotSupportedException(); - } } } diff --git a/PlexRequests.Store/packages.config b/PlexRequests.Store/packages.config index 0347c0d1b..457f93723 100644 --- a/PlexRequests.Store/packages.config +++ b/PlexRequests.Store/packages.config @@ -1,7 +1,7 @@  - - + + \ No newline at end of file diff --git a/PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.min.css b/PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.min.css deleted file mode 100644 index f2f72839a..000000000 --- a/PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.min.css +++ /dev/null @@ -1 +0,0 @@ -@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#fff;}hr{border-color:#777;}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;border-radius:0;box-shadow:0 0 0 !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li{font-size:13px;line-height:21px;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.nav-tabs>li>a>.fa{padding:3px 5px 3px 3px;}.nav-tabs>li.nav-tab-right{float:right;}.nav-tabs>li.nav-tab-right a{margin-right:0;margin-left:2px;}.nav-tabs>li.nav-tab-icononly .fa{padding:3px;}.navbar .nav a .fa,.dropdown-menu a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.dropdown-menu a .fa{top:2px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;}.scroll-top-wrapper{position:fixed;opacity:0;visibility:hidden;overflow:hidden;text-align:center;z-index:99999999;background-color:#4e5d6c;color:#eee;width:50px;height:48px;line-height:48px;right:30px;bottom:30px;padding-top:2px;border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;}.scroll-top-wrapper:hover{background-color:#637689;}.scroll-top-wrapper.show{visibility:visible;cursor:pointer;opacity:1;}.scroll-top-wrapper i.fa{line-height:inherit;}.no-search-results{text-align:center;}.no-search-results .no-search-results-icon{font-size:10em;color:#4e5d6c;}.no-search-results .no-search-results-text{margin:20px 0;color:#ccc;}.form-control-search{padding:13px 105px 13px 16px;height:100%;}.form-control-withbuttons{padding-right:105px;}.input-group-addon .btn-group{position:absolute;right:45px;z-index:3;top:10px;box-shadow:0 0 0;}.input-group-addon .btn-group .btn{border:1px solid rgba(255,255,255,.7) !important;padding:3px 12px;color:rgba(255,255,255,.7) !important;}.btn-split .btn{border-radius:0 !important;}.btn-split .btn:not(.dropdown-toggle){border-radius:.25rem 0 0 .25rem !important;}.btn-split .btn.dropdown-toggle{border-radius:0 .25rem .25rem 0 !important;padding:12px 8px;}#updateAvailable{background-color:#df691a;text-align:center;font-size:15px;padding:3px 0;}.checkbox label{display:inline-block;cursor:pointer;position:relative;padding-left:25px;margin-right:15px;font-size:13px;margin-bottom:10px;}.checkbox label:before{content:"";display:inline-block;width:18px;height:18px;margin-right:10px;position:absolute;left:0;bottom:1px;border:2px solid #eee;border-radius:3px;}.checkbox input[type=checkbox]{display:none;}.checkbox input[type=checkbox]:checked+label:before{content:"✓";font-size:13px;color:#fafafa;text-align:center;line-height:13px;}.input-group-sm{padding-top:2px;padding-bottom:2px;}.tab-pane .form-horizontal .form-group{margin-right:15px;margin-left:15px;} \ No newline at end of file diff --git a/PlexRequests.UI/Content/Themes/PlexBootstrap.css b/PlexRequests.UI/Content/Themes/PlexBootstrap.css deleted file mode 100644 index 9d88eaa83..000000000 --- a/PlexRequests.UI/Content/Themes/PlexBootstrap.css +++ /dev/null @@ -1,7007 +0,0 @@ -@import url("https://fonts.googleapis.com/css?family=Lato:300,400,700"); -/*! - * bootswatch v3.3.6 - * Homepage: http://bootswatch.com - * Copyright 2012-2016 Thomas Park - * Licensed under MIT - * Based on Bootstrap -*/ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ -html { - font-family: sans-serif; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; -} -body { - margin: 60; -} -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} -audio, -canvas, -progress, -video { - display: inline-block; - vertical-align: baseline; -} -audio:not([controls]) { - display: none; - height: 0; -} -[hidden], -template { - display: none; -} -a { - background-color: transparent; -} -a:active, -a:hover { - outline: 0; -} -abbr[title] { - border-bottom: 1px dotted; -} -b, -strong { - font-weight: bold; -} -dfn { - font-style: italic; -} -h1 { - font-size: 2em; - margin: 0.67em 0; -} -mark { - background: #ff0; - color: #000; -} -small { - font-size: 80%; -} -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sup { - top: -0.5em; -} -sub { - bottom: -0.25em; -} -img { - border: 0; -} -svg:not(:root) { - overflow: hidden; -} -figure { - margin: 1em 40px; -} -hr { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; -} -pre { - overflow: auto; -} -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} -button, -input, -optgroup, -select, -textarea { - color: inherit; - font: inherit; - margin: 0; -} -button { - overflow: visible; -} -button, -select { - text-transform: none; -} -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; - cursor: pointer; -} -button[disabled], -html input[disabled] { - cursor: default; -} -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} -input { - line-height: normal; -} -input[type="checkbox"], -input[type="radio"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 0; -} -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} -input[type="search"] { - -webkit-appearance: textfield; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} -legend { - border: 0; - padding: 0; -} -textarea { - overflow: auto; -} -optgroup { - font-weight: bold; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -td, -th { - padding: 0; -} -/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ -@media print { - *, - *:before, - *:after { - background: transparent !important; - color: #000 !important; - -webkit-box-shadow: none !important; - box-shadow: none !important; - text-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - a[href^="#"]:after, - a[href^="javascript:"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } - .navbar { - display: none; - } - .btn > .caret, - .dropup > .btn > .caret { - border-top-color: #000 !important; - } - .label { - border: 1px solid #000; - } - .table { - border-collapse: collapse !important; - } - .table td, - .table th { - background-color: #fff !important; - } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } -} -@font-face { - font-family: 'Glyphicons Halflings'; - src: url('../Content/fonts/glyphicons-halflings-regular.eot'); - src: url('../Content/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../Content/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../Content/fonts/glyphicons-halflings-regular.woff') format('woff'), url('../Content/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../Content/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); -} -.glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-style: normal; - font-weight: normal; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -.glyphicon-asterisk:before { - content: "\002a"; -} -.glyphicon-plus:before { - content: "\002b"; -} -.glyphicon-euro:before, -.glyphicon-eur:before { - content: "\20ac"; -} -.glyphicon-minus:before { - content: "\2212"; -} -.glyphicon-cloud:before { - content: "\2601"; -} -.glyphicon-envelope:before { - content: "\2709"; -} -.glyphicon-pencil:before { - content: "\270f"; -} -.glyphicon-glass:before { - content: "\e001"; -} -.glyphicon-music:before { - content: "\e002"; -} -.glyphicon-search:before { - content: "\e003"; -} -.glyphicon-heart:before { - content: "\e005"; -} -.glyphicon-star:before { - content: "\e006"; -} -.glyphicon-star-empty:before { - content: "\e007"; -} -.glyphicon-user:before { - content: "\e008"; -} -.glyphicon-film:before { - content: "\e009"; -} -.glyphicon-th-large:before { - content: "\e010"; -} -.glyphicon-th:before { - content: "\e011"; -} -.glyphicon-th-list:before { - content: "\e012"; -} -.glyphicon-ok:before { - content: "\e013"; -} -.glyphicon-remove:before { - content: "\e014"; -} -.glyphicon-zoom-in:before { - content: "\e015"; -} -.glyphicon-zoom-out:before { - content: "\e016"; -} -.glyphicon-off:before { - content: "\e017"; -} -.glyphicon-signal:before { - content: "\e018"; -} -.glyphicon-cog:before { - content: "\e019"; -} -.glyphicon-trash:before { - content: "\e020"; -} -.glyphicon-home:before { - content: "\e021"; -} -.glyphicon-file:before { - content: "\e022"; -} -.glyphicon-time:before { - content: "\e023"; -} -.glyphicon-road:before { - content: "\e024"; -} -.glyphicon-download-alt:before { - content: "\e025"; -} -.glyphicon-download:before { - content: "\e026"; -} -.glyphicon-upload:before { - content: "\e027"; -} -.glyphicon-inbox:before { - content: "\e028"; -} -.glyphicon-play-circle:before { - content: "\e029"; -} -.glyphicon-repeat:before { - content: "\e030"; -} -.glyphicon-refresh:before { - content: "\e031"; -} -.glyphicon-list-alt:before { - content: "\e032"; -} -.glyphicon-lock:before { - content: "\e033"; -} -.glyphicon-flag:before { - content: "\e034"; -} -.glyphicon-headphones:before { - content: "\e035"; -} -.glyphicon-volume-off:before { - content: "\e036"; -} -.glyphicon-volume-down:before { - content: "\e037"; -} -.glyphicon-volume-up:before { - content: "\e038"; -} -.glyphicon-qrcode:before { - content: "\e039"; -} -.glyphicon-barcode:before { - content: "\e040"; -} -.glyphicon-tag:before { - content: "\e041"; -} -.glyphicon-tags:before { - content: "\e042"; -} -.glyphicon-book:before { - content: "\e043"; -} -.glyphicon-bookmark:before { - content: "\e044"; -} -.glyphicon-print:before { - content: "\e045"; -} -.glyphicon-camera:before { - content: "\e046"; -} -.glyphicon-font:before { - content: "\e047"; -} -.glyphicon-bold:before { - content: "\e048"; -} -.glyphicon-italic:before { - content: "\e049"; -} -.glyphicon-text-height:before { - content: "\e050"; -} -.glyphicon-text-width:before { - content: "\e051"; -} -.glyphicon-align-left:before { - content: "\e052"; -} -.glyphicon-align-center:before { - content: "\e053"; -} -.glyphicon-align-right:before { - content: "\e054"; -} -.glyphicon-align-justify:before { - content: "\e055"; -} -.glyphicon-list:before { - content: "\e056"; -} -.glyphicon-indent-left:before { - content: "\e057"; -} -.glyphicon-indent-right:before { - content: "\e058"; -} -.glyphicon-facetime-video:before { - content: "\e059"; -} -.glyphicon-picture:before { - content: "\e060"; -} -.glyphicon-map-marker:before { - content: "\e062"; -} -.glyphicon-adjust:before { - content: "\e063"; -} -.glyphicon-tint:before { - content: "\e064"; -} -.glyphicon-edit:before { - content: "\e065"; -} -.glyphicon-share:before { - content: "\e066"; -} -.glyphicon-check:before { - content: "\e067"; -} -.glyphicon-move:before { - content: "\e068"; -} -.glyphicon-step-backward:before { - content: "\e069"; -} -.glyphicon-fast-backward:before { - content: "\e070"; -} -.glyphicon-backward:before { - content: "\e071"; -} -.glyphicon-play:before { - content: "\e072"; -} -.glyphicon-pause:before { - content: "\e073"; -} -.glyphicon-stop:before { - content: "\e074"; -} -.glyphicon-forward:before { - content: "\e075"; -} -.glyphicon-fast-forward:before { - content: "\e076"; -} -.glyphicon-step-forward:before { - content: "\e077"; -} -.glyphicon-eject:before { - content: "\e078"; -} -.glyphicon-chevron-left:before { - content: "\e079"; -} -.glyphicon-chevron-right:before { - content: "\e080"; -} -.glyphicon-plus-sign:before { - content: "\e081"; -} -.glyphicon-minus-sign:before { - content: "\e082"; -} -.glyphicon-remove-sign:before { - content: "\e083"; -} -.glyphicon-ok-sign:before { - content: "\e084"; -} -.glyphicon-question-sign:before { - content: "\e085"; -} -.glyphicon-info-sign:before { - content: "\e086"; -} -.glyphicon-screenshot:before { - content: "\e087"; -} -.glyphicon-remove-circle:before { - content: "\e088"; -} -.glyphicon-ok-circle:before { - content: "\e089"; -} -.glyphicon-ban-circle:before { - content: "\e090"; -} -.glyphicon-arrow-left:before { - content: "\e091"; -} -.glyphicon-arrow-right:before { - content: "\e092"; -} -.glyphicon-arrow-up:before { - content: "\e093"; -} -.glyphicon-arrow-down:before { - content: "\e094"; -} -.glyphicon-share-alt:before { - content: "\e095"; -} -.glyphicon-resize-full:before { - content: "\e096"; -} -.glyphicon-resize-small:before { - content: "\e097"; -} -.glyphicon-exclamation-sign:before { - content: "\e101"; -} -.glyphicon-gift:before { - content: "\e102"; -} -.glyphicon-leaf:before { - content: "\e103"; -} -.glyphicon-fire:before { - content: "\e104"; -} -.glyphicon-eye-open:before { - content: "\e105"; -} -.glyphicon-eye-close:before { - content: "\e106"; -} -.glyphicon-warning-sign:before { - content: "\e107"; -} -.glyphicon-plane:before { - content: "\e108"; -} -.glyphicon-calendar:before { - content: "\e109"; -} -.glyphicon-random:before { - content: "\e110"; -} -.glyphicon-comment:before { - content: "\e111"; -} -.glyphicon-magnet:before { - content: "\e112"; -} -.glyphicon-chevron-up:before { - content: "\e113"; -} -.glyphicon-chevron-down:before { - content: "\e114"; -} -.glyphicon-retweet:before { - content: "\e115"; -} -.glyphicon-shopping-cart:before { - content: "\e116"; -} -.glyphicon-folder-close:before { - content: "\e117"; -} -.glyphicon-folder-open:before { - content: "\e118"; -} -.glyphicon-resize-vertical:before { - content: "\e119"; -} -.glyphicon-resize-horizontal:before { - content: "\e120"; -} -.glyphicon-hdd:before { - content: "\e121"; -} -.glyphicon-bullhorn:before { - content: "\e122"; -} -.glyphicon-bell:before { - content: "\e123"; -} -.glyphicon-certificate:before { - content: "\e124"; -} -.glyphicon-thumbs-up:before { - content: "\e125"; -} -.glyphicon-thumbs-down:before { - content: "\e126"; -} -.glyphicon-hand-right:before { - content: "\e127"; -} -.glyphicon-hand-left:before { - content: "\e128"; -} -.glyphicon-hand-up:before { - content: "\e129"; -} -.glyphicon-hand-down:before { - content: "\e130"; -} -.glyphicon-circle-arrow-right:before { - content: "\e131"; -} -.glyphicon-circle-arrow-left:before { - content: "\e132"; -} -.glyphicon-circle-arrow-up:before { - content: "\e133"; -} -.glyphicon-circle-arrow-down:before { - content: "\e134"; -} -.glyphicon-globe:before { - content: "\e135"; -} -.glyphicon-wrench:before { - content: "\e136"; -} -.glyphicon-tasks:before { - content: "\e137"; -} -.glyphicon-filter:before { - content: "\e138"; -} -.glyphicon-briefcase:before { - content: "\e139"; -} -.glyphicon-fullscreen:before { - content: "\e140"; -} -.glyphicon-dashboard:before { - content: "\e141"; -} -.glyphicon-paperclip:before { - content: "\e142"; -} -.glyphicon-heart-empty:before { - content: "\e143"; -} -.glyphicon-link:before { - content: "\e144"; -} -.glyphicon-phone:before { - content: "\e145"; -} -.glyphicon-pushpin:before { - content: "\e146"; -} -.glyphicon-usd:before { - content: "\e148"; -} -.glyphicon-gbp:before { - content: "\e149"; -} -.glyphicon-sort:before { - content: "\e150"; -} -.glyphicon-sort-by-alphabet:before { - content: "\e151"; -} -.glyphicon-sort-by-alphabet-alt:before { - content: "\e152"; -} -.glyphicon-sort-by-order:before { - content: "\e153"; -} -.glyphicon-sort-by-order-alt:before { - content: "\e154"; -} -.glyphicon-sort-by-attributes:before { - content: "\e155"; -} -.glyphicon-sort-by-attributes-alt:before { - content: "\e156"; -} -.glyphicon-unchecked:before { - content: "\e157"; -} -.glyphicon-expand:before { - content: "\e158"; -} -.glyphicon-collapse-down:before { - content: "\e159"; -} -.glyphicon-collapse-up:before { - content: "\e160"; -} -.glyphicon-log-in:before { - content: "\e161"; -} -.glyphicon-flash:before { - content: "\e162"; -} -.glyphicon-log-out:before { - content: "\e163"; -} -.glyphicon-new-window:before { - content: "\e164"; -} -.glyphicon-record:before { - content: "\e165"; -} -.glyphicon-save:before { - content: "\e166"; -} -.glyphicon-open:before { - content: "\e167"; -} -.glyphicon-saved:before { - content: "\e168"; -} -.glyphicon-import:before { - content: "\e169"; -} -.glyphicon-export:before { - content: "\e170"; -} -.glyphicon-send:before { - content: "\e171"; -} -.glyphicon-floppy-disk:before { - content: "\e172"; -} -.glyphicon-floppy-saved:before { - content: "\e173"; -} -.glyphicon-floppy-remove:before { - content: "\e174"; -} -.glyphicon-floppy-save:before { - content: "\e175"; -} -.glyphicon-floppy-open:before { - content: "\e176"; -} -.glyphicon-credit-card:before { - content: "\e177"; -} -.glyphicon-transfer:before { - content: "\e178"; -} -.glyphicon-cutlery:before { - content: "\e179"; -} -.glyphicon-header:before { - content: "\e180"; -} -.glyphicon-compressed:before { - content: "\e181"; -} -.glyphicon-earphone:before { - content: "\e182"; -} -.glyphicon-phone-alt:before { - content: "\e183"; -} -.glyphicon-tower:before { - content: "\e184"; -} -.glyphicon-stats:before { - content: "\e185"; -} -.glyphicon-sd-video:before { - content: "\e186"; -} -.glyphicon-hd-video:before { - content: "\e187"; -} -.glyphicon-subtitles:before { - content: "\e188"; -} -.glyphicon-sound-stereo:before { - content: "\e189"; -} -.glyphicon-sound-dolby:before { - content: "\e190"; -} -.glyphicon-sound-5-1:before { - content: "\e191"; -} -.glyphicon-sound-6-1:before { - content: "\e192"; -} -.glyphicon-sound-7-1:before { - content: "\e193"; -} -.glyphicon-copyright-mark:before { - content: "\e194"; -} -.glyphicon-registration-mark:before { - content: "\e195"; -} -.glyphicon-cloud-download:before { - content: "\e197"; -} -.glyphicon-cloud-upload:before { - content: "\e198"; -} -.glyphicon-tree-conifer:before { - content: "\e199"; -} -.glyphicon-tree-deciduous:before { - content: "\e200"; -} -.glyphicon-cd:before { - content: "\e201"; -} -.glyphicon-save-file:before { - content: "\e202"; -} -.glyphicon-open-file:before { - content: "\e203"; -} -.glyphicon-level-up:before { - content: "\e204"; -} -.glyphicon-copy:before { - content: "\e205"; -} -.glyphicon-paste:before { - content: "\e206"; -} -.glyphicon-alert:before { - content: "\e209"; -} -.glyphicon-equalizer:before { - content: "\e210"; -} -.glyphicon-king:before { - content: "\e211"; -} -.glyphicon-queen:before { - content: "\e212"; -} -.glyphicon-pawn:before { - content: "\e213"; -} -.glyphicon-bishop:before { - content: "\e214"; -} -.glyphicon-knight:before { - content: "\e215"; -} -.glyphicon-baby-formula:before { - content: "\e216"; -} -.glyphicon-tent:before { - content: "\26fa"; -} -.glyphicon-blackboard:before { - content: "\e218"; -} -.glyphicon-bed:before { - content: "\e219"; -} -.glyphicon-apple:before { - content: "\f8ff"; -} -.glyphicon-erase:before { - content: "\e221"; -} -.glyphicon-hourglass:before { - content: "\231b"; -} -.glyphicon-lamp:before { - content: "\e223"; -} -.glyphicon-duplicate:before { - content: "\e224"; -} -.glyphicon-piggy-bank:before { - content: "\e225"; -} -.glyphicon-scissors:before { - content: "\e226"; -} -.glyphicon-bitcoin:before { - content: "\e227"; -} -.glyphicon-btc:before { - content: "\e227"; -} -.glyphicon-xbt:before { - content: "\e227"; -} -.glyphicon-yen:before { - content: "\00a5"; -} -.glyphicon-jpy:before { - content: "\00a5"; -} -.glyphicon-ruble:before { - content: "\20bd"; -} -.glyphicon-rub:before { - content: "\20bd"; -} -.glyphicon-scale:before { - content: "\e230"; -} -.glyphicon-ice-lolly:before { - content: "\e231"; -} -.glyphicon-ice-lolly-tasted:before { - content: "\e232"; -} -.glyphicon-education:before { - content: "\e233"; -} -.glyphicon-option-horizontal:before { - content: "\e234"; -} -.glyphicon-option-vertical:before { - content: "\e235"; -} -.glyphicon-menu-hamburger:before { - content: "\e236"; -} -.glyphicon-modal-window:before { - content: "\e237"; -} -.glyphicon-oil:before { - content: "\e238"; -} -.glyphicon-grain:before { - content: "\e239"; -} -.glyphicon-sunglasses:before { - content: "\e240"; -} -.glyphicon-text-size:before { - content: "\e241"; -} -.glyphicon-text-color:before { - content: "\e242"; -} -.glyphicon-text-background:before { - content: "\e243"; -} -.glyphicon-object-align-top:before { - content: "\e244"; -} -.glyphicon-object-align-bottom:before { - content: "\e245"; -} -.glyphicon-object-align-horizontal:before { - content: "\e246"; -} -.glyphicon-object-align-left:before { - content: "\e247"; -} -.glyphicon-object-align-vertical:before { - content: "\e248"; -} -.glyphicon-object-align-right:before { - content: "\e249"; -} -.glyphicon-triangle-right:before { - content: "\e250"; -} -.glyphicon-triangle-left:before { - content: "\e251"; -} -.glyphicon-triangle-bottom:before { - content: "\e252"; -} -.glyphicon-triangle-top:before { - content: "\e253"; -} -.glyphicon-console:before { - content: "\e254"; -} -.glyphicon-superscript:before { - content: "\e255"; -} -.glyphicon-subscript:before { - content: "\e256"; -} -.glyphicon-menu-left:before { - content: "\e257"; -} -.glyphicon-menu-right:before { - content: "\e258"; -} -.glyphicon-menu-down:before { - content: "\e259"; -} -.glyphicon-menu-up:before { - content: "\e260"; -} -* { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -*:before, -*:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -html { - font-size: 16px; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} -body { - font-family:Open Sans Regular,Helvetica Neue,Helvetica,Arial,sans-serif; - font-size: 15px; - line-height: 1.42857143; - color: #eee; - background-color: #1f1f1f; -} -input, -button, -select, -textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} -a { - color: #df691a; - text-decoration: none; -} -a:hover, -a:focus { - color: #df691a; - text-decoration: underline; -} -a:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -figure { - margin: 0; -} -img { - vertical-align: middle; -} -.img-responsive, -.thumbnail > img, -.thumbnail a > img, -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - max-width: 100%; - height: auto; -} -.img-rounded { - border-radius: 0; -} -.img-thumbnail { - padding: 4px; - line-height: 1.42857143; - background-color: #2b3e50; - border: 1px solid #dddddd; - border-radius: 0; - -webkit-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - display: inline-block; - max-width: 100%; - height: auto; -} -.img-circle { - border-radius: 50%; -} -hr { - margin-top: 21px; - margin-bottom: 21px; - border: 0; - border-top: 1px dashed #5cb85c; -} -.sr-only { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; -} -.sr-only-focusable:active, -.sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - margin: 0; - overflow: visible; - clip: auto; -} -[role="button"] { - cursor: pointer; -} -h1, -h2, -h3, -h4, -h5, -h6, -.h1, -.h2, -.h3, -.h4, -.h5, -.h6 { - font-family: inherit; - font-weight: 400; - line-height: 1.1; - color: inherit; -} -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small, -.h1 small, -.h2 small, -.h3 small, -.h4 small, -.h5 small, -.h6 small, -h1 .small, -h2 .small, -h3 .small, -h4 .small, -h5 .small, -h6 .small, -.h1 .small, -.h2 .small, -.h3 .small, -.h4 .small, -.h5 .small, -.h6 .small { - font-weight: normal; - line-height: 1; - color: #ebebeb; -} -h1, -.h1, -h2, -.h2, -h3, -.h3 { - margin-top: 21px; - margin-bottom: 10.5px; -} -h1 small, -.h1 small, -h2 small, -.h2 small, -h3 small, -.h3 small, -h1 .small, -.h1 .small, -h2 .small, -.h2 .small, -h3 .small, -.h3 .small { - font-size: 65%; -} -h4, -.h4, -h5, -.h5, -h6, -.h6 { - margin-top: 10.5px; - margin-bottom: 10.5px; -} -h4 small, -.h4 small, -h5 small, -.h5 small, -h6 small, -.h6 small, -h4 .small, -.h4 .small, -h5 .small, -.h5 .small, -h6 .small, -.h6 .small { - font-size: 75%; -} -h1, -.h1 { - font-size: 39px; -} -h2, -.h2 { - font-size: 32px; -} -h3, -.h3 { - font-size: 26px; -} -h4, -.h4 { - font-size: 19px; -} -h5, -.h5 { - font-size: 15px; -} -h6, -.h6 { - font-size: 13px; -} -p { - margin: 0 0 10.5px; -} -.lead { - margin-bottom: 21px; - font-size: 17px; - font-weight: 300; - line-height: 1.4; -} -@media (min-width: 768px) { - .lead { - font-size: 22.5px; - } -} -small, -.small { - font-size: 80%; -} -mark, -.mark { - background-color: #f0ad4e; - padding: .2em; -} -.text-left { - text-align: left; -} -.text-right { - text-align: right; -} -.text-center { - text-align: center; -} -.text-justify { - text-align: justify; -} -.text-nowrap { - white-space: nowrap; -} -.text-lowercase { - text-transform: lowercase; -} -.text-uppercase { - text-transform: uppercase; -} -.text-capitalize { - text-transform: capitalize; -} -.text-muted { - color: #4e5d6c; -} -.text-primary { - color: #df691a; -} -a.text-primary:hover, -a.text-primary:focus { - color: #b15315; -} -.text-success { - color: #ebebeb; -} -a.text-success:hover, -a.text-success:focus { - color: #d2d2d2; -} -.text-info { - color: #ebebeb; -} -a.text-info:hover, -a.text-info:focus { - color: #d2d2d2; -} -.text-warning { - color: #ebebeb; -} -a.text-warning:hover, -a.text-warning:focus { - color: #d2d2d2; -} -.text-danger { - color: #ebebeb; -} -a.text-danger:hover, -a.text-danger:focus { - color: #d2d2d2; -} -.bg-primary { - color: #fff; - background-color: #df691a; -} -a.bg-primary:hover, -a.bg-primary:focus { - background-color: #b15315; -} -.bg-success { - background-color: #5cb85c; -} -a.bg-success:hover, -a.bg-success:focus { - background-color: #449d44; -} -.bg-info { - background-color: #5bc0de; -} -a.bg-info:hover, -a.bg-info:focus { - background-color: #31b0d5; -} -.bg-warning { - background-color: #f0ad4e; -} -a.bg-warning:hover, -a.bg-warning:focus { - background-color: #ec971f; -} -.bg-danger { - background-color: #d9534f; -} -a.bg-danger:hover, -a.bg-danger:focus { - background-color: #c9302c; -} -.page-header { - padding-bottom: 9.5px; - margin: 42px 0 21px; - border-bottom: 1px solid #ebebeb; -} -ul, -ol { - margin-top: 0; - margin-bottom: 10.5px; -} -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} -.list-unstyled { - padding-left: 0; - list-style: none; -} -.list-inline { - padding-left: 0; - list-style: none; - margin-left: -5px; -} -.list-inline > li { - display: inline-block; - padding-left: 5px; - padding-right: 5px; -} -dl { - margin-top: 0; - margin-bottom: 21px; -} -dt, -dd { - line-height: 1.42857143; -} -dt { - font-weight: bold; -} -dd { - margin-left: 0; -} -@media (min-width: 768px) { - .dl-horizontal dt { - float: left; - width: 160px; - clear: left; - text-align: right; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .dl-horizontal dd { - margin-left: 180px; - } -} -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #4e5d6c; -} -.initialism { - font-size: 90%; - text-transform: uppercase; -} -blockquote { - padding: 10.5px 21px; - margin: 0 0 21px; - font-size: 18.75px; - border-left: 5px solid #4e5d6c; -} -blockquote p:last-child, -blockquote ul:last-child, -blockquote ol:last-child { - margin-bottom: 0; -} -blockquote footer, -blockquote small, -blockquote .small { - display: block; - font-size: 80%; - line-height: 1.42857143; - color: #ebebeb; -} -blockquote footer:before, -blockquote small:before, -blockquote .small:before { - content: '\2014 \00A0'; -} -.blockquote-reverse, -blockquote.pull-right { - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #4e5d6c; - border-left: 0; - text-align: right; -} -.blockquote-reverse footer:before, -blockquote.pull-right footer:before, -.blockquote-reverse small:before, -blockquote.pull-right small:before, -.blockquote-reverse .small:before, -blockquote.pull-right .small:before { - content: ''; -} -.blockquote-reverse footer:after, -blockquote.pull-right footer:after, -.blockquote-reverse small:after, -blockquote.pull-right small:after, -.blockquote-reverse .small:after, -blockquote.pull-right .small:after { - content: '\00A0 \2014'; -} -address { - margin-bottom: 21px; - font-style: normal; - line-height: 1.42857143; -} -code, -kbd, -pre, -samp { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; -} -code { - padding: 2px 4px; - font-size: 90%; - color: #c7254e; - background-color: #f9f2f4; - border-radius: 0; -} -kbd { - padding: 2px 4px; - font-size: 90%; - color: #ffffff; - background-color: #333333; - border-radius: 0; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); -} -kbd kbd { - padding: 0; - font-size: 100%; - font-weight: bold; - -webkit-box-shadow: none; - box-shadow: none; -} -pre { - display: block; - padding: 10px; - margin: 0 0 10.5px; - font-size: 14px; - line-height: 1.42857143; - word-break: break-all; - word-wrap: break-word; - color: #333333; - background-color: #f5f5f5; - border: 1px solid #cccccc; - border-radius: 0; -} -pre code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border-radius: 0; -} -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} -.container { - margin-right: auto; - margin-left: auto; - padding-left: .9375rem; - padding-right: .9375rem; -} -@media (min-width: 768px) { - .container { - width: 750px; - } -} -@media (min-width: 992px) { - .container { - width: 970px; - } -} -@media (min-width: 1200px) { - .container { - width: 1170px; - } -} -.container-fluid { - margin-right: auto; - margin-left: auto; - padding-left: 15px; - padding-right: 15px; -} -.row { - margin-left: -15px; - margin-right: -15px; -} -.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { - position: relative; - min-height: 1px; - padding-left: 15px; - padding-right: 15px; -} -.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { - float: left; -} -.col-xs-12 { - width: 100%; -} -.col-xs-11 { - width: 91.66666667%; -} -.col-xs-10 { - width: 83.33333333%; -} -.col-xs-9 { - width: 75%; -} -.col-xs-8 { - width: 66.66666667%; -} -.col-xs-7 { - width: 58.33333333%; -} -.col-xs-6 { - width: 50%; -} -.col-xs-5 { - width: 41.66666667%; -} -.col-xs-4 { - width: 33.33333333%; -} -.col-xs-3 { - width: 25%; -} -.col-xs-2 { - width: 16.66666667%; -} -.col-xs-1 { - width: 8.33333333%; -} -.col-xs-pull-12 { - right: 100%; -} -.col-xs-pull-11 { - right: 91.66666667%; -} -.col-xs-pull-10 { - right: 83.33333333%; -} -.col-xs-pull-9 { - right: 75%; -} -.col-xs-pull-8 { - right: 66.66666667%; -} -.col-xs-pull-7 { - right: 58.33333333%; -} -.col-xs-pull-6 { - right: 50%; -} -.col-xs-pull-5 { - right: 41.66666667%; -} -.col-xs-pull-4 { - right: 33.33333333%; -} -.col-xs-pull-3 { - right: 25%; -} -.col-xs-pull-2 { - right: 16.66666667%; -} -.col-xs-pull-1 { - right: 8.33333333%; -} -.col-xs-pull-0 { - right: auto; -} -.col-xs-push-12 { - left: 100%; -} -.col-xs-push-11 { - left: 91.66666667%; -} -.col-xs-push-10 { - left: 83.33333333%; -} -.col-xs-push-9 { - left: 75%; -} -.col-xs-push-8 { - left: 66.66666667%; -} -.col-xs-push-7 { - left: 58.33333333%; -} -.col-xs-push-6 { - left: 50%; -} -.col-xs-push-5 { - left: 41.66666667%; -} -.col-xs-push-4 { - left: 33.33333333%; -} -.col-xs-push-3 { - left: 25%; -} -.col-xs-push-2 { - left: 16.66666667%; -} -.col-xs-push-1 { - left: 8.33333333%; -} -.col-xs-push-0 { - left: auto; -} -.col-xs-offset-12 { - margin-left: 100%; -} -.col-xs-offset-11 { - margin-left: 91.66666667%; -} -.col-xs-offset-10 { - margin-left: 83.33333333%; -} -.col-xs-offset-9 { - margin-left: 75%; -} -.col-xs-offset-8 { - margin-left: 66.66666667%; -} -.col-xs-offset-7 { - margin-left: 58.33333333%; -} -.col-xs-offset-6 { - margin-left: 50%; -} -.col-xs-offset-5 { - margin-left: 41.66666667%; -} -.col-xs-offset-4 { - margin-left: 33.33333333%; -} -.col-xs-offset-3 { - margin-left: 25%; -} -.col-xs-offset-2 { - margin-left: 16.66666667%; -} -.col-xs-offset-1 { - margin-left: 8.33333333%; -} -.col-xs-offset-0 { - margin-left: 0%; -} -@media (min-width: 768px) { - .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { - float: left; - } - .col-sm-12 { - width: 100%; - } - .col-sm-11 { - width: 91.66666667%; - } - .col-sm-10 { - width: 83.33333333%; - } - .col-sm-9 { - width: 75%; - } - .col-sm-8 { - width: 66.66666667%; - } - .col-sm-7 { - width: 58.33333333%; - } - .col-sm-6 { - width: 50%; - } - .col-sm-5 { - width: 41.66666667%; - } - .col-sm-4 { - width: 33.33333333%; - } - .col-sm-3 { - width: 25%; - } - .col-sm-2 { - width: 16.66666667%; - } - .col-sm-1 { - width: 8.33333333%; - } - .col-sm-pull-12 { - right: 100%; - } - .col-sm-pull-11 { - right: 91.66666667%; - } - .col-sm-pull-10 { - right: 83.33333333%; - } - .col-sm-pull-9 { - right: 75%; - } - .col-sm-pull-8 { - right: 66.66666667%; - } - .col-sm-pull-7 { - right: 58.33333333%; - } - .col-sm-pull-6 { - right: 50%; - } - .col-sm-pull-5 { - right: 41.66666667%; - } - .col-sm-pull-4 { - right: 33.33333333%; - } - .col-sm-pull-3 { - right: 25%; - } - .col-sm-pull-2 { - right: 16.66666667%; - } - .col-sm-pull-1 { - right: 8.33333333%; - } - .col-sm-pull-0 { - right: auto; - } - .col-sm-push-12 { - left: 100%; - } - .col-sm-push-11 { - left: 91.66666667%; - } - .col-sm-push-10 { - left: 83.33333333%; - } - .col-sm-push-9 { - left: 75%; - } - .col-sm-push-8 { - left: 66.66666667%; - } - .col-sm-push-7 { - left: 58.33333333%; - } - .col-sm-push-6 { - left: 50%; - } - .col-sm-push-5 { - left: 41.66666667%; - } - .col-sm-push-4 { - left: 33.33333333%; - } - .col-sm-push-3 { - left: 25%; - } - .col-sm-push-2 { - left: 16.66666667%; - } - .col-sm-push-1 { - left: 8.33333333%; - } - .col-sm-push-0 { - left: auto; - } - .col-sm-offset-12 { - margin-left: 100%; - } - .col-sm-offset-11 { - margin-left: 91.66666667%; - } - .col-sm-offset-10 { - margin-left: 83.33333333%; - } - .col-sm-offset-9 { - margin-left: 75%; - } - .col-sm-offset-8 { - margin-left: 66.66666667%; - } - .col-sm-offset-7 { - margin-left: 58.33333333%; - } - .col-sm-offset-6 { - margin-left: 50%; - } - .col-sm-offset-5 { - margin-left: 41.66666667%; - } - .col-sm-offset-4 { - margin-left: 33.33333333%; - } - .col-sm-offset-3 { - margin-left: 25%; - } - .col-sm-offset-2 { - margin-left: 16.66666667%; - } - .col-sm-offset-1 { - margin-left: 8.33333333%; - } - .col-sm-offset-0 { - margin-left: 0%; - } -} -@media (min-width: 992px) { - .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { - float: left; - } - .col-md-12 { - width: 100%; - } - .col-md-11 { - width: 91.66666667%; - } - .col-md-10 { - width: 83.33333333%; - } - .col-md-9 { - width: 75%; - } - .col-md-8 { - width: 66.66666667%; - } - .col-md-7 { - width: 58.33333333%; - } - .col-md-6 { - width: 50%; - } - .col-md-5 { - width: 41.66666667%; - } - .col-md-4 { - width: 33.33333333%; - } - .col-md-3 { - width: 25%; - } - .col-md-2 { - width: 16.66666667%; - } - .col-md-1 { - width: 8.33333333%; - } - .col-md-pull-12 { - right: 100%; - } - .col-md-pull-11 { - right: 91.66666667%; - } - .col-md-pull-10 { - right: 83.33333333%; - } - .col-md-pull-9 { - right: 75%; - } - .col-md-pull-8 { - right: 66.66666667%; - } - .col-md-pull-7 { - right: 58.33333333%; - } - .col-md-pull-6 { - right: 50%; - } - .col-md-pull-5 { - right: 41.66666667%; - } - .col-md-pull-4 { - right: 33.33333333%; - } - .col-md-pull-3 { - right: 25%; - } - .col-md-pull-2 { - right: 16.66666667%; - } - .col-md-pull-1 { - right: 8.33333333%; - } - .col-md-pull-0 { - right: auto; - } - .col-md-push-12 { - left: 100%; - } - .col-md-push-11 { - left: 91.66666667%; - } - .col-md-push-10 { - left: 83.33333333%; - } - .col-md-push-9 { - left: 75%; - } - .col-md-push-8 { - left: 66.66666667%; - } - .col-md-push-7 { - left: 58.33333333%; - } - .col-md-push-6 { - left: 50%; - } - .col-md-push-5 { - left: 41.66666667%; - } - .col-md-push-4 { - left: 33.33333333%; - } - .col-md-push-3 { - left: 25%; - } - .col-md-push-2 { - left: 16.66666667%; - } - .col-md-push-1 { - left: 8.33333333%; - } - .col-md-push-0 { - left: auto; - } - .col-md-offset-12 { - margin-left: 100%; - } - .col-md-offset-11 { - margin-left: 91.66666667%; - } - .col-md-offset-10 { - margin-left: 83.33333333%; - } - .col-md-offset-9 { - margin-left: 75%; - } - .col-md-offset-8 { - margin-left: 66.66666667%; - } - .col-md-offset-7 { - margin-left: 58.33333333%; - } - .col-md-offset-6 { - margin-left: 50%; - } - .col-md-offset-5 { - margin-left: 41.66666667%; - } - .col-md-offset-4 { - margin-left: 33.33333333%; - } - .col-md-offset-3 { - margin-left: 25%; - } - .col-md-offset-2 { - margin-left: 16.66666667%; - } - .col-md-offset-1 { - margin-left: 8.33333333%; - } - .col-md-offset-0 { - margin-left: 0%; - } -} -@media (min-width: 1200px) { - .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { - float: left; - } - .col-lg-12 { - width: 100%; - } - .col-lg-11 { - width: 91.66666667%; - } - .col-lg-10 { - width: 83.33333333%; - } - .col-lg-9 { - width: 75%; - } - .col-lg-8 { - width: 66.66666667%; - } - .col-lg-7 { - width: 58.33333333%; - } - .col-lg-6 { - width: 50%; - } - .col-lg-5 { - width: 41.66666667%; - } - .col-lg-4 { - width: 33.33333333%; - } - .col-lg-3 { - width: 25%; - } - .col-lg-2 { - width: 16.66666667%; - } - .col-lg-1 { - width: 8.33333333%; - } - .col-lg-pull-12 { - right: 100%; - } - .col-lg-pull-11 { - right: 91.66666667%; - } - .col-lg-pull-10 { - right: 83.33333333%; - } - .col-lg-pull-9 { - right: 75%; - } - .col-lg-pull-8 { - right: 66.66666667%; - } - .col-lg-pull-7 { - right: 58.33333333%; - } - .col-lg-pull-6 { - right: 50%; - } - .col-lg-pull-5 { - right: 41.66666667%; - } - .col-lg-pull-4 { - right: 33.33333333%; - } - .col-lg-pull-3 { - right: 25%; - } - .col-lg-pull-2 { - right: 16.66666667%; - } - .col-lg-pull-1 { - right: 8.33333333%; - } - .col-lg-pull-0 { - right: auto; - } - .col-lg-push-12 { - left: 100%; - } - .col-lg-push-11 { - left: 91.66666667%; - } - .col-lg-push-10 { - left: 83.33333333%; - } - .col-lg-push-9 { - left: 75%; - } - .col-lg-push-8 { - left: 66.66666667%; - } - .col-lg-push-7 { - left: 58.33333333%; - } - .col-lg-push-6 { - left: 50%; - } - .col-lg-push-5 { - left: 41.66666667%; - } - .col-lg-push-4 { - left: 33.33333333%; - } - .col-lg-push-3 { - left: 25%; - } - .col-lg-push-2 { - left: 16.66666667%; - } - .col-lg-push-1 { - left: 8.33333333%; - } - .col-lg-push-0 { - left: auto; - } - .col-lg-offset-12 { - margin-left: 100%; - } - .col-lg-offset-11 { - margin-left: 91.66666667%; - } - .col-lg-offset-10 { - margin-left: 83.33333333%; - } - .col-lg-offset-9 { - margin-left: 75%; - } - .col-lg-offset-8 { - margin-left: 66.66666667%; - } - .col-lg-offset-7 { - margin-left: 58.33333333%; - } - .col-lg-offset-6 { - margin-left: 50%; - } - .col-lg-offset-5 { - margin-left: 41.66666667%; - } - .col-lg-offset-4 { - margin-left: 33.33333333%; - } - .col-lg-offset-3 { - margin-left: 25%; - } - .col-lg-offset-2 { - margin-left: 16.66666667%; - } - .col-lg-offset-1 { - margin-left: 8.33333333%; - } - .col-lg-offset-0 { - margin-left: 0%; - } -} -table { - background-color: transparent; -} -caption { - padding-top: 6px; - padding-bottom: 6px; - color: #4e5d6c; - text-align: left; -} -th { - text-align: left; -} -.table { - width: 100%; - max-width: 100%; - margin-bottom: 21px; -} -.table > thead > tr > th, -.table > tbody > tr > th, -.table > tfoot > tr > th, -.table > thead > tr > td, -.table > tbody > tr > td, -.table > tfoot > tr > td { - padding: 6px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #4e5d6c; -} -.table > thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid #4e5d6c; -} -.table > caption + thead > tr:first-child > th, -.table > colgroup + thead > tr:first-child > th, -.table > thead:first-child > tr:first-child > th, -.table > caption + thead > tr:first-child > td, -.table > colgroup + thead > tr:first-child > td, -.table > thead:first-child > tr:first-child > td { - border-top: 0; -} -.table > tbody + tbody { - border-top: 2px solid #4e5d6c; -} -.table .table { - background-color: #2b3e50; -} -.table-condensed > thead > tr > th, -.table-condensed > tbody > tr > th, -.table-condensed > tfoot > tr > th, -.table-condensed > thead > tr > td, -.table-condensed > tbody > tr > td, -.table-condensed > tfoot > tr > td { - padding: 3px; -} -.table-bordered { - border: 1px solid #4e5d6c; -} -.table-bordered > thead > tr > th, -.table-bordered > tbody > tr > th, -.table-bordered > tfoot > tr > th, -.table-bordered > thead > tr > td, -.table-bordered > tbody > tr > td, -.table-bordered > tfoot > tr > td { - border: 1px solid #4e5d6c; -} -.table-bordered > thead > tr > th, -.table-bordered > thead > tr > td { - border-bottom-width: 2px; -} -.table-striped > tbody > tr:nth-of-type(odd) { - background-color: #333333; -} -.table-hover > tbody > tr:hover { - background-color: #282828; -} -table col[class*="col-"] { - position: static; - float: none; - display: table-column; -} -table td[class*="col-"], -table th[class*="col-"] { - position: static; - float: none; - display: table-cell; -} -.table > thead > tr > td.active, -.table > tbody > tr > td.active, -.table > tfoot > tr > td.active, -.table > thead > tr > th.active, -.table > tbody > tr > th.active, -.table > tfoot > tr > th.active, -.table > thead > tr.active > td, -.table > tbody > tr.active > td, -.table > tfoot > tr.active > td, -.table > thead > tr.active > th, -.table > tbody > tr.active > th, -.table > tfoot > tr.active > th { - background-color: #485563; -} -.table-hover > tbody > tr > td.active:hover, -.table-hover > tbody > tr > th.active:hover, -.table-hover > tbody > tr.active:hover > td, -.table-hover > tbody > tr:hover > .active, -.table-hover > tbody > tr.active:hover > th { - background-color: #3d4954; -} -.table > thead > tr > td.success, -.table > tbody > tr > td.success, -.table > tfoot > tr > td.success, -.table > thead > tr > th.success, -.table > tbody > tr > th.success, -.table > tfoot > tr > th.success, -.table > thead > tr.success > td, -.table > tbody > tr.success > td, -.table > tfoot > tr.success > td, -.table > thead > tr.success > th, -.table > tbody > tr.success > th, -.table > tfoot > tr.success > th { - background-color: #5cb85c; -} -.table-hover > tbody > tr > td.success:hover, -.table-hover > tbody > tr > th.success:hover, -.table-hover > tbody > tr.success:hover > td, -.table-hover > tbody > tr:hover > .success, -.table-hover > tbody > tr.success:hover > th { - background-color: #4cae4c; -} -.table > thead > tr > td.info, -.table > tbody > tr > td.info, -.table > tfoot > tr > td.info, -.table > thead > tr > th.info, -.table > tbody > tr > th.info, -.table > tfoot > tr > th.info, -.table > thead > tr.info > td, -.table > tbody > tr.info > td, -.table > tfoot > tr.info > td, -.table > thead > tr.info > th, -.table > tbody > tr.info > th, -.table > tfoot > tr.info > th { - background-color: #5bc0de; -} -.table-hover > tbody > tr > td.info:hover, -.table-hover > tbody > tr > th.info:hover, -.table-hover > tbody > tr.info:hover > td, -.table-hover > tbody > tr:hover > .info, -.table-hover > tbody > tr.info:hover > th { - background-color: #46b8da; -} -.table > thead > tr > td.warning, -.table > tbody > tr > td.warning, -.table > tfoot > tr > td.warning, -.table > thead > tr > th.warning, -.table > tbody > tr > th.warning, -.table > tfoot > tr > th.warning, -.table > thead > tr.warning > td, -.table > tbody > tr.warning > td, -.table > tfoot > tr.warning > td, -.table > thead > tr.warning > th, -.table > tbody > tr.warning > th, -.table > tfoot > tr.warning > th { - background-color: #f0ad4e; -} -.table-hover > tbody > tr > td.warning:hover, -.table-hover > tbody > tr > th.warning:hover, -.table-hover > tbody > tr.warning:hover > td, -.table-hover > tbody > tr:hover > .warning, -.table-hover > tbody > tr.warning:hover > th { - background-color: #eea236; -} -.table > thead > tr > td.danger, -.table > tbody > tr > td.danger, -.table > tfoot > tr > td.danger, -.table > thead > tr > th.danger, -.table > tbody > tr > th.danger, -.table > tfoot > tr > th.danger, -.table > thead > tr.danger > td, -.table > tbody > tr.danger > td, -.table > tfoot > tr.danger > td, -.table > thead > tr.danger > th, -.table > tbody > tr.danger > th, -.table > tfoot > tr.danger > th { - background-color: #d9534f; -} -.table-hover > tbody > tr > td.danger:hover, -.table-hover > tbody > tr > th.danger:hover, -.table-hover > tbody > tr.danger:hover > td, -.table-hover > tbody > tr:hover > .danger, -.table-hover > tbody > tr.danger:hover > th { - background-color: #d43f3a; -} -.table-responsive { - overflow-x: auto; - min-height: 0.01%; -} -@media screen and (max-width: 767px) { - .table-responsive { - width: 100%; - margin-bottom: 15.75px; - overflow-y: hidden; - -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid #4e5d6c; - } - .table-responsive > .table { - margin-bottom: 0; - } - .table-responsive > .table > thead > tr > th, - .table-responsive > .table > tbody > tr > th, - .table-responsive > .table > tfoot > tr > th, - .table-responsive > .table > thead > tr > td, - .table-responsive > .table > tbody > tr > td, - .table-responsive > .table > tfoot > tr > td { - white-space: nowrap; - } - .table-responsive > .table-bordered { - border: 0; - } - .table-responsive > .table-bordered > thead > tr > th:first-child, - .table-responsive > .table-bordered > tbody > tr > th:first-child, - .table-responsive > .table-bordered > tfoot > tr > th:first-child, - .table-responsive > .table-bordered > thead > tr > td:first-child, - .table-responsive > .table-bordered > tbody > tr > td:first-child, - .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; - } - .table-responsive > .table-bordered > thead > tr > th:last-child, - .table-responsive > .table-bordered > tbody > tr > th:last-child, - .table-responsive > .table-bordered > tfoot > tr > th:last-child, - .table-responsive > .table-bordered > thead > tr > td:last-child, - .table-responsive > .table-bordered > tbody > tr > td:last-child, - .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; - } - .table-responsive > .table-bordered > tbody > tr:last-child > th, - .table-responsive > .table-bordered > tfoot > tr:last-child > th, - .table-responsive > .table-bordered > tbody > tr:last-child > td, - .table-responsive > .table-bordered > tfoot > tr:last-child > td { - border-bottom: 0; - } -} -fieldset { - padding: 15px; - margin: 0; - border: 0; - min-width: 0; -} -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 21px; - font-size: 22.5px; - line-height: inherit; - color: #ebebeb; - border: 0; - border-bottom: 1px solid #333333; -} -label { - display: inline-block; - max-width: 100%; - margin-bottom: 5px; - font-weight: bold; -} -input[type="search"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; - line-height: normal; -} -input[type="file"] { - display: block; -} -input[type="range"] { - display: block; - width: 100%; -} -select[multiple], -select[size] { - height: auto; -} -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -output { - display: block; - padding-top: 9px; - font-size: 15px; - line-height: 1.42857143; - color: #2b3e50; -} -.form-control { - display: block; - width: 100%; - height: 39px; - padding: 8px 16px; - font-size: 15px; - line-height: 1.42857143; - color: #fefefe; - background-color: #333333; - background-image: none; - border: 1px solid transparent; - border-radius: .25rem; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -} -.form-control:focus { - border-color: transparent; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 0, 0, 0.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 0, 0, 0.6); -} -.form-control::-moz-placeholder { - color: #cccccc; - opacity: 1; -} -.form-control:-ms-input-placeholder { - color: #cccccc; -} -.form-control::-webkit-input-placeholder { - color: #cccccc; -} -.form-control::-ms-expand { - border: 0; - background-color: transparent; -} -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - background-color: #ebebeb; - opacity: 1; -} -.form-control[disabled], -fieldset[disabled] .form-control { - cursor: not-allowed; -} -textarea.form-control { - height: auto; -} -input[type="search"] { - -webkit-appearance: none; -} -@media screen and (-webkit-min-device-pixel-ratio: 0) { - input[type="date"].form-control, - input[type="time"].form-control, - input[type="datetime-local"].form-control, - input[type="month"].form-control { - line-height: 39px; - } - input[type="date"].input-sm, - input[type="time"].input-sm, - input[type="datetime-local"].input-sm, - input[type="month"].input-sm, - .input-group-sm input[type="date"], - .input-group-sm input[type="time"], - .input-group-sm input[type="datetime-local"], - .input-group-sm input[type="month"] { - line-height: 30px; - } - input[type="date"].input-lg, - input[type="time"].input-lg, - input[type="datetime-local"].input-lg, - input[type="month"].input-lg, - .input-group-lg input[type="date"], - .input-group-lg input[type="time"], - .input-group-lg input[type="datetime-local"], - .input-group-lg input[type="month"] { - line-height: 52px; - } -} -.form-group { - margin-bottom: 15px; -} -.radio, -.checkbox { - position: relative; - display: block; - margin-top: 10px; - margin-bottom: 10px; -} -.radio label, -.checkbox label { - min-height: 21px; - padding-left: 20px; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; -} -.radio input[type="radio"], -.radio-inline input[type="radio"], -.checkbox input[type="checkbox"], -.checkbox-inline input[type="checkbox"] { - position: absolute; - margin-left: -0px; - margin-top: 4px \9; -} -.radio + .radio, -.checkbox + .checkbox { - margin-top: -5px; -} -.radio-inline, -.checkbox-inline { - position: relative; - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - vertical-align: middle; - font-weight: normal; - cursor: pointer; -} -.radio-inline + .radio-inline, -.checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; -} -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"].disabled, -input[type="checkbox"].disabled, -fieldset[disabled] input[type="radio"], -fieldset[disabled] input[type="checkbox"] { - cursor: not-allowed; -} -.radio-inline.disabled, -.checkbox-inline.disabled, -fieldset[disabled] .radio-inline, -fieldset[disabled] .checkbox-inline { - cursor: not-allowed; -} -.radio.disabled label, -.checkbox.disabled label, -fieldset[disabled] .radio label, -fieldset[disabled] .checkbox label { - cursor: not-allowed; -} -.form-control-static { - padding-top: 9px; - padding-bottom: 9px; - margin-bottom: 0; - min-height: 36px; -} -.form-control-static.input-lg, -.form-control-static.input-sm { - padding-left: 0; - padding-right: 0; -} -.input-sm { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 0; -} -select.input-sm { - height: 30px; - line-height: 30px; -} -textarea.input-sm, -select[multiple].input-sm { - height: auto; -} -.form-group-sm .form-control { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 0; -} -.form-group-sm select.form-control { - height: 30px; - line-height: 30px; -} -.form-group-sm textarea.form-control, -.form-group-sm select[multiple].form-control { - height: auto; -} -.form-group-sm .form-control-static { - height: 30px; - min-height: 33px; - padding: 6px 10px; - font-size: 12px; - line-height: 1.5; -} -.input-lg { - height: 52px; - padding: 12px 24px; - font-size: 19px; - line-height: 1.3333333; - border-radius: 0; -} -select.input-lg { - height: 52px; - line-height: 52px; -} -textarea.input-lg, -select[multiple].input-lg { - height: auto; -} -.form-group-lg .form-control { - height: 52px; - padding: 12px 24px; - font-size: 19px; - line-height: 1.3333333; - border-radius: 0; -} -.form-group-lg select.form-control { - height: 52px; - line-height: 52px; -} -.form-group-lg textarea.form-control, -.form-group-lg select[multiple].form-control { - height: auto; -} -.form-group-lg .form-control-static { - height: 52px; - min-height: 40px; - padding: 13px 24px; - font-size: 19px; - line-height: 1.3333333; -} -.has-feedback { - position: relative; -} -.has-feedback .form-control { - padding-right: 48.75px; -} -.form-control-feedback { - position: absolute; - top: 0; - right: 0; - z-index: 2; - display: block; - width: 39px; - height: 39px; - line-height: 39px; - text-align: center; - pointer-events: none; -} -.input-lg + .form-control-feedback, -.input-group-lg + .form-control-feedback, -.form-group-lg .form-control + .form-control-feedback { - width: 52px; - height: 52px; - line-height: 52px; -} -.input-sm + .form-control-feedback, -.input-group-sm + .form-control-feedback, -.form-group-sm .form-control + .form-control-feedback { - width: 30px; - height: 30px; - line-height: 30px; -} -.has-success .help-block, -.has-success .control-label, -.has-success .radio, -.has-success .checkbox, -.has-success .radio-inline, -.has-success .checkbox-inline, -.has-success.radio label, -.has-success.checkbox label, -.has-success.radio-inline label, -.has-success.checkbox-inline label { - color: #ebebeb; -} -.has-success .form-control { - border-color: #ebebeb; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-success .form-control:focus { - border-color: #d2d2d2; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; -} -.has-success .input-group-addon { - color: #ebebeb; - border-color: #ebebeb; - background-color: #5cb85c; -} -.has-success .form-control-feedback { - color: #ebebeb; -} -.has-warning .help-block, -.has-warning .control-label, -.has-warning .radio, -.has-warning .checkbox, -.has-warning .radio-inline, -.has-warning .checkbox-inline, -.has-warning.radio label, -.has-warning.checkbox label, -.has-warning.radio-inline label, -.has-warning.checkbox-inline label { - color: #ebebeb; -} -.has-warning .form-control { - border-color: #ebebeb; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-warning .form-control:focus { - border-color: #d2d2d2; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; -} -.has-warning .input-group-addon { - color: #ebebeb; - border-color: #ebebeb; - background-color: #f0ad4e; -} -.has-warning .form-control-feedback { - color: #ebebeb; -} -.has-error .help-block, -.has-error .control-label, -.has-error .radio, -.has-error .checkbox, -.has-error .radio-inline, -.has-error .checkbox-inline, -.has-error.radio label, -.has-error.checkbox label, -.has-error.radio-inline label, -.has-error.checkbox-inline label { - color: #ebebeb; -} -.has-error .form-control { - border-color: #ebebeb; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-error .form-control:focus { - border-color: #d2d2d2; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; -} -.has-error .input-group-addon { - color: #ebebeb; - border-color: #ebebeb; - background-color: #d9534f; -} -.has-error .form-control-feedback { - color: #ebebeb; -} -.has-feedback label ~ .form-control-feedback { - top: 26px; -} -.has-feedback label.sr-only ~ .form-control-feedback { - top: 0; -} -.help-block { - display: block; - margin-top: 5px; - margin-bottom: 10px; - color: #ffffff; -} -@media (min-width: 768px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .form-inline .form-control-static { - display: inline-block; - } - .form-inline .input-group { - display: inline-table; - vertical-align: middle; - } - .form-inline .input-group .input-group-addon, - .form-inline .input-group .input-group-btn, - .form-inline .input-group .form-control { - width: auto; - } - .form-inline .input-group > .form-control { - width: 100%; - } - .form-inline .control-label { - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .radio, - .form-inline .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .radio label, - .form-inline .checkbox label { - padding-left: 0; - } - .form-inline .radio input[type="radio"], - .form-inline .checkbox input[type="checkbox"] { - position: relative; - margin-left: 0; - } - .form-inline .has-feedback .form-control-feedback { - top: 0; - } -} -.form-horizontal .radio, -.form-horizontal .checkbox, -.form-horizontal .radio-inline, -.form-horizontal .checkbox-inline { - margin-top: -15px; - margin-bottom: 0; - padding-top: 9px; -} -.form-horizontal .radio, -.form-horizontal .checkbox { - min-height: 30px; -} -.form-horizontal .form-group { - margin-left: -15px; - margin-right: -15px; -} -@media (min-width: 768px) { - .form-horizontal .control-label { - text-align: right; - margin-bottom: 0; - padding-top: 9px; - } -} -.form-horizontal .has-feedback .form-control-feedback { - right: 15px; -} -@media (min-width: 768px) { - .form-horizontal .form-group-lg .control-label { - padding-top: 13px; - font-size: 19px; - } -} -@media (min-width: 768px) { - .form-horizontal .form-group-sm .control-label { - padding-top: 6px; - font-size: 12px; - } -} -.btn { - display: inline-block; - margin-bottom: 0; - font-weight: normal; - text-align: center; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - background-image: none; - border: 1px solid transparent; - white-space: nowrap; - padding: 8px 16px; - font-size: 15px; - line-height: 1.42857143; - border-radius: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.btn:focus, -.btn:active:focus, -.btn.active:focus, -.btn.focus, -.btn:active.focus, -.btn.active.focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.btn:hover, -.btn:focus, -.btn.focus { - color: #ffffff; - text-decoration: none; -} -.btn:active, -.btn.active { - outline: 0; - background-image: none; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn.disabled, -.btn[disabled], -fieldset[disabled] .btn { - cursor: not-allowed; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; -} -a.btn.disabled, -fieldset[disabled] a.btn { - pointer-events: none; -} -.btn-default { - color: #ffffff; - background-color: #4e5d6c; - border-color: transparent; -} -.btn-default:focus, -.btn-default.focus { - color: #ffffff; - background-color: #39444e; - border-color: rgba(0, 0, 0, 0); -} -.btn-default:hover { - color: #ffffff; - background-color: #39444e; - border-color: rgba(0, 0, 0, 0); -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - color: #ffffff; - background-color: #39444e; - border-color: rgba(0, 0, 0, 0); -} -.btn-default:active:hover, -.btn-default.active:hover, -.open > .dropdown-toggle.btn-default:hover, -.btn-default:active:focus, -.btn-default.active:focus, -.open > .dropdown-toggle.btn-default:focus, -.btn-default:active.focus, -.btn-default.active.focus, -.open > .dropdown-toggle.btn-default.focus { - color: #ffffff; - background-color: #2a323a; - border-color: rgba(0, 0, 0, 0); -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - background-image: none; -} -.btn-default.disabled:hover, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default:hover, -.btn-default.disabled:focus, -.btn-default[disabled]:focus, -fieldset[disabled] .btn-default:focus, -.btn-default.disabled.focus, -.btn-default[disabled].focus, -fieldset[disabled] .btn-default.focus { - background-color: #4e5d6c; - border-color: transparent; -} -.btn-default .badge { - color: #4e5d6c; - background-color: #ffffff; -} -.btn-primary { - color: #ffffff; - background-color: #df691a; - border-color: transparent; -} -.btn-primary:focus, -.btn-primary.focus { - color: #ffffff; - background-color: #b15315; - border-color: rgba(0, 0, 0, 0); -} -.btn-primary:hover { - color: #ffffff; - background-color: #b15315; - border-color: rgba(0, 0, 0, 0); -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #b15315; - border-color: rgba(0, 0, 0, 0); -} -.btn-primary:active:hover, -.btn-primary.active:hover, -.open > .dropdown-toggle.btn-primary:hover, -.btn-primary:active:focus, -.btn-primary.active:focus, -.open > .dropdown-toggle.btn-primary:focus, -.btn-primary:active.focus, -.btn-primary.active.focus, -.open > .dropdown-toggle.btn-primary.focus { - color: #ffffff; - background-color: #914411; - border-color: rgba(0, 0, 0, 0); -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - background-image: none; -} -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled.focus, -.btn-primary[disabled].focus, -fieldset[disabled] .btn-primary.focus { - background-color: #df691a; - border-color: transparent; -} -.btn-primary .badge { - color: #df691a; - background-color: #ffffff; -} -.btn-success { - color: #ffffff; - background-color: #5cb85c; - border-color: transparent; -} -.btn-success:focus, -.btn-success.focus { - color: #ffffff; - background-color: #449d44; - border-color: rgba(0, 0, 0, 0); -} -.btn-success:hover { - color: #ffffff; - background-color: #449d44; - border-color: rgba(0, 0, 0, 0); -} -.btn-success:active, -.btn-success.active, -.open > .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #449d44; - border-color: rgba(0, 0, 0, 0); -} -.btn-success:active:hover, -.btn-success.active:hover, -.open > .dropdown-toggle.btn-success:hover, -.btn-success:active:focus, -.btn-success.active:focus, -.open > .dropdown-toggle.btn-success:focus, -.btn-success:active.focus, -.btn-success.active.focus, -.open > .dropdown-toggle.btn-success.focus { - color: #ffffff; - background-color: #398439; - border-color: rgba(0, 0, 0, 0); -} -.btn-success:active, -.btn-success.active, -.open > .dropdown-toggle.btn-success { - background-image: none; -} -.btn-success.disabled:hover, -.btn-success[disabled]:hover, -fieldset[disabled] .btn-success:hover, -.btn-success.disabled:focus, -.btn-success[disabled]:focus, -fieldset[disabled] .btn-success:focus, -.btn-success.disabled.focus, -.btn-success[disabled].focus, -fieldset[disabled] .btn-success.focus { - background-color: #5cb85c; - border-color: transparent; -} -.btn-success .badge { - color: #5cb85c; - background-color: #ffffff; -} -.btn-info { - color: #ffffff; - background-color: #5bc0de; - border-color: transparent; -} -.btn-info:focus, -.btn-info.focus { - color: #ffffff; - background-color: #31b0d5; - border-color: rgba(0, 0, 0, 0); -} -.btn-info:hover { - color: #ffffff; - background-color: #31b0d5; - border-color: rgba(0, 0, 0, 0); -} -.btn-info:active, -.btn-info.active, -.open > .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #31b0d5; - border-color: rgba(0, 0, 0, 0); -} -.btn-info:active:hover, -.btn-info.active:hover, -.open > .dropdown-toggle.btn-info:hover, -.btn-info:active:focus, -.btn-info.active:focus, -.open > .dropdown-toggle.btn-info:focus, -.btn-info:active.focus, -.btn-info.active.focus, -.open > .dropdown-toggle.btn-info.focus { - color: #ffffff; - background-color: #269abc; - border-color: rgba(0, 0, 0, 0); -} -.btn-info:active, -.btn-info.active, -.open > .dropdown-toggle.btn-info { - background-image: none; -} -.btn-info.disabled:hover, -.btn-info[disabled]:hover, -fieldset[disabled] .btn-info:hover, -.btn-info.disabled:focus, -.btn-info[disabled]:focus, -fieldset[disabled] .btn-info:focus, -.btn-info.disabled.focus, -.btn-info[disabled].focus, -fieldset[disabled] .btn-info.focus { - background-color: #5bc0de; - border-color: transparent; -} -.btn-info .badge { - color: #5bc0de; - background-color: #ffffff; -} -.btn-warning { - color: #ffffff; - background-color: #f0ad4e; - border-color: transparent; -} -.btn-warning:focus, -.btn-warning.focus { - color: #ffffff; - background-color: #ec971f; - border-color: rgba(0, 0, 0, 0); -} -.btn-warning:hover { - color: #ffffff; - background-color: #ec971f; - border-color: rgba(0, 0, 0, 0); -} -.btn-warning:active, -.btn-warning.active, -.open > .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #ec971f; - border-color: rgba(0, 0, 0, 0); -} -.btn-warning:active:hover, -.btn-warning.active:hover, -.open > .dropdown-toggle.btn-warning:hover, -.btn-warning:active:focus, -.btn-warning.active:focus, -.open > .dropdown-toggle.btn-warning:focus, -.btn-warning:active.focus, -.btn-warning.active.focus, -.open > .dropdown-toggle.btn-warning.focus { - color: #ffffff; - background-color: #d58512; - border-color: rgba(0, 0, 0, 0); -} -.btn-warning:active, -.btn-warning.active, -.open > .dropdown-toggle.btn-warning { - background-image: none; -} -.btn-warning.disabled:hover, -.btn-warning[disabled]:hover, -fieldset[disabled] .btn-warning:hover, -.btn-warning.disabled:focus, -.btn-warning[disabled]:focus, -fieldset[disabled] .btn-warning:focus, -.btn-warning.disabled.focus, -.btn-warning[disabled].focus, -fieldset[disabled] .btn-warning.focus { - background-color: #f0ad4e; - border-color: transparent; -} -.btn-warning .badge { - color: #f0ad4e; - background-color: #ffffff; -} -.btn-danger { - color: #ffffff; - background-color: #d9534f; - border-color: transparent; -} -.btn-danger:focus, -.btn-danger.focus { - color: #ffffff; - background-color: #c9302c; - border-color: rgba(0, 0, 0, 0); -} -.btn-danger:hover { - color: #ffffff; - background-color: #c9302c; - border-color: rgba(0, 0, 0, 0); -} -.btn-danger:active, -.btn-danger.active, -.open > .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #c9302c; - border-color: rgba(0, 0, 0, 0); -} -.btn-danger:active:hover, -.btn-danger.active:hover, -.open > .dropdown-toggle.btn-danger:hover, -.btn-danger:active:focus, -.btn-danger.active:focus, -.open > .dropdown-toggle.btn-danger:focus, -.btn-danger:active.focus, -.btn-danger.active.focus, -.open > .dropdown-toggle.btn-danger.focus { - color: #ffffff; - background-color: #ac2925; - border-color: rgba(0, 0, 0, 0); -} -.btn-danger:active, -.btn-danger.active, -.open > .dropdown-toggle.btn-danger { - background-image: none; -} -.btn-danger.disabled:hover, -.btn-danger[disabled]:hover, -fieldset[disabled] .btn-danger:hover, -.btn-danger.disabled:focus, -.btn-danger[disabled]:focus, -fieldset[disabled] .btn-danger:focus, -.btn-danger.disabled.focus, -.btn-danger[disabled].focus, -fieldset[disabled] .btn-danger.focus { - background-color: #d9534f; - border-color: transparent; -} -.btn-danger .badge { - color: #d9534f; - background-color: #ffffff; -} -.btn-link { - color: #df691a; - font-weight: normal; - border-radius: 0; -} -.btn-link, -.btn-link:active, -.btn-link.active, -.btn-link[disabled], -fieldset[disabled] .btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; -} -.btn-link, -.btn-link:hover, -.btn-link:focus, -.btn-link:active { - border-color: transparent; -} -.btn-link:hover, -.btn-link:focus { - color: #df691a; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, -fieldset[disabled] .btn-link:hover, -.btn-link[disabled]:focus, -fieldset[disabled] .btn-link:focus { - color: #4e5d6c; - text-decoration: none; -} -.btn-lg, -.btn-group-lg > .btn { - padding: 12px 24px; - font-size: 19px; - line-height: 1.3333333; - border-radius: 0; -} -.btn-sm, -.btn-group-sm > .btn { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 0; -} -.btn-xs, -.btn-group-xs > .btn { - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 0; -} -.btn-block { - display: block; - width: 100%; -} -.btn-block + .btn-block { - margin-top: 5px; -} -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} -.fade.in { - opacity: 1; -} -.collapse { - display: none; -} -.collapse.in { - display: block; -} -tr.collapse.in { - display: table-row; -} -tbody.collapse.in { - display: table-row-group; -} -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition-property: height, visibility; - -o-transition-property: height, visibility; - transition-property: height, visibility; - -webkit-transition-duration: 0.35s; - -o-transition-duration: 0.35s; - transition-duration: 0.35s; - -webkit-transition-timing-function: ease; - -o-transition-timing-function: ease; - transition-timing-function: ease; -} -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px dashed; - border-top: 4px solid \9; - border-right: 4px solid transparent; - border-left: 4px solid transparent; -} -.dropup, -.dropdown { - position: relative; -} -.dropdown-toggle:focus { - outline: 0; -} -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 15px; - text-align: left; - background-color: #282828; - border: 1px solid transparent; - border-radius: 0; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - -webkit-background-clip: padding-box; - background-clip: padding-box; -} -.dropdown-menu.pull-right { - right: 0; - left: auto; -} -.dropdown-menu .divider { - height: 1px; - margin: 9.5px 0; - overflow: hidden; - background-color: #333333; -} -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #ebebeb; - white-space: nowrap; -} -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - text-decoration: none; - color: #ebebeb; - background-color: #333333; -} -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #ffffff; - text-decoration: none; - outline: 0; - background-color: #df691a; -} -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #2b3e50; -} -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - cursor: not-allowed; -} -.open > .dropdown-menu { - display: block; -} -.open > a { - outline: 0; -} -.dropdown-menu-right { - left: auto; - right: 0; -} -.dropdown-menu-left { - left: 0; - right: auto; -} -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.42857143; - color: #2b3e50; - white-space: nowrap; -} -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: 990; -} -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px dashed; - border-bottom: 4px solid \9; - content: ""; -} -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 2px; -} -@media (min-width: 768px) { - .navbar-right .dropdown-menu { - left: auto; - right: 0; - } - .navbar-right .dropdown-menu-left { - left: 0; - right: auto; - } -} -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; -} -.btn-group > .btn, -.btn-group-vertical > .btn { - position: relative; - float: left; -} -.btn-group > .btn:hover, -.btn-group-vertical > .btn:hover, -.btn-group > .btn:focus, -.btn-group-vertical > .btn:focus, -.btn-group > .btn:active, -.btn-group-vertical > .btn:active, -.btn-group > .btn.active, -.btn-group-vertical > .btn.active { - z-index: 2; -} -.btn-group .btn + .btn, -.btn-group .btn + .btn-group, -.btn-group .btn-group + .btn, -.btn-group .btn-group + .btn-group { - margin-left: -1px; -} -.btn-toolbar { - margin-left: -5px; -} -.btn-toolbar .btn, -.btn-toolbar .btn-group, -.btn-toolbar .input-group { - float: left; -} -.btn-toolbar > .btn, -.btn-toolbar > .btn-group, -.btn-toolbar > .input-group { - margin-left: 5px; -} -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; -} -.btn-group > .btn:first-child { - margin-left: 0; -} -.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.btn-group > .btn:last-child:not(:first-child), -.btn-group > .dropdown-toggle:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.btn-group > .btn-group { - float: left; -} -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, -.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; -} -.btn-group > .btn-lg + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; -} -.btn-group.open .dropdown-toggle { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn-group.open .dropdown-toggle.btn-link { - -webkit-box-shadow: none; - box-shadow: none; -} -.btn .caret { - margin-left: 0; -} -.btn-lg .caret { - border-width: 5px 5px 0; - border-bottom-width: 0; -} -.dropup .btn-lg .caret { - border-width: 0 5px 5px; -} -.btn-group-vertical > .btn, -.btn-group-vertical > .btn-group, -.btn-group-vertical > .btn-group > .btn { - display: block; - float: none; - width: 100%; - max-width: 100%; -} -.btn-group-vertical > .btn-group > .btn { - float: none; -} -.btn-group-vertical > .btn + .btn, -.btn-group-vertical > .btn + .btn-group, -.btn-group-vertical > .btn-group + .btn, -.btn-group-vertical > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; -} -.btn-group-vertical > .btn:not(:first-child):not(:last-child) { - border-radius: 0; -} -.btn-group-vertical > .btn:first-child:not(:last-child) { - border-top-right-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.btn-group-vertical > .btn:last-child:not(:first-child) { - border-top-right-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, -.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.btn-group-justified { - display: table; - width: 100%; - table-layout: fixed; - border-collapse: separate; -} -.btn-group-justified > .btn, -.btn-group-justified > .btn-group { - float: none; - display: table-cell; - width: 1%; -} -.btn-group-justified > .btn-group .btn { - width: 100%; -} -.btn-group-justified > .btn-group .dropdown-menu { - left: auto; -} -[data-toggle="buttons"] > .btn input[type="radio"], -[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], -[data-toggle="buttons"] > .btn input[type="checkbox"], -[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none; -} -.input-group { - position: relative; - display: table; - border-collapse: separate; -} -.input-group[class*="col-"] { - float: none; - padding-left: 0; - padding-right: 0; -} -.input-group .form-control { - position: relative; - z-index: 2; - float: left; - width: 100%; - margin-bottom: 0; -} -.input-group .form-control:focus { - z-index: 3; -} -.input-group-lg > .form-control, -.input-group-lg > .input-group-addon, -.input-group-lg > .input-group-btn > .btn { - height: 52px; - padding: 12px 24px; - font-size: 19px; - line-height: 1.3333333; - border-radius: 0; -} -select.input-group-lg > .form-control, -select.input-group-lg > .input-group-addon, -select.input-group-lg > .input-group-btn > .btn { - height: 52px; - line-height: 52px; -} -textarea.input-group-lg > .form-control, -textarea.input-group-lg > .input-group-addon, -textarea.input-group-lg > .input-group-btn > .btn, -select[multiple].input-group-lg > .form-control, -select[multiple].input-group-lg > .input-group-addon, -select[multiple].input-group-lg > .input-group-btn > .btn { - height: auto; -} -.input-group-sm > .form-control, -.input-group-sm > .input-group-addon, -.input-group-sm > .input-group-btn > .btn { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 0; -} -select.input-group-sm > .form-control, -select.input-group-sm > .input-group-addon, -select.input-group-sm > .input-group-btn > .btn { - height: 30px; - line-height: 30px; -} -textarea.input-group-sm > .form-control, -textarea.input-group-sm > .input-group-addon, -textarea.input-group-sm > .input-group-btn > .btn, -select[multiple].input-group-sm > .form-control, -select[multiple].input-group-sm > .input-group-addon, -select[multiple].input-group-sm > .input-group-btn > .btn { - height: auto; -} -.input-group-addon, -.input-group-btn, -.input-group .form-control { - display: table-cell; -} -.input-group-addon:not(:first-child):not(:last-child), -.input-group-btn:not(:first-child):not(:last-child), -.input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; -} -.input-group-addon, -.input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle; -} -.input-group-addon { - padding: 8px 16px; - font-size: 15px; - font-weight: normal; - line-height: 1; - color: #2b3e50; - text-align: center; - background-color: #333333; - border: 1px solid transparent; - border-radius: 0; -} -.input-group-addon.input-sm { - padding: 5px 10px; - font-size: 12px; - border-radius: 0; -} -.input-group-addon.input-lg { - padding: 12px 24px; - font-size: 19px; - border-radius: 0; -} -.input-group-addon input[type="radio"], -.input-group-addon input[type="checkbox"] { - margin-top: 0; -} -.input-group .form-control:first-child, -.input-group-addon:first-child, -.input-group-btn:first-child > .btn, -.input-group-btn:first-child > .btn-group > .btn, -.input-group-btn:first-child > .dropdown-toggle, -.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), -.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group-addon:first-child { - border-right: 0; -} -.input-group .form-control:last-child, -.input-group-addon:last-child, -.input-group-btn:last-child > .btn, -.input-group-btn:last-child > .btn-group > .btn, -.input-group-btn:last-child > .dropdown-toggle, -.input-group-btn:first-child > .btn:not(:first-child), -.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.input-group-addon:last-child { - border-left: 0; -} -.input-group-btn { - position: relative; - font-size: 0; - white-space: nowrap; -} -.input-group-btn > .btn { - position: relative; -} -.input-group-btn > .btn + .btn { - margin-left: -1px; -} -.input-group-btn > .btn:hover, -.input-group-btn > .btn:focus, -.input-group-btn > .btn:active { - z-index: 2; -} -.input-group-btn:first-child > .btn, -.input-group-btn:first-child > .btn-group { - margin-right: -1px; -} -.input-group-btn:last-child > .btn, -.input-group-btn:last-child > .btn-group { - z-index: 2; - margin-left: -1px; -} -.nav { - margin-bottom: 0; - padding-left: 0; - list-style: none; -} -.nav > li { - position: relative; - display: block; -} -.nav > li > a { - position: relative; - display: block; - padding: 10px 15px; -} -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #df691a; -} -.nav > li.disabled > a { - color: #4e5d6c; -} -.nav > li.disabled > a:hover, -.nav > li.disabled > a:focus { - color: #4e5d6c; - text-decoration: none; - background-color: transparent; - cursor: not-allowed; -} -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - background-color: #4e5d6c; - border-color: #df691a; -} -.nav .nav-divider { - height: 1px; - margin: 9.5px 0; - overflow: hidden; - background-color: #e5e5e5; -} -.nav > li > a > img { - max-width: none; -} -.nav-tabs { - border-bottom: 1px solid transparent; -} -.nav-tabs > li { - float: left; - margin-bottom: -1px; -} -.nav-tabs > li > a { - margin-right: 2px; - line-height: 1.42857143; - border: 1px solid transparent; - border-radius: 0 0 0 0; -} -.nav-tabs > li > a:hover { - border-color: #df691a #df691a transparent; - - -} -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - color: #ebebeb; - background-color: #df691a; - border: 1px solid #df691a; - border-bottom-color: transparent; - cursor: default; -} -.nav-tabs.nav-justified { - width: 100%; - border-bottom: 0; -} -.nav-tabs.nav-justified > li { - float: none; -} -.nav-tabs.nav-justified > li > a { - text-align: center; - margin-bottom: 5px; -} -.nav-tabs.nav-justified > .dropdown .dropdown-menu { - top: auto; - left: auto; -} -@media (min-width: 768px) { - .nav-tabs.nav-justified > li { - display: table-cell; - width: 1%; - } - .nav-tabs.nav-justified > li > a { - margin-bottom: 0; - } -} -.nav-tabs.nav-justified > li > a { - margin-right: 0; - border-radius: 0; -} -.nav-tabs.nav-justified > .active > a, -.nav-tabs.nav-justified > .active > a:hover, -.nav-tabs.nav-justified > .active > a:focus { - border: 1px solid #df691a; -} -@media (min-width: 768px) { - .nav-tabs.nav-justified > li > a { - border-bottom: 1px solid #4e5d6c; - border-radius: 0 0 0 0; - } - .nav-tabs.nav-justified > .active > a, - .nav-tabs.nav-justified > .active > a:hover, - .nav-tabs.nav-justified > .active > a:focus { - border-bottom-color: #4e5d6c; - } -} -.nav-pills > li { - float: left; -} -.nav-pills > li > a { - border-radius: 0; -} -.nav-pills > li + li { - margin-left: 2px; -} -.nav-pills > li.active > a, -.nav-pills > li.active > a:hover, -.nav-pills > li.active > a:focus { - color: #ffffff; - background-color: #df691a; -} -.nav-stacked > li { - float: none; -} -.nav-stacked > li + li { - margin-top: 2px; - margin-left: 0; -} -.nav-justified { - width: 100%; -} -.nav-justified > li { - float: none; -} -.nav-justified > li > a { - text-align: center; - margin-bottom: 5px; -} -.nav-justified > .dropdown .dropdown-menu { - top: auto; - left: auto; -} -@media (min-width: 768px) { - .nav-justified > li { - display: table-cell; - width: 1%; - } - .nav-justified > li > a { - margin-bottom: 0; - } -} -.nav-tabs-justified { - border-bottom: 0; -} -.nav-tabs-justified > li > a { - margin-right: 0; - border-radius: 0; -} -.nav-tabs-justified > .active > a, -.nav-tabs-justified > .active > a:hover, -.nav-tabs-justified > .active > a:focus { - border: 1px solid #4e5d6c; -} -@media (min-width: 768px) { - .nav-tabs-justified > li > a { - border-bottom: 1px solid #4e5d6c; - border-radius: 0 0 0 0; - } - .nav-tabs-justified > .active > a, - .nav-tabs-justified > .active > a:hover, - .nav-tabs-justified > .active > a:focus { - border-bottom-color: #4e5d6c; - } -} -.tab-content > .tab-pane { - display: none; -} -.tab-content > .active { - display: block; -} -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.navbar { - position: fixed; - top: 0px; - right: 0px; - left: 0px; - z-index: 1000; - padding: 0px 3px; - font-size: 24px; - background-color: #000; - box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.2); -} - - -@media (min-width: 768px) { - .navbar { - border-radius: 0; - } -} -@media (min-width: 768px) { - .navbar-header { - float: left; - } -} -.navbar-collapse { - overflow-x: visible; - padding-right: 15px; - padding-left: 15px; - border-top: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - -webkit-overflow-scrolling: touch; -} -.navbar-collapse.in { - overflow-y: auto; -} -@media (min-width: 768px) { - .navbar-collapse { - width: auto; - border-top: 0; - -webkit-box-shadow: none; - box-shadow: none; - } - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - .navbar-collapse.in { - overflow-y: visible; - } - .navbar-fixed-top .navbar-collapse, - .navbar-static-top .navbar-collapse, - .navbar-fixed-bottom .navbar-collapse { - padding-left: 0; - padding-right: 0; - } -} -.navbar-fixed-top .navbar-collapse, -.navbar-fixed-bottom .navbar-collapse { - max-height: 340px; -} -@media (max-device-width: 480px) and (orientation: landscape) { - .navbar-fixed-top .navbar-collapse, - .navbar-fixed-bottom .navbar-collapse { - max-height: 200px; - } -} -.container > .navbar-header, -.container-fluid > .navbar-header, -.container > .navbar-collapse, -.container-fluid > .navbar-collapse { - margin-right: -15px; - margin-left: -15px; -} -@media (min-width: 768px) { - .container > .navbar-header, - .container-fluid > .navbar-header, - .container > .navbar-collapse, - .container-fluid > .navbar-collapse { - margin-right: 0; - margin-left: 0; - } -} -.navbar-static-top { - z-index: 1000; - border-width: 0 0 1px; -} -@media (min-width: 768px) { - .navbar-static-top { - border-radius: 0; - } -} -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; -} -@media (min-width: 768px) { - .navbar-fixed-top, - .navbar-fixed-bottom { - border-radius: 0; - } -} -.navbar-fixed-top { - top: 0; - border-width: 0 0 1px; -} -.navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; - border-width: 1px 0 0; -} -.navbar-brand { - float: left; - padding: 9.5px 15px; - font-size: 19px; - line-height: 21px; - height: 40px; -} -.navbar-brand:hover, -.navbar-brand:focus { - text-decoration: none; -} -.navbar-brand > img { - display: block; -} -@media (min-width: 768px) { - .navbar > .container .navbar-brand, - .navbar > .container-fluid .navbar-brand { - margin-left: -15px; - } -} -.navbar-toggle { - position: relative; - float: right; - margin-right: 15px; - padding: 9px 10px; - margin-top: 3px; - margin-bottom: 3px; - background-color: transparent; - background-image: none; - border: 1px solid transparent; - border-radius: 0; -} -.navbar-toggle:focus { - outline: 0; -} -.navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; -} -.navbar-toggle .icon-bar + .icon-bar { - margin-top: 4px; -} -@media (min-width: 768px) { - .navbar-toggle { - display: none; - } -} -.navbar-nav { - margin: 4.75px -15px; -} -.navbar-nav > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 21px; -} -@media (max-width: 767px) { - .navbar-nav .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - -webkit-box-shadow: none; - box-shadow: none; - } - .navbar-nav .open .dropdown-menu > li > a, - .navbar-nav .open .dropdown-menu .dropdown-header { - padding: 5px 15px 5px 25px; - } - .navbar-nav .open .dropdown-menu > li > a { - line-height: 21px; - } - .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-nav .open .dropdown-menu > li > a:focus { - background-image: none; - } -} -@media (min-width: 768px) { - .navbar-nav { - float: left; - margin: 0; - } - .navbar-nav > li { - float: left; - } - .navbar-nav > li > a { - padding-top: 9.5px; - padding-bottom: 9.5px; - } -} -.navbar-form { - margin-left: -15px; - margin-right: -15px; - padding: 10px 15px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - margin-top: 0.5px; - margin-bottom: 0.5px; -} -@media (min-width: 768px) { - .navbar-form .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .navbar-form .form-control-static { - display: inline-block; - } - .navbar-form .input-group { - display: inline-table; - vertical-align: middle; - } - .navbar-form .input-group .input-group-addon, - .navbar-form .input-group .input-group-btn, - .navbar-form .input-group .form-control { - width: auto; - } - .navbar-form .input-group > .form-control { - width: 100%; - } - .navbar-form .control-label { - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .radio, - .navbar-form .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .radio label, - .navbar-form .checkbox label { - padding-left: 0; - } - .navbar-form .radio input[type="radio"], - .navbar-form .checkbox input[type="checkbox"] { - position: relative; - margin-left: 0; - } - .navbar-form .has-feedback .form-control-feedback { - top: 0; - } -} -@media (max-width: 767px) { - .navbar-form .form-group { - margin-bottom: 5px; - } - .navbar-form .form-group:last-child { - margin-bottom: 0; - } -} -@media (min-width: 768px) { - .navbar-form { - width: auto; - border: 0; - margin-left: 0; - margin-right: 0; - padding-top: 0; - padding-bottom: 0; - -webkit-box-shadow: none; - box-shadow: none; - } -} -.navbar-nav > li > .dropdown-menu { - margin-top: 0; - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { - margin-bottom: 0; - border-top-right-radius: 0; - border-top-left-radius: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.navbar-btn { - margin-top: 0.5px; - margin-bottom: 0.5px; -} -.navbar-btn.btn-sm { - margin-top: 5px; - margin-bottom: 5px; -} -.navbar-btn.btn-xs { - margin-top: 9px; - margin-bottom: 9px; -} -.navbar-text { - margin-top: 9.5px; - margin-bottom: 9.5px; -} -@media (min-width: 768px) { - .navbar-text { - float: left; - margin-left: 15px; - margin-right: 15px; - } -} -@media (min-width: 768px) { - .navbar-left { - float: left !important; - } - .navbar-right { - float: right !important; - margin-right: -15px; - } - .navbar-right ~ .navbar-right { - margin-right: 0; - } -} -.navbar-default { - background-color: #0a0a0a; - border-color: transparent; -} -.navbar-default .navbar-brand { - color: #DF691A; -} -.navbar-default .navbar-brand:hover, -.navbar-default .navbar-brand:focus { - color: #ebebeb; - background-color: transparent; -} -.navbar-default .navbar-text { - color: #ebebeb; -} -.navbar-default .navbar-nav > li > a { - color: #ebebeb; -} -.navbar-default .navbar-nav > li > a:hover, -.navbar-default .navbar-nav > li > a:focus { - color: #F0ad4e; - background-color: #282828; -} -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #009688; - background-color: #282828; -} -.navbar-default .navbar-nav > .disabled > a, -.navbar-default .navbar-nav > .disabled > a:hover, -.navbar-default .navbar-nav > .disabled > a:focus { - color: #cccccc; - background-color: transparent; -} -.navbar-default .navbar-toggle { - border-color: transparent; -} -.navbar-default .navbar-toggle:hover, -.navbar-default .navbar-toggle:focus { - background-color: #485563; -} -.navbar-default .navbar-toggle .icon-bar { - background-color: #ebebeb; -} -.navbar-default .navbar-collapse, -.navbar-default .navbar-form { - border-color: transparent; -} -.navbar-default .navbar-nav > .open > a, -.navbar-default .navbar-nav > .open > a:hover, -.navbar-default .navbar-nav > .open > a:focus { - background-color: #f9be03; - color: #282828; -} -@media (max-width: 767px) { - .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #ebebeb; - } - .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: #ebebeb; - background-color: #485563; - } - .navbar-default .navbar-nav .open .dropdown-menu > .active > a, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #ebebeb; - background-color: #485563; - } - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #cccccc; - background-color: transparent; - } -} -.navbar-default .navbar-link { - color: #ebebeb; -} -.navbar-default .navbar-link:hover { - color: #ebebeb; -} -.navbar-default .btn-link { - color: #ebebeb; -} -.navbar-default .btn-link:hover, -.navbar-default .btn-link:focus { - color: #ebebeb; -} -.navbar-default .btn-link[disabled]:hover, -fieldset[disabled] .navbar-default .btn-link:hover, -.navbar-default .btn-link[disabled]:focus, -fieldset[disabled] .navbar-default .btn-link:focus { - color: #cccccc; -} -.navbar-inverse { - background-color: #df691a; - border-color: transparent; -} -.navbar-inverse .navbar-brand { - color: #ebebeb; -} -.navbar-inverse .navbar-brand:hover, -.navbar-inverse .navbar-brand:focus { - color: #ebebeb; - background-color: transparent; -} -.navbar-inverse .navbar-text { - color: #ebebeb; -} -.navbar-inverse .navbar-nav > li > a { - color: #ebebeb; -} -.navbar-inverse .navbar-nav > li > a:hover, -.navbar-inverse .navbar-nav > li > a:focus { - color: #ebebeb; - background-color: #c85e17; -} -.navbar-inverse .navbar-nav > .active > a, -.navbar-inverse .navbar-nav > .active > a:hover, -.navbar-inverse .navbar-nav > .active > a:focus { - color: #ebebeb; - background-color: #c85e17; -} -.navbar-inverse .navbar-nav > .disabled > a, -.navbar-inverse .navbar-nav > .disabled > a:hover, -.navbar-inverse .navbar-nav > .disabled > a:focus { - color: #444444; - background-color: transparent; -} -.navbar-inverse .navbar-toggle { - border-color: transparent; -} -.navbar-inverse .navbar-toggle:hover, -.navbar-inverse .navbar-toggle:focus { - background-color: #c85e17; -} -.navbar-inverse .navbar-toggle .icon-bar { - background-color: #ebebeb; -} -.navbar-inverse .navbar-collapse, -.navbar-inverse .navbar-form { - border-color: #bf5a16; -} -.navbar-inverse .navbar-nav > .open > a, -.navbar-inverse .navbar-nav > .open > a:hover, -.navbar-inverse .navbar-nav > .open > a:focus { - background-color: #c85e17; - color: #ebebeb; -} -@media (max-width: 767px) { - .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { - border-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu .divider { - background-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { - color: #ebebeb; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { - color: #ebebeb; - background-color: #c85e17; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #ebebeb; - background-color: #c85e17; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #444444; - background-color: transparent; - } -} -.navbar-inverse .navbar-link { - color: #ebebeb; -} -.navbar-inverse .navbar-link:hover { - color: #ebebeb; -} -.navbar-inverse .btn-link { - color: #ebebeb; -} -.navbar-inverse .btn-link:hover, -.navbar-inverse .btn-link:focus { - color: #ebebeb; -} -.navbar-inverse .btn-link[disabled]:hover, -fieldset[disabled] .navbar-inverse .btn-link:hover, -.navbar-inverse .btn-link[disabled]:focus, -fieldset[disabled] .navbar-inverse .btn-link:focus { - color: #444444; -} -.breadcrumb { - padding: 8px 15px; - margin-bottom: 21px; - list-style: none; - background-color: #4e5d6c; - border-radius: 0; -} -.breadcrumb > li { - display: inline-block; -} -.breadcrumb > li + li:before { - content: "/\00a0"; - padding: 0 5px; - color: #ebebeb; -} -.breadcrumb > .active { - color: #ebebeb; -} -.pagination { - display: inline-block; - padding-left: 0; - margin: 21px 0; - border-radius: 0; -} -.pagination > li { - display: inline; -} -.pagination > li > a, -.pagination > li > span { - position: relative; - float: left; - padding: 8px 16px; - line-height: 1.42857143; - text-decoration: none; - color: #ebebeb; - background-color: #282828; - border: 1px solid transparent; - margin-left: -1px; -} -.pagination > li:first-child > a, -.pagination > li:first-child > span { - margin-left: 0; - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.pagination > li:last-child > a, -.pagination > li:last-child > span { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.pagination > li > a:hover, -.pagination > li > span:hover, -.pagination > li > a:focus, -.pagination > li > span:focus { - z-index: 2; - color: #ebebeb; - background-color: #333333; - border-color: transparent; -} -.pagination > .active > a, -.pagination > .active > span, -.pagination > .active > a:hover, -.pagination > .active > span:hover, -.pagination > .active > a:focus, -.pagination > .active > span:focus { - z-index: 3; - color: #ebebeb; - background-color: #df691a; - border-color: transparent; - cursor: default; -} -.pagination > .disabled > span, -.pagination > .disabled > span:hover, -.pagination > .disabled > span:focus, -.pagination > .disabled > a, -.pagination > .disabled > a:hover, -.pagination > .disabled > a:focus { - color: #fefefe; - background-color: #333333; - border-color: transparent; - cursor: not-allowed; -} -.pagination-lg > li > a, -.pagination-lg > li > span { - padding: 12px 24px; - font-size: 19px; - line-height: 1.3333333; -} -.pagination-lg > li:first-child > a, -.pagination-lg > li:first-child > span { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.pagination-lg > li:last-child > a, -.pagination-lg > li:last-child > span { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.pagination-sm > li > a, -.pagination-sm > li > span { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; -} -.pagination-sm > li:first-child > a, -.pagination-sm > li:first-child > span { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.pagination-sm > li:last-child > a, -.pagination-sm > li:last-child > span { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.pager { - padding-left: 0; - margin: 21px 0; - list-style: none; - text-align: center; -} -.pager li { - display: inline; -} -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #4e5d6c; - border: 1px solid transparent; - border-radius: 15px; -} -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #485563; -} -.pager .next > a, -.pager .next > span { - float: right; -} -.pager .previous > a, -.pager .previous > span { - float: left; -} -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #323c46; - background-color: #4e5d6c; - cursor: not-allowed; -} -.label { - display: inline; - padding: .2em .6em .3em; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: .25em; -} -a.label:hover, -a.label:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} -.label:empty { - display: none; -} -.btn .label { - position: relative; - top: -1px; -} -.label-default { - background-color: #4e5d6c; -} -.label-default[href]:hover, -.label-default[href]:focus { - background-color: #39444e; -} -.label-primary { - background-color: #df691a; -} -.label-primary[href]:hover, -.label-primary[href]:focus { - background-color: #b15315; -} -.label-success { - background-color: #5cb85c; -} -.label-success[href]:hover, -.label-success[href]:focus { - background-color: #449d44; -} -.label-info { - background-color: #5bc0de; -} -.label-info[href]:hover, -.label-info[href]:focus { - background-color: #31b0d5; -} -.label-warning { - background-color: #f0ad4e; -} -.label-warning[href]:hover, -.label-warning[href]:focus { - background-color: #ec971f; -} -.label-danger { - background-color: #d9534f; -} -.label-danger[href]:hover, -.label-danger[href]:focus { - background-color: #c9302c; -} -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: 12px; - font-weight: 300; - color: #ebebeb; - line-height: 1; - vertical-align: middle; - white-space: nowrap; - text-align: center; - background-color: #4e5d6c; - border-radius: 10px; -} -.badge:empty { - display: none; -} -.btn .badge { - position: relative; - top: -1px; -} -.btn-xs .badge, -.btn-group-xs > .btn .badge { - top: 0; - padding: 1px 5px; -} -a.badge:hover, -a.badge:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} -.list-group-item.active > .badge, -.nav-pills > .active > a > .badge { - color: #df691a; - background-color: #ffffff; -} -.list-group-item > .badge { - float: right; -} -.list-group-item > .badge + .badge { - margin-right: 5px; -} -.nav-pills > li > a > .badge { - margin-left: 3px; -} -.jumbotron { - padding-top: 30px; - padding-bottom: 30px; - margin-bottom: 30px; - color: inherit; - background-color: #4e5d6c; -} -.jumbotron h1, -.jumbotron .h1 { - color: inherit; -} -.jumbotron p { - margin-bottom: 15px; - font-size: 23px; - font-weight: 200; -} -.jumbotron > hr { - border-top-color: #39444e; -} -.container .jumbotron, -.container-fluid .jumbotron { - border-radius: 0; - padding-left: 15px; - padding-right: 15px; -} -.jumbotron .container { - max-width: 100%; -} -@media screen and (min-width: 768px) { - .jumbotron { - padding-top: 48px; - padding-bottom: 48px; - } - .container .jumbotron, - .container-fluid .jumbotron { - padding-left: 60px; - padding-right: 60px; - } - .jumbotron h1, - .jumbotron .h1 { - font-size: 68px; - } -} -.thumbnail { - display: block; - padding: 4px; - margin-bottom: 21px; - line-height: 1.42857143; - background-color: #2b3e50; - border: 1px solid #dddddd; - border-radius: 0; - -webkit-transition: border 0.2s ease-in-out; - -o-transition: border 0.2s ease-in-out; - transition: border 0.2s ease-in-out; -} -.thumbnail > img, -.thumbnail a > img { - margin-left: auto; - margin-right: auto; -} -a.thumbnail:hover, -a.thumbnail:focus, -a.thumbnail.active { - border-color: #df691a; -} -.thumbnail .caption { - padding: 9px; - color: #ebebeb; -} -.alert { - padding: 15px; - margin-bottom: 21px; - border: 1px solid transparent; - border-radius: 0; -} -.alert h4 { - margin-top: 0; - color: inherit; -} -.alert .alert-link { - font-weight: bold; -} -.alert > p, -.alert > ul { - margin-bottom: 0; -} -.alert > p + p { - margin-top: 5px; -} -.alert-dismissable, -.alert-dismissible { - padding-right: 35px; -} -.alert-dismissable .close, -.alert-dismissible .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; -} -.alert-success { - background-color: #5cb85c; - border-color: transparent; - color: #ebebeb; -} -.alert-success hr { - border-top-color: rgba(0, 0, 0, 0); -} -.alert-success .alert-link { - color: #d2d2d2; -} -.alert-info { - background-color: #5bc0de; - border-color: transparent; - color: #ebebeb; -} -.alert-info hr { - border-top-color: rgba(0, 0, 0, 0); -} -.alert-info .alert-link { - color: #d2d2d2; -} -.alert-warning { - background-color: #f0ad4e; - border-color: transparent; - color: #ebebeb; -} -.alert-warning hr { - border-top-color: rgba(0, 0, 0, 0); -} -.alert-warning .alert-link { - color: #d2d2d2; -} -.alert-danger { - background-color: #d9534f; - border-color: transparent; - color: #ebebeb; -} -.alert-danger hr { - border-top-color: rgba(0, 0, 0, 0); -} -.alert-danger .alert-link { - color: #d2d2d2; -} -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-o-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -.progress { - overflow: hidden; - height: 21px; - margin-bottom: 21px; - background-color: #4e5d6c; - border-radius: 0; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} -.progress-bar { - float: left; - width: 0%; - height: 100%; - font-size: 12px; - line-height: 21px; - color: #ffffff; - text-align: center; - background-color: #df691a; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; -} -.progress-striped .progress-bar, -.progress-bar-striped { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - -webkit-background-size: 40px 40px; - background-size: 40px 40px; -} -.progress.active .progress-bar, -.progress-bar.active { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} -.progress-bar-success { - background-color: #5cb85c; -} -.progress-striped .progress-bar-success { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-info { - background-color: #5bc0de; -} -.progress-striped .progress-bar-info { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-warning { - background-color: #f0ad4e; -} -.progress-striped .progress-bar-warning { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-danger { - background-color: #d9534f; -} -.progress-striped .progress-bar-danger { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.media { - margin-top: 15px; -} -.media:first-child { - margin-top: 0; -} -.media, -.media-body { - zoom: 1; - overflow: hidden; -} -.media-body { - width: 10000px; -} -.media-object { - display: block; -} -.media-object.img-thumbnail { - max-width: none; -} -.media-right, -.media > .pull-right { - padding-left: 10px; -} -.media-left, -.media > .pull-left { - padding-right: 10px; -} -.media-left, -.media-right, -.media-body { - display: table-cell; - vertical-align: top; -} -.media-middle { - vertical-align: middle; -} -.media-bottom { - vertical-align: bottom; -} -.media-heading { - margin-top: 0; - margin-bottom: 5px; -} -.media-list { - padding-left: 0; - list-style: none; -} -.list-group { - margin-bottom: 20px; - padding-left: 0; -} -.list-group-item { - position: relative; - display: block; - padding: 10px 15px; - margin-bottom: -1px; - background-color: #282828; - border: 1px solid transparent; -} -.list-group-item:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -a.list-group-item, -button.list-group-item { - color: #ebebeb; -} -a.list-group-item .list-group-item-heading, -button.list-group-item .list-group-item-heading { - color: #ebebeb; -} -a.list-group-item:hover, -button.list-group-item:hover, -a.list-group-item:focus, -button.list-group-item:focus { - text-decoration: none; - color: #ebebeb; - background-color: #333333; -} -button.list-group-item { - width: 100%; - text-align: left; -} -.list-group-item.disabled, -.list-group-item.disabled:hover, -.list-group-item.disabled:focus { - background-color: #ebebeb; - color: #4e5d6c; - cursor: not-allowed; -} -.list-group-item.disabled .list-group-item-heading, -.list-group-item.disabled:hover .list-group-item-heading, -.list-group-item.disabled:focus .list-group-item-heading { - color: inherit; -} -.list-group-item.disabled .list-group-item-text, -.list-group-item.disabled:hover .list-group-item-text, -.list-group-item.disabled:focus .list-group-item-text { - color: #4e5d6c; -} -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - z-index: 2; - color: #ffffff; - background-color: #df691a; - border-color: #df691a; -} -.list-group-item.active .list-group-item-heading, -.list-group-item.active:hover .list-group-item-heading, -.list-group-item.active:focus .list-group-item-heading, -.list-group-item.active .list-group-item-heading > small, -.list-group-item.active:hover .list-group-item-heading > small, -.list-group-item.active:focus .list-group-item-heading > small, -.list-group-item.active .list-group-item-heading > .small, -.list-group-item.active:hover .list-group-item-heading > .small, -.list-group-item.active:focus .list-group-item-heading > .small { - color: inherit; -} -.list-group-item.active .list-group-item-text, -.list-group-item.active:hover .list-group-item-text, -.list-group-item.active:focus .list-group-item-text { - color: #f9decc; -} -.list-group-item-success { - color: #ebebeb; - background-color: #5cb85c; -} -a.list-group-item-success, -button.list-group-item-success { - color: #ebebeb; -} -a.list-group-item-success .list-group-item-heading, -button.list-group-item-success .list-group-item-heading { - color: inherit; -} -a.list-group-item-success:hover, -button.list-group-item-success:hover, -a.list-group-item-success:focus, -button.list-group-item-success:focus { - color: #ebebeb; - background-color: #4cae4c; -} -a.list-group-item-success.active, -button.list-group-item-success.active, -a.list-group-item-success.active:hover, -button.list-group-item-success.active:hover, -a.list-group-item-success.active:focus, -button.list-group-item-success.active:focus { - color: #fff; - background-color: #ebebeb; - border-color: #ebebeb; -} -.list-group-item-info { - color: #ebebeb; - background-color: #5bc0de; -} -a.list-group-item-info, -button.list-group-item-info { - color: #ebebeb; -} -a.list-group-item-info .list-group-item-heading, -button.list-group-item-info .list-group-item-heading { - color: inherit; -} -a.list-group-item-info:hover, -button.list-group-item-info:hover, -a.list-group-item-info:focus, -button.list-group-item-info:focus { - color: #ebebeb; - background-color: #46b8da; -} -a.list-group-item-info.active, -button.list-group-item-info.active, -a.list-group-item-info.active:hover, -button.list-group-item-info.active:hover, -a.list-group-item-info.active:focus, -button.list-group-item-info.active:focus { - color: #fff; - background-color: #ebebeb; - border-color: #ebebeb; -} -.list-group-item-warning { - color: #ebebeb; - background-color: #f0ad4e; -} -a.list-group-item-warning, -button.list-group-item-warning { - color: #ebebeb; -} -a.list-group-item-warning .list-group-item-heading, -button.list-group-item-warning .list-group-item-heading { - color: inherit; -} -a.list-group-item-warning:hover, -button.list-group-item-warning:hover, -a.list-group-item-warning:focus, -button.list-group-item-warning:focus { - color: #ebebeb; - background-color: #eea236; -} -a.list-group-item-warning.active, -button.list-group-item-warning.active, -a.list-group-item-warning.active:hover, -button.list-group-item-warning.active:hover, -a.list-group-item-warning.active:focus, -button.list-group-item-warning.active:focus { - color: #fff; - background-color: #ebebeb; - border-color: #ebebeb; -} -.list-group-item-danger { - color: #ebebeb; - background-color: #d9534f; -} -a.list-group-item-danger, -button.list-group-item-danger { - color: #ebebeb; -} -a.list-group-item-danger .list-group-item-heading, -button.list-group-item-danger .list-group-item-heading { - color: inherit; -} -a.list-group-item-danger:hover, -button.list-group-item-danger:hover, -a.list-group-item-danger:focus, -button.list-group-item-danger:focus { - color: #ebebeb; - background-color: #d43f3a; -} -a.list-group-item-danger.active, -button.list-group-item-danger.active, -a.list-group-item-danger.active:hover, -button.list-group-item-danger.active:hover, -a.list-group-item-danger.active:focus, -button.list-group-item-danger.active:focus { - color: #fff; - background-color: #ebebeb; - border-color: #ebebeb; -} -.list-group-item-heading { - margin-top: 0; - margin-bottom: 5px; -} -.list-group-item-text { - margin-bottom: 0; - line-height: 1.3; -} -.panel { - margin-bottom: 21px; - background-color: #4e5d6c; - border: 1px solid transparent; - border-radius: 0; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); -} -.panel-body { - padding: 15px; -} -.panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - border-top-right-radius: -1; - border-top-left-radius: -1; -} -.panel-heading > .dropdown .dropdown-toggle { - color: inherit; -} -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: 17px; - color: inherit; -} -.panel-title > a, -.panel-title > small, -.panel-title > .small, -.panel-title > small > a, -.panel-title > .small > a { - color: inherit; -} -.panel-footer { - padding: 10px 15px; - background-color: #485563; - border-top: 1px solid transparent; - border-bottom-right-radius: -1; - border-bottom-left-radius: -1; -} -.panel > .list-group, -.panel > .panel-collapse > .list-group { - margin-bottom: 0; -} -.panel > .list-group .list-group-item, -.panel > .panel-collapse > .list-group .list-group-item { - border-width: 1px 0; - border-radius: 0; -} -.panel > .list-group:first-child .list-group-item:first-child, -.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { - border-top: 0; - border-top-right-radius: -1; - border-top-left-radius: -1; -} -.panel > .list-group:last-child .list-group-item:last-child, -.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { - border-bottom: 0; - border-bottom-right-radius: -1; - border-bottom-left-radius: -1; -} -.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.panel-heading + .list-group .list-group-item:first-child { - border-top-width: 0; -} -.list-group + .panel-footer { - border-top-width: 0; -} -.panel > .table, -.panel > .table-responsive > .table, -.panel > .panel-collapse > .table { - margin-bottom: 0; -} -.panel > .table caption, -.panel > .table-responsive > .table caption, -.panel > .panel-collapse > .table caption { - padding-left: 15px; - padding-right: 15px; -} -.panel > .table:first-child, -.panel > .table-responsive:first-child > .table:first-child { - border-top-right-radius: -1; - border-top-left-radius: -1; -} -.panel > .table:first-child > thead:first-child > tr:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { - border-top-left-radius: -1; - border-top-right-radius: -1; -} -.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, -.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { - border-top-left-radius: -1; -} -.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, -.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, -.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, -.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { - border-top-right-radius: -1; -} -.panel > .table:last-child, -.panel > .table-responsive:last-child > .table:last-child { - border-bottom-right-radius: -1; - border-bottom-left-radius: -1; -} -.panel > .table:last-child > tbody:last-child > tr:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { - border-bottom-left-radius: -1; - border-bottom-right-radius: -1; -} -.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, -.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { - border-bottom-left-radius: -1; -} -.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, -.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { - border-bottom-right-radius: -1; -} -.panel > .panel-body + .table, -.panel > .panel-body + .table-responsive, -.panel > .table + .panel-body, -.panel > .table-responsive + .panel-body { - border-top: 1px solid #4e5d6c; -} -.panel > .table > tbody:first-child > tr:first-child th, -.panel > .table > tbody:first-child > tr:first-child td { - border-top: 0; -} -.panel > .table-bordered, -.panel > .table-responsive > .table-bordered { - border: 0; -} -.panel > .table-bordered > thead > tr > th:first-child, -.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, -.panel > .table-bordered > tbody > tr > th:first-child, -.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, -.panel > .table-bordered > tfoot > tr > th:first-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, -.panel > .table-bordered > thead > tr > td:first-child, -.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, -.panel > .table-bordered > tbody > tr > td:first-child, -.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, -.panel > .table-bordered > tfoot > tr > td:first-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; -} -.panel > .table-bordered > thead > tr > th:last-child, -.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, -.panel > .table-bordered > tbody > tr > th:last-child, -.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, -.panel > .table-bordered > tfoot > tr > th:last-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, -.panel > .table-bordered > thead > tr > td:last-child, -.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, -.panel > .table-bordered > tbody > tr > td:last-child, -.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, -.panel > .table-bordered > tfoot > tr > td:last-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; -} -.panel > .table-bordered > thead > tr:first-child > td, -.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, -.panel > .table-bordered > tbody > tr:first-child > td, -.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, -.panel > .table-bordered > thead > tr:first-child > th, -.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, -.panel > .table-bordered > tbody > tr:first-child > th, -.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { - border-bottom: 0; -} -.panel > .table-bordered > tbody > tr:last-child > td, -.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, -.panel > .table-bordered > tfoot > tr:last-child > td, -.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, -.panel > .table-bordered > tbody > tr:last-child > th, -.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, -.panel > .table-bordered > tfoot > tr:last-child > th, -.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { - border-bottom: 0; -} -.panel > .table-responsive { - border: 0; - margin-bottom: 0; -} -.panel-group { - margin-bottom: 21px; -} -.panel-group .panel { - margin-bottom: 0; - border-radius: 0; -} -.panel-group .panel + .panel { - margin-top: 5px; -} -.panel-group .panel-heading { - border-bottom: 0; -} -.panel-group .panel-heading + .panel-collapse > .panel-body, -.panel-group .panel-heading + .panel-collapse > .list-group { - border-top: 1px solid transparent; -} -.panel-group .panel-footer { - border-top: 0; -} -.panel-group .panel-footer + .panel-collapse .panel-body { - border-bottom: 1px solid transparent; -} -.panel-default { - border-color: transparent; -} -.panel-default > .panel-heading { - color: #333333; - background-color: #f5f5f5; - border-color: transparent; -} -.panel-default > .panel-heading + .panel-collapse > .panel-body { - border-top-color: transparent; -} -.panel-default > .panel-heading .badge { - color: #f5f5f5; - background-color: #333333; -} -.panel-default > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: transparent; -} -.panel-primary { - border-color: transparent; -} -.panel-primary > .panel-heading { - color: #ffffff; - background-color: #df691a; - border-color: transparent; -} -.panel-primary > .panel-heading + .panel-collapse > .panel-body { - border-top-color: transparent; -} -.panel-primary > .panel-heading .badge { - color: #df691a; - background-color: #ffffff; -} -.panel-primary > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: transparent; -} -.panel-success { - border-color: transparent; -} -.panel-success > .panel-heading { - color: #ebebeb; - background-color: #5cb85c; - border-color: transparent; -} -.panel-success > .panel-heading + .panel-collapse > .panel-body { - border-top-color: transparent; -} -.panel-success > .panel-heading .badge { - color: #5cb85c; - background-color: #ebebeb; -} -.panel-success > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: transparent; -} -.panel-info { - border-color: transparent; -} -.panel-info > .panel-heading { - color: #ebebeb; - background-color: #5bc0de; - border-color: transparent; -} -.panel-info > .panel-heading + .panel-collapse > .panel-body { - border-top-color: transparent; -} -.panel-info > .panel-heading .badge { - color: #5bc0de; - background-color: #ebebeb; -} -.panel-info > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: transparent; -} -.panel-warning { - border-color: transparent; -} -.panel-warning > .panel-heading { - color: #ebebeb; - background-color: #f0ad4e; - border-color: transparent; -} -.panel-warning > .panel-heading + .panel-collapse > .panel-body { - border-top-color: transparent; -} -.panel-warning > .panel-heading .badge { - color: #f0ad4e; - background-color: #ebebeb; -} -.panel-warning > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: transparent; -} -.panel-danger { - border-color: transparent; -} -.panel-danger > .panel-heading { - color: #ebebeb; - background-color: #d9534f; - border-color: transparent; -} -.panel-danger > .panel-heading + .panel-collapse > .panel-body { - border-top-color: transparent; -} -.panel-danger > .panel-heading .badge { - color: #d9534f; - background-color: #ebebeb; -} -.panel-danger > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: transparent; -} -.embed-responsive { - position: relative; - display: block; - height: 0; - padding: 0; - overflow: hidden; -} -.embed-responsive .embed-responsive-item, -.embed-responsive iframe, -.embed-responsive embed, -.embed-responsive object, -.embed-responsive video { - position: absolute; - top: 0; - left: 0; - bottom: 0; - height: 100%; - width: 100%; - border: 0; -} -.embed-responsive-16by9 { - padding-bottom: 56.25%; -} -.embed-responsive-4by3 { - padding-bottom: 75%; -} -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #4e5d6c; - border: 1px solid transparent; - border-radius: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} -.well-lg { - padding: 24px; - border-radius: 0; -} -.well-sm { - padding: 9px; - border-radius: 0; -} -.close { - float: right; - font-size: 22.5px; - font-weight: bold; - line-height: 1; - color: #ebebeb; - text-shadow: none; - opacity: 0.2; - filter: alpha(opacity=20); -} -.close:hover, -.close:focus { - color: #ebebeb; - text-decoration: none; - cursor: pointer; - opacity: 0.5; - filter: alpha(opacity=50); -} -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} -.modal-open { - overflow: hidden; -} -.modal { - display: none; - overflow: hidden; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1050; - -webkit-overflow-scrolling: touch; - outline: 0; -} -.modal.fade .modal-dialog { - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - -o-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; -} -.modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0); -} -.modal-open .modal { - overflow-x: hidden; - overflow-y: auto; -} -.modal-dialog { - position: relative; - width: auto; - margin: 10px; -} -.modal-content { - position: relative; - background-color: #282828; - border: 1px solid transparent; - border-radius: 0; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - -webkit-background-clip: padding-box; - background-clip: padding-box; - outline: 0; -} -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000000; -} -.modal-backdrop.fade { - opacity: 0; - filter: alpha(opacity=0); -} -.modal-backdrop.in { - opacity: 0.5; - filter: alpha(opacity=50); -} -.modal-header { - padding: 15px; - border-bottom: 1px solid #2b3e50; -} -.modal-header .close { - margin-top: -2px; -} -.modal-title { - margin: 0; - line-height: 1.42857143; -} -.modal-body { - position: relative; - padding: 20px; -} -.modal-footer { - padding: 20px; - text-align: right; - border-top: 1px solid #2b3e50; -} -.modal-footer .btn + .btn { - margin-left: 5px; - margin-bottom: 0; -} -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; -} -@media (min-width: 768px) { - .modal-dialog { - width: 600px; - margin: 30px auto; - } - .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - } - .modal-sm { - width: 300px; - } -} -@media (min-width: 992px) { - .modal-lg { - width: 900px; - } -} -.tooltip { - position: absolute; - z-index: 1070; - display: block; - font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-style: normal; - font-weight: normal; - letter-spacing: normal; - line-break: auto; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - font-size: 12px; - opacity: 0; - filter: alpha(opacity=0); -} -.tooltip.in { - opacity: 0.9; - filter: alpha(opacity=90); -} -.tooltip.top { - margin-top: -3px; - padding: 5px 0; -} -.tooltip.right { - margin-left: 3px; - padding: 0 5px; -} -.tooltip.bottom { - margin-top: 3px; - padding: 5px 0; -} -.tooltip.left { - margin-left: -3px; - padding: 0 5px; -} -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - background-color: #000000; - border-radius: 0; -} -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000000; -} -.tooltip.top-left .tooltip-arrow { - bottom: 0; - right: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000000; -} -.tooltip.top-right .tooltip-arrow { - bottom: 0; - left: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000000; -} -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000000; -} -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000000; -} -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000000; -} -.tooltip.bottom-left .tooltip-arrow { - top: 0; - right: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000000; -} -.tooltip.bottom-right .tooltip-arrow { - top: 0; - left: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000000; -} -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: none; - max-width: 276px; - padding: 1px; - font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-style: normal; - font-weight: normal; - letter-spacing: normal; - line-break: auto; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - font-size: 15px; - background-color: #4e5d6c; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid transparent; - border-radius: 0; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -} -.popover.top { - margin-top: -10px; -} -.popover.right { - margin-left: 10px; -} -.popover.bottom { - margin-top: 10px; -} -.popover.left { - margin-left: -10px; -} -.popover-title { - margin: 0; - padding: 8px 14px; - font-size: 15px; - background-color: #485563; - border-bottom: 1px solid #3d4954; - border-radius: -1 -1 0 0; -} -.popover-content { - padding: 9px 14px; -} -.popover > .arrow, -.popover > .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.popover > .arrow { - border-width: 11px; -} -.popover > .arrow:after { - border-width: 10px; - content: ""; -} -.popover.top > .arrow { - left: 50%; - margin-left: -11px; - border-bottom-width: 0; - border-top-color: transparent; - bottom: -11px; -} -.popover.top > .arrow:after { - content: " "; - bottom: 1px; - margin-left: -10px; - border-bottom-width: 0; - border-top-color: #4e5d6c; -} -.popover.right > .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-left-width: 0; - border-right-color: transparent; -} -.popover.right > .arrow:after { - content: " "; - left: 1px; - bottom: -10px; - border-left-width: 0; - border-right-color: #4e5d6c; -} -.popover.bottom > .arrow { - left: 50%; - margin-left: -11px; - border-top-width: 0; - border-bottom-color: transparent; - top: -11px; -} -.popover.bottom > .arrow:after { - content: " "; - top: 1px; - margin-left: -10px; - border-top-width: 0; - border-bottom-color: #4e5d6c; -} -.popover.left > .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-right-width: 0; - border-left-color: transparent; -} -.popover.left > .arrow:after { - content: " "; - right: 1px; - border-right-width: 0; - border-left-color: #4e5d6c; - bottom: -10px; -} -.carousel { - position: relative; -} -.carousel-inner { - position: relative; - overflow: hidden; - width: 100%; -} -.carousel-inner > .item { - display: none; - position: relative; - -webkit-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - line-height: 1; -} -@media all and (transform-3d), (-webkit-transform-3d) { - .carousel-inner > .item { - -webkit-transition: -webkit-transform 0.6s ease-in-out; - -o-transition: -o-transform 0.6s ease-in-out; - transition: transform 0.6s ease-in-out; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -webkit-perspective: 1000px; - perspective: 1000px; - } - .carousel-inner > .item.next, - .carousel-inner > .item.active.right { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - left: 0; - } - .carousel-inner > .item.prev, - .carousel-inner > .item.active.left { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - left: 0; - } - .carousel-inner > .item.next.left, - .carousel-inner > .item.prev.right, - .carousel-inner > .item.active { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - left: 0; - } -} -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} -.carousel-inner > .active { - left: 0; -} -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} -.carousel-inner > .next { - left: 100%; -} -.carousel-inner > .prev { - left: -100%; -} -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} -.carousel-inner > .active.left { - left: -100%; -} -.carousel-inner > .active.right { - left: 100%; -} -.carousel-control { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: 15%; - opacity: 0.5; - filter: alpha(opacity=50); - font-size: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); - background-color: rgba(0, 0, 0, 0); -} -.carousel-control.left { - background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); -} -.carousel-control.right { - left: auto; - right: 0; - background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); -} -.carousel-control:hover, -.carousel-control:focus { - outline: 0; - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} -.carousel-control .icon-prev, -.carousel-control .icon-next, -.carousel-control .glyphicon-chevron-left, -.carousel-control .glyphicon-chevron-right { - position: absolute; - top: 50%; - margin-top: -10px; - z-index: 5; - display: inline-block; -} -.carousel-control .icon-prev, -.carousel-control .glyphicon-chevron-left { - left: 50%; - margin-left: -10px; -} -.carousel-control .icon-next, -.carousel-control .glyphicon-chevron-right { - right: 50%; - margin-right: -10px; -} -.carousel-control .icon-prev, -.carousel-control .icon-next { - width: 20px; - height: 20px; - line-height: 1; - font-family: serif; -} -.carousel-control .icon-prev:before { - content: '\2039'; -} -.carousel-control .icon-next:before { - content: '\203a'; -} -.carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - margin-left: -30%; - padding-left: 0; - list-style: none; - text-align: center; -} -.carousel-indicators li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - border: 1px solid #ffffff; - border-radius: 10px; - cursor: pointer; - background-color: #000 \9; - background-color: rgba(0, 0, 0, 0); -} -.carousel-indicators .active { - margin: 0; - width: 12px; - height: 12px; - background-color: #ffffff; -} -.carousel-caption { - position: absolute; - left: 15%; - right: 15%; - bottom: 20px; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); -} -.carousel-caption .btn { - text-shadow: none; -} -@media screen and (min-width: 768px) { - .carousel-control .glyphicon-chevron-left, - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-prev, - .carousel-control .icon-next { - width: 30px; - height: 30px; - margin-top: -10px; - font-size: 30px; - } - .carousel-control .glyphicon-chevron-left, - .carousel-control .icon-prev { - margin-left: -10px; - } - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-next { - margin-right: -10px; - } - .carousel-caption { - left: 20%; - right: 20%; - padding-bottom: 30px; - } - .carousel-indicators { - bottom: 20px; - } -} -.clearfix:before, -.clearfix:after, -.dl-horizontal dd:before, -.dl-horizontal dd:after, -.container:before, -.container:after, -.container-fluid:before, -.container-fluid:after, -.row:before, -.row:after, -.form-horizontal .form-group:before, -.form-horizontal .form-group:after, -.btn-toolbar:before, -.btn-toolbar:after, -.btn-group-vertical > .btn-group:before, -.btn-group-vertical > .btn-group:after, -.nav:before, -.nav:after, -.navbar:before, -.navbar:after, -.navbar-header:before, -.navbar-header:after, -.navbar-collapse:before, -.navbar-collapse:after, -.pager:before, -.pager:after, -.panel-body:before, -.panel-body:after, -.modal-header:before, -.modal-header:after, -.modal-footer:before, -.modal-footer:after { - content: " "; - display: table; -} -.clearfix:after, -.dl-horizontal dd:after, -.container:after, -.container-fluid:after, -.row:after, -.form-horizontal .form-group:after, -.btn-toolbar:after, -.btn-group-vertical > .btn-group:after, -.nav:after, -.navbar:after, -.navbar-header:after, -.navbar-collapse:after, -.pager:after, -.panel-body:after, -.modal-header:after, -.modal-footer:after { - clear: both; -} -.center-block { - display: block; - margin-left: auto; - margin-right: auto; -} -.pull-right { - float: right !important; -} -.pull-left { - float: left !important; -} -.hide { - display: none !important; -} -.show { - display: block !important; -} -.invisible { - visibility: hidden; -} -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} -.hidden { - display: none !important; -} -.affix { - position: fixed; -} -@-ms-viewport { - width: device-width; -} -.visible-xs, -.visible-sm, -.visible-md, -.visible-lg { - display: none !important; -} -.visible-xs-block, -.visible-xs-inline, -.visible-xs-inline-block, -.visible-sm-block, -.visible-sm-inline, -.visible-sm-inline-block, -.visible-md-block, -.visible-md-inline, -.visible-md-inline-block, -.visible-lg-block, -.visible-lg-inline, -.visible-lg-inline-block { - display: none !important; -} -@media (max-width: 767px) { - .visible-xs { - display: block !important; - } - table.visible-xs { - display: table !important; - } - tr.visible-xs { - display: table-row !important; - } - th.visible-xs, - td.visible-xs { - display: table-cell !important; - } -} -@media (max-width: 767px) { - .visible-xs-block { - display: block !important; - } -} -@media (max-width: 767px) { - .visible-xs-inline { - display: inline !important; - } -} -@media (max-width: 767px) { - .visible-xs-inline-block { - display: inline-block !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm { - display: block !important; - } - table.visible-sm { - display: table !important; - } - tr.visible-sm { - display: table-row !important; - } - th.visible-sm, - td.visible-sm { - display: table-cell !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-block { - display: block !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-inline { - display: inline !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-inline-block { - display: inline-block !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md { - display: block !important; - } - table.visible-md { - display: table !important; - } - tr.visible-md { - display: table-row !important; - } - th.visible-md, - td.visible-md { - display: table-cell !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-block { - display: block !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-inline { - display: inline !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-inline-block { - display: inline-block !important; - } -} -@media (min-width: 1200px) { - .visible-lg { - display: block !important; - } - table.visible-lg { - display: table !important; - } - tr.visible-lg { - display: table-row !important; - } - th.visible-lg, - td.visible-lg { - display: table-cell !important; - } -} -@media (min-width: 1200px) { - .visible-lg-block { - display: block !important; - } -} -@media (min-width: 1200px) { - .visible-lg-inline { - display: inline !important; - } -} -@media (min-width: 1200px) { - .visible-lg-inline-block { - display: inline-block !important; - } -} -@media (max-width: 767px) { - .hidden-xs { - display: none !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .hidden-sm { - display: none !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-md { - display: none !important; - } -} -@media (min-width: 1200px) { - .hidden-lg { - display: none !important; - } -} -.visible-print { - display: none !important; -} -@media print { - .visible-print { - display: block !important; - } - table.visible-print { - display: table !important; - } - tr.visible-print { - display: table-row !important; - } - th.visible-print, - td.visible-print { - display: table-cell !important; - } -} -.visible-print-block { - display: none !important; -} -@media print { - .visible-print-block { - display: block !important; - } -} -.visible-print-inline { - display: none !important; -} -@media print { - .visible-print-inline { - display: inline !important; - } -} -.visible-print-inline-block { - display: none !important; -} -@media print { - .visible-print-inline-block { - display: inline-block !important; - } -} -@media print { - .hidden-print { - display: none !important; - } -} -.navbar { - -webkit-box-shadow: none; - box-shadow: none; - border: none; - font-size: 12px; -} -.navbar-default .badge { - background-color: #fff; - color: #4e5d6c; -} -.navbar-inverse .badge { - background-color: #fff; - color: #df691a; -} -.btn-default:hover { - background-color: #485563; -} -.btn-sm, -.btn-xs { - font-size: 12px; -} -.text-primary, -.text-primary:hover { - color: #df691a; -} -.text-success, -.text-success:hover { - color: #5cb85c; -} -.text-danger, -.text-danger:hover { - color: #d9534f; -} -.text-warning, -.text-warning:hover { - color: #f0ad4e; -} -.text-info, -.text-info:hover { - color: #5bc0de; -} -.page-header { - border-bottom-color: #4e5d6c; -} -.dropdown-menu { - border: none; - margin: 0; - -webkit-box-shadow: none; - box-shadow: none; -} -.dropdown-menu > li > a { - font-size: 12px; -} -.btn-group.open .dropdown-toggle { - -webkit-box-shadow: none; - box-shadow: none; -} -.dropdown-header { - font-size: 12px; -} -table, -.table { - font-size: 12px; -} -table a:not(.btn), -.table a:not(.btn) { - color: #fff; - text-decoration: underline; -} -table .dropdown-menu a, -.table .dropdown-menu a { - text-decoration: none; -} -table .text-muted, -.table .text-muted { - color: #4e5d6c; -} -table > thead > tr > th, -.table > thead > tr > th, -table > tbody > tr > th, -.table > tbody > tr > th, -table > tfoot > tr > th, -.table > tfoot > tr > th, -table > thead > tr > td, -.table > thead > tr > td, -table > tbody > tr > td, -.table > tbody > tr > td, -table > tfoot > tr > td, -.table > tfoot > tr > td { - border-color: transparent; -} -input, -textarea { - color: #2b3e50; -} -label, -.radio label, -.checkbox label, -.help-block { - font-size: 12px; -} -.input-addon, -.input-group-addon { - color: #df691a; -} -.has-warning .help-block, -.has-warning .control-label, -.has-warning .radio, -.has-warning .checkbox, -.has-warning .radio-inline, -.has-warning .checkbox-inline, -.has-warning.radio label, -.has-warning.checkbox label, -.has-warning.radio-inline label, -.has-warning.checkbox-inline label, -.has-warning .form-control-feedback { - color: #f0ad4e; -} -.has-warning .input-group-addon { - border: none; -} -.has-error .help-block, -.has-error .control-label, -.has-error .radio, -.has-error .checkbox, -.has-error .radio-inline, -.has-error .checkbox-inline, -.has-error.radio label, -.has-error.checkbox label, -.has-error.radio-inline label, -.has-error.checkbox-inline label, -.has-error .form-control-feedback { - color: #d9534f; -} -.has-error .input-group-addon { - border: none; -} -.has-success .help-block, -.has-success .control-label, -.has-success .radio, -.has-success .checkbox, -.has-success .radio-inline, -.has-success .checkbox-inline, -.has-success.radio label, -.has-success.checkbox label, -.has-success.radio-inline label, -.has-success.checkbox-inline label, -.has-success .form-control-feedback { - color: #5cb85c; -} -.has-success .input-group-addon { - border: none; -} -.form-control:focus { - -webkit-box-shadow: none; - box-shadow: none; -} -.has-warning .form-control:focus, -.has-error .form-control:focus, -.has-success .form-control:focus { - -webkit-box-shadow: none; - box-shadow: none; -} -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - border-color: transparent; -} -.nav-tabs > li > a { - color: #ebebeb; -} -.nav-pills > li > a { - color: #ebebeb; -} -.pager a { - color: #ebebeb; -} -.alert { - color: #fff; -} -.alert a, -.alert .alert-link { - color: #fff; -} -.close { - opacity: 0.4; -} -.close:hover, -.close:focus { - opacity: 1; -} -.well { - -webkit-box-shadow: none; - box-shadow: none; -} -a.list-group-item.active, -a.list-group-item.active:hover, -a.list-group-item.active:focus { - border: none; -} -a.list-group-item-success.active { - background-color: #5cb85c; -} -a.list-group-item-success.active:hover, -a.list-group-item-success.active:focus { - background-color: #4cae4c; -} -a.list-group-item-warning.active { - background-color: #f0ad4e; -} -a.list-group-item-warning.active:hover, -a.list-group-item-warning.active:focus { - background-color: #eea236; -} -a.list-group-item-danger.active { - background-color: #d9534f; -} -a.list-group-item-danger.active:hover, -a.list-group-item-danger.active:focus { - background-color: #d43f3a; -} -.panel { - border: none; -} -.panel-default > .panel-heading { - background-color: #485563; - color: #ebebeb; -} -.thumbnail { - background-color: #4e5d6c; - border: none; -} -.modal { - padding: 0; -} -.modal-header, -.modal-footer { - background-color: #282828; - border: none; - border-radius: 0; -} -.popover-title { - border: none; -} - diff --git a/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.css b/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.css deleted file mode 100644 index 5cc85cf8a..000000000 --- a/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.css +++ /dev/null @@ -1,295 +0,0 @@ -@media (min-width: 768px) { - .row { - position: relative; } - .bottom-align-text { - position: absolute; - bottom: 0; - right: 0; } } - -@media (max-width: 48em) { - .home { - padding-top: 1rem; } } - -@media (min-width: 48em) { - .home { - padding-top: 4rem; } } - -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #fff; } - -hr { - border-color: #777; } - -body.update-available { - margin-top: 80px; } - -.btn { - border-radius: 0.25rem !important; } - -.multiSelect { - background-color: #4e5d6c; } - -.form-control-custom { - background-color: #333333 !important; - color: white !important; - border-radius: 0; - box-shadow: 0 0 0 !important; } - -h1 { - font-size: 3.5rem !important; - font-weight: 600 !important; } - -.request-title { - margin-top: 0 !important; - font-size: 1.9rem !important; } - -p { - font-size: 1.1rem !important; } - -label { - display: inline-block !important; - margin-bottom: 0.5rem !important; - font-size: 16px !important; } - -.nav-tabs > li { - font-size: 13px; - line-height: 21px; } - -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - background: #df691a; } - -.nav-tabs > li > a > .fa { - padding: 3px 5px 3px 3px; } - -.nav-tabs > li.nav-tab-right { - float: right; } - -.nav-tabs > li.nav-tab-right a { - margin-right: 0; - margin-left: 2px; } - -.nav-tabs > li.nav-tab-icononly .fa { - padding: 3px; } - -.navbar .nav a .fa, -.dropdown-menu a .fa { - font-size: 130%; - top: 1px; - position: relative; - display: inline-block; - margin-right: 5px; } - -.dropdown-menu a .fa { - top: 2px; } - -.btn-danger-outline { - color: #d9534f !important; - background-color: transparent; - background-image: none; - border-color: #d9534f !important; } - -.btn-danger-outline:focus, -.btn-danger-outline.focus, -.btn-danger-outline:active, -.btn-danger-outline.active, -.btn-danger-outline:hover, -.open > .btn-danger-outline.dropdown-toggle { - color: #fff !important; - background-color: #d9534f !important; - border-color: #d9534f !important; } - -.btn-primary-outline { - color: #ff761b !important; - background-color: transparent; - background-image: none; - border-color: #ff761b !important; } - -.btn-primary-outline:focus, -.btn-primary-outline.focus, -.btn-primary-outline:active, -.btn-primary-outline.active, -.btn-primary-outline:hover, -.open > .btn-primary-outline.dropdown-toggle { - color: #fff !important; - background-color: #df691a !important; - border-color: #df691a !important; } - -.btn-info-outline { - color: #5bc0de !important; - background-color: transparent; - background-image: none; - border-color: #5bc0de !important; } - -.btn-info-outline:focus, -.btn-info-outline.focus, -.btn-info-outline:active, -.btn-info-outline.active, -.btn-info-outline:hover, -.open > .btn-info-outline.dropdown-toggle { - color: #fff !important; - background-color: #5bc0de !important; - border-color: #5bc0de !important; } - -.btn-warning-outline { - color: #f0ad4e !important; - background-color: transparent; - background-image: none; - border-color: #f0ad4e !important; } - -.btn-warning-outline:focus, -.btn-warning-outline.focus, -.btn-warning-outline:active, -.btn-warning-outline.active, -.btn-warning-outline:hover, -.open > .btn-warning-outline.dropdown-toggle { - color: #fff !important; - background-color: #f0ad4e !important; - border-color: #f0ad4e !important; } - -.btn-success-outline { - color: #5cb85c !important; - background-color: transparent; - background-image: none; - border-color: #5cb85c !important; } - -.btn-success-outline:focus, -.btn-success-outline.focus, -.btn-success-outline:active, -.btn-success-outline.active, -.btn-success-outline:hover, -.open > .btn-success-outline.dropdown-toggle { - color: #fff !important; - background-color: #5cb85c !important; - border-color: #5cb85c !important; } - -#movieList .mix { - display: none; } - -#tvList .mix { - display: none; } - -.scroll-top-wrapper { - position: fixed; - opacity: 0; - visibility: hidden; - overflow: hidden; - text-align: center; - z-index: 99999999; - background-color: #333333; - color: #eeeeee; - width: 50px; - height: 48px; - line-height: 48px; - right: 30px; - bottom: 30px; - padding-top: 2px; - border-top-left-radius: 10px; - border-top-right-radius: 10px; - border-bottom-right-radius: 10px; - border-bottom-left-radius: 10px; - -webkit-transition: all 0.5s ease-in-out; - -moz-transition: all 0.5s ease-in-out; - -ms-transition: all 0.5s ease-in-out; - -o-transition: all 0.5s ease-in-out; - transition: all 0.5s ease-in-out; } - -.scroll-top-wrapper:hover { - background-color: #df691a; } - -.scroll-top-wrapper.show { - visibility: visible; - cursor: pointer; - opacity: 1.0; } - -.scroll-top-wrapper i.fa { - line-height: inherit; } - -.no-search-results { - text-align: center; } - -.no-search-results .no-search-results-icon { - font-size: 10em; - color: #4e5d6c; } - -.no-search-results .no-search-results-text { - margin: 20px 0; - color: #ccc; } - -.form-control-search { - padding: 13px 105px 13px 16px; - height: 100%; } - -.form-control-withbuttons { - padding-right: 105px; } - -.input-group-addon .btn-group { - position: absolute; - right: 45px; - z-index: 3; - top: 10px; - box-shadow: 0 0 0; } - -.input-group-addon .btn-group .btn { - border: 1px solid rgba(255, 255, 255, 0.7) !important; - padding: 3px 12px; - color: rgba(255, 255, 255, 0.7) !important; } - -.btn-split .btn { - border-radius: 0 !important; } - -.btn-split .btn:not(.dropdown-toggle) { - border-radius: 0.25rem 0 0 0.25rem !important; } - -.btn-split .btn.dropdown-toggle { - border-radius: 0 0.25rem 0.25rem 0 !important; - padding: 12px 8px; } - -#updateAvailable { - background-color: #df691a; - text-align: center; - font-size: 15px; - padding: 3px 0; } - -.checkbox label { - display: inline-block; - cursor: pointer; - position: relative; - padding-left: 25px; - margin-right: 15px; - font-size: 13px; - margin-bottom: 10px; } - -.checkbox label:before { - content: ""; - display: inline-block; - width: 18px; - height: 18px; - margin-right: 10px; - position: absolute; - left: 0; - bottom: 1px; - border: 2px solid #eee; - border-radius: 3px; } - -.checkbox input[type=checkbox] { - display: none; } - -.checkbox input[type=checkbox]:checked + label:before { - content: "\2713"; - font-size: 13px; - color: #fafafa; - text-align: center; - line-height: 13px; } - -.input-group-sm { - padding-top: 2px; - padding-bottom: 2px; } - -.tab-pane .form-horizontal .form-group { - margin-right: 15px; - margin-left: 15px; } - diff --git a/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.min.css b/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.min.css deleted file mode 100644 index 5c3bef0cd..000000000 --- a/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.min.css +++ /dev/null @@ -1 +0,0 @@ -@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#fff;}hr{border-color:#777;}body.update-available{margin-top:80px;}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#333 !important;color:#fff !important;border-radius:0;box-shadow:0 0 0 !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li{font-size:13px;line-height:21px;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#df691a;}.nav-tabs>li>a>.fa{padding:3px 5px 3px 3px;}.nav-tabs>li.nav-tab-right{float:right;}.nav-tabs>li.nav-tab-right a{margin-right:0;margin-left:2px;}.nav-tabs>li.nav-tab-icononly .fa{padding:3px;}.navbar .nav a .fa,.dropdown-menu a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.dropdown-menu a .fa{top:2px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;}.scroll-top-wrapper{position:fixed;opacity:0;visibility:hidden;overflow:hidden;text-align:center;z-index:99999999;background-color:#333;color:#eee;width:50px;height:48px;line-height:48px;right:30px;bottom:30px;padding-top:2px;border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;}.scroll-top-wrapper:hover{background-color:#df691a;}.scroll-top-wrapper.show{visibility:visible;cursor:pointer;opacity:1;}.scroll-top-wrapper i.fa{line-height:inherit;}.no-search-results{text-align:center;}.no-search-results .no-search-results-icon{font-size:10em;color:#4e5d6c;}.no-search-results .no-search-results-text{margin:20px 0;color:#ccc;}.form-control-search{padding:13px 105px 13px 16px;height:100%;}.form-control-withbuttons{padding-right:105px;}.input-group-addon .btn-group{position:absolute;right:45px;z-index:3;top:10px;box-shadow:0 0 0;}.input-group-addon .btn-group .btn{border:1px solid rgba(255,255,255,.7) !important;padding:3px 12px;color:rgba(255,255,255,.7) !important;}.btn-split .btn{border-radius:0 !important;}.btn-split .btn:not(.dropdown-toggle){border-radius:.25rem 0 0 .25rem !important;}.btn-split .btn.dropdown-toggle{border-radius:0 .25rem .25rem 0 !important;padding:12px 8px;}#updateAvailable{background-color:#df691a;text-align:center;font-size:15px;padding:3px 0;}.checkbox label{display:inline-block;cursor:pointer;position:relative;padding-left:25px;margin-right:15px;font-size:13px;margin-bottom:10px;}.checkbox label:before{content:"";display:inline-block;width:18px;height:18px;margin-right:10px;position:absolute;left:0;bottom:1px;border:2px solid #eee;border-radius:3px;}.checkbox input[type=checkbox]{display:none;}.checkbox input[type=checkbox]:checked+label:before{content:"✓";font-size:13px;color:#fafafa;text-align:center;line-height:13px;}.input-group-sm{padding-top:2px;padding-bottom:2px;}.tab-pane .form-horizontal .form-group{margin-right:15px;margin-left:15px;} \ No newline at end of file diff --git a/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.scss b/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.scss deleted file mode 100644 index cf72d924c..000000000 --- a/PlexRequests.UI/Content/Themes/PlexBootstrapCustom.scss +++ /dev/null @@ -1,365 +0,0 @@ -$form-color: #4e5d6c; -$form-color-lighter: #637689; -$primary-colour: #df691a; -$primary-colour-outline: #ff761b; -$info-colour: #5bc0de; -$warning-colour: #f0ad4e; -$danger-colour: #d9534f; -$success-colour: #5cb85c; -$bg-colour: #333333; -$i: -!important; - -@media (min-width: 768px ) { - .row { - position: relative; - } - - .bottom-align-text { - position: absolute; - bottom: 0; - right: 0; - } -} - -@media (max-width: 48em) { - .home { - padding-top: 1rem; - } -} - -@media (min-width: 48em) { - .home { - padding-top: 4rem; - } -} - -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #fff; -} - -hr { - border-color: #777; -} - -body.update-available { - margin-top: 80px; -} - -.btn { - border-radius: .25rem $i; -} - -.multiSelect { - background-color: $form-color; -} - -.form-control-custom { - background-color: $bg-colour $i; - color: white $i; - border-radius: 0; - box-shadow: 0 0 0 !important; -} - - -h1 { - font-size: 3.5rem $i; - font-weight: 600 $i; -} - -.request-title { - margin-top: 0 $i; - font-size: 1.9rem $i; -} - -p { - font-size: 1.1rem $i; -} - -label { - display: inline-block $i; - margin-bottom: .5rem $i; - font-size: 16px $i; -} - -.nav-tabs > li { - font-size: 13px; - line-height: 21px; -} - -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - background: $primary-colour; -} - -.nav-tabs > li > a > .fa { - padding: 3px 5px 3px 3px; -} - -.nav-tabs > li.nav-tab-right { - float: right; -} - -.nav-tabs > li.nav-tab-right a { - margin-right: 0; - margin-left: 2px; -} - -.nav-tabs > li.nav-tab-icononly .fa { - padding: 3px; -} - -.navbar .nav a .fa, -.dropdown-menu a .fa { - font-size: 130%; - top: 1px; - position: relative; - display: inline-block; - margin-right: 5px; -} - -.dropdown-menu a .fa { - top: 2px; -} - -.btn-danger-outline { - color: $danger-colour $i; - background-color: transparent; - background-image: none; - border-color: $danger-colour $i; -} - -.btn-danger-outline:focus, -.btn-danger-outline.focus, -.btn-danger-outline:active, -.btn-danger-outline.active, -.btn-danger-outline:hover, -.open > .btn-danger-outline.dropdown-toggle { - color: #fff $i; - background-color: $danger-colour $i; - border-color: $danger-colour $i; -} - - -.btn-primary-outline { - color: $primary-colour-outline $i; - background-color: transparent; - background-image: none; - border-color: $primary-colour-outline $i; -} - -.btn-primary-outline:focus, -.btn-primary-outline.focus, -.btn-primary-outline:active, -.btn-primary-outline.active, -.btn-primary-outline:hover, -.open > .btn-primary-outline.dropdown-toggle { - color: #fff $i; - background-color: $primary-colour $i; - border-color: $primary-colour $i; -} - -.btn-info-outline { - color: $info-colour $i; - background-color: transparent; - background-image: none; - border-color: $info-colour $i; -} - -.btn-info-outline:focus, -.btn-info-outline.focus, -.btn-info-outline:active, -.btn-info-outline.active, -.btn-info-outline:hover, -.open > .btn-info-outline.dropdown-toggle { - color: #fff $i; - background-color: $info-colour $i; - border-color: $info-colour $i; -} - -.btn-warning-outline { - color: $warning-colour $i; - background-color: transparent; - background-image: none; - border-color: $warning-colour $i; -} - -.btn-warning-outline:focus, -.btn-warning-outline.focus, -.btn-warning-outline:active, -.btn-warning-outline.active, -.btn-warning-outline:hover, -.open > .btn-warning-outline.dropdown-toggle { - color: #fff $i; - background-color: $warning-colour $i; - border-color: $warning-colour $i; -} - -.btn-success-outline { - color: $success-colour $i; - background-color: transparent; - background-image: none; - border-color: $success-colour $i; -} - -.btn-success-outline:focus, -.btn-success-outline.focus, -.btn-success-outline:active, -.btn-success-outline.active, -.btn-success-outline:hover, -.open > .btn-success-outline.dropdown-toggle { - color: #fff $i; - background-color: $success-colour $i; - border-color: $success-colour $i; -} - -#movieList .mix { - display: none; -} - -#tvList .mix { - display: none; -} - -$border-radius: 10px; - -.scroll-top-wrapper { - position: fixed; - opacity: 0; - visibility: hidden; - overflow: hidden; - text-align: center; - z-index: 99999999; - background-color: $bg-colour; - color: #eeeeee; - width: 50px; - height: 48px; - line-height: 48px; - right: 30px; - bottom: 30px; - padding-top: 2px; - border-top-left-radius: $border-radius; - border-top-right-radius: $border-radius; - border-bottom-right-radius: $border-radius; - border-bottom-left-radius: $border-radius; - -webkit-transition: all 0.5s ease-in-out; - -moz-transition: all 0.5s ease-in-out; - -ms-transition: all 0.5s ease-in-out; - -o-transition: all 0.5s ease-in-out; - transition: all 0.5s ease-in-out; -} - -.scroll-top-wrapper:hover { - background-color: $primary-colour; -} - -.scroll-top-wrapper.show { - visibility: visible; - cursor: pointer; - opacity: 1.0; -} - -.scroll-top-wrapper i.fa { - line-height: inherit; -} - - -.no-search-results { - text-align: center; -} - -.no-search-results .no-search-results-icon { - font-size: 10em; - color: $form-color; -} - -.no-search-results .no-search-results-text { - margin: 20px 0; - color: #ccc; -} - -.form-control-search { - padding: 13px 105px 13px 16px; - height: 100%; -} - -.form-control-withbuttons { - padding-right: 105px; -} - -.input-group-addon .btn-group { - position: absolute; - right: 45px; - z-index: 3; - top: 10px; - box-shadow: 0 0 0; -} - -.input-group-addon .btn-group .btn { - border: 1px solid rgba(255,255,255,.7) !important; - padding: 3px 12px; - color: rgba(255,255,255,.7) !important; -} - -.btn-split .btn { - border-radius: 0 !important; -} - -.btn-split .btn:not(.dropdown-toggle) { - border-radius: .25rem 0 0 .25rem $i; -} - -.btn-split .btn.dropdown-toggle { - border-radius: 0 .25rem .25rem 0 $i; - padding: 12px 8px; -} - -#updateAvailable { - background-color: #df691a; - text-align: center; - font-size: 15px; - padding: 3px 0; -} - -.checkbox label { - display: inline-block; - cursor: pointer; - position: relative; - padding-left: 25px; - margin-right: 15px; - font-size: 13px; - margin-bottom: 10px; } - - .checkbox label:before { - content: ""; - display: inline-block; - width: 18px; - height: 18px; - margin-right: 10px; - position: absolute; - left: 0; - bottom: 1px; - border: 2px solid #eee; - border-radius: 3px; } - - .checkbox input[type=checkbox] { - display: none; } - - .checkbox input[type=checkbox]:checked + label:before { - content: "\2713"; - font-size: 13px; - color: #fafafa; - text-align: center; - line-height: 13px; } - -.input-group-sm{ - padding-top: 2px; - padding-bottom: 2px; -} - -.tab-pane .form-horizontal .form-group { - margin-right: 15px; - margin-left: 15px; } \ No newline at end of file diff --git a/PlexRequests.UI/Content/Themes/original.css b/PlexRequests.UI/Content/Themes/original.css new file mode 100644 index 000000000..e02abfc9b --- /dev/null +++ b/PlexRequests.UI/Content/Themes/original.css @@ -0,0 +1 @@ + diff --git a/PlexRequests.UI/Content/Themes/original.min.css b/PlexRequests.UI/Content/Themes/original.min.css new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/PlexRequests.UI/Content/Themes/original.min.css @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/PlexRequests.UI/Content/Themes/original.scss b/PlexRequests.UI/Content/Themes/original.scss new file mode 100644 index 000000000..46800d16a --- /dev/null +++ b/PlexRequests.UI/Content/Themes/original.scss @@ -0,0 +1,2 @@ +body { +} diff --git a/PlexRequests.UI/Content/Themes/plex.css b/PlexRequests.UI/Content/Themes/plex.css new file mode 100644 index 000000000..c0a7597af --- /dev/null +++ b/PlexRequests.UI/Content/Themes/plex.css @@ -0,0 +1,158 @@ +.form-control-custom { + background-color: #333333 !important; } + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background: #df691a; } + +scroll-top-wrapper { + background-color: #333333; } + +.scroll-top-wrapper:hover { + background-color: #df691a; } + +body { + font-family: Open Sans Regular,Helvetica Neue,Helvetica,Arial,sans-serif; + color: #eee; + background-color: #1f1f1f; } + +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #333; } + +.table-hover > tbody > tr:hover { + background-color: #282828; } + +fieldset { + padding: 15px; } + +legend { + border-bottom: 1px solid #333333; } + +.form-control { + color: #fefefe; + background-color: #333; } + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + margin-left: -0px; } + +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: -15px; } + +.dropdown-menu { + background-color: #282828; } + +.dropdown-menu .divider { + background-color: #333333; } + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #333; } + +.input-group-addon { + background-color: #333333; } + +.nav > li > a:hover, +.nav > li > a:focus { + background-color: #df691a; } + +.nav-tabs > li > a:hover { + border-color: #df691a #df691a transparent; } + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background-color: #df691a; + border: 1px solid #df691a; } + +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #df691a; } + +/*.navbar { + position: relative; + min-height: 40px; + margin-bottom: 21px; + z-index: 1000; + padding: 0px 3px; + font-size: 24px; + background-color: #000; + box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.2); +}*/ +.navbar-default { + background-color: #0a0a0a; } + +.navbar-default .navbar-brand { + color: #DF691A; } + +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #F0ad4e; + background-color: #282828; } + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + background-color: #282828; } + +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: #df691a; + color: #fff; } + +.pagination > li > a, +.pagination > li > span { + background-color: #282828; } + +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + background-color: #333; } + +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #fefefe; + background-color: #333333; } + +.list-group-item { + background-color: #282828; } + +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + background-color: #333333; } + +.input-addon, +.input-group-addon { + color: #df691a; } + +.modal-header, +.modal-footer { + background-color: #282828; } + +.modal-content { + position: relative; + background-color: #282828; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + outline: 0; } + diff --git a/PlexRequests.UI/Content/Themes/plex.min.css b/PlexRequests.UI/Content/Themes/plex.min.css new file mode 100644 index 000000000..2fa5bbcc9 --- /dev/null +++ b/PlexRequests.UI/Content/Themes/plex.min.css @@ -0,0 +1 @@ +.form-control-custom{background-color:#333 !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#df691a;}scroll-top-wrapper{background-color:#333;}.scroll-top-wrapper:hover{background-color:#df691a;}body{font-family:Open Sans Regular,Helvetica Neue,Helvetica,Arial,sans-serif;color:#eee;background-color:#1f1f1f;}.table-striped>tbody>tr:nth-of-type(odd){background-color:#333;}.table-hover>tbody>tr:hover{background-color:#282828;}fieldset{padding:15px;}legend{border-bottom:1px solid #333;}.form-control{color:#fefefe;background-color:#333;}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{margin-left:-0;}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:-15px;}.dropdown-menu{background-color:#282828;}.dropdown-menu .divider{background-color:#333;}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#333;}.input-group-addon{background-color:#333;}.nav>li>a:hover,.nav>li>a:focus{background-color:#df691a;}.nav-tabs>li>a:hover{border-color:#df691a #df691a transparent;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background-color:#df691a;border:1px solid #df691a;}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #df691a;}.navbar-default{background-color:#0a0a0a;}.navbar-default .navbar-brand{color:#df691a;}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#f0ad4e;background-color:#282828;}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{background-color:#282828;}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#df691a;color:#fff;}.pagination>li>a,.pagination>li>span{background-color:#282828;}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#333;}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#fefefe;background-color:#333;}.list-group-item{background-color:#282828;}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{background-color:#333;}.input-addon,.input-group-addon{color:#df691a;}.modal-header,.modal-footer{background-color:#282828;}.modal-content{position:relative;background-color:#282828;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:0;} \ No newline at end of file diff --git a/PlexRequests.UI/Content/Themes/plex.scss b/PlexRequests.UI/Content/Themes/plex.scss new file mode 100644 index 000000000..1de0e2092 --- /dev/null +++ b/PlexRequests.UI/Content/Themes/plex.scss @@ -0,0 +1,196 @@ +$primary-colour: #df691a; +$primary-colour-outline: #ff761b; +$bg-colour: #333333; +$i: !important; + +.form-control-custom { + background-color: $bg-colour $i; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background: $primary-colour; +} + +scroll-top-wrapper { + background-color: $bg-colour; +} + +.scroll-top-wrapper:hover { + background-color: $primary-colour; +} + +body { + font-family: Open Sans Regular,Helvetica Neue,Helvetica,Arial,sans-serif; + color: #eee; + background-color: #1f1f1f; +} + +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #333; +} + +.table-hover > tbody > tr:hover { + background-color: #282828; +} + +fieldset { + padding: 15px; +} + +legend { + border-bottom: 1px solid #333333; +} + +.form-control { + color: #fefefe; + background-color: #333; +} + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + margin-left: -0px; +} + +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: -15px; +} + +.dropdown-menu { + background-color: #282828; +} + +.dropdown-menu .divider { + background-color: #333333; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #333; +} + +.input-group-addon { + background-color: #333333; +} + +.nav > li > a:hover, +.nav > li > a:focus { + background-color: #df691a; +} + +.nav-tabs > li > a:hover { + border-color: #df691a #df691a transparent; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background-color: #df691a; + border: 1px solid #df691a; +} + +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #df691a; +} + +/*.navbar { + position: relative; + min-height: 40px; + margin-bottom: 21px; + z-index: 1000; + padding: 0px 3px; + font-size: 24px; + background-color: #000; + box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.2); +}*/ + +.navbar-default { + background-color: #0a0a0a; +} + +.navbar-default .navbar-brand { + color: #DF691A; +} + +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #F0ad4e; + background-color: #282828; +} + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + background-color: #282828; +} + +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: #df691a; + color: #fff; +} + +.pagination > li > a, +.pagination > li > span { + background-color: #282828; +} + +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + background-color: #333; +} + +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #fefefe; + background-color: #333333; +} + +.list-group-item { + background-color: #282828; +} + +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + background-color: #333333; +} + +.input-addon, +.input-group-addon { + color: #df691a; +} + +.modal-header, +.modal-footer { + background-color: #282828; +} + +.modal-content { + position: relative; + background-color: #282828; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + outline: 0; +} diff --git a/PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.css b/PlexRequests.UI/Content/base.css similarity index 98% rename from PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.css rename to PlexRequests.UI/Content/base.css index 6c1f89cc6..d0479a8d1 100644 --- a/PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.css +++ b/PlexRequests.UI/Content/base.css @@ -20,11 +20,15 @@ color: #fff; } hr { - border-color: #777; } + border: 1px dashed #777; } .btn { border-radius: 0.25rem !important; } +.btn-group-separated .btn, +.btn-group-separated .btn + .btn { + margin-left: 3px; } + .multiSelect { background-color: #4e5d6c; } diff --git a/PlexRequests.UI/Content/base.min.css b/PlexRequests.UI/Content/base.min.css new file mode 100644 index 000000000..a16d98f54 --- /dev/null +++ b/PlexRequests.UI/Content/base.min.css @@ -0,0 +1 @@ +@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#fff;}hr{border:1px dashed #777;}.btn{border-radius:.25rem !important;}.btn-group-separated .btn,.btn-group-separated .btn+.btn{margin-left:3px;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;border-radius:0;box-shadow:0 0 0 !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li{font-size:13px;line-height:21px;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.nav-tabs>li>a>.fa{padding:3px 5px 3px 3px;}.nav-tabs>li.nav-tab-right{float:right;}.nav-tabs>li.nav-tab-right a{margin-right:0;margin-left:2px;}.nav-tabs>li.nav-tab-icononly .fa{padding:3px;}.navbar .nav a .fa,.dropdown-menu a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.dropdown-menu a .fa{top:2px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;}.scroll-top-wrapper{position:fixed;opacity:0;visibility:hidden;overflow:hidden;text-align:center;z-index:99999999;background-color:#4e5d6c;color:#eee;width:50px;height:48px;line-height:48px;right:30px;bottom:30px;padding-top:2px;border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;}.scroll-top-wrapper:hover{background-color:#637689;}.scroll-top-wrapper.show{visibility:visible;cursor:pointer;opacity:1;}.scroll-top-wrapper i.fa{line-height:inherit;}.no-search-results{text-align:center;}.no-search-results .no-search-results-icon{font-size:10em;color:#4e5d6c;}.no-search-results .no-search-results-text{margin:20px 0;color:#ccc;}.form-control-search{padding:13px 105px 13px 16px;height:100%;}.form-control-withbuttons{padding-right:105px;}.input-group-addon .btn-group{position:absolute;right:45px;z-index:3;top:10px;box-shadow:0 0 0;}.input-group-addon .btn-group .btn{border:1px solid rgba(255,255,255,.7) !important;padding:3px 12px;color:rgba(255,255,255,.7) !important;}.btn-split .btn{border-radius:0 !important;}.btn-split .btn:not(.dropdown-toggle){border-radius:.25rem 0 0 .25rem !important;}.btn-split .btn.dropdown-toggle{border-radius:0 .25rem .25rem 0 !important;padding:12px 8px;}#updateAvailable{background-color:#df691a;text-align:center;font-size:15px;padding:3px 0;}.checkbox label{display:inline-block;cursor:pointer;position:relative;padding-left:25px;margin-right:15px;font-size:13px;margin-bottom:10px;}.checkbox label:before{content:"";display:inline-block;width:18px;height:18px;margin-right:10px;position:absolute;left:0;bottom:1px;border:2px solid #eee;border-radius:3px;}.checkbox input[type=checkbox]{display:none;}.checkbox input[type=checkbox]:checked+label:before{content:"✓";font-size:13px;color:#fafafa;text-align:center;line-height:13px;}.input-group-sm{padding-top:2px;padding-bottom:2px;}.tab-pane .form-horizontal .form-group{margin-right:15px;margin-left:15px;} \ No newline at end of file diff --git a/PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.scss b/PlexRequests.UI/Content/base.scss similarity index 97% rename from PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.scss rename to PlexRequests.UI/Content/base.scss index 85fcc1a73..7cb008433 100644 --- a/PlexRequests.UI/Content/Themes/OriginalBootstrapCustom.scss +++ b/PlexRequests.UI/Content/base.scss @@ -6,8 +6,7 @@ $info-colour: #5bc0de; $warning-colour: #f0ad4e; $danger-colour: #d9534f; $success-colour: #5cb85c; -$i: -!important; +$i: !important; @media (min-width: 768px ) { .row { @@ -40,13 +39,18 @@ $i: } hr { - border-color: #777; + border: 1px dashed #777; } .btn { border-radius: .25rem $i; } +.btn-group-separated .btn, +.btn-group-separated .btn + .btn { + margin-left: 3px; +} + .multiSelect { background-color: $form-color; } diff --git a/PlexRequests.UI/Content/Themes/OriginalBootstrap.css b/PlexRequests.UI/Content/bootstrap.css similarity index 100% rename from PlexRequests.UI/Content/Themes/OriginalBootstrap.css rename to PlexRequests.UI/Content/bootstrap.css diff --git a/PlexRequests.UI/Content/requests-1.7.js b/PlexRequests.UI/Content/requests-1.7.js index 96b7ae4da..37538e97c 100644 --- a/PlexRequests.UI/Content/requests-1.7.js +++ b/PlexRequests.UI/Content/requests-1.7.js @@ -12,6 +12,8 @@ var albumTemplate = Handlebars.compile(albumSource); var movieTimer = 0; var tvimer = 0; var base = $('#baseUrl').text(); +var tvLoaded = false; +var albumLoaded = false; var mixItUpDefault = { animation: { enable: true }, @@ -40,9 +42,14 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { var $tvl = $('#tvList'); var $musicL = $('#musicList'); - $('.approve-category').hide(); + $('.approve-category,.delete-category').hide(); if (target === "#TvShowTab") { - $('#approveTVShows').show(); + if (!tvLoaded) { + tvLoaded = true; + tvLoad(); + } + + $('#approveTVShows,#deleteTVShows').show(); if ($ml.mixItUp('isLoaded')) { activeState = $ml.mixItUp('getState'); $ml.mixItUp('destroy'); @@ -51,11 +58,11 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { activeState = $musicL.mixItUp('getState'); $musicL.mixItUp('destroy'); } - if ($tvl.mixItUp('isLoaded')) $tvl.mixItUp('destroy'); - $tvl.mixItUp(mixItUpConfig(activeState)); // init or reinit + //if ($tvl.mixItUp('isLoaded')) $tvl.mixItUp('destroy'); + //$tvl.mixItUp(mixItUpConfig(activeState)); // init or reinit } if (target === "#MoviesTab") { - $('#approveMovies').show(); + $('#approveMovies,#deleteMovies').show(); if ($tvl.mixItUp('isLoaded')) { activeState = $tvl.mixItUp('getState'); $tvl.mixItUp('destroy'); @@ -69,7 +76,11 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { } if (target === "#MusicTab") { - $('#approveMusic').show(); + if (!albumLoaded) { + albumLoaded = true; + albumLoad(); + } + $('#approveMusic,#deleteMusic').show(); if ($tvl.mixItUp('isLoaded')) { activeState = $tvl.mixItUp('getState'); $tvl.mixItUp('destroy'); @@ -124,7 +135,7 @@ $('#approveTVShows').click(function (e) { return; } - loadingButton(buttonId, "success"); + loadingButton(buttonId, "warning"); var url = createBaseUrl(base, '/approval/approvealltvshows'); $.ajax({ type: 'post', @@ -140,6 +151,72 @@ $('#approveTVShows').click(function (e) { console.log(e); generateNotify("Something went wrong!", "danger"); }, + complete: function (e) { + finishLoading(buttonId, "warning", origHtml); + } + }); +}); + +$('#deleteMovies').click(function (e) { + e.preventDefault(); + if (!confirm("Are you sure you want to delete all TV show requests?")) return; + + var buttonId = e.target.id; + var origHtml = $(this).html(); + + if ($('#' + buttonId).text() === " Loading...") { + return; + } + + loadingButton(buttonId, "warning"); + + var url = createBaseUrl(base, '/approval/deleteallmovies'); + $.ajax({ + type: 'post', + url: url, + dataType: "json", + success: function (response) { + if (checkJsonResponse(response)) { + generateNotify("Success! All Movie requests deleted!", "success"); + movieLoad(); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + }, + complete: function (e) { + finishLoading(buttonId, "warning", origHtml); + } + }); +}); +$('#deleteTVShows').click(function (e) { + e.preventDefault(); + if (!confirm("Are you sure you want to delete all TV show requests?")) return; + + var buttonId = e.target.id; + var origHtml = $(this).html(); + + if ($('#' + buttonId).text() === " Loading...") { + return; + } + + loadingButton(buttonId, "warning"); + var url = createBaseUrl(base, '/approval/deletealltvshows'); + $.ajax({ + type: 'post', + url: url, + dataType: "json", + success: function (response) { + if (checkJsonResponse(response)) { + generateNotify("Success! All TV Show requests deleted!", "success"); + tvLoad(); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + }, complete: function (e) { finishLoading(buttonId, "success", origHtml); } @@ -448,10 +525,10 @@ function mixItUpConfig(activeState) { return conf; }; +var position = 0; function initLoad() { movieLoad(); - tvLoad(); - albumLoad(); + } function movieLoad() { diff --git a/PlexRequests.UI/Helpers/BaseUrlHelper.cs b/PlexRequests.UI/Helpers/BaseUrlHelper.cs index 2732714ed..f186054b9 100644 --- a/PlexRequests.UI/Helpers/BaseUrlHelper.cs +++ b/PlexRequests.UI/Helpers/BaseUrlHelper.cs @@ -57,12 +57,15 @@ namespace PlexRequests.UI.Helpers { settings.ThemeName = Themes.PlexTheme; } - - sb.AppendLine($""); - sb.AppendLine($""); + if (settings.ThemeName == "PlexBootstrap.css") settings.ThemeName = Themes.PlexTheme; + if (settings.ThemeName == "OriginalBootstrap.css") settings.ThemeName = Themes.OriginalTheme; + + sb.AppendLine($""); sb.AppendLine($""); sb.AppendLine($""); sb.AppendLine($""); + sb.AppendLine($""); + sb.AppendLine($""); sb.AppendLine($""); sb.AppendLine($""); diff --git a/PlexRequests.UI/Helpers/Themes.cs b/PlexRequests.UI/Helpers/Themes.cs index 2e7e54fa1..a5e3af613 100644 --- a/PlexRequests.UI/Helpers/Themes.cs +++ b/PlexRequests.UI/Helpers/Themes.cs @@ -28,7 +28,7 @@ namespace PlexRequests.UI.Helpers { public static class Themes { - public const string OriginalTheme = "OriginalBootstrap.css"; - public const string PlexTheme = "PlexBootstrap.css"; + public const string OriginalTheme = "original.css"; + public const string PlexTheme = "plex.css"; } } \ No newline at end of file diff --git a/PlexRequests.UI/Jobs/Scheduler.cs b/PlexRequests.UI/Jobs/Scheduler.cs index 0ccae710b..63ffe8b64 100644 --- a/PlexRequests.UI/Jobs/Scheduler.cs +++ b/PlexRequests.UI/Jobs/Scheduler.cs @@ -56,13 +56,15 @@ namespace PlexRequests.UI.Jobs var sickrage = JobBuilder.Create().WithIdentity("SickRageCacher", "Cache").Build(); var sonarr = JobBuilder.Create().WithIdentity("SonarrCacher", "Cache").Build(); var cp = JobBuilder.Create().WithIdentity("CouchPotatoCacher", "Cache").Build(); - var store = JobBuilder.Create().WithIdentity("StoreBackup", "Backup").Build(); + var store = JobBuilder.Create().WithIdentity("StoreBackup", "Database").Build(); + var storeClean = JobBuilder.Create().WithIdentity("StoreCleanup", "Database").Build(); jobs.Add(plex); jobs.Add(sickrage); jobs.Add(sonarr); jobs.Add(cp); jobs.Add(store); + jobs.Add(storeClean); return jobs; } @@ -129,17 +131,25 @@ namespace PlexRequests.UI.Jobs var storeBackup = TriggerBuilder.Create() - .WithIdentity("StoreBackup", "Backup") + .WithIdentity("StoreBackup", "Database") .StartNow() .WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever()) .Build(); + var storeCleanup = + TriggerBuilder.Create() + .WithIdentity("StoreCleanup", "Database") + .StartNow() + .WithSimpleSchedule(x => x.WithIntervalInHours(24).RepeatForever()) + .Build(); + triggers.Add(plexAvailabilityChecker); triggers.Add(srCacher); triggers.Add(sonarrCacher); triggers.Add(cpCacher); triggers.Add(storeBackup); + triggers.Add(storeCleanup); return triggers; } diff --git a/PlexRequests.UI/Modules/AdminModule.cs b/PlexRequests.UI/Modules/AdminModule.cs index c62b7ff46..bdf0248a6 100644 --- a/PlexRequests.UI/Modules/AdminModule.cs +++ b/PlexRequests.UI/Modules/AdminModule.cs @@ -481,8 +481,7 @@ namespace PlexRequests.UI.Modules { return Response.AsJson(valid.SendJsonError()); } - Log.Trace(settings.DumpJson()); - + var result = EmailService.SaveSettings(settings); if (settings.Enabled) diff --git a/PlexRequests.UI/Modules/ApprovalModule.cs b/PlexRequests.UI/Modules/ApprovalModule.cs index c7e95dbd3..47ba387ef 100644 --- a/PlexRequests.UI/Modules/ApprovalModule.cs +++ b/PlexRequests.UI/Modules/ApprovalModule.cs @@ -50,7 +50,7 @@ namespace PlexRequests.UI.Modules ISettingsService sonarrSettings, ISickRageApi srApi, ISettingsService srSettings, ISettingsService hpSettings, IHeadphonesApi hpApi, ISettingsService pr) : base("approval", pr) { - this.RequiresClaims(UserClaims.Admin); + this.RequiresClaims(UserClaims.Admin); Service = service; CpService = cpService; @@ -66,6 +66,8 @@ namespace PlexRequests.UI.Modules Post["/approveall"] = x => ApproveAll(); Post["/approveallmovies"] = x => ApproveAllMovies(); Post["/approvealltvshows"] = x => ApproveAllTVShows(); + Post["/deleteallmovies"] = x => DeleteAllMovies(); + Post["/deletealltvshows"] = x => DeleteAllTVShows(); } private IRequestService Service { get; } @@ -130,7 +132,7 @@ namespace PlexRequests.UI.Modules Log.Trace("Approval result: {0}", requestResult); if (requestResult) { - return Response.AsJson(new JsonResponseModel {Result = true}); + return Response.AsJson(new JsonResponseModel { Result = true }); } return Response.AsJson(new JsonResponseModel @@ -156,11 +158,9 @@ namespace PlexRequests.UI.Modules request.Approved = true; var requestResult = Service.UpdateRequest(request); Log.Trace("Approval result: {0}", requestResult); - if (requestResult) - { - return Response.AsJson(new JsonResponseModel { Result = true }); - } - return Response.AsJson(new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" }); + return Response.AsJson(requestResult + ? new JsonResponseModel { Result = true } + : new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" }); } return Response.AsJson(new JsonResponseModel { @@ -168,17 +168,19 @@ namespace PlexRequests.UI.Modules Message = result?.message != null ? "Message From SickRage: " + result.message : "Could not add the series to SickRage" }); } - return Response.AsJson(new JsonResponseModel - { - Result = false, - Message = "SickRage or Sonarr are not set up!" - }); + + + request.Approved = true; + var res = Service.UpdateRequest(request); + return Response.AsJson(res + ? new JsonResponseModel { Result = true, Message = "This has been approved, but It has not been sent to Sonarr/SickRage because it has not been configured" } + : new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" }); } private Response RequestMovieAndUpdateStatus(RequestedModel request, string qualityId) { var cpSettings = CpService.GetSettings(); - var cp = new CouchPotatoApi(); + Log.Info("Adding movie to CouchPotato : {0}", request.Title); if (!cpSettings.Enabled) { @@ -197,7 +199,7 @@ namespace PlexRequests.UI.Modules }); } - var result = cp.AddMovie(request.ImdbId, cpSettings.ApiKey, request.Title, cpSettings.FullUri, string.IsNullOrEmpty(qualityId) ? cpSettings.ProfileId : qualityId); + var result = CpApi.AddMovie(request.ImdbId, cpSettings.ApiKey, request.Title, cpSettings.FullUri, string.IsNullOrEmpty(qualityId) ? cpSettings.ProfileId : qualityId); Log.Trace("Adding movie to CP result {0}", result); if (result) { @@ -248,9 +250,9 @@ namespace PlexRequests.UI.Modules var sender = new HeadphonesSender(HeadphoneApi, hpSettings, Service); var result = sender.AddAlbum(request); - - return Response.AsJson( new JsonResponseModel { Result = true, Message = "We have sent the approval to Headphones for processing, This can take a few minutes."} ); + + return Response.AsJson(new JsonResponseModel { Result = true, Message = "We have sent the approval to Headphones for processing, This can take a few minutes." }); } private Response ApproveAllMovies() @@ -274,6 +276,27 @@ namespace PlexRequests.UI.Modules } } + private Response DeleteAllMovies() + { + + var requests = Service.GetAll().Where(x => x.Type == RequestType.Movie); + var requestedModels = requests as RequestedModel[] ?? requests.ToArray(); + if (!requestedModels.Any()) + { + return Response.AsJson(new JsonResponseModel { Result = false, Message = "There are no movie requests to delete. Please refresh." }); + } + + try + { + return DeleteRequests(requestedModels); + } + catch (Exception e) + { + Log.Fatal(e); + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something bad happened, please check the logs!" }); + } + } + private Response ApproveAllTVShows() { var requests = Service.GetAll().Where(x => x.CanApprove && x.Type == RequestType.TvShow); @@ -294,6 +317,27 @@ namespace PlexRequests.UI.Modules } } + private Response DeleteAllTVShows() + { + + var requests = Service.GetAll().Where(x => x.Type == RequestType.TvShow); + var requestedModels = requests as RequestedModel[] ?? requests.ToArray(); + if (!requestedModels.Any()) + { + return Response.AsJson(new JsonResponseModel { Result = false, Message = "There are no tv show requests to delete. Please refresh." }); + } + + try + { + return DeleteRequests(requestedModels); + } + catch (Exception e) + { + Log.Fatal(e); + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something bad happened, please check the logs!" }); + } + } + /// /// Approves all. /// @@ -319,6 +363,22 @@ namespace PlexRequests.UI.Modules } + private Response DeleteRequests(RequestedModel[] requestedModels) + { + try + { + var result = Service.BatchDelete(requestedModels.ToList()); + return Response.AsJson(result + ? new JsonResponseModel { Result = true } + : new JsonResponseModel { Result = false, Message = "We could not delete all of the requests. Please try again or check the logs." }); + } + catch (Exception e) + { + Log.Fatal(e); + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something bad happened, please check the logs!" }); + } + } + private Response UpdateRequests(RequestedModel[] requestedModels) { var cpSettings = CpService.GetSettings(); @@ -327,15 +387,23 @@ namespace PlexRequests.UI.Modules { if (r.Type == RequestType.Movie) { - var res = SendMovie(cpSettings, r, CpApi); - if (res) + if (cpSettings.Enabled) { - r.Approved = true; - updatedRequests.Add(r); + var res = SendMovie(cpSettings, r, CpApi); + if (res) + { + r.Approved = true; + updatedRequests.Add(r); + } + else + { + Log.Error("Could not approve and send the movie {0} to couch potato!", r.Title); + } } else { - Log.Error("Could not approve and send the movie {0} to couch potato!", r.Title); + r.Approved = true; + updatedRequests.Add(r); } } if (r.Type == RequestType.TvShow) @@ -358,7 +426,7 @@ namespace PlexRequests.UI.Modules } } - if (sonarr.Enabled) + else if (sonarr.Enabled) { var res = sender.SendToSonarr(sonarr, r); if (!string.IsNullOrEmpty(res?.title)) @@ -372,11 +440,15 @@ namespace PlexRequests.UI.Modules res?.ErrorMessages.ForEach(x => Log.Error("Error messages: {0}", x)); } } + else + { + r.Approved = true; + updatedRequests.Add(r); + } } } try { - var result = Service.BatchUpdate(updatedRequests); return Response.AsJson(result ? new JsonResponseModel { Result = true } diff --git a/PlexRequests.UI/Modules/LoginModule.cs b/PlexRequests.UI/Modules/LoginModule.cs index 326b7ec13..8e6a9d39c 100644 --- a/PlexRequests.UI/Modules/LoginModule.cs +++ b/PlexRequests.UI/Modules/LoginModule.cs @@ -35,6 +35,7 @@ using Nancy.Security; using PlexRequests.Core; using PlexRequests.Core.SettingModels; +using PlexRequests.Helpers; using PlexRequests.UI.Models; namespace PlexRequests.UI.Modules @@ -103,7 +104,7 @@ namespace PlexRequests.UI.Modules { return Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/register?error=true" : "~/register?error=true"); } - var userId = UserMapper.CreateUser(username, Request.Form.Password, new[] { "Admin" }); + var userId = UserMapper.CreateAdmin(username, Request.Form.Password); Session[SessionKeys.UsernameKey] = username; return this.LoginAndRedirect((Guid)userId); }; diff --git a/PlexRequests.UI/Modules/RequestsModule.cs b/PlexRequests.UI/Modules/RequestsModule.cs index f813c038d..16bbd1cb2 100644 --- a/PlexRequests.UI/Modules/RequestsModule.cs +++ b/PlexRequests.UI/Modules/RequestsModule.cs @@ -74,17 +74,17 @@ namespace PlexRequests.UI.Modules Cache = cache; Get["/"] = _ => LoadRequests(); - Get["/movies"] = _ => GetMovies(); - Get["/tvshows"] = _ => GetTvShows(); - Get["/albums"] = _ => GetAlbumRequests(); - Post["/delete"] = _ => DeleteRequest((int)Request.Form.id); - Post["/reportissue"] = _ => ReportIssue((int)Request.Form.requestId, (IssueState)(int)Request.Form.issue, null); - Post["/reportissuecomment"] = _ => ReportIssue((int)Request.Form.requestId, IssueState.Other, (string)Request.Form.commentArea); + Get["/movies", true] = async (x, ct) => await GetMovies(); + Get["/tvshows", true] = async (c, ct) => await GetTvShows(); + Get["/albums", true] = async (x,ct) => await GetAlbumRequests(); + Post["/delete", true] = async (x, ct) => await DeleteRequest((int)Request.Form.id); + Post["/reportissue", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, (IssueState)(int)Request.Form.issue, null); + Post["/reportissuecomment", true] = async (x, ct) => await ReportIssue((int)Request.Form.requestId, IssueState.Other, (string)Request.Form.commentArea); - Post["/clearissues"] = _ => ClearIssue((int)Request.Form.Id); + Post["/clearissues", true] = async (x, ct) => await ClearIssue((int)Request.Form.Id); - Post["/changeavailability"] = _ => ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available); - Post["/addnote"] = _ => AddNote((int)Request.Form.requestId, (string)Request.Form.noteArea); + Post["/changeavailability", true] = async (x, ct) => await ChangeRequestAvailability((int)Request.Form.Id, (bool)Request.Form.Available); + Post["/addnote", true] = async (x, ct) => await AddNote((int)Request.Form.requestId, (string)Request.Form.noteArea); } private IRequestService Service { get; } @@ -105,122 +105,94 @@ namespace PlexRequests.UI.Modules return View["Index", settings]; } - private Response GetMovies() // TODO: async await the API calls + private async Task GetMovies() { var settings = PrSettings.GetSettings(); - List taskList = new List(); + var allRequests = await Service.GetAllAsync(); + allRequests = allRequests.Where(x => x.Type == RequestType.Movie); - List dbMovies = new List(); - taskList.Add(Task.Factory.StartNew(() => - { - return Service.GetAll().Where(x => x.Type == RequestType.Movie); + var dbMovies = allRequests.ToList(); - }).ContinueWith((t) => + if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) { - dbMovies = t.Result.ToList(); - - if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) - { - dbMovies = dbMovies.Where(x => x.UserHasRequested(Username)).ToList(); - } - })); - + dbMovies = dbMovies.Where(x => x.UserHasRequested(Username)).ToList(); + } List qualities = new List(); - if (IsAdmin) + if (IsAdmin) { var cpSettings = CpSettings.GetSettings(); if (cpSettings.Enabled) { - taskList.Add(Task.Factory.StartNew(() => - { - return Cache.GetOrSet(CacheKeys.CouchPotatoQualityProfiles, () => - { - return CpApi.GetProfiles(cpSettings.FullUri, cpSettings.ApiKey); // TODO: cache this! - }); - }).ContinueWith((t) => + + var result = await Cache.GetOrSetAsync(CacheKeys.CouchPotatoQualityProfiles, async () => { - qualities = t.Result.list.Select(x => new QualityModel() { Id = x._id, Name = x.label }).ToList(); - })); + return await Task.Run(() => CpApi.GetProfiles(cpSettings.FullUri, cpSettings.ApiKey)).ConfigureAwait(false); + }); + + qualities = result.list.Select(x => new QualityModel() { Id = x._id, Name = x.label }).ToList(); } } - Task.WaitAll(taskList.ToArray()); - - var viewModel = dbMovies.Select(movie => + var viewModel = dbMovies.Select(movie => new RequestViewModel { - return new RequestViewModel - { - ProviderId = movie.ProviderId, - Type = movie.Type, - Status = movie.Status, - ImdbId = movie.ImdbId, - Id = movie.Id, - PosterPath = movie.PosterPath, - ReleaseDate = movie.ReleaseDate, - ReleaseDateTicks = movie.ReleaseDate.Ticks, - RequestedDate = movie.RequestedDate, - Released = DateTime.Now > movie.ReleaseDate, - RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(movie.RequestedDate, DateTimeOffset).Ticks, - Approved = movie.Available || movie.Approved, - Title = movie.Title, - Overview = movie.Overview, - RequestedUsers = IsAdmin ? movie.AllUsers.ToArray() : new string[] { }, - ReleaseYear = movie.ReleaseDate.Year.ToString(), - Available = movie.Available, - Admin = IsAdmin, - Issues = movie.Issues.ToString().CamelCaseToWords(), - OtherMessage = movie.OtherMessage, - AdminNotes = movie.AdminNote, - Qualities = qualities.ToArray() - }; + ProviderId = movie.ProviderId, + Type = movie.Type, + Status = movie.Status, + ImdbId = movie.ImdbId, + Id = movie.Id, + PosterPath = movie.PosterPath, + ReleaseDate = movie.ReleaseDate, + ReleaseDateTicks = movie.ReleaseDate.Ticks, + RequestedDate = movie.RequestedDate, + Released = DateTime.Now > movie.ReleaseDate, + RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(movie.RequestedDate, DateTimeOffset).Ticks, + Approved = movie.Available || movie.Approved, + Title = movie.Title, + Overview = movie.Overview, + RequestedUsers = IsAdmin ? movie.AllUsers.ToArray() : new string[] { }, + ReleaseYear = movie.ReleaseDate.Year.ToString(), + Available = movie.Available, + Admin = IsAdmin, + Issues = movie.Issues.ToString().CamelCaseToWords(), + OtherMessage = movie.OtherMessage, + AdminNotes = movie.AdminNote, + Qualities = qualities.ToArray() }).ToList(); return Response.AsJson(viewModel); } - private Response GetTvShows() // TODO: async await the API calls + private async Task GetTvShows() { var settings = PrSettings.GetSettings(); - List taskList = new List(); + var requests = await Service.GetAllAsync(); + requests = requests.Where(x => x.Type == RequestType.TvShow); - List dbTv = new List(); - taskList.Add(Task.Factory.StartNew(() => - { - return Service.GetAll().Where(x => x.Type == RequestType.TvShow); + var dbTv = requests; - }).ContinueWith((t) => + if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) { - dbTv = t.Result.ToList(); - - if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) - { - dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList(); - } - })); + dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList(); + } - List qualities = new List(); + IEnumerable qualities = new List(); if (IsAdmin) { var sonarrSettings = SonarrSettings.GetSettings(); if (sonarrSettings.Enabled) { - taskList.Add(Task.Factory.StartNew(() => + var result = Cache.GetOrSetAsync(CacheKeys.SonarrQualityProfiles, async () => { - return Cache.GetOrSet(CacheKeys.SonarrQualityProfiles, () => - { - return SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri); // TODO: cache this! - + return await Task.Run(() => SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri)); }); - }).ContinueWith((t) => - { - qualities = t.Result.Select(x => new QualityModel() { Id = x.id.ToString(), Name = x.name }).ToList(); - })); + qualities = result.Result.Select(x => new QualityModel() { Id = x.id.ToString(), Name = x.name }).ToList(); } - else { + else + { var sickRageSettings = SickRageSettings.GetSettings(); if (sickRageSettings.Enabled) { @@ -229,8 +201,6 @@ namespace PlexRequests.UI.Modules } } - Task.WaitAll(taskList.ToArray()); - var viewModel = dbTv.Select(tv => { return new RequestViewModel @@ -264,10 +234,11 @@ namespace PlexRequests.UI.Modules return Response.AsJson(viewModel); } - private Response GetAlbumRequests() + private async Task GetAlbumRequests() { var settings = PrSettings.GetSettings(); - var dbAlbum = Service.GetAll().Where(x => x.Type == RequestType.Album); + var dbAlbum = await Service.GetAllAsync(); + dbAlbum = dbAlbum.Where(x => x.Type == RequestType.Album); if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) { dbAlbum = dbAlbum.Where(x => x.UserHasRequested(Username)); @@ -308,12 +279,12 @@ namespace PlexRequests.UI.Modules return Response.AsJson(viewModel); } - private Response DeleteRequest(int requestid) - { - this.RequiresClaims (UserClaims.Admin); + private async Task DeleteRequest(int requestid) + { + this.RequiresClaims(UserClaims.Admin); - var currentEntity = Service.Get(requestid); - Service.DeleteRequest(currentEntity); + var currentEntity = await Service.GetAsync(requestid); + await Service.DeleteRequestAsync(currentEntity); return Response.AsJson(new JsonResponseModel { Result = true }); } @@ -325,9 +296,9 @@ namespace PlexRequests.UI.Modules /// The issue. /// The comment. /// - private Response ReportIssue(int requestId, IssueState issue, string comment) + private async Task ReportIssue(int requestId, IssueState issue, string comment) { - var originalRequest = Service.Get(requestId); + var originalRequest = await Service.GetAsync(requestId); if (originalRequest == null) { return Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" }); @@ -338,7 +309,7 @@ namespace PlexRequests.UI.Modules : string.Empty; - var result = Service.UpdateRequest(originalRequest); + var result = await Service.UpdateRequestAsync(originalRequest); var model = new NotificationModel { @@ -348,18 +319,18 @@ namespace PlexRequests.UI.Modules DateTime = DateTime.Now, Body = issue == IssueState.Other ? comment : issue.ToString().CamelCaseToWords() }; - NotificationService.Publish(model); + await NotificationService.Publish(model); return Response.AsJson(result ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" }); } - private Response ClearIssue(int requestId) + private async Task ClearIssue(int requestId) { - this.RequiresClaims ( UserClaims.Admin); + this.RequiresClaims(UserClaims.Admin); - var originalRequest = Service.Get(requestId); + var originalRequest = await Service.GetAsync(requestId); if (originalRequest == null) { return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to clear it!" }); @@ -367,16 +338,16 @@ namespace PlexRequests.UI.Modules originalRequest.Issues = IssueState.None; originalRequest.OtherMessage = string.Empty; - var result = Service.UpdateRequest(originalRequest); + var result = await Service.UpdateRequestAsync(originalRequest); return Response.AsJson(result ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not clear issue, please try again or check the logs" }); } - private Response ChangeRequestAvailability(int requestId, bool available) - { - this.RequiresClaims (UserClaims.Admin); - var originalRequest = Service.Get(requestId); + private async Task ChangeRequestAvailability(int requestId, bool available) + { + this.RequiresClaims(UserClaims.Admin); + var originalRequest = await Service.GetAsync(requestId); if (originalRequest == null) { return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to change the availability!" }); @@ -384,16 +355,16 @@ namespace PlexRequests.UI.Modules originalRequest.Available = available; - var result = Service.UpdateRequest(originalRequest); + var result = await Service.UpdateRequestAsync(originalRequest); return Response.AsJson(result ? new { Result = true, Available = available, Message = string.Empty } : new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" }); } - private Response AddNote(int requestId, string noteArea) - { - this.RequiresClaims (UserClaims.Admin); - var originalRequest = Service.Get(requestId); + private async Task AddNote(int requestId, string noteArea) + { + this.RequiresClaims(UserClaims.Admin); + var originalRequest = await Service.GetAsync(requestId); if (originalRequest == null) { return Response.AsJson(new JsonResponseModel { Result = false, Message = "Request does not exist to add a note!" }); @@ -401,7 +372,7 @@ namespace PlexRequests.UI.Modules originalRequest.AdminNote = noteArea; - var result = Service.UpdateRequest(originalRequest); + var result = await Service.UpdateRequestAsync(originalRequest); return Response.AsJson(result ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not update the notes, please try again or check the logs" }); diff --git a/PlexRequests.UI/Modules/SearchModule.cs b/PlexRequests.UI/Modules/SearchModule.cs index efae9678a..0de1a23b9 100644 --- a/PlexRequests.UI/Modules/SearchModule.cs +++ b/PlexRequests.UI/Modules/SearchModule.cs @@ -47,7 +47,7 @@ using PlexRequests.Store; using PlexRequests.UI.Helpers; using PlexRequests.UI.Models; using System.Threading.Tasks; -using System.Windows.Forms; + using Nancy.Extensions; using PlexRequests.Api.Models.Tv; using PlexRequests.Store.Models; @@ -92,22 +92,22 @@ namespace PlexRequests.UI.Modules EmailNotificationSettings = email; - Get["/"] = parameters => RequestLoad(); + Get["/", true] = async (x, ct) => await RequestLoad(); - Get["movie/{searchTerm}"] = parameters => SearchMovie((string)parameters.searchTerm); - Get["tv/{searchTerm}"] = parameters => SearchTvShow((string)parameters.searchTerm); - Get["music/{searchTerm}"] = parameters => SearchMusic((string)parameters.searchTerm); + Get["movie/{searchTerm}", true] = async (x, ct) => await SearchMovie((string)x.searchTerm); + Get["tv/{searchTerm}", true] = async (x, ct) => await SearchTvShow((string)x.searchTerm); + Get["music/{searchTerm}", true] = async (x, ct) => await SearchMusic((string)x.searchTerm); Get["music/coverArt/{id}"] = p => GetMusicBrainzCoverArt((string)p.id); - Get["movie/upcoming"] = parameters => UpcomingMovies(); - Get["movie/playing"] = parameters => CurrentlyPlayingMovies(); + Get["movie/upcoming", true] = async (x, ct) => await UpcomingMovies(); + Get["movie/playing", true] = async (x, ct) => await CurrentlyPlayingMovies(); - Post["request/movie"] = parameters => RequestMovie((int)Request.Form.movieId); - Post["request/tv"] = parameters => RequestTvShow((int)Request.Form.tvId, (string)Request.Form.seasons); - Post["request/album"] = parameters => RequestAlbum((string)Request.Form.albumId); + Post["request/movie", true] = async (x, ct) => await RequestMovie((int)Request.Form.movieId); + Post["request/tv", true] = async (x, ct) => await RequestTvShow((int)Request.Form.tvId, (string)Request.Form.seasons); + Post["request/album", true] = async (x, ct) => await RequestAlbum((string)Request.Form.albumId); - Post["/notifyuser"] = x => NotifyUser((bool)Request.Form.notify); - Get["/notifyuser"] = x => GetUserNotificationSettings(); + Post["/notifyuser", true] = async (x, ct) => await NotifyUser((bool)Request.Form.notify); + Get["/notifyuser", true] = async (x, ct) => await GetUserNotificationSettings(); Get["/seasons"] = x => GetSeasons(); } @@ -136,87 +136,86 @@ namespace PlexRequests.UI.Modules private IRepository UsersToNotifyRepo { get; } private static Logger Log = LogManager.GetCurrentClassLogger(); - private Negotiator RequestLoad() + private async Task RequestLoad() { - var settings = PrService.GetSettings(); + var settings = await PrService.GetSettingsAsync(); Log.Trace("Loading Index"); return View["Search/Index", settings]; } - private Response UpcomingMovies() + private async Task UpcomingMovies() { Log.Trace("Loading upcoming movies"); - return ProcessMovies(MovieSearchType.Upcoming, string.Empty); + return await ProcessMovies(MovieSearchType.Upcoming, string.Empty); } - private Response CurrentlyPlayingMovies() + private async Task CurrentlyPlayingMovies() { Log.Trace("Loading currently playing movies"); - return ProcessMovies(MovieSearchType.CurrentlyPlaying, string.Empty); + return await ProcessMovies(MovieSearchType.CurrentlyPlaying, string.Empty); } - private Response SearchMovie(string searchTerm) + private async Task SearchMovie(string searchTerm) { Log.Trace("Searching for Movie {0}", searchTerm); - return ProcessMovies(MovieSearchType.Search, searchTerm); + return await ProcessMovies(MovieSearchType.Search, searchTerm); } - private Response ProcessMovies(MovieSearchType searchType, string searchTerm) + private async Task ProcessMovies(MovieSearchType searchType, string searchTerm) { - var taskList = new List(); - var apiMovies = new List(); - taskList.Add(Task.Factory.StartNew(() => - { - switch (searchType) + await Task.Factory.StartNew( + () => { - case MovieSearchType.Search: - return MovieApi.SearchMovie(searchTerm).Result.Select(x => new MovieResult() - { - Adult = x.Adult, - BackdropPath = x.BackdropPath, - GenreIds = x.GenreIds, - Id = x.Id, - OriginalLanguage = x.OriginalLanguage, - OriginalTitle = x.OriginalTitle, - Overview = x.Overview, - Popularity = x.Popularity, - PosterPath = x.PosterPath, - ReleaseDate = x.ReleaseDate, - Title = x.Title, - Video = x.Video, - VoteAverage = x.VoteAverage, - VoteCount = x.VoteCount - }).ToList(); - case MovieSearchType.CurrentlyPlaying: - return MovieApi.GetCurrentPlayingMovies().Result.ToList(); - case MovieSearchType.Upcoming: - return MovieApi.GetUpcomingMovies().Result.ToList(); - default: - return new List(); - } - }).ContinueWith((t) => - { - apiMovies = t.Result; - })); + switch (searchType) + { + case MovieSearchType.Search: + return + MovieApi.SearchMovie(searchTerm) + .Result.Select( + x => + new MovieResult() + { + Adult = x.Adult, + BackdropPath = x.BackdropPath, + GenreIds = x.GenreIds, + Id = x.Id, + OriginalLanguage = x.OriginalLanguage, + OriginalTitle = x.OriginalTitle, + Overview = x.Overview, + Popularity = x.Popularity, + PosterPath = x.PosterPath, + ReleaseDate = x.ReleaseDate, + Title = x.Title, + Video = x.Video, + VoteAverage = x.VoteAverage, + VoteCount = x.VoteCount + }) + .ToList(); + case MovieSearchType.CurrentlyPlaying: + return MovieApi.GetCurrentPlayingMovies().Result.ToList(); + case MovieSearchType.Upcoming: + return MovieApi.GetUpcomingMovies().Result.ToList(); + default: + return new List(); + } + }).ContinueWith( + (t) => + { + apiMovies = t.Result; + }); - Dictionary dbMovies = new Dictionary(); - taskList.Add(Task.Factory.StartNew(() => - { - return RequestService.GetAll().Where(x => x.Type == RequestType.Movie); + var allResults = await RequestService.GetAllAsync(); + allResults = allResults.Where(x => x.Type == RequestType.Movie); - }).ContinueWith((t) => - { - var distinctResults = t.Result.DistinctBy(x => x.ProviderId); - dbMovies = distinctResults.ToDictionary(x => x.ProviderId); - })); + var distinctResults = allResults.DistinctBy(x => x.ProviderId); + var dbMovies = distinctResults.ToDictionary(x => x.ProviderId); - Task.WaitAll(taskList.ToArray()); var cpCached = CpCacher.QueuedIds(); var plexMovies = Checker.GetPlexMovies(); - var settings = PrService.GetSettings(); + var settings = await PrService.GetSettingsAsync(); var viewMovies = new List(); foreach (MovieResult movie in apiMovies) { @@ -272,33 +271,20 @@ namespace PlexRequests.UI.Modules return true; } - private Response SearchTvShow(string searchTerm) + private async Task SearchTvShow(string searchTerm) { Log.Trace("Searching for TV Show {0}", searchTerm); - var taskList = new List(); - var apiTv = new List(); - taskList.Add(Task.Factory.StartNew(() => - { - return new TvMazeApi().Search(searchTerm); - - }).ContinueWith((t) => + await Task.Factory.StartNew(() => new TvMazeApi().Search(searchTerm)).ContinueWith((t) => { apiTv = t.Result; - })); - - var dbTv = new Dictionary(); - taskList.Add(Task.Factory.StartNew(() => - { - return RequestService.GetAll().Where(x => x.Type == RequestType.TvShow); + }); - }).ContinueWith((t) => - { - dbTv = t.Result.ToDictionary(x => x.ProviderId); - })); + var allResults = await RequestService.GetAllAsync(); + allResults = allResults.Where(x => x.Type == RequestType.TvShow); - Task.WaitAll(taskList.ToArray()); + var dbTv = allResults.ToDictionary(x => x.ProviderId); if (!apiTv.Any()) { @@ -361,31 +347,18 @@ namespace PlexRequests.UI.Modules return Response.AsJson(viewTv); } - private Response SearchMusic(string searchTerm) + private async Task SearchMusic(string searchTerm) { - var taskList = new List(); - var apiAlbums = new List(); - taskList.Add(Task.Factory.StartNew(() => - { - return MusicBrainzApi.SearchAlbum(searchTerm); - - }).ContinueWith((t) => + await Task.Run(() => MusicBrainzApi.SearchAlbum(searchTerm)).ContinueWith((t) => { apiAlbums = t.Result.releases ?? new List(); - })); - - var dbAlbum = new Dictionary(); - taskList.Add(Task.Factory.StartNew(() => - { - return RequestService.GetAll().Where(x => x.Type == RequestType.Album); + }); - }).ContinueWith((t) => - { - dbAlbum = t.Result.ToDictionary(x => x.MusicBrainzId); - })); + var allResults = await RequestService.GetAllAsync(); + allResults = allResults.Where(x => x.Type == RequestType.Album); - Task.WaitAll(taskList.ToArray()); + var dbAlbum = allResults.ToDictionary(x => x.MusicBrainzId); var plexAlbums = Checker.GetPlexAlbums(); @@ -407,7 +380,7 @@ namespace PlexRequests.UI.Modules DateTime release; DateTimeHelper.CustomParse(a.ReleaseEvents?.FirstOrDefault()?.date, out release); var artist = a.ArtistCredit?.FirstOrDefault()?.artist; - if (Checker.IsAlbumAvailable(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist.name)) + if (Checker.IsAlbumAvailable(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist?.name)) { viewA.Available = true; } @@ -425,27 +398,26 @@ namespace PlexRequests.UI.Modules return Response.AsJson(viewAlbum); } - private Response RequestMovie(int movieId) + private async Task RequestMovie(int movieId) { var movieApi = new TheMovieDbApi(); var movieInfo = movieApi.GetMovieInformation(movieId).Result; var fullMovieName = $"{movieInfo.Title}{(movieInfo.ReleaseDate.HasValue ? $" ({movieInfo.ReleaseDate.Value.Year})" : string.Empty)}"; Log.Trace("Getting movie info from TheMovieDb"); - Log.Trace(movieInfo.DumpJson); //#if !DEBUG - var settings = PrService.GetSettings(); + var settings = await PrService.GetSettingsAsync(); // check if the movie has already been requested Log.Info("Requesting movie with id {0}", movieId); - var existingRequest = RequestService.CheckRequest(movieId); + var existingRequest = await RequestService.CheckRequestAsync(movieId); if (existingRequest != null) { // check if the current user is already marked as a requester for this movie, if not, add them if (!existingRequest.UserHasRequested(Username)) { existingRequest.RequestedUsers.Add(Username); - RequestService.UpdateRequest(existingRequest); + await RequestService.UpdateRequestAsync(existingRequest); } return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullMovieName} was successfully added!" : $"{fullMovieName} has already been requested!" }); @@ -461,8 +433,9 @@ namespace PlexRequests.UI.Modules return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullMovieName} is already in Plex!" }); } } - catch (ApplicationSettingsException) + catch (Exception e) { + Log.Error(e); return Response.AsJson(new JsonResponseModel { Result = false, Message = $"We could not check if {fullMovieName} is in Plex, are you sure it's correctly setup?" }); } //#endif @@ -473,7 +446,7 @@ namespace PlexRequests.UI.Modules Type = RequestType.Movie, Overview = movieInfo.Overview, ImdbId = movieInfo.ImdbId, - PosterPath = "http://image.tmdb.org/t/p/w150/" + movieInfo.PosterPath, + PosterPath = "https://image.tmdb.org/t/p/w150/" + movieInfo.PosterPath, Title = movieInfo.Title, ReleaseDate = movieInfo.ReleaseDate ?? DateTime.MinValue, Status = movieInfo.Status, @@ -484,13 +457,10 @@ namespace PlexRequests.UI.Modules }; - Log.Trace(settings.DumpJson()); if (ShouldAutoApprove(RequestType.Movie, settings)) { - var cpSettings = CpService.GetSettings(); + var cpSettings = await CpService.GetSettingsAsync(); - Log.Trace("Settings: "); - Log.Trace(cpSettings.DumpJson); if (cpSettings.Enabled) { Log.Info("Adding movie to CP (No approval required)"); @@ -501,8 +471,7 @@ namespace PlexRequests.UI.Modules { model.Approved = true; Log.Info("Adding movie to database (No approval required)"); - RequestService.AddRequest(model); - + await RequestService.AddRequestAsync(model); if (ShouldSendNotification()) { @@ -513,7 +482,7 @@ namespace PlexRequests.UI.Modules DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notificationModel); + await NotificationService.Publish(notificationModel); } return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" }); } @@ -529,7 +498,7 @@ namespace PlexRequests.UI.Modules { model.Approved = true; Log.Info("Adding movie to database (No approval required)"); - RequestService.AddRequest(model); + await RequestService.AddRequestAsync(model); if (ShouldSendNotification()) { @@ -540,7 +509,7 @@ namespace PlexRequests.UI.Modules DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notificationModel); + await NotificationService.Publish(notificationModel); } return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" }); @@ -550,10 +519,10 @@ namespace PlexRequests.UI.Modules try { Log.Info("Adding movie to database"); - var id = RequestService.AddRequest(model); + var id = await RequestService.AddRequestAsync(model); var notificationModel = new NotificationModel { Title = model.Title, User = Username, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notificationModel); + await NotificationService.Publish(notificationModel); return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullMovieName} was successfully added!" }); } @@ -570,9 +539,8 @@ namespace PlexRequests.UI.Modules /// /// The show identifier. /// The seasons. - /// if set to true [notify]. /// - private Response RequestTvShow(int showId, string seasons) + private async Task RequestTvShow(int showId, string seasons) { var tvApi = new TvMazeApi(); @@ -582,18 +550,18 @@ namespace PlexRequests.UI.Modules string fullShowName = $"{showInfo.name} ({firstAir.Year})"; //#if !DEBUG - var settings = PrService.GetSettings(); + var settings = await PrService.GetSettingsAsync(); // check if the show has already been requested Log.Info("Requesting tv show with id {0}", showId); - var existingRequest = RequestService.CheckRequest(showId); + var existingRequest = await RequestService.CheckRequestAsync(showId); if (existingRequest != null) { // check if the current user is already marked as a requester for this show, if not, add them if (!existingRequest.UserHasRequested(Username)) { existingRequest.RequestedUsers.Add(Username); - RequestService.UpdateRequest(existingRequest); + await RequestService.UpdateRequestAsync(existingRequest); } return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullShowName} was successfully added!" : $"{fullShowName} has already been requested!" }); } @@ -606,7 +574,7 @@ namespace PlexRequests.UI.Modules return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} is already in Plex!" }); } } - catch (ApplicationSettingsException) + catch (Exception) { return Response.AsJson(new JsonResponseModel { Result = false, Message = $"We could not check if {fullShowName} is in Plex, are you sure it's correctly setup?" }); } @@ -627,7 +595,7 @@ namespace PlexRequests.UI.Modules RequestedUsers = new List { Username }, Issues = IssueState.None, ImdbId = showInfo.externals?.imdb ?? string.Empty, - SeasonCount = showInfo.seasonCount + SeasonCount = showInfo.seasonCount, }; var seasonsList = new List(); @@ -645,6 +613,7 @@ namespace PlexRequests.UI.Modules model.SeasonsRequested = "All"; break; default: + model.SeasonsRequested = seasons; var split = seasons.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var seasonsCount = new int[split.Length]; for (var i = 0; i < split.Length; i++) @@ -661,16 +630,16 @@ namespace PlexRequests.UI.Modules if (ShouldAutoApprove(RequestType.TvShow, settings)) { - var sonarrSettings = SonarrService.GetSettings(); + var sonarrSettings = await SonarrService.GetSettingsAsync(); var sender = new TvSender(SonarrApi, SickrageApi); if (sonarrSettings.Enabled) { var result = sender.SendToSonarr(sonarrSettings, model); - if (result != null && !string.IsNullOrEmpty(result.title)) + if (!string.IsNullOrEmpty(result?.title)) { model.Approved = true; Log.Debug("Adding tv to database requests (No approval required & Sonarr)"); - RequestService.AddRequest(model); + await RequestService.AddRequestAsync(model); if (ShouldSendNotification()) { @@ -681,7 +650,7 @@ namespace PlexRequests.UI.Modules DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notify1); + await NotificationService.Publish(notify1); } return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" }); } @@ -699,7 +668,7 @@ namespace PlexRequests.UI.Modules { model.Approved = true; Log.Debug("Adding tv to database requests (No approval required & SickRage)"); - RequestService.AddRequest(model); + await RequestService.AddRequestAsync(model); if (ShouldSendNotification()) { var notify2 = new NotificationModel @@ -709,7 +678,7 @@ namespace PlexRequests.UI.Modules DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notify2); + await NotificationService.Publish(notify2); } return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" }); @@ -717,14 +686,33 @@ namespace PlexRequests.UI.Modules return Response.AsJson(new JsonResponseModel { Result = false, Message = result?.message != null ? "Message From SickRage: " + result.message : "Something went wrong adding the movie to SickRage! Please check your settings." }); } + if (!srSettings.Enabled && !sonarrSettings.Enabled) + { + model.Approved = true; + Log.Debug("Adding tv to database requests (No approval required) and Sonarr/Sickrage not setup"); + await RequestService.AddRequestAsync(model); + if (ShouldSendNotification()) + { + var notify2 = new NotificationModel + { + Title = model.Title, + User = Username, + DateTime = DateTime.Now, + NotificationType = NotificationType.NewRequest + }; + await NotificationService.Publish(notify2); + } + return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" }); + } + return Response.AsJson(new JsonResponseModel { Result = false, Message = "The request of TV Shows is not correctly set up. Please contact your admin." }); } - RequestService.AddRequest(model); + await RequestService.AddRequestAsync(model); var notificationModel = new NotificationModel { Title = model.Title, User = Username, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notificationModel); + await NotificationService.Publish(notificationModel); return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" }); } @@ -735,7 +723,8 @@ namespace PlexRequests.UI.Modules var claims = Context.CurrentUser?.Claims; if (claims != null) { - if (claims.Contains(UserClaims.Admin) || claims.Contains(UserClaims.PowerUser)) + var enumerable = claims as string[] ?? claims.ToArray(); + if (enumerable.Contains(UserClaims.Admin) || enumerable.Contains(UserClaims.PowerUser)) { sendNotification = false; // Don't bother sending a notification if the user is an admin } @@ -744,10 +733,10 @@ namespace PlexRequests.UI.Modules } - private Response RequestAlbum(string releaseId) + private async Task RequestAlbum(string releaseId) { - var settings = PrService.GetSettings(); - var existingRequest = RequestService.CheckRequest(releaseId); + var settings = await PrService.GetSettingsAsync(); + var existingRequest = await RequestService.CheckRequestAsync(releaseId); Log.Debug("Checking for an existing request"); if (existingRequest != null) @@ -758,12 +747,11 @@ namespace PlexRequests.UI.Modules Log.Debug("Not in the requested list so adding them and updating the request. User: {0}", Username); existingRequest.RequestedUsers.Add(Username); - RequestService.UpdateRequest(existingRequest); + await RequestService.UpdateRequestAsync(existingRequest); } return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{existingRequest.Title} was successfully added!" : $"{existingRequest.Title} has already been requested!" }); } - Log.Debug("This is a new request"); var albumInfo = MusicBrainzApi.GetAlbum(releaseId); @@ -823,7 +811,7 @@ namespace PlexRequests.UI.Modules if (!hpSettings.Enabled) { - RequestService.AddRequest(model); + await RequestService.AddRequestAsync(model); return Response.AsJson(new JsonResponseModel { @@ -833,9 +821,9 @@ namespace PlexRequests.UI.Modules } var sender = new HeadphonesSender(HeadphonesApi, hpSettings, RequestService); - sender.AddAlbum(model).Wait(); + await sender.AddAlbum(model); model.Approved = true; - RequestService.AddRequest(model); + await RequestService.AddRequestAsync(model); if (ShouldSendNotification()) { @@ -846,7 +834,7 @@ namespace PlexRequests.UI.Modules DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notify2); + await NotificationService.Publish(notify2); } return @@ -866,9 +854,9 @@ namespace PlexRequests.UI.Modules DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest }; - NotificationService.Publish(notify2); + await NotificationService.Publish(notify2); } - var result = RequestService.AddRequest(model); + await RequestService.AddRequestAsync(model); return Response.AsJson(new JsonResponseModel { Result = true, @@ -909,20 +897,22 @@ namespace PlexRequests.UI.Modules } } - private Response NotifyUser(bool notify) + private async Task NotifyUser(bool notify) { - var auth = Auth.GetSettings().UserAuthentication; - var email = EmailNotificationSettings.GetSettings().EnableUserEmailNotifications; + var authSettings = await Auth.GetSettingsAsync(); + var auth = authSettings.UserAuthentication; + var emailSettings = await EmailNotificationSettings.GetSettingsAsync(); + var email = emailSettings.EnableUserEmailNotifications; if (!auth) { - return Response.AsJson(new JsonResponseModel { Result = false, Message = "Sorry, but this functionality is currently only for users with Plex accounts"}); + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Sorry, but this functionality is currently only for users with Plex accounts" }); } if (!email) { return Response.AsJson(new JsonResponseModel { Result = false, Message = "Sorry, but your administrator has not yet enabled this functionality." }); } var username = Username; - var originalList = UsersToNotifyRepo.GetAll(); + var originalList = await UsersToNotifyRepo.GetAllAsync(); if (!notify) { if (originalList == null) @@ -932,7 +922,7 @@ namespace PlexRequests.UI.Modules var userToRemove = originalList.FirstOrDefault(x => x.Username == username); if (userToRemove != null) { - UsersToNotifyRepo.Delete(userToRemove); + await UsersToNotifyRepo.DeleteAsync(userToRemove); } return Response.AsJson(new JsonResponseModel { Result = true }); } @@ -941,7 +931,7 @@ namespace PlexRequests.UI.Modules if (originalList == null) { var userModel = new UsersToNotify { Username = username }; - var insertResult = UsersToNotifyRepo.Insert(userModel); + var insertResult = await UsersToNotifyRepo.InsertAsync(userModel); return Response.AsJson(insertResult != -1 ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not save, please try again" }); } @@ -953,15 +943,16 @@ namespace PlexRequests.UI.Modules else { var userModel = new UsersToNotify { Username = username }; - var insertResult = UsersToNotifyRepo.Insert(userModel); + var insertResult = await UsersToNotifyRepo.InsertAsync(userModel); return Response.AsJson(insertResult != -1 ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Could not save, please try again" }); } } - private Response GetUserNotificationSettings() + private async Task GetUserNotificationSettings() { - var retval = UsersToNotifyRepo.GetAll().FirstOrDefault(x => x.Username == Username); - return Response.AsJson(retval != null); + var all = await UsersToNotifyRepo.GetAllAsync(); + var retVal = all.FirstOrDefault(x => x.Username == Username); + return Response.AsJson(retVal != null); } private Response GetSeasons() diff --git a/PlexRequests.UI/Modules/UserManagementModule.cs b/PlexRequests.UI/Modules/UserManagementModule.cs index c93977cd7..0d6dee073 100644 --- a/PlexRequests.UI/Modules/UserManagementModule.cs +++ b/PlexRequests.UI/Modules/UserManagementModule.cs @@ -46,24 +46,24 @@ namespace PlexRequests.UI.Modules return Response.AsJson(users); } - private Response CreateUser(string username, string password, string claims) - { - if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) - { - return Response.AsJson(new JsonResponseModel - { - Result = true, - Message = "Please enter in a valid Username and Password" - }); - } - var user = UserMapper.CreateUser(username, password, new string[] {claims}); - if (user.HasValue) - { - return Response.AsJson(new JsonResponseModel {Result = true}); - } + //private Response CreateUser(string username, string password, string claims) + //{ + // if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) + // { + // return Response.AsJson(new JsonResponseModel + // { + // Result = true, + // Message = "Please enter in a valid Username and Password" + // }); + // } + // var user = UserMapper.CreateUser(username, password, new string[] {claims}); + // if (user.HasValue) + // { + // return Response.AsJson(new JsonResponseModel {Result = true}); + // } - return Response.AsJson(new JsonResponseModel {Result = false, Message = "Could not save user"}); - } + // return Response.AsJson(new JsonResponseModel {Result = false, Message = "Could not save user"}); + //} } } diff --git a/PlexRequests.UI/PlexRequests.UI.csproj b/PlexRequests.UI/PlexRequests.UI.csproj index 0029e9ed6..2e226b54f 100644 --- a/PlexRequests.UI/PlexRequests.UI.csproj +++ b/PlexRequests.UI/PlexRequests.UI.csproj @@ -210,7 +210,15 @@ PreserveNewest - + + base.scss + PreserveNewest + + + base.css + PreserveNewest + + PreserveNewest @@ -286,22 +294,21 @@ PreserveNewest - - OriginalBootstrapCustom.scss - - - OriginalBootstrapCustom.css - Always + + original.scss + PreserveNewest - - Always + + original.css + PreserveNewest - - PlexBootstrapCustom.scss + + plex.scss + PreserveNewest - - PlexBootstrapCustom.css - Always + + plex.css + PreserveNewest PreserveNewest @@ -387,8 +394,9 @@ PreserveNewest - - + + + Always diff --git a/PlexRequests.UI/Views/Admin/Authentication.cshtml b/PlexRequests.UI/Views/Admin/Authentication.cshtml index db3fc8819..67e5e5db4 100644 --- a/PlexRequests.UI/Views/Admin/Authentication.cshtml +++ b/PlexRequests.UI/Views/Admin/Authentication.cshtml @@ -77,7 +77,7 @@

Current users that are allowed to authenticate:

- +
@@ -161,7 +161,7 @@ $('#users').append(""); return; } - if (response.users.length > 1) { + if (response.users.length > 0) { $(response.users).each(function () { $('#users').append(""); }); diff --git a/PlexRequests.UI/Views/Admin/Status.cshtml b/PlexRequests.UI/Views/Admin/Status.cshtml index eb5f1b743..efea96a0f 100644 --- a/PlexRequests.UI/Views/Admin/Status.cshtml +++ b/PlexRequests.UI/Views/Admin/Status.cshtml @@ -54,10 +54,10 @@ var dots = new Array(count % 10).join('.'); document.getElementById('autoUpdate').innerHTML = "Updating" + dots; }, 1000); - var url = createBaseUrl(base, "autoupdate"); + $.ajax({ type: "Post", - url: url, + url: "autoupdate", data: { url: "@Model.DownloadUri" }, dataType: "json", error: function () { diff --git a/PlexRequests.UI/Views/Requests/Index.cshtml b/PlexRequests.UI/Views/Requests/Index.cshtml index cdf45b288..03722c18b 100644 --- a/PlexRequests.UI/Views/Requests/Index.cshtml +++ b/PlexRequests.UI/Views/Requests/Index.cshtml @@ -35,19 +35,22 @@
-
+
@if (Context.CurrentUser.IsAuthenticated()) //TODO replace with IsAdmin { @if (Model.SearchForMovies) { + } @if (Model.SearchForTvShows) { + } @if (Model.SearchForMusic) { + } } @@ -132,7 +135,7 @@
{{#if_eq type "movie"}} {{#if posterPath}} - poster + poster {{/if}} {{/if_eq}} {{#if_eq type "tv"}} @@ -169,7 +172,7 @@ {{/if_eq}}
{{#if_eq type "tv"}} -
Series Requested: {{seriesRequested}}
+
Seasons Requested: {{seriesRequested}}
{{/if_eq}} {{#if requestedUsers}}
Requested By: {{requestedUsers}}
diff --git a/PlexRequests.UI/Views/Search/Index.cshtml b/PlexRequests.UI/Views/Search/Index.cshtml index 64f56a0ce..a34bec151 100644 --- a/PlexRequests.UI/Views/Search/Index.cshtml +++ b/PlexRequests.UI/Views/Search/Index.cshtml @@ -144,7 +144,7 @@ {{#if_eq type "movie"}} {{#if posterPath}} - poster + poster {{/if}} {{/if_eq}} {{#if_eq type "tv"}} diff --git a/PlexRequests.UI/compilerconfig.json b/PlexRequests.UI/compilerconfig.json index 0fbfabdd4..1e826536c 100644 --- a/PlexRequests.UI/compilerconfig.json +++ b/PlexRequests.UI/compilerconfig.json @@ -1,8 +1,4 @@ [ - { - "outputFile": "Content/custom.css", - "inputFile": "Content/custom.scss" - }, { "outputFile": "Content/pace.css", "inputFile": "Content/pace.scss" @@ -18,5 +14,17 @@ { "outputFile": "Content/Themes/PlexBootstrapCustom.css", "inputFile": "Content/Themes/PlexBootstrapCustom.scss" + }, + { + "outputFile": "Content/base.css", + "inputFile": "Content/base.scss" + }, + { + "outputFile": "Content/Themes/plex.css", + "inputFile": "Content/Themes/plex.scss" + }, + { + "outputFile": "Content/Themes/original.css", + "inputFile": "Content/Themes/original.scss" } ] \ No newline at end of file diff --git a/PlexRequests.sln b/PlexRequests.sln index 77eb7e978..93ac3b1f4 100644 --- a/PlexRequests.sln +++ b/PlexRequests.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 14 VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.UI", "PlexRequests.UI\PlexRequests.UI.csproj", "{68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}" @@ -35,20 +35,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.Services.Tests EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.Updater", "PlexRequests.Updater\PlexRequests.Updater.csproj", "{EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexRequests.Helpers.Tests", "PlexRequests.Helpers.Tests\PlexRequests.Helpers.Tests.csproj", "{0E6395D3-B074-49E8-898D-0EB99E507E0E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1252336D-42A3-482A-804C-836E60173DFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1252336D-42A3-482A-804C-836E60173DFA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1252336D-42A3-482A-804C-836E60173DFA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1252336D-42A3-482A-804C-836E60173DFA}.Release|Any CPU.Build.0 = Release|Any CPU - {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Release|Any CPU.Build.0 = Release|Any CPU {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Debug|Any CPU.Build.0 = Debug|Any CPU {68F5F5F3-B8BB-4911-875F-6F00AAE04EA6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -57,26 +51,38 @@ Global {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Debug|Any CPU.Build.0 = Debug|Any CPU {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Release|Any CPU.ActiveCfg = Release|Any CPU {8CB8D235-2674-442D-9C6A-35FCAEEB160D}.Release|Any CPU.Build.0 = Release|Any CPU - {92433867-2B7B-477B-A566-96C382427525}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92433867-2B7B-477B-A566-96C382427525}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92433867-2B7B-477B-A566-96C382427525}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92433867-2B7B-477B-A566-96C382427525}.Release|Any CPU.Build.0 = Release|Any CPU {95834072-A675-415D-AA8F-877C91623810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {95834072-A675-415D-AA8F-877C91623810}.Debug|Any CPU.Build.0 = Debug|Any CPU {95834072-A675-415D-AA8F-877C91623810}.Release|Any CPU.ActiveCfg = Release|Any CPU {95834072-A675-415D-AA8F-877C91623810}.Release|Any CPU.Build.0 = Release|Any CPU + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.Build.0 = Release|Any CPU + {92433867-2B7B-477B-A566-96C382427525}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92433867-2B7B-477B-A566-96C382427525}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92433867-2B7B-477B-A566-96C382427525}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92433867-2B7B-477B-A566-96C382427525}.Release|Any CPU.Build.0 = Release|Any CPU + {1252336D-42A3-482A-804C-836E60173DFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1252336D-42A3-482A-804C-836E60173DFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1252336D-42A3-482A-804C-836E60173DFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1252336D-42A3-482A-804C-836E60173DFA}.Release|Any CPU.Build.0 = Release|Any CPU {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Debug|Any CPU.Build.0 = Debug|Any CPU {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Release|Any CPU.ActiveCfg = Release|Any CPU {A930E2CF-79E2-45F9-B06A-9A719A254CE4}.Release|Any CPU.Build.0 = Release|Any CPU + {FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.Build.0 = Release|Any CPU + {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {566EFA49-68F8-4716-9693-A6B3F2624DEA}.Release|Any CPU.Build.0 = Release|Any CPU {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Debug|Any CPU.Build.0 = Debug|Any CPU {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Release|Any CPU.ActiveCfg = Release|Any CPU {CB37A5F8-6DFC-4554-99D3-A42B502E4591}.Release|Any CPU.Build.0 = Release|Any CPU - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DD7DC444-D3BF-4027-8AB9-EFC71F5EC581}.Release|Any CPU.Build.0 = Release|Any CPU {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Debug|Any CPU.Build.0 = Debug|Any CPU {EAADB4AC-064F-4D3A-AFF9-64A33131A9A7}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -85,12 +91,10 @@ Global {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Debug|Any CPU.Build.0 = Debug|Any CPU {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Release|Any CPU.ActiveCfg = Release|Any CPU {EBE6FC1C-7B4B-47E9-AF54-0EE0604A2BE5}.Release|Any CPU.Build.0 = Release|Any CPU - {FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FCFECD5D-47F6-454D-8692-E27A921BE655}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FCFECD5D-47F6-454D-8692-E27A921BE655}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution + {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E6395D3-B074-49E8-898D-0EB99E507E0E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/appveyor.yml b/appveyor.yml index 08772ff6e..ee0d12bee 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,9 +3,9 @@ configuration: Release assembly_info: patch: true file: '**\AssemblyInfo.*' - assembly_version: '1.7.4' + assembly_version: '1.7.5' assembly_file_version: '{version}' - assembly_informational_version: '1.7.4' + assembly_informational_version: '1.7.5' before_build: - cmd: appveyor-retry nuget restore build: