diff --git a/.gitignore b/.gitignore index eafec5b0..0cec5db4 100644 --- a/.gitignore +++ b/.gitignore @@ -43,11 +43,13 @@ tx.exe /Output/Vocaluxe_x64.exe* /Output/Vocaluxe.vshost.exe* /Output/VocaluxeLib.dll -/Output/VocaluxeServerConfig.exe -/Output/VocaluxeServerConfig.exe.config /Output/Photos /Output/Screenshots /Output/Website +/Output/WebServer.pfx +/Output/WebServer.json +/Output/WebCache +/VocaluxeWeb/bin /Output/Songs /Output/Playlists/*.xml /Output/Profiles/*.xml diff --git a/HowToBuildWin.md b/HowToBuildWin.md index 95285b79..09bb02cf 100644 --- a/HowToBuildWin.md +++ b/HowToBuildWin.md @@ -11,6 +11,8 @@ * Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) is installed +* Make sure [Node.js (LTS)](https://nodejs.org) is installed. It is needed to build the WebApp (folder `WebApp`), which is built automatically together with the project `VocaluxeWeb`. Restart Visual Studio after installing it. + * Clone the repository and open it **Method A: Use Visual Studio (2013+)'s git client:** diff --git a/Output/Languages/en.xml b/Output/Languages/en.xml index 8f0acff1..7e9151e3 100644 --- a/Output/Languages/en.xml +++ b/Output/Languages/en.xml @@ -166,6 +166,21 @@ Video %d songs No songs found + WebApp Queue + Up next + Add songs with the WebApp + The webserver is off - switch it on under Options - Server to use the WebApp + The queue is empty. + Add songs with the WebApp (QR code: Server address). + WebApp Queue + added by %s + Singers: %s + Singers are chosen before singing + + %d more + Game mode + Audio + Change players + Sing Random In order Full song diff --git a/Output/Themes/Changelog/Changelog_ScreenSong.txt b/Output/Themes/Changelog/Changelog_ScreenSong.txt index 0f0a690f..48d340ab 100644 --- a/Output/Themes/Changelog/Changelog_ScreenSong.txt +++ b/Output/Themes/Changelog/Changelog_ScreenSong.txt @@ -1,5 +1,11 @@ ScreenSong +++++++++++ +Version 17: + +Add: + (opens the WebApp queue, below the playlist selection in the playlist group of the song options) + ++++++++++ Version 16: diff --git a/Output/Themes/Changelog/Changelog_ScreenWebQueue.txt b/Output/Themes/Changelog/Changelog_ScreenWebQueue.txt new file mode 100644 index 00000000..5b7fbd7c --- /dev/null +++ b/Output/Themes/Changelog/Changelog_ScreenWebQueue.txt @@ -0,0 +1,6 @@ +ScreenWebQueue + +++++++++++ +Version 1: + +New screen: queue of the WebApp (next song with requester, game mode, audio mode and singers, list of the following songs; sing the next song, change players, server address) diff --git a/Output/Themes/Vocaluxe 2024/Screens/ScreenSong.xml b/Output/Themes/Vocaluxe 2024/Screens/ScreenSong.xml index 9985d42a..9708df96 100644 --- a/Output/Themes/Vocaluxe 2024/Screens/ScreenSong.xml +++ b/Output/Themes/Vocaluxe 2024/Screens/ScreenSong.xml @@ -2,7 +2,7 @@ ScreenSong - 16 + 17 @@ -104,13 +104,13 @@ - OptionsGroupSmall + OptionsGroupLarge 60 630 540 - 110 + 160 -2.105 @@ -262,7 +262,7 @@ 76 - 767 + 817 36 36 -2.13 @@ -273,7 +273,7 @@ 351 - 767 + 817 36 36 -2.13 @@ -990,7 +990,7 @@ SongSelectButton 335 - 755 + 805 265 60 -2.11 @@ -1290,6 +1290,33 @@ TR_SCREENSONG_BUTTON_RANDOMMEDLEY + + + + + + + + + + + + + + + + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 82.5 + 700 + 600 + 60 + 0 + + + 88.5 + 703.0 + 54 + 54 + 0 + + + 622.5 + 703.0 + 54 + 54 + 0 + + + + + + + + 36 + 66 + 0 + 380 + Outline + Bold + 1 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 82.5 + 812 + 600 + 60 + 0 + + + 88.5 + 815.0 + 54 + 54 + 0 + + + 622.5 + 815.0 + 54 + 54 + 0 + + + + + + + + 36 + 66 + 0 + 380 + Outline + Bold + 1 + + + + + + + + + diff --git a/PhoneGap/config.xml b/PhoneGap/config.xml deleted file mode 100644 index d0ee02a0..00000000 --- a/PhoneGap/config.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - Vocaluxe - - - Interact with Vocaluxe via your mobile device. - - - - Vocaluxe Team - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index 837714b3..47adfa1c 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ Building Vocaluxe is easy: Just follow the guide on our wiki to clone the repository and create your own Vocaluxe build: [Build Vocaluxe (Windows)](https://github.com/Vocaluxe/Vocaluxe/wiki/HowTo:-Build-Vocaluxe-(Windows)) +The WebApp and the webserver (build with Node.js, development, REST API, translations) are described in [VocaluxeWeb/README.md](VocaluxeWeb/README.md). + ### Submit your change Upload your changes to your fork and open a new pull request. diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 45cfb32f..d4cc5b5d 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -85,6 +85,10 @@ + + + + @@ -103,6 +107,10 @@ {2a1e0f2d-5392-4bb7-b0a1-a9dfa13e79ff} Vocaluxe + + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60} + VocaluxeWeb + diff --git a/Tests/VocaluxeWeb/CPinHasherTest.cs b/Tests/VocaluxeWeb/CPinHasherTest.cs new file mode 100644 index 00000000..8400b604 --- /dev/null +++ b/Tests/VocaluxeWeb/CPinHasherTest.cs @@ -0,0 +1,81 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using System; +using System.Security.Cryptography; +using System.Text; +using NUnit.Framework; +using VocaluxeWeb.Services; + +namespace Tests.VocaluxeWeb +{ + [TestFixture] + public class CPinHasherTest + { + [Test] + public void TestHashAndVerify() + { + CPinHasher.Hash("1234", out var hash, out var salt); + Assert.That(CPinHasher.Verify("1234", hash, salt), Is.True); + Assert.That(CPinHasher.Verify("4321", hash, salt), Is.False); + Assert.That(CPinHasher.Verify("", hash, salt), Is.False); + Assert.That(CPinHasher.NeedsUpgrade(salt), Is.False); + } + + [Test] + public void TestSaltIsRandom() + { + CPinHasher.Hash("1234", out var hash1, out var salt1); + CPinHasher.Hash("1234", out var hash2, out var salt2); + Assert.That(salt1, Is.Not.EqualTo(salt2)); + Assert.That(hash1, Is.Not.EqualTo(hash2)); + } + + [Test] + public void TestMissingValues() + { + CPinHasher.Hash("1234", out var hash, out var salt); + Assert.That(CPinHasher.Verify(null, hash, salt), Is.False); + Assert.That(CPinHasher.Verify("1234", null, salt), Is.False); + Assert.That(CPinHasher.Verify("1234", hash, null), Is.False); + } + + [Test] + public void TestLegacyPin() + { + var salt = new byte[32]; + new Random(1).NextBytes(salt); + var hash = _LegacyHash("0815", salt); + + Assert.That(CPinHasher.NeedsUpgrade(salt), Is.True); + Assert.That(CPinHasher.Verify("0815", hash, salt), Is.True); + Assert.That(CPinHasher.Verify("0816", hash, salt), Is.False); + } + + private static byte[] _LegacyHash(string pin, byte[] salt) + { + var password = Encoding.UTF8.GetBytes(pin); + var data = new byte[password.Length + salt.Length]; + password.CopyTo(data, 0); + salt.CopyTo(data, password.Length); + using (var sha = SHA256.Create()) + { + return sha.ComputeHash(data); + } + } + } +} diff --git a/Tests/VocaluxeWeb/CQueueServiceTest.cs b/Tests/VocaluxeWeb/CQueueServiceTest.cs new file mode 100644 index 00000000..d68a0782 --- /dev/null +++ b/Tests/VocaluxeWeb/CQueueServiceTest.cs @@ -0,0 +1,249 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using NUnit.Framework; +using VocaluxeWeb; +using VocaluxeWeb.Contracts; +using VocaluxeWeb.Dispatching; +using VocaluxeWeb.Remote; +using VocaluxeWeb.Services; + +namespace Tests.VocaluxeWeb +{ + [TestFixture] + public class CQueueServiceTest + { + private sealed class CFakeRemote : IVocaluxeRemote + { + public readonly List Playlists = new List(); + + public string Version => "test"; + public bool IsReady => true; + public int SongLibraryVersion => 1; + + public RemoteState GetState() + { + return new RemoteState { Screen = "Main" }; + } + + public IList GetProfiles() + { + return new List(); + } + + public Guid CreateProfile(ProfileChange change) + { + throw new NotSupportedException(); + } + + public void UpdateProfile(Guid profileId, ProfileChange change) { } + + public void DeleteProfile(Guid profileId) { } + + public IList GetAvatars() + { + return new List(); + } + + public IList GetSongs() + { + return Enumerable.Range(0, 20) + .Select(i => new RemoteSong + { + Id = i, + Title = "Song " + i, + Artist = "Artist", + Languages = new string[0], + Genres = new string[0], + Editions = new string[0], + GameModes = new List(), + AudioModes = new List() + }) + .ToList(); + } + + public IList GetPlaylists() + { + return Playlists.Select(p => new RemotePlaylist { Id = p.Id, Name = p.Name, Entries = p.Entries.ToList() }).ToList(); + } + + public int CreatePlaylist(string name) + { + var playlist = new RemotePlaylist { Id = Playlists.Count + 1, Name = name, Entries = new List() }; + Playlists.Add(playlist); + return playlist.Id; + } + + public void RenamePlaylist(int playlistId, string name) { } + + public void DeletePlaylist(int playlistId) { } + + public void SetPlaylistEntries(int playlistId, IList entries) + { + Playlists.First(p => p.Id == playlistId).Entries = entries.ToList(); + } + + public ERemoteStartResult StartSong(RemoteStartRequest request) + { + return ERemoteStartResult.Singing; + } + + public void SendKey(ERemoteKey key) { } + + public void SendText(string text) { } + } + + private readonly CSession _Anna = new CSession { ProfileId = Guid.NewGuid(), ProfileName = "Anna" }; + private readonly CSession _Ben = new CSession { ProfileId = Guid.NewGuid(), ProfileName = "Ben" }; + private readonly CSession _Cleo = new CSession { ProfileId = Guid.NewGuid(), ProfileName = "Cleo" }; + private CFakeRemote _Remote; + private CQueueService _Queue; + private CancellationTokenSource _Stop; + private Task _MainThread; + + [SetUp] + public void SetUp() + { + _Remote = new CFakeRemote(); + var dispatcher = new CMainThreadDispatcher(TimeSpan.FromSeconds(5)); + _Queue = new CQueueService(_Remote, dispatcher, new CWebSettingsStore(null), new CSongLibrary(_Remote, dispatcher), new CLiveEvents()); + _Stop = new CancellationTokenSource(); + _MainThread = Task.Run(async () => + { + while (!_Stop.IsCancellationRequested) + { + dispatcher.ProcessPending(); + await Task.Delay(1); + } + }); + } + + [TearDown] + public void TearDown() + { + _Stop.Cancel(); + _MainThread.Wait(); + } + + [Test] + public void TestFairOrder() + { + _Add(1, _Anna); + _Add(2, _Anna); + _Add(3, _Anna); + _Add(4, _Ben); + _Add(5, _Ben); + var queue = _Add(6, _Cleo); + + Assert.That(_Requesters(queue), Is.EqualTo(new[] { "Anna", "Ben", "Cleo", "Anna", "Ben", "Anna" })); + Assert.That(queue.Select(e => e.Song.Id), Is.EqualTo(new[] { 1, 4, 6, 2, 5, 3 })); + Assert.That(queue.Select(e => e.Position), Is.EqualTo(Enumerable.Range(0, 6))); + } + + [Test] + public void TestAddMany() + { + _Add(1, _Ben); + var queue = _Queue.AddManyAsync(new[] { 2, 3, 4 }.Select(id => new RemotePlaylistEntry { SongId = id }).ToList(), _Anna).Result; + + Assert.That(_Requesters(queue), Is.EqualTo(new[] { "Ben", "Anna", "Anna", "Anna" })); + Assert.That(_Requesters(_Add(5, _Ben)), Is.EqualTo(new[] { "Ben", "Anna", "Anna", "Ben", "Anna" })); + } + + [Test] + public void TestPlaylistIsUpdated() + { + _Add(7, _Anna); + _Add(8, _Ben); + + var playlist = _Remote.Playlists.Single(p => p.Name == "WebApp Queue"); + Assert.That(playlist.Entries.Select(e => e.SongId), Is.EqualTo(new[] { 7, 8 })); + } + + [Test] + public void TestSongsAddedInTheGame() + { + _Add(1, _Anna); + _Remote.Playlists[0].Entries.Add(new RemotePlaylistEntry { SongId = 9 }); + + var queue = _Add(2, _Anna); + Assert.That(queue.Select(e => e.Song.Id), Is.EqualTo(new[] { 1, 9, 2 })); + Assert.That(queue[1].RequestedBy, Is.Null); + } + + [Test] + public void TestOnlyOwnerOrManagerMayRemove() + { + var entry = _Add(1, _Anna)[0]; + + Exception error = null; + try + { + _Queue.RemoveAsync(entry.Id, _Ben, false).Wait(); + } + catch (AggregateException e) + { + error = e.InnerException; + } + + Assert.That(error, Is.InstanceOf()); + Assert.That(_Queue.GetAsync().Result, Has.Count.EqualTo(1)); + + Assert.That(_Queue.RemoveAsync(entry.Id, _Ben, true).Result, Is.Empty); + _Add(2, _Anna); + Assert.That(_Queue.RemoveAsync(_Queue.GetAsync().Result[0].Id, _Anna, false).Result, Is.Empty); + } + + [Test] + public void TestMove() + { + _Add(1, _Anna); + _Add(2, _Ben); + var queue = _Add(3, _Cleo); + + queue = _Queue.MoveAsync(queue[2].Id, 0).Result; + Assert.That(queue.Select(e => e.Song.Id), Is.EqualTo(new[] { 3, 1, 2 })); + queue = _Queue.MoveAsync(queue[0].Id, 99).Result; + Assert.That(queue.Select(e => e.Song.Id), Is.EqualTo(new[] { 1, 2, 3 })); + } + + [Test] + public void TestRemoveSung() + { + _Add(1, _Anna); + _Add(2, _Ben); + + var queue = _Queue.RemoveSungAsync(1).Result; + Assert.That(queue.Select(e => e.Song.Id), Is.EqualTo(new[] { 2 })); + Assert.That(_Queue.RemoveSungAsync(5).Result, Has.Count.EqualTo(1)); + } + + private IList _Add(int songId, CSession session) + { + return _Queue.AddAsync(songId, ESongGameMode.Normal, ESongAudioMode.Normal, null, session).Result; + } + + private static IEnumerable _Requesters(IEnumerable queue) + { + return queue.Select(e => e.RequestedBy?.Name); + } + } +} diff --git a/Tests/VocaluxeWeb/CUserAgentTest.cs b/Tests/VocaluxeWeb/CUserAgentTest.cs new file mode 100644 index 00000000..aa69a03b --- /dev/null +++ b/Tests/VocaluxeWeb/CUserAgentTest.cs @@ -0,0 +1,39 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using NUnit.Framework; +using VocaluxeWeb.Services; + +namespace Tests.VocaluxeWeb +{ + [TestFixture] + public class CUserAgentTest + { + [TestCase("Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1", "iPhone · Safari")] + [TestCase("Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Mobile Safari/537.36", "Android phone · Chrome")] + [TestCase("Mozilla/5.0 (Linux; Android 14; SM-X710) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/26.0 Chrome/122.0.0.0 Safari/537.36", "Android tablet · Samsung Internet")] + [TestCase("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0", "Windows · Edge")] + [TestCase("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:132.0) Gecko/20100101 Firefox/132.0", "Mac · Firefox")] + [TestCase("curl/8.7.1", "curl/8.7.1")] + [TestCase("", null)] + [TestCase(null, null)] + public void TestDescribe(string userAgent, string expected) + { + Assert.That(CUserAgent.Describe(userAgent), Is.EqualTo(expected)); + } + } +} diff --git a/Tests/VocaluxeWeb/CWebSettingsTest.cs b/Tests/VocaluxeWeb/CWebSettingsTest.cs new file mode 100644 index 00000000..9e5c5b5e --- /dev/null +++ b/Tests/VocaluxeWeb/CWebSettingsTest.cs @@ -0,0 +1,113 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using System; +using System.IO; +using System.Linq; +using NUnit.Framework; +using VocaluxeWeb.Contracts; +using VocaluxeWeb.Remote; +using VocaluxeWeb.Services; + +namespace Tests.VocaluxeWeb +{ + [TestFixture] + public class CWebSettingsTest + { + private string _Path; + + [SetUp] + public void SetUp() + { + _Path = Path.Combine(Path.GetTempPath(), "VocaluxeWebTest_" + Guid.NewGuid().ToString("N"), "WebSettings.json"); + } + + [TearDown] + public void TearDown() + { + var directory = Path.GetDirectoryName(_Path); + if (Directory.Exists(directory)) + { + Directory.Delete(directory, true); + } + } + + [Test] + public void TestAdminHasAllPermissions() + { + var settings = new CWebSettings(); + settings.GuestPermissions.Clear(); + settings.PlayerPermissions.Clear(); + var all = Enum.GetValues(typeof(EPermission)).Cast().ToList(); + + Assert.That(settings.GetPermissions(ERemoteRole.Admin), Is.EquivalentTo(all)); + Assert.That(settings.GetPermissions(ERemoteRole.Guest), Is.Empty); + Assert.That(settings.GetPermissions(ERemoteRole.Player), Is.Empty); + } + + [Test] + public void TestDefaults() + { + var settings = new CWebSettings(); + Assert.That(settings.GetPermissions(ERemoteRole.Guest), Is.EquivalentTo(new[] { EPermission.AddToQueue })); + Assert.That(settings.GetPermissions(ERemoteRole.Player), Does.Contain(EPermission.AddToQueue)); + Assert.That(settings.GetPermissions(ERemoteRole.Player), Does.Not.Contain(EPermission.EditAllProfiles)); + } + + [Test] + public void TestStoreSavesAndLoads() + { + var store = new CWebSettingsStore(_Path); + store.Update(s => + { + s.AllowProfileCreation = false; + s.QueuePlaylistName = "Party queue"; + s.GuestPermissions.Add(EPermission.UseKeyboard); + }); + + var loaded = new CWebSettingsStore(_Path).Current; + Assert.That(loaded.AllowProfileCreation, Is.False); + Assert.That(loaded.QueuePlaylistName, Is.EqualTo("Party queue")); + Assert.That(loaded.GetPermissions(ERemoteRole.Guest), Does.Contain(EPermission.UseKeyboard)); + } + + [Test] + public void TestCurrentIsACopy() + { + var store = new CWebSettingsStore(_Path); + store.Current.GuestPermissions.Add(EPermission.DeletePlaylists); + Assert.That(store.Current.GuestPermissions, Does.Not.Contain(EPermission.DeletePlaylists)); + } + + [Test] + public void TestBrokenFile() + { + Directory.CreateDirectory(Path.GetDirectoryName(_Path)); + File.WriteAllText(_Path, "{ broken"); + var store = new CWebSettingsStore(_Path); + Assert.That(store.Current.QueuePlaylistName, Is.EqualTo("WebApp Queue")); + } + + [Test] + public void TestFileWithRemovedSettings() + { + Directory.CreateDirectory(Path.GetDirectoryName(_Path)); + File.WriteAllText(_Path, "{ \"RequireJoinToken\": true, \"JoinToken\": \"abc\", \"QueuePlaylistName\": \"Party\" }"); + Assert.That(new CWebSettingsStore(_Path).Current.QueuePlaylistName, Is.EqualTo("Party")); + } + } +} diff --git a/Vocaluxe.sln b/Vocaluxe.sln index b1556cb0..78838776 100644 --- a/Vocaluxe.sln +++ b/Vocaluxe.sln @@ -5,7 +5,6 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vocaluxe", "Vocaluxe\Vocaluxe.csproj", "{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}" ProjectSection(ProjectDependencies) = postProject {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41} = {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41} - {55F89808-4E79-4FFE-BC13-48258913F5C9} = {55F89808-4E79-4FFE-BC13-48258913F5C9} {6F3E1874-F28A-40E9-AFBD-31934D593679} = {6F3E1874-F28A-40E9-AFBD-31934D593679} {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53} = {9D4F1C27-3B8E-4A62-B5D0-7E1A2C6F9B53} {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} = {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} @@ -25,7 +24,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModeChallenge", "Party EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModeTournament", "PartyModes\PartyModeTournament\PartyModeTournament.csproj", "{3C7D2E51-8A64-4F0B-9E2A-6B1D4C8F7A20}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebserverInitalConfig", "WebserverInitalConfig\WebserverInitalConfig.csproj", "{55F89808-4E79-4FFE-BC13-48258913F5C9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VocaluxeWeb", "VocaluxeWeb\VocaluxeWeb.csproj", "{4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModeRuleRoulette", "PartyModes\PartyModeRuleRoulette\PartyModeRuleRoulette.csproj", "{2E6A9B48-71C3-4D05-8F2B-C4A7D19E6E3F}" EndProject @@ -169,22 +168,6 @@ Global {3C7D2E51-8A64-4F0B-9E2A-6B1D4C8F7A20}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU {3C7D2E51-8A64-4F0B-9E2A-6B1D4C8F7A20}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU {3C7D2E51-8A64-4F0B-9E2A-6B1D4C8F7A20}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugLinux|x64.ActiveCfg = Debug|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugLinux|x86.ActiveCfg = Debug|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x64.ActiveCfg = Debug|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x64.Build.0 = Debug|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x86.ActiveCfg = Debug|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x86.Build.0 = Debug|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x64.ActiveCfg = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x64.Build.0 = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x86.ActiveCfg = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x86.Build.0 = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseLinux|x64.ActiveCfg = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x64.ActiveCfg = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x64.Build.0 = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x86.ActiveCfg = Release|Any CPU - {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x86.Build.0 = Release|Any CPU {2E6A9B48-71C3-4D05-8F2B-C4A7D19E6E3F}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU {2E6A9B48-71C3-4D05-8F2B-C4A7D19E6E3F}.DebugLinux|x64.Build.0 = DebugLinux|Any CPU {2E6A9B48-71C3-4D05-8F2B-C4A7D19E6E3F}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU @@ -265,6 +248,22 @@ Global {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU {7B2E4A19-5C3D-4E8F-A16B-2D9C0F3E8B41}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.DebugWin|x64.Build.0 = DebugWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.DebugWin|x86.Build.0 = DebugWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.InstallerWin|x64.ActiveCfg = InstallerWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.InstallerWin|x64.Build.0 = InstallerWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.InstallerWin|x86.ActiveCfg = InstallerWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.InstallerWin|x86.Build.0 = InstallerWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Vocaluxe/Base/CController.cs b/Vocaluxe/Base/CController.cs index e6447c66..70ee3e7a 100644 --- a/Vocaluxe/Base/CController.cs +++ b/Vocaluxe/Base/CController.cs @@ -16,7 +16,7 @@ #endregion using System.Collections.Generic; -using Vocaluxe.Base.Server; +using Vocaluxe.Base.Web; using Vocaluxe.Lib.Input; using Vocaluxe.Lib.Input.WiiMote; using VocaluxeLib; @@ -38,7 +38,7 @@ namespace Vocaluxe.Base _AddController(new CWiiMote()); _AddController(new CGamePad()); - _AddController(CVocaluxeServer.Controller); + _AddController(CWebServer.Controller); } private static void _AddController(IController controller) diff --git a/Vocaluxe/Base/CGraphics.cs b/Vocaluxe/Base/CGraphics.cs index 713e36b1..b1c12853 100644 --- a/Vocaluxe/Base/CGraphics.cs +++ b/Vocaluxe/Base/CGraphics.cs @@ -47,6 +47,14 @@ namespace Vocaluxe.Base public static float ZOffset { get; private set; } public static IMenu CurrentScreen { get; private set; } + public static EScreen CurrentScreenType + { + get + { + var id = _Screens.IndexOf(CurrentScreen); + return (EScreen)id; + } + } public static IMenu NextScreen { get; private set; } public static EScreen NextScreenType @@ -89,6 +97,7 @@ namespace Vocaluxe.Base _Screens.Add(new CScreenStatisticsDetail()); _Screens.Add(new CScreenJukebox()); _Screens.Add(new CScreenJukeboxPlayer()); + _Screens.Add(new CScreenWebQueue()); Debug.Assert(_Screens.Count == (int)EScreen.CountEntry, "Screen list and screens enum do not match"); diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index 5d770c39..546d7257 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -135,6 +135,7 @@ namespace Vocaluxe.Base public const string FolderNameThemeFonts = "Fonts"; public const string FolderNameScreens = "Screens"; public const string FolderNamePhotos = "Photos"; + public const string FolderNameWebsite = "Website"; public const string FolderNameSounds = "Sounds"; public const string FolderNameLanguages = "Languages"; public const string FolderNameScreenshots = "Screenshots"; diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs deleted file mode 100644 index 992c0a86..00000000 --- a/Vocaluxe/Base/Server/CVocaluxeServer.cs +++ /dev/null @@ -1,1016 +0,0 @@ -#region license -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -#endregion - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Net; -using System.Security.Cryptography; -using System.ServiceModel; -using System.ServiceModel.Web; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using Vocaluxe.Lib.Input; -using Vocaluxe.Lib.Playlist; -using VocaluxeLib; -using VocaluxeLib.Menu; -using VocaluxeLib.Profile; -using VocaluxeLib.Songs; - -namespace Vocaluxe.Base.Server -{ - static class CVocaluxeServer - { - private static ServiceHost _Host; - private static Uri _BaseAddress; - private static bool _Encrypted; - private static readonly Queue _ServerTaskQueue = new Queue(); - - private class CServerController : CControllerFramework - { - public override string GetName() - { - return "App controller"; - } - - public override void Connect() { } - - public override void Disconnect() { } - - public override bool IsConnected() - { - return true; - } - - public override void SetRumble(float duration) { } - } - - public static readonly CControllerFramework Controller = new CServerController(); - - #region server control - public static void Init() - { - var port = CConfig.Config.Server.ServerPort; - var encrypted = CConfig.Config.Server.ServerEncryption == EOffOn.TR_CONFIG_ON; - var hostname = Dns.GetHostName(); - var protocol = encrypted ? "https" : "http"; - _BaseAddress = new Uri(protocol + "://" + hostname + ":" + port + "/"); - _Encrypted = encrypted; - _Host = new WebServiceHost(typeof(CWebservice), _BaseAddress); - - var wb = new WebHttpBinding - { - MaxReceivedMessageSize = 10485760, - MaxBufferSize = 10485760, - MaxBufferPoolSize = 10485760, - ReaderQuotas = { MaxStringContentLength = 10485760, MaxArrayLength = 10485760, MaxBytesPerRead = 10485760 } - }; - if (encrypted) - { - wb.Security.Mode = WebHttpSecurityMode.Transport; - wb.Security.Transport = new HttpTransportSecurity { ClientCredentialType = HttpClientCredentialType.None }; - } - - _Host.AddServiceEndpoint(typeof(ICWebservice), wb, ""); - - Start(); - - //_Discover = new CDiscover(CConfig.ServerPort, CCommands.BroadcastKeyword); - } - - public static void Start() - { - if (CConfig.Config.Server.ServerActive == EOffOn.TR_CONFIG_ON) - { - try - { - _RegisterUrlAndCert(_BaseAddress.Port, false); - _Host.Open(); - } - catch (CommunicationException e) - { - if (e is AddressAccessDeniedException || e is AddressAlreadyInUseException) - { - _RegisterUrlAndCert(_BaseAddress.Port, true); - try - { - _Host.Abort(); - Init(); - _Host.Open(); - } - catch (CommunicationException) - { - _Host.Abort(); - MessageBox.Show("Problem while initialization of webserver. You may try a different port (Change it in config.xml)"); - } - } - else - { - _Host.Abort(); - } - } - } - } - - public static void Close() - { - if (_Host != null) - { - try - { - _Host.Close(); - } - catch (CommunicationException) - { - _Host.Abort(); - } - } - } - - private static void _RegisterUrlAndCert(int port, bool reserve) - { -#if WIN - var info = new ProcessStartInfo - { - FileName = "VocaluxeServerConfig.exe", - WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory, - Arguments = AppDomain.CurrentDomain.FriendlyName + " " + port + " " + (_Encrypted ? "true" : "false") + (reserve ? " true" : ""), - UseShellExecute = true, - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden, - }; - try - { - using (var p = Process.Start(info)) - { - p.WaitForExit(); - if (p.ExitCode != 0) - { - MessageBox.Show("Registering the Server failed (Code " + p.ExitCode + ")!\r\nThe Server might not work correctly."); - } - - p.Close(); - } - } - catch (Exception e) - { - MessageBox.Show("Registering the Server failed (" + e + ")!\r\nThe Server might not work correctly."); - } -#else - //Required? - -#endif - } - - public static string GetServerAddress() - { - return _BaseAddress == null ? "" : _BaseAddress.AbsoluteUri; - } - - public static bool IsServerRunning() - { - if (_Host == null) - { - return false; - } - - return _Host.State == CommunicationState.Opened; - } - #endregion - - #region task control - public static void ProcessServerTasks() - { - //Serial processing - one by one - while (_ServerTaskQueue.Count > 0) - { - //Get a task from the queue - var task = _ServerTaskQueue.Dequeue(); - //Start the task - task.RunSynchronously(TaskScheduler.FromCurrentSynchronizationContext()); - } - } - - public static TReturnType DoTask(Func action) - { - var task = new Task(action); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - return task.Result; - } - - public static TReturnType DoTask(Func action, TParameterType parameter) - { - var task = new Task(() => action(parameter)); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - return task.Result; - } - - public static TReturnType DoTask(Func action, TParameterType1 parameter1, - TParameterType2 parameter2) - { - var task = new Task(() => action(parameter1, parameter2)); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - return task.Result; - } - - public static TReturnType DoTask( - Func action, TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3) - { - var task = new Task(() => action(parameter1, parameter2, parameter3)); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - return task.Result; - } - - public static TReturnType DoTask( - Func action, TParameterType1 parameter1, TParameterType2 parameter2, - TParameterType3 parameter3, TParameterType4 parameter4) - { - var task = new Task(() => action(parameter1, parameter2, parameter3, parameter4)); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - return task.Result; - } - - public static void DoTaskWithoutReturn(Action action) - { - var task = new Task(action); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - } - - public static void DoTaskWithoutReturn(Action action, TParameterType parameter) - { - var task = new Task(() => action(parameter)); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - } - - public static void DoTaskWithoutReturn(Action action, TParameterType1 parameter1, - TParameterType2 parameter2) - { - var task = new Task(() => action(parameter1, parameter2)); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - } - - public static void DoTaskWithoutReturn(Action action, - TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3) - { - var task = new Task(() => action(parameter1, parameter2, parameter3)); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - } - - public static void DoTaskWithoutReturn( - Action action, TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3, - TParameterType4 parameter4) - { - var task = new Task(() => action(parameter1, parameter2, parameter3, parameter4)); - _ServerTaskQueue.Enqueue(task); - task.Wait(); //wait until the task is completed - } - #endregion - - public static bool SendKeyEvent(string key) - { - var result = false; - var lowerKey = key.ToLower(); - - if (!string.IsNullOrEmpty(lowerKey)) - { - switch (lowerKey) - { - case "up": - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Up)); - result = true; - break; - case "down": - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Down)); - result = true; - break; - case "left": - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Left)); - result = true; - break; - case "right": - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Right)); - result = true; - break; - case "escape": - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Escape)); - result = true; - break; - case "return": - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Return)); - result = true; - break; - case "tab": - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Tab)); - result = true; - break; - case "backspace": - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Back)); - result = true; - break; - default: - if (lowerKey.StartsWith("f")) - { - var numberString = lowerKey.Substring(1); - int number; - Keys fKey; - - if (Int32.TryParse(numberString, out number) && number >= 1 - && number <= 12 - && Enum.TryParse("F" + number, true, out fKey)) - { - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, fKey)); - result = true; - } - } - - break; - } - } - - return result; - } - - public static bool SendKeyStringEvent(string keyString, bool isShiftPressed, bool isAltPressed, bool isCtrlPressed) - { - var result = false; - - foreach (var key in keyString) - { - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, isAltPressed, - Char.IsUpper(key) || isShiftPressed, - isCtrlPressed, true, - isShiftPressed ? Char.ToUpper(key) : key, - _ParseKeys(key))); - result = true; - } - - return result; - } - - private static Keys _ParseKeys(char keyText) - { - Keys key; - - if (!Enum.TryParse(keyText.ToString(), true, out key)) - { - switch (keyText) - { - case ' ': - key = Keys.Space; - break; - default: - key = Keys.None; - break; - } - } - - return key; - } - - #region profile - public static SProfileData GetProfileData(Guid profileId, bool isReadonly) - { - var profile = CProfiles.GetProfile(profileId); - if (profile == null) - { - return new SProfileData(); - } - - return _CreateProfileData(profile, isReadonly); - } - - public static bool SendProfileData(SProfileData profile) - { - CProfile newProfile; - var existingProfile = CProfiles.GetProfile(profile.ProfileId); - - if (existingProfile != null) - { - newProfile = new CProfile - { - Id = existingProfile.Id, - FilePath = existingProfile.FilePath, - Active = existingProfile.Active, - Avatar = existingProfile.Avatar, - Difficulty = existingProfile.Difficulty, - UserRole = existingProfile.UserRole, - PlayerName = existingProfile.PlayerName - }; - } - else - { - newProfile = new CProfile - { - Active = EOffOn.TR_CONFIG_ON, - UserRole = EUserRole.TR_USERROLE_NORMAL - }; - } - - if (profile.Avatar != null) - { - newProfile.Avatar = _AddAvatar(profile.Avatar); - } - else if (newProfile.Avatar == null || newProfile.Avatar.Id == -1) - { - newProfile.Avatar = CProfiles.GetAvatars().First(); - - /*CAvatar avatar = new CAvatar(-1); - avatar.LoadFromFile("Profiles\\Avatar_f.png"); - CProfiles.AddAvatar(avatar); - newProfile.Avatar = avatar;*/ - } - - if (!string.IsNullOrEmpty(profile.PlayerName)) - { - newProfile.PlayerName = profile.PlayerName; - } - else if (!string.IsNullOrEmpty(newProfile.PlayerName)) - { - newProfile.PlayerName = "DummyName"; - } - - if (profile.Difficulty >= 0 && profile.Difficulty <= 2) - { - newProfile.Difficulty = (EGameDifficulty)profile.Difficulty; - } - - if (profile.Type >= 0 && profile.Type <= 1) - { - var option = profile.Type == 0 ? EUserRole.TR_USERROLE_GUEST : EUserRole.TR_USERROLE_NORMAL; - //Only allow the change of TR_USERROLE_GUEST and TR_USERROLE_NORMAL - const EUserRole mask = EUserRole.TR_USERROLE_NORMAL; - newProfile.UserRole = (newProfile.UserRole & mask) | option; - } - - if (!string.IsNullOrEmpty(profile.Password)) - { - if (profile.Password == "***__CLEAR_PASSWORD__***") - { - newProfile.PasswordSalt = null; - newProfile.PasswordHash = null; - } - else - { - var rng = new RNGCryptoServiceProvider(); - var buffer = new byte[32]; - rng.GetNonZeroBytes(buffer); - var salt = buffer; - var hashedPassword = _Hash(new UTF8Encoding().GetBytes(profile.Password), salt); - - newProfile.PasswordSalt = salt; - newProfile.PasswordHash = hashedPassword; - } - } - - if (existingProfile != null) - { - CProfiles.EditProfile(newProfile); - CProfiles.Update(); - CProfiles.SaveProfiles(); - } - else - { - CProfiles.AddProfile(newProfile); - } - - return true; - } - - public static SProfileData[] GetProfileList() - { - var result = new List(CProfiles.NumProfiles); - - result.AddRange(CProfiles.GetProfiles().Select(profile => _CreateProfileData(profile, true))); - - return result.ToArray(); - } - - private static SProfileData _CreateProfileData(CProfile profile, bool isReadonly) - { - var profileData = new SProfileData - { - IsEditable = !isReadonly, - ProfileId = profile.Id, - PlayerName = profile.PlayerName, - //Is TR_USERROLE_GUEST or TR_USERROLE_NORMAL? - Type = profile.UserRole.HasFlag(EUserRole.TR_USERROLE_NORMAL) ? 1 : 0, - Difficulty = (int)profile.Difficulty - }; - - var avatar = profile.Avatar; - if (avatar != null) - { - if (File.Exists(avatar.FileName)) - { - profileData.Avatar = new CBase64Image(_CreateDelayedImage(avatar.FileName)); - } - } - - return profileData; - } - - private static CAvatar _AddAvatar(CBase64Image avatarData) - { - try - { - var filename = _SaveImage(avatarData, "snapshot", CConfig.ProfileFolders[0]); - - var avatar = CAvatar.GetAvatar(filename); - if (avatar != null) - { - CProfiles.AddAvatar(avatar); - return avatar; - } - - return null; - } - catch - { - return null; - } - } - #endregion - - #region photo - private static readonly List _PhotosOfThisRound = new List(); - - public static bool SendPhoto(SPhotoData photoData) - { - if (photoData.Photo == null) - { - return false; - } - - var name = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); - var filePath = _SaveImage(photoData.Photo, name, CSettings.FolderNamePhotos); - if (!string.IsNullOrEmpty(filePath)) - { - _PhotosOfThisRound.Add(filePath); - return true; - } - - return false; - } - - internal static string[] GetPhotosOfThisRound() - { - var result = _PhotosOfThisRound.ToArray(); - _PhotosOfThisRound.Clear(); - return result; - } - #endregion - - #region website - private static readonly Dictionary _DelayedImagePath = new Dictionary(); - - public static byte[] GetSiteFile(string filename) - { - var path = "Website/" + filename; - path = path.Replace("..", ""); - - if (!File.Exists(path)) - { - return null; - } - - /*string content = File.ReadAllText(path); - - content = content.Replace("%SERVER%", System.Net.Dns.GetHostName() + ":" + CConfig.ServerPort); - - - return Encoding.UTF8.GetBytes(content);*/ - - return File.ReadAllBytes(path); - } - - private static string _CreateDelayedImage(string filename) - { - var by = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(filename)); - var sb = new StringBuilder(); - foreach (var b in by) - { - sb.Append(b.ToString("x2")); - } - - var hashedFilename = sb.ToString(); - - if (!_DelayedImagePath.ContainsKey(hashedFilename)) - { - _DelayedImagePath.Add(hashedFilename, filename); - } - - return hashedFilename; - } - - public static string GetServerVersion() - { - return Application.ProductVersion; - } - - public static CBase64Image GetDelayedImage(string hashedFilename) - { - if (!_DelayedImagePath.ContainsKey(hashedFilename)) - { - throw new FileNotFoundException("Image not found"); - } - - var fileName = _DelayedImagePath[hashedFilename]; - - if (File.Exists(fileName)) - { - var image = Image.FromFile(fileName); - return new CBase64Image(image, image.RawFormat); - } - - throw new FileNotFoundException("Image not found"); - } - #endregion - - #region songs - public static SSongInfo GetSong(int songId) - { - var song = CSongs.GetSong(songId); - return _GetSongInfo(song, true); - } - - private static SSongInfo[] _SongInfoCache = null; - - public static SSongInfo[] GetAllSongs() - { - var sendCovers = CConfig.Config.Server.SongCountCoverThreshold == -1 || CConfig.Config.Server.SongCountCoverThreshold > CSongs.Songs.Count; - - if (_SongInfoCache == null) - { - var songs = CSongs.Songs; - _SongInfoCache = (from s in songs - select _GetSongInfo(s, sendCovers)).AsParallel().ToArray(); - } - - return _SongInfoCache; - } - - public static string GetMp3Path(int songId) - { - var song = CSongs.GetSong(songId); - return song.GetMP3(); - } - - public static int GetCurrentSongId() - { - var song = CGame.GetSong(); - if (song == null) - { - return -1; - } - - return song.Id; - } - - private static SSongInfo _GetSongInfo(CSong song, bool includeCover) - { - var result = new SSongInfo(); - if (song != null) - { - result.Title = song.Title; - result.Artist = song.Artist; - result.Genre = song.Genres.FirstOrDefault(); - result.Language = song.Languages.FirstOrDefault(); - result.Year = song.Year; - result.IsDuet = song.IsDuet; - result.SongId = song.Id; - if (includeCover) - { - if (song.Cover == "") - { - result.Cover = new CBase64Image(_CreateDelayedImage("Website\\img\\noCover.png")); - } - else - { - result.Cover = new CBase64Image(_CreateDelayedImage(song.Folder + "\\" + song.Cover)); - } - } - } - - return result; - } - #endregion - - #region playlist - public static SPlaylistData[] GetPlaylists() - { - return (from p in CPlaylists.Playlists - select _GetPlaylistInfo(p)).ToArray(); - } - - public static SPlaylistData GetPlaylist(int playlistId) - { - if (CPlaylists.Get(playlistId) == null) - { - throw new ArgumentException("invalid playlistId"); - } - - return _GetPlaylistInfo(CPlaylists.Get(playlistId)); - } - - public static void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates) - { - if (CPlaylists.Get(playlistId) == null) - { - throw new ArgumentException("invalid playlistId"); - } - - if (allowDuplicates || !PlaylistContainsSong(songId, playlistId)) - { - CPlaylists.AddSong(playlistId, songId); - CPlaylists.Save(playlistId); - } - else - { - throw new ArgumentException("song exists in this playlist"); - } - } - - public static void RemoveSongFromPlaylist(int position, int playlistId, int songId) - { - var pl = CPlaylists.Get(playlistId); - if (pl == null) - { - throw new ArgumentException("invalid playlistId"); - } - - if (!PlaylistContainsSong(songId, playlistId)) - { - throw new ArgumentException("invalid songId"); - } - - if (position < 0 || pl.Songs.Count <= position - || pl.Songs[position].SongId != songId) - { - throw new ArgumentException("invalid position"); - } - - pl.DeleteSong(position); - pl.Save(); - } - - public static void MoveSongInPlaylist(int newPosition, int playlistId, int songId) - { - var pl = CPlaylists.Get(playlistId); - if (pl == null) - { - throw new ArgumentException("invalid playlistId"); - } - - if (!PlaylistContainsSong(songId, playlistId)) - { - throw new ArgumentException("invalid songId"); - } - - if (pl.Songs.Count < newPosition) - { - throw new ArgumentException("invalid newPosition"); - } - - var oldPosition = pl.Songs.FindIndex(s => s.SongId == songId); - pl.MoveSong(oldPosition, newPosition); - pl.Save(); - } - - public static bool PlaylistContainsSong(int songId, int playlistId) - { - var pl = CPlaylists.Get(playlistId); - if (pl == null) - { - throw new ArgumentException("invalid playlistId"); - } - - return pl.Songs.Any(s => s.SongId == songId); - } - - public static SPlaylistSongInfo[] GetPlaylistSongs(int playlistId) - { - var pl = CPlaylists.Get(playlistId); - if (pl == null) - { - throw new ArgumentException("invalid playlistId"); - } - - return _GetPlaylistSongInfos(pl); - } - - private static SPlaylistSongInfo _GetPlaylistSongInfo(CPlaylistSong playlistSong, int playlistId, int playlistPos) - { - var result = new SPlaylistSongInfo(); - if (playlistSong != null) - { - result.PlaylistId = playlistId; - result.GameMode = (int)playlistSong.GameMode; - result.PlaylistPosition = playlistPos; - result.Song = _GetSongInfo(CSongs.GetSong(playlistSong.SongId), true); - } - - return result; - } - - private static SPlaylistSongInfo[] _GetPlaylistSongInfos(CPlaylistFile playlist) - { - var result = new SPlaylistSongInfo[playlist.Songs.Count]; - for (var i = 0; i < playlist.Songs.Count; i++) - { - result[i] = _GetPlaylistSongInfo(playlist.Songs[i], playlist.Id, i); - } - - return result; - } - - private static SPlaylistData _GetPlaylistInfo(CPlaylistFile playlist) - { - return new SPlaylistData - { - PlaylistId = playlist.Id, - PlaylistName = playlist.Name, - SongCount = playlist.Songs.Count, - LastChanged = DateTime.Now.ToLongDateString() - }; - } - - public static void RemovePlaylist(int playlistId) - { - if (CPlaylists.Get(playlistId) == null) - { - throw new ArgumentException("invalid playlistId"); - } - - CPlaylists.Delete(playlistId); - } - - public static int AddPlaylist(string playlistName) - { - var newPlaylistId = CPlaylists.NewPlaylist(playlistName); - CPlaylists.Save(newPlaylistId); - - return newPlaylistId; - } - #endregion - - #region user management - public static bool ValidatePassword(Guid profileId, string password) - { - var profile = CProfiles.GetProfile(profileId); - if (profile == null) - { - return false; - } - - if (profile.PasswordHash == null) - { - if (string.IsNullOrEmpty(password)) - { - return true; //Allow empty passwords - } - - return false; - } - - var salt = profile.PasswordSalt; - return _Hash(new UTF8Encoding().GetBytes(password), salt).SequenceEqual(profile.PasswordHash); - } - - public static bool ValidatePassword(Guid profileId, byte[] hashedPassword) - { - var profile = CProfiles.GetProfile(profileId); - if (profile == null) - { - return false; - } - - if (profile.PasswordHash == null) - { - if (hashedPassword == null) - { - return true; //Allow empty passwords - } - - return false; - } - - //byte[] salt = profile.PasswordSalt; - return hashedPassword.SequenceEqual(profile.PasswordHash); - } - - private static byte[] _GetPasswordSalt(Guid profileId) - { - var profile = CProfiles.GetProfile(profileId); - if (profile == null) - { - throw new ArgumentException("Invalid profileId"); - } - - if (profile.PasswordHash == null) - { - throw new ArgumentException("Empty password"); - } - - return profile.PasswordSalt; - } - - public static int GetUserRole(Guid profileId) - { - var profile = CProfiles.GetProfile(profileId); - if (profile == null) - { - throw new ArgumentException("Invalid profileId"); - } - - //Hide TR_USERROLE_GUEST and TR_USERROLE_NORMAL - //const EUserRole mask = (EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL); - - return (int)profile.UserRole; - } - - public static void SetUserRole(Guid profileId, int userRole) - { - var profile = CProfiles.GetProfile(profileId); - if (profile == null) - { - throw new ArgumentException("Invalid profileId"); - } - - var option = (EUserRole)userRole; - - //Only allow the change of all options exept TR_USERROLE_GUEST and TR_USERROLE_NORMAL - const EUserRole mask = EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL; - option &= ~mask; - - profile.UserRole = (profile.UserRole & mask) | option; - - CProfiles.EditProfile(profile); - CProfiles.Update(); - CProfiles.SaveProfiles(); - } - - public static Guid GetUserIdFromUsername(string username) - { - var playerIds = from p in CProfiles.GetProfiles() - where String.Equals(p.PlayerName, username, StringComparison.OrdinalIgnoreCase) - select p.Id; - return playerIds.FirstOrDefault(); - } - - private static byte[] _Hash(byte[] password, byte[] salt) - { - HashAlgorithm hashAlgo = new SHA256Managed(); - - var data = new byte[password.Length + salt.Length]; - - password.CopyTo(data, 0); - salt.CopyTo(data, password.Length); - - return hashAlgo.ComputeHash(data); - } - #endregion - - private static string _SaveImage(CBase64Image imageDate, string name, string folder) - { - var avatarImage = imageDate.GetImage(); - var extension = imageDate.GetImageType(); - - if (!Directory.Exists(folder)) - { - Directory.CreateDirectory(folder); - } - - var file = CHelper.GetUniqueFileName(folder, name + "." + extension); - - avatarImage.Save(file); - return file; - } - } -} \ No newline at end of file diff --git a/Vocaluxe/Base/Server/CWebservice.cs b/Vocaluxe/Base/Server/CWebservice.cs deleted file mode 100644 index b6a6473c..00000000 --- a/Vocaluxe/Base/Server/CWebservice.cs +++ /dev/null @@ -1,629 +0,0 @@ -#region license -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -#endregion - -using System; -using System.IO; -using System.Net; -using System.ServiceModel; -using System.ServiceModel.Channels; -using System.ServiceModel.Web; - -namespace Vocaluxe.Base.Server -{ - class CWebservice : ICWebservice - { - private static Guid _GetSession() - { - var sessionKey = Guid.Empty; - var sessionHeader = - ((HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties["httpRequest"]).Headers["session"]; - if (string.IsNullOrEmpty(sessionHeader)) - { - return sessionKey; - } - - try - { - sessionKey = Guid.Parse(sessionHeader); - } - catch (Exception) { } - - CSessionControl.ResetSessionTimeout(sessionKey); - return sessionKey; - } - - public void SendKeyEvent(string key) - { - if (!_CheckRight(EUserRights.UseKeyboard)) - { - return; - } - - - CVocaluxeServer.DoTask(CVocaluxeServer.SendKeyEvent, key); - } - - public void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false) - { - if (!_CheckRight(EUserRights.UseKeyboard)) - { - return; - } - - CVocaluxeServer.DoTask(CVocaluxeServer.SendKeyStringEvent, keyString, isShiftPressed, isAltPressed, isCtrlPressed); - } - - #region profile - public Guid GetOwnProfileId() - { - var sessionKey = _GetSession(); - if (sessionKey == Guid.Empty) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session"; - } - - return Guid.Empty; - } - - var profileId = CSessionControl.GetUserIdFromSession(sessionKey); - if (profileId == Guid.Empty) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session"; - } - - return Guid.Empty; - } - - return profileId; - } - - public void SendProfile(SProfileData profile) - { - var sessionKey = _GetSession(); - - if (profile.ProfileId != Guid.Empty) //Guid.Empty is the id for a new profile - { - if (CSessionControl.GetUserIdFromSession(sessionKey) != profile.ProfileId - && !_CheckRight(EUserRights.EditAllProfiles)) - { - return; - } - } - - CVocaluxeServer.DoTask(CVocaluxeServer.SendProfileData, profile); - } - - public SProfileData GetProfile(Guid profileId) - { - var sessionKey = _GetSession(); - if (CSessionControl.GetUserIdFromSession(sessionKey) == profileId || _CheckRight(EUserRights.ViewOtherProfiles)) - { - var isReadonly = !CSessionControl.RequestRight(sessionKey, EUserRights.EditAllProfiles) && - CSessionControl.GetUserIdFromSession(sessionKey) != profileId; - - - return CVocaluxeServer.DoTask(CVocaluxeServer.GetProfileData, profileId, isReadonly); - } - - return new SProfileData(); - } - - public SProfileData[] GetProfileList() - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetProfileList); - } - #endregion - - #region photo - public void SendPhoto(SPhotoData photo) - { - if (_CheckRight(EUserRights.UploadPhotos)) - { - CVocaluxeServer.DoTask(CVocaluxeServer.SendPhoto, photo); - } - } - #endregion - - #region website - public Guid Login(string username, string password) - { - var sessionId = CSessionControl.OpenSession(username, password); - if (sessionId == Guid.Empty) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = "Wrong username or password"; - } - } - - return sessionId; - } - - public void Logout() - { - var sessionKey = _GetSession(); - CSessionControl.InvalidateSessionById(sessionKey); - } - - public Stream Index() - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "text/html"; - } - - return new MemoryStream(CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "index.html")); - } - - public Stream GetJsFile(string filename) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "text/javascript"; - WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow; - WebOperationContext.Current.OutgoingResponse.Headers.Add( - HttpResponseHeader.Expires, - DateTime.UtcNow.AddHours(4).ToString("r")); - } - - var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "js/" + filename); - - if (data != null) - { - return new MemoryStream(data); - } - - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; - } - - return null; - } - - public Stream GetCssFile(string filename) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "text/css"; - WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow; - WebOperationContext.Current.OutgoingResponse.Headers.Add( - HttpResponseHeader.Expires, - DateTime.UtcNow.AddHours(4).ToString("r")); - } - - var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "css/" + filename); - - if (data != null) - { - return new MemoryStream(data); - } - - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; - } - - return null; - } - - public Stream GetCssImageFile(string filename) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "image/png"; - WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow; - WebOperationContext.Current.OutgoingResponse.Headers.Add( - HttpResponseHeader.Expires, - DateTime.UtcNow.AddYears(1).ToString("r")); - } - - var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "css\\images\\" + filename); - - if (data != null) - { - return new MemoryStream(data); - } - - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; - } - - return null; - } - - public Stream GetImgFile(string filename) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "image/png"; - WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow; - WebOperationContext.Current.OutgoingResponse.Headers.Add( - HttpResponseHeader.Expires, - DateTime.UtcNow.AddYears(1).ToString("r")); - } - - var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "img/" + filename); - - if (data != null) - { - return new MemoryStream(data); - } - - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; - } - - return null; - } - - public Stream GetLocaleFile(string filename) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "text/javascript"; - WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow; - WebOperationContext.Current.OutgoingResponse.Headers.Add( - HttpResponseHeader.Expires, - DateTime.UtcNow.AddHours(4).ToString("r")); - } - - var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "locales/" + filename); - - if (data != null) - { - return new MemoryStream(data); - } - - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; - } - - return null; - } - - public CBase64Image GetDelayedImage(string id) - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetDelayedImage, id); - } - - public bool IsServerOnline() - { - _GetSession(); - return true; - } - - public string GetServerVersion() - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetServerVersion); - } - #endregion - - #region songs - public SSongInfo GetSong(int songId) - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetSong, songId); - } - - public int GetCurrentSongId() - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetCurrentSongId); - } - - public SSongInfo[] GetAllSongs() - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetAllSongs); - } - - public Stream GetMp3File(int songId) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow; - WebOperationContext.Current.OutgoingResponse.Headers.Add( - HttpResponseHeader.Expires, - DateTime.UtcNow.AddYears(1).ToString("r")); - } - - - var path = CVocaluxeServer.DoTask(CVocaluxeServer.GetMp3Path, songId); - path = path.Replace("..", ""); - - - if (!File.Exists(path) - || !(path.EndsWith(".mp3", StringComparison.InvariantCulture) - || path.EndsWith(".ogg", StringComparison.InvariantCulture) - || path.EndsWith(".wav", StringComparison.InvariantCulture) - || path.EndsWith(".webm", StringComparison.InvariantCulture))) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; - } - - return null; - } - - if (WebOperationContext.Current != null) - { - if (path.EndsWith(".mp3", StringComparison.InvariantCulture)) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "audio/mpeg"; - } - else if (path.EndsWith(".ogg", StringComparison.InvariantCulture)) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "audio/ogg"; - } - else if (path.EndsWith(".wav", StringComparison.InvariantCulture)) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "audio/wav"; - } - else if (path.EndsWith(".webm", StringComparison.InvariantCulture)) - { - WebOperationContext.Current.OutgoingResponse.ContentType = "audio/webm"; - } - } - - return File.OpenRead(path); - } - #endregion - - #region playlist - public SPlaylistData[] GetPlaylists() - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetPlaylists); - } - - public SPlaylistData GetPlaylist(int playlistId) - { - try - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetPlaylist, playlistId); - } - catch (ArgumentException e) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message; - } - - return new SPlaylistData(); - } - } - - public void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates) - { - if (!_CheckRight(EUserRights.AddSongToPlaylist)) - { - return; - } - - try - { - CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.AddSongToPlaylist, songId, playlistId, allowDuplicates); - } - catch (ArgumentException e) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message; - } - } - } - - public void RemoveSongFromPlaylist(int position, int playlistId, int songId) - { - if (!_CheckRight(EUserRights.RemoveSongsFromPlaylists)) - { - return; - } - - try - { - CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.RemoveSongFromPlaylist, position, playlistId, songId); - } - catch (ArgumentException e) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message; - } - } - } - - public void MoveSongInPlaylist(int newPosition, int playlistId, int songId) - { - if (!_CheckRight(EUserRights.ReorderPlaylists)) - { - return; - } - - try - { - CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.MoveSongInPlaylist, newPosition, playlistId, songId); - } - catch (ArgumentException e) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message; - } - } - } - - public bool PlaylistContainsSong(int songId, int playlistId) - { - try - { - return CVocaluxeServer.DoTask(CVocaluxeServer.PlaylistContainsSong, songId, playlistId); - } - catch (ArgumentException e) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message; - } - - return false; - } - } - - public SPlaylistSongInfo[] GetPlaylistSongs(int playlistId) - { - try - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetPlaylistSongs, playlistId); - } - catch (ArgumentException e) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message; - } - - return new SPlaylistSongInfo[0]; - } - } - - public void RemovePlaylist(int playlistId) - { - if (!_CheckRight(EUserRights.DeletePlaylists)) - { - return; - } - - try - { - CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.RemovePlaylist, playlistId); - } - catch (ArgumentException e) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message; - } - } - } - - public int AddPlaylist(string playlistName) - { - if (!_CheckRight(EUserRights.CreatePlaylists)) - { - return -1; - } - - try - { - return CVocaluxeServer.DoTask(CVocaluxeServer.AddPlaylist, playlistName); - } - catch (ArgumentException e) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message; - } - - return -1; - } - } - #endregion - - #region user management - public int GetUserRole(Guid profileId) - { - return CVocaluxeServer.DoTask(CVocaluxeServer.GetUserRole, profileId); - } - - public void SetUserRole(Guid profileId, int userRole) - { - if (_CheckRight(EUserRights.EditAllProfiles)) - { - CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.SetUserRole, profileId, userRole); - } - } - - public bool HasUserRight(int right) - { - return _CheckRightWithNoErrorMessage((EUserRights)right); - } - - private static bool _CheckRight(EUserRights requestedRight) - { - var sessionKey = _GetSession(); - - if (sessionKey == Guid.Empty) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session"; - } - - return false; - } - - if (!CSessionControl.RequestRight(sessionKey, requestedRight)) - { - if (WebOperationContext.Current != null) - { - WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; - WebOperationContext.Current.OutgoingResponse.StatusDescription = "Not allowed"; - } - - return false; - } - - return true; - } - - private static bool _CheckRightWithNoErrorMessage(EUserRights requestedRight) - { - var sessionKey = _GetSession(); - - if (sessionKey == Guid.Empty) - { - return false; - } - - if (!CSessionControl.RequestRight(sessionKey, requestedRight)) - { - return false; - } - - return true; - } - #endregion - } -} \ No newline at end of file diff --git a/Vocaluxe/Base/Server/ICWebservice.cs b/Vocaluxe/Base/Server/ICWebservice.cs deleted file mode 100644 index 26f13a9d..00000000 --- a/Vocaluxe/Base/Server/ICWebservice.cs +++ /dev/null @@ -1,211 +0,0 @@ -#region license -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -#endregion - -using System; -using System.IO; -using System.ServiceModel; -using System.ServiceModel.Web; - -namespace Vocaluxe.Base.Server -{ - [ServiceContract] - public interface ICWebservice - { - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/sendKeyEvent?key={key}")] - void SendKeyEvent(string key); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/sendKeyStringEvent?keyString={keyString}&shift={isShiftPressed}&alt={isAltPressed}&ctrl={isCtrlPressed}")] - void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false); - - #region profile - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getOwnProfileId")] - Guid GetOwnProfileId(); - - [OperationContract, WebInvoke(Method = "POST", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/sendProfile")] - void SendProfile(SProfileData profile); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getProfile?profileId={profileId}")] - SProfileData GetProfile(Guid profileId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getProfileList")] - SProfileData[] GetProfileList(); - #endregion - - #region photo - [OperationContract, WebInvoke(Method = "POST", - RequestFormat = WebMessageFormat.Json, - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/sendPhoto")] - void SendPhoto(SPhotoData photo); - #endregion - - #region website - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/login?username={username}&password={password}")] - Guid Login(string username, string password); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/logout")] - void Logout(); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "")] - Stream Index(); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/js/{filename}")] - Stream GetJsFile(String filename); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/css/{filename}")] - Stream GetCssFile(String filename); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/css/images/{filename}")] - Stream GetCssImageFile(String filename); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/img/{filename}")] - Stream GetImgFile(String filename); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/locales/{filename}")] - Stream GetLocaleFile(String filename); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/delayedImage?id={id}")] - CBase64Image GetDelayedImage(String id); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/isServerOnline")] - bool IsServerOnline(); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getServerVersion")] - String GetServerVersion(); - #endregion - - #region songs - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getSong?songId={songId}")] - SSongInfo GetSong(int songId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getCurrentSongId")] - int GetCurrentSongId(); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getAllSongs")] - SSongInfo[] GetAllSongs(); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getMp3?songId={songId}")] - Stream GetMp3File(int songId); - #endregion - - #region playlist - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getPlaylists")] - SPlaylistData[] GetPlaylists(); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getPlaylist?id={playlistId}")] - SPlaylistData GetPlaylist(int playlistId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/addSongToPlaylist?songId={songId}&playlistId={playlistId}&duplicates={allowDuplicates}")] - void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/removeSongFromPlaylist?position={position}&playlistId={playlistId}&songId={songId}")] - void RemoveSongFromPlaylist(int position, int playlistId, int songId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/moveSongInPlaylist?newPosition={newPosition}&playlistId={playlistId}&songId={songId}")] - void MoveSongInPlaylist(int newPosition, int playlistId, int songId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/playlistContainsSong?songId={songId}&playlistId={playlistId}")] - bool PlaylistContainsSong(int songId, int playlistId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getPlaylistSongs?playlistId={playlistId}")] - SPlaylistSongInfo[] GetPlaylistSongs(int playlistId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/removePlaylist?playlistId={playlistId}")] - void RemovePlaylist(int playlistId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/addPlaylist?playlistName={playlistName}")] - int AddPlaylist(string playlistName); - #endregion - - #region user management - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/getUserRole?profileId={profileId}")] - int GetUserRole(Guid profileId); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/setUserRole?profileId={profileId}&userRole={userRole}")] - void SetUserRole(Guid profileId, int userRole); - - [OperationContract, WebInvoke(Method = "GET", - ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/hasUserRight?right={right}")] - bool HasUserRight(int right); - #endregion - } -} \ No newline at end of file diff --git a/Vocaluxe/Base/Server/SessionControl.cs b/Vocaluxe/Base/Server/SessionControl.cs deleted file mode 100644 index 8f95b1bd..00000000 --- a/Vocaluxe/Base/Server/SessionControl.cs +++ /dev/null @@ -1,126 +0,0 @@ -#region license -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Timers; - -namespace Vocaluxe.Base.Server -{ - static class CSessionControl - { - private static readonly Dictionary _ActiveSessions; - private const int _UserTimeoutCheckIntervall = 120000; - private const int _UserTimeout = 120000; - - static CSessionControl() - { - _ActiveSessions = new Dictionary(); - var timer = new Timer(_UserTimeoutCheckIntervall) { AutoReset = true, Enabled = true }; - timer.Elapsed += _CheckForUserTimeouts; - timer.Start(); - } - - private static void _CheckForUserTimeouts(object sender, ElapsedEventArgs e) - { - var sessionIdsToRemove = _ActiveSessions.Where(pair => (DateTime.Now - pair.Value.LastSeen).TotalMilliseconds > _UserTimeout) - .Select(pair => pair.Key) - .ToList(); - - foreach (var sessionToRemove in sessionIdsToRemove) - { - InvalidateSessionById(sessionToRemove); - } - } - - public static Guid OpenSession(string userName, string password) - { - if (!_ValidateUserAndPassword(userName, password)) - { - return Guid.Empty; - } - - var newId = Guid.NewGuid(); - var id = _GetProfileIdFormUsername(userName); - var roles = _GetUserRoles(id); - var session = new CSession(newId, id, roles); - //InvalidateSessions(id); - _ActiveSessions.Add(newId, session); - - return newId; - } - - private static bool _ValidateUserAndPassword(string userName, string password) - { - return CVocaluxeServer.ValidatePassword(_GetProfileIdFormUsername(userName), password); - } - - private static Guid _GetProfileIdFormUsername(string username) - { - return CVocaluxeServer.GetUserIdFromUsername(username); - } - - private static EUserRoles _GetUserRoles(Guid profileId) - { - return (EUserRoles)CVocaluxeServer.GetUserRole(profileId); - } - - internal static void InvalidateSessionByProfile(Guid profileId) - { - foreach (var s in (from kv in _ActiveSessions - where kv.Value.ProfileId == profileId - select kv).ToList()) - { - _ActiveSessions.Remove(s.Key); - } - } - - internal static void InvalidateSessionById(Guid sessionId) - { - if (_ActiveSessions.ContainsKey(sessionId)) - { - _ActiveSessions.Remove(sessionId); - } - } - - internal static bool RequestRight(Guid sessionId, EUserRights requestedRight) - { - return CUserRoleControl.GetUserRightsFromUserRole(_ActiveSessions[sessionId].Roles) - .HasFlag(requestedRight); - } - - internal static Guid GetUserIdFromSession(Guid sessionId) - { - if (!_ActiveSessions.ContainsKey(sessionId)) - { - return Guid.Empty; - } - - return _ActiveSessions[sessionId].ProfileId; - } - - internal static void ResetSessionTimeout(Guid sessionId) - { - CSession value; - if (_ActiveSessions.TryGetValue(sessionId, out value)) - { - value.LastSeen = DateTime.Now; - } - } - } -} \ No newline at end of file diff --git a/Vocaluxe/Base/Server/UserRights.cs b/Vocaluxe/Base/Server/UserRights.cs deleted file mode 100644 index 85921333..00000000 --- a/Vocaluxe/Base/Server/UserRights.cs +++ /dev/null @@ -1,36 +0,0 @@ -#region license -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -#endregion - -using System; - -namespace Vocaluxe.Base.Server -{ - [Flags] - enum EUserRights - { - None = 0, - EditAllProfiles = 1, - UploadPhotos = 2, - ViewOtherProfiles = 4, - UseKeyboard = 8, - ReorderPlaylists = 16, - AddSongToPlaylist = 32, - CreatePlaylists = 64, - DeletePlaylists = 128, - RemoveSongsFromPlaylists = 256 - } -} \ No newline at end of file diff --git a/Vocaluxe/Base/Server/UserRoleControl.cs b/Vocaluxe/Base/Server/UserRoleControl.cs deleted file mode 100644 index 5bbe842f..00000000 --- a/Vocaluxe/Base/Server/UserRoleControl.cs +++ /dev/null @@ -1,77 +0,0 @@ -#region license -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -#endregion - -using System.Collections.Generic; -using System.Linq; - -namespace Vocaluxe.Base.Server -{ - static class CUserRoleControl - { - private static readonly Dictionary _RoleRightsMapping = new Dictionary - { - { - EUserRoles.TR_USERROLE_ADMIN, - EUserRights.EditAllProfiles | - EUserRights.UploadPhotos | - EUserRights.ViewOtherProfiles | - EUserRights.UseKeyboard | - EUserRights.AddSongToPlaylist | - EUserRights.ReorderPlaylists | - EUserRights.CreatePlaylists | - EUserRights.DeletePlaylists | - EUserRights.RemoveSongsFromPlaylists - }, - { - EUserRoles.TR_USERROLE_GUEST, - EUserRights.None - }, - { - EUserRoles.TR_USERROLE_NORMAL, - EUserRights.UploadPhotos | - EUserRights.ViewOtherProfiles - }, - { - EUserRoles.TR_USERROLE_KEYBOARDUSER, - EUserRights.UseKeyboard - }, - { - EUserRoles.TR_USERROLE_ADDSONGSUSER, - EUserRights.AddSongToPlaylist - }, - { - EUserRoles.TR_USERROLE_PLAYLISTEDITOR, - EUserRights.AddSongToPlaylist | - EUserRights.ReorderPlaylists | - EUserRights.CreatePlaylists | - EUserRights.DeletePlaylists | - EUserRights.RemoveSongsFromPlaylists - }, - { - EUserRoles.TR_USERROLE_PROFILEEDITOR, - EUserRights.EditAllProfiles - } - }; - - internal static EUserRights GetUserRightsFromUserRole(EUserRoles userRole) - { - return _RoleRightsMapping.Where(role => userRole.HasFlag(role.Key)) - .Select(role => role.Value) - .Aggregate(EUserRights.None, (current, r) => current | r); - } - } -} \ No newline at end of file diff --git a/Vocaluxe/Base/Server/UserRoles.cs b/Vocaluxe/Base/Server/UserRoles.cs deleted file mode 100644 index ed836433..00000000 --- a/Vocaluxe/Base/Server/UserRoles.cs +++ /dev/null @@ -1,35 +0,0 @@ -#region license -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -#endregion - -using System; - -namespace Vocaluxe.Base.Server -{ - [Flags] - enum EUserRoles - { - // ReSharper disable InconsistentNaming - TR_USERROLE_GUEST = 0, - TR_USERROLE_NORMAL = 1, - TR_USERROLE_ADMIN = 2, - TR_USERROLE_KEYBOARDUSER = 4, - TR_USERROLE_ADDSONGSUSER = 8, - TR_USERROLE_PLAYLISTEDITOR = 16, - TR_USERROLE_PROFILEEDITOR = 32 - // ReSharper restore InconsistentNaming - } -} \ No newline at end of file diff --git a/Vocaluxe/Base/Server/VocaluxeStructs.cs b/Vocaluxe/Base/Server/VocaluxeStructs.cs deleted file mode 100644 index efe46e46..00000000 --- a/Vocaluxe/Base/Server/VocaluxeStructs.cs +++ /dev/null @@ -1,160 +0,0 @@ -#region license -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -#endregion - -using System; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Runtime.Serialization; -using System.Text.RegularExpressions; - -namespace Vocaluxe.Base.Server -{ - public struct SLoginData - { - public byte[] Sha256; - } - - public struct SPicture - { - public int Width; - public int Height; - public byte[] Data; - } - - public struct SProfile - { - public SPicture Avatar; - public string PlayerName; - public int Difficulty; - } - - [DataContract] - public struct SProfileData - { - [DataMember] - public CBase64Image Avatar; - [DataMember] - public string PlayerName; - [DataMember] - public int Type; - [DataMember] - public int Difficulty; - [DataMember] - public Guid ProfileId; - [DataMember] - public bool IsEditable; - [DataMember] - public string Password; - } - - [DataContract] - public struct SPhotoData - { - [DataMember] - public CBase64Image Photo; - //Add infomation about the user who took this image?? - } - - [DataContract] - public class CBase64Image - { - // ReSharper disable InconsistentNaming - [DataMember] - private string base64Data = ""; - [DataMember] - private string imageId = ""; - // ReSharper restore InconsistentNaming - - public CBase64Image(Image img, ImageFormat format) - { - var ms = new MemoryStream(); - img.Save(ms, format); - var formatString = ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == format.Guid).FilenameExtension.Replace("*.", "").ToLower(); - base64Data = "data:image/" + formatString + ";base64," + Convert.ToBase64String(ms.ToArray()); - } - - public CBase64Image(string imageId) - { - this.imageId = imageId; - } - - public Image GetImage() - { - var onlyBase64Data = base64Data.Substring(base64Data.IndexOf(";base64,") + ";base64,".Length); - var imageData = Convert.FromBase64String(onlyBase64Data); - var ms = new MemoryStream(imageData, 0, imageData.Length); - ms.Write(imageData, 0, imageData.Length); - var image = Image.FromStream(ms, true); - return image; - } - - public string GetImageType() - { - var match = Regex.Match(base64Data, "(?<=data:image/)[a-zA-Z]+(?=;base64)"); - return match.Success ? match.Groups[0].Value : ""; - } - } - - [DataContract] - public struct SSongInfo - { - [DataMember] - public string Title; - [DataMember] - public string Artist; - [DataMember] - public CBase64Image Cover; - [DataMember] - public string Genre { get; set; } - [DataMember] - public string Language { get; set; } - [DataMember] - public string Year { get; set; } - [DataMember] - public bool IsDuet { get; set; } - [DataMember] - public int SongId { get; set; } - } - - [DataContract] - public struct SPlaylistSongInfo - { - [DataMember] - public SSongInfo Song; - [DataMember] - public int PlaylistId; - [DataMember] - public int PlaylistPosition; - [DataMember] - public int GameMode; - } - - [DataContract] - public struct SPlaylistData - { - [DataMember] - public int PlaylistId; - [DataMember] - public string PlaylistName; - [DataMember] - public int SongCount; - [DataMember] - public string LastChanged; - } -} \ No newline at end of file diff --git a/Vocaluxe/Base/Server/Session.cs b/Vocaluxe/Base/Web/CRemoteKeyboard.cs similarity index 58% rename from Vocaluxe/Base/Server/Session.cs rename to Vocaluxe/Base/Web/CRemoteKeyboard.cs index 7928caf6..14376030 100644 --- a/Vocaluxe/Base/Server/Session.cs +++ b/Vocaluxe/Base/Web/CRemoteKeyboard.cs @@ -1,40 +1,41 @@ -#region license +#region license // This file is part of Vocaluxe. -// +// // Vocaluxe is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // Vocaluxe is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with Vocaluxe. If not, see . #endregion -using System; +using Vocaluxe.Lib.Input; -namespace Vocaluxe.Base.Server +namespace Vocaluxe.Base.Web { - class CSession + /// Key events coming from the WebApp's remote keyboard. + class CRemoteKeyboard : CControllerFramework { - public Guid Id { get; } - - public Guid ProfileId { get; } - - internal EUserRoles Roles { get; } - - public DateTime LastSeen { get; internal set; } - - public CSession(Guid id, Guid profileId, EUserRoles roles) + public override string GetName() { - Id = id; - ProfileId = profileId; - Roles = roles; - LastSeen = DateTime.Now; + return "WebApp"; } + + public override void Connect() { } + + public override void Disconnect() { } + + public override bool IsConnected() + { + return true; + } + + public override void SetRumble(float duration) { } } -} \ No newline at end of file +} diff --git a/Vocaluxe/Base/Web/CVocaluxeRemote.cs b/Vocaluxe/Base/Web/CVocaluxeRemote.cs new file mode 100644 index 00000000..4a490471 --- /dev/null +++ b/Vocaluxe/Base/Web/CVocaluxeRemote.cs @@ -0,0 +1,402 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using Vocaluxe.Lib.Input; +using VocaluxeLib; +using VocaluxeLib.Menu; +using VocaluxeLib.Profile; +using VocaluxeLib.Songs; +using VocaluxeWeb; +using VocaluxeWeb.Remote; + +namespace Vocaluxe.Base.Web +{ + /// Gives the webserver access to the game. Everything except , and runs on the main thread. + class CVocaluxeRemote : IVocaluxeRemote + { + private const EUserRole _RoleMask = EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL | EUserRole.TR_USERROLE_ADMIN; + private const string _UploadPrefix = "WebApp_"; + + private readonly CControllerFramework _Keyboard; + + public CVocaluxeRemote(CControllerFramework keyboard) + { + _Keyboard = keyboard; + } + + public string Version { get; } = CSettings.FullVersion; + + public bool IsReady => CGraphics.CurrentScreenType != EScreen.Load; + + private void _CheckReady() + { + if (!IsReady) + { + throw new TimeoutException("Vocaluxe is still loading"); + } + } + + public RemoteState GetState() + { + return new RemoteState { Screen = CGraphics.CurrentScreenType.ToString(), SongId = CGame.GetSong()?.Id }; + } + + #region profiles + public IList GetProfiles() + { + return CProfiles.GetProfiles().Select(p => new RemoteProfile + { + Id = p.Id, + Name = p.PlayerName, + Role = _ToRemoteRole(p.UserRole), + Difficulty = (int)p.Difficulty, + IsActive = p.Active == EOffOn.TR_CONFIG_ON, + AvatarPath = p.Avatar == null || string.IsNullOrEmpty(p.Avatar.FileName) ? null : Path.GetFullPath(p.Avatar.FileName), + PinHash = p.PasswordHash, + PinSalt = p.PasswordSalt + }).ToList(); + } + + public Guid CreateProfile(ProfileChange change) + { + var profile = new CProfile { Active = EOffOn.TR_CONFIG_ON, UserRole = EUserRole.TR_USERROLE_NORMAL }; + _Apply(profile, change); + CProfiles.AddProfile(profile); + CProfiles.Update(); + return profile.Id; + } + + public void UpdateProfile(Guid profileId, ProfileChange change) + { + var existing = CProfiles.GetProfile(profileId); + if (existing == null) + { + throw new KeyNotFoundException("Profile not found"); + } + + var profile = new CProfile + { + Id = existing.Id, + FilePath = existing.FilePath, + PlayerName = existing.PlayerName, + Difficulty = existing.Difficulty, + UserRole = existing.UserRole, + Active = existing.Active, + Avatar = existing.Avatar, + PasswordHash = existing.PasswordHash, + PasswordSalt = existing.PasswordSalt + }; + _Apply(profile, change); + CProfiles.EditProfile(profile); + CProfiles.Update(); + profile.SaveProfile(); + } + + public void DeleteProfile(Guid profileId) + { + CProfiles.DeleteProfile(profileId); + CProfiles.Update(); + } + + public IList GetAvatars() + { + return (CProfiles.GetAvatars() ?? Enumerable.Empty()) + .Where(a => !string.IsNullOrEmpty(a.FileName) && !Path.GetFileName(a.FileName).StartsWith(_UploadPrefix)) + .OrderBy(a => Path.GetFileName(a.FileName), StringComparer.OrdinalIgnoreCase) + .Select(a => new RemoteAvatar { Id = a.Id, Path = Path.GetFullPath(a.FileName) }) + .ToList(); + } + + private static void _Apply(CProfile profile, ProfileChange change) + { + if (!string.IsNullOrEmpty(change.Name)) + { + profile.PlayerName = change.Name; + } + + if (change.Difficulty.HasValue) + { + profile.Difficulty = (EGameDifficulty)change.Difficulty.Value; + } + + if (change.IsActive.HasValue) + { + profile.Active = change.IsActive.Value ? EOffOn.TR_CONFIG_ON : EOffOn.TR_CONFIG_OFF; + } + + if (change.Role.HasValue) + { + profile.UserRole = (profile.UserRole & ~_RoleMask) | _ToUserRole(change.Role.Value); + } + + if (change.ClearPin) + { + profile.PasswordHash = null; + profile.PasswordSalt = null; + } + else if (change.PinHash != null) + { + profile.PasswordHash = change.PinHash; + profile.PasswordSalt = change.PinSalt; + } + + if (change.AvatarId.HasValue) + { + var avatar = CProfiles.GetAvatars()?.FirstOrDefault(a => a.Id == change.AvatarId.Value); + if (avatar != null) + { + profile.Avatar = avatar; + } + } + + if (change.AvatarJpeg != null) + { + var avatar = _CreateAvatar(change.AvatarJpeg); + if (avatar != null) + { + profile.Avatar = avatar; + } + } + } + + private static CAvatar _CreateAvatar(byte[] jpeg) + { + var folder = CConfig.ProfileFolders[0]; + Directory.CreateDirectory(folder); + var fileName = Path.Combine(folder, _UploadPrefix + Guid.NewGuid().ToString("N") + ".jpg"); + File.WriteAllBytes(fileName, jpeg); + + var avatar = CAvatar.GetAvatar(fileName); + if (avatar != null) + { + CProfiles.AddAvatar(avatar); + } + + return avatar; + } + + private static ERemoteRole _ToRemoteRole(EUserRole role) + { + if (role.HasFlag(EUserRole.TR_USERROLE_ADMIN)) + { + return ERemoteRole.Admin; + } + + return role.HasFlag(EUserRole.TR_USERROLE_NORMAL) ? ERemoteRole.Player : ERemoteRole.Guest; + } + + private static EUserRole _ToUserRole(ERemoteRole role) + { + switch (role) + { + case ERemoteRole.Admin: + return EUserRole.TR_USERROLE_ADMIN; + case ERemoteRole.Player: + return EUserRole.TR_USERROLE_NORMAL; + default: + return EUserRole.TR_USERROLE_GUEST; + } + } + #endregion + + #region songs + public int SongLibraryVersion => CSongs.AllSongs.Count * 2 + (CSongs.SongsLoaded ? 1 : 0); + + public IList GetSongs() + { + _CheckReady(); + return CSongs.AllSongs.Select(s => new RemoteSong + { + Id = s.Id, + Title = s.Title, + Artist = s.Artist, + Year = s.Year, + Languages = s.Languages.ToList(), + Genres = s.Genres.ToList(), + Editions = s.Editions.ToList(), + IsDuet = s.IsDuet, + GameModes = s.AvailableGameModes.Select(m => (int)m).ToList(), + AudioModes = _GetAudioModes(s), + CoverPath = _GetFullPath(s, s.Cover), + AudioPath = _GetFullPath(s, s.Audio), + PreviewStart = s.Preview.Source == EDataSource.None ? (float?)null : s.Preview.StartTime, + NumPlayed = s.NumPlayed, + DateAdded = s.DateAdded + }).ToList(); + } + + private static IList _GetAudioModes(CSong song) + { + var modes = new List(); + if (song.HasInstrumental()) + { + modes.Add((int)EAudioMode.TR_AUDIOMODE_NORMAL); + modes.Add((int)EAudioMode.TR_AUDIOMODE_INSTRUMENTAL); + if (song.HasVocals()) + { + modes.Add((int)EAudioMode.TR_AUDIOMODE_VOCALS); + } + + modes.Add((int)EAudioMode.TR_AUDIOMODE_KARAOKE); + } + + return modes; + } + + private static string _GetFullPath(CSong song, string file) + { + if (string.IsNullOrEmpty(file)) + { + return null; + } + + try + { + return Path.GetFullPath(Path.Combine(song.Folder, file)); + } + catch (ArgumentException) + { + return null; + } + } + #endregion + + #region playlists + public IList GetPlaylists() + { + _CheckReady(); + return CPlaylists.Playlists.Select(p => new RemotePlaylist + { + Id = p.Id, + Name = p.Name, + Entries = p.Songs.Select(s => new RemotePlaylistEntry { SongId = s.SongId, GameMode = (int)s.GameMode, AudioMode = (int)s.AudioMode }).ToList() + }).ToList(); + } + + public int CreatePlaylist(string name) + { + _CheckReady(); + var id = CPlaylists.NewPlaylist(name); + CPlaylists.Save(id); + return id; + } + + public void RenamePlaylist(int playlistId, string name) + { + CPlaylists.SetName(playlistId, name); + CPlaylists.Save(playlistId); + } + + public void DeletePlaylist(int playlistId) + { + CPlaylists.Delete(playlistId); + } + + public void SetPlaylistEntries(int playlistId, IList entries) + { + var playlist = CPlaylists.Get(playlistId); + if (playlist == null) + { + throw new KeyNotFoundException("Playlist not found"); + } + + playlist.Songs = entries.Select(e => new CPlaylistSong(e.SongId, (EGameMode)e.GameMode) { AudioMode = (EAudioMode)e.AudioMode }).ToList(); + playlist.Save(); + CWebServer.NotifyPlaylistChanged(); + } + #endregion + + #region game + public ERemoteStartResult StartSong(RemoteStartRequest request) + { + if (!CWebQueue.Start(request.SongId, (EGameMode)request.GameMode, (EAudioMode)request.AudioMode, request.PlayerIds, false, out var singsNow)) + { + return ERemoteStartResult.Busy; + } + + return singsNow ? ERemoteStartResult.Singing : ERemoteStartResult.PlayerSelection; + } + #endregion + + #region input + public void SendKey(ERemoteKey key) + { + _Keyboard.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, char.MinValue, _ToKeys(key))); + } + + public void SendText(string text) + { + foreach (var chr in text) + { + _Keyboard.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, char.IsUpper(chr), false, true, chr, _CharToKeys(chr))); + } + } + + private static Keys _CharToKeys(char chr) + { + var upper = char.ToUpperInvariant(chr); + if (upper >= 'A' && upper <= 'Z') + { + return Keys.A + (upper - 'A'); + } + + if (chr >= '0' && chr <= '9') + { + return Keys.D0 + (chr - '0'); + } + + return chr == ' ' ? Keys.Space : Keys.None; + } + + private static Keys _ToKeys(ERemoteKey key) + { + switch (key) + { + case ERemoteKey.Up: + return Keys.Up; + case ERemoteKey.Down: + return Keys.Down; + case ERemoteKey.Left: + return Keys.Left; + case ERemoteKey.Right: + return Keys.Right; + case ERemoteKey.Enter: + return Keys.Return; + case ERemoteKey.Escape: + return Keys.Escape; + case ERemoteKey.Tab: + return Keys.Tab; + case ERemoteKey.Backspace: + return Keys.Back; + case ERemoteKey.Space: + return Keys.Space; + case ERemoteKey.PageUp: + return Keys.PageUp; + case ERemoteKey.PageDown: + return Keys.PageDown; + default: + return Keys.None; + } + } + #endregion + } +} diff --git a/Vocaluxe/Base/Web/CWebQueue.cs b/Vocaluxe/Base/Web/CWebQueue.cs new file mode 100644 index 00000000..c45b6b5f --- /dev/null +++ b/Vocaluxe/Base/Web/CWebQueue.cs @@ -0,0 +1,171 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using VocaluxeLib; +using VocaluxeLib.Log; +using VocaluxeLib.Menu; + +namespace Vocaluxe.Base.Web +{ + /// The WebApp queue as the game sees it: a playlist plus requester and singers from the webserver. + /// Used by the queue screen and by the webserver to start songs. + static class CWebQueue + { + public sealed class CItem + { + public int SongId; + public EGameMode GameMode; + public EAudioMode AudioMode; + public string RequestedBy; + public IList PlayerIds = new List(); + public IList PlayerNames = new List(); + } + + private static readonly EScreen[] _BusyScreens = { EScreen.Load, EScreen.Sing, EScreen.JukeboxPlayer, EScreen.Party }; + + /// Song that was started from the queue; after singing it the game returns to the queue screen. + private static int _StartedSongId = -1; + + public static int PlaylistId + { + get + { + var name = CWebServer.GetQueuePlaylistName(); + var playlist = CPlaylists.Playlists.FirstOrDefault(p => p.Name == name); + return playlist?.Id ?? -1; + } + } + + public static bool IsQueuePlaylist(int playlistId) + { + return playlistId >= 0 && playlistId == PlaylistId; + } + + /// The entries in queue order. Without running webserver only the playlist is known (no requesters and singers). + public static IList GetItems() + { + var items = CWebServer.GetQueueItems(); + if (items != null) + { + return items; + } + + var playlist = CPlaylists.Get(PlaylistId); + if (playlist == null) + { + return new List(); + } + + return playlist.Songs.Select(s => new CItem { SongId = s.SongId, GameMode = s.GameMode, AudioMode = s.AudioMode }).ToList(); + } + + public static bool CanStart() + { + return CParty.CurrentPartyModeId == -1 && !_BusyScreens.Contains(CGraphics.CurrentScreenType); + } + + /// Starts singing the song. With singers and configured microphones the player selection is skipped; + /// otherwise (or when requested) the player selection is shown with the singers already chosen. + public static bool Start(int songId, EGameMode gameMode, EAudioMode audioMode, IList playerIds, bool showPlayerSelection, out bool singsNow) + { + singsNow = false; + if (!CanStart() || CSongs.GetSong(songId) == null) + { + return false; + } + + CParty.SetNormalGameMode(); + CGame.Reset(); + CGame.ClearSongs(); + CGame.AddSong(songId, gameMode, audioMode); + if (CGame.GetNumSongs() == 0) + { + return false; + } + + var players = (playerIds ?? new List()).Where(CProfiles.IsProfileIdValid).Distinct().Take(CSettings.MaxNumPlayer).ToList(); + if (players.Count > 0) + { + CConfig.Config.Game.NumPlayers = players.Count; + CGame.NumPlayers = players.Count; + var isDuet = CGame.GetSong(0).IsDuet; + for (var i = 0; i < CSettings.MaxNumPlayer; i++) + { + CGame.Players[i].ProfileId = i < players.Count ? players[i] : Guid.Empty; + CGame.Players[i].VoiceNr = isDuet ? i % 2 : 0; + } + } + + _StartedSongId = songId; + var micsReady = Enumerable.Range(1, players.Count).All(CConfig.IsMicConfig); + singsNow = players.Count > 0 && micsReady && !showPlayerSelection; + CLog.Information("WebApp queue: starting song {SongId} with {Players} of {Chosen} chosen singers, microphones ready: {MicsReady}, player selection: {Selection}", + new object[] { songId, players.Count, playerIds?.Count ?? 0, micsReady, !singsNow }); + if (!singsNow) + { + CBackgroundMusic.LoadPreview(CSongs.GetSong(songId)); + } + + CGraphics.FadeTo(singsNow ? EScreen.Sing : EScreen.Names); + return true; + } + + /// Called when leaving the score screens: goes back to the queue screen if the song was started from the queue. + public static bool ReturnAfterSinging() + { + var startedFromQueue = _StartedSongId >= 0 && CParty.CurrentPartyModeId == -1 && CGame.GetSong(0)?.Id == _StartedSongId; + _StartedSongId = -1; + if (!startedFromQueue) + { + return false; + } + + CGraphics.FadeTo(EScreen.WebQueue); + return true; + } + + public static void SetModes(int index, EGameMode gameMode, EAudioMode audioMode) + { + var playlist = CPlaylists.Get(PlaylistId); + if (playlist == null || index < 0 || index >= playlist.Songs.Count) + { + return; + } + + playlist.Songs[index].GameMode = gameMode; + playlist.Songs[index].AudioMode = audioMode; + playlist.Save(); + CWebServer.NotifyPlaylistChanged(); + } + + public static void Remove(int index) + { + var playlist = CPlaylists.Get(PlaylistId); + if (playlist == null || index < 0 || index >= playlist.Songs.Count) + { + return; + } + + playlist.DeleteSong(index); + playlist.Save(); + CWebServer.NotifyPlaylistChanged(); + } + } +} diff --git a/Vocaluxe/Base/Web/CWebServer.cs b/Vocaluxe/Base/Web/CWebServer.cs new file mode 100644 index 00000000..32785fd0 --- /dev/null +++ b/Vocaluxe/Base/Web/CWebServer.cs @@ -0,0 +1,196 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using VocaluxeLib; +using VocaluxeLib.Log; +#if WIN +using Newtonsoft.Json.Linq; +#endif +#if WIN +using VocaluxeWeb.Hosting; +#endif + +namespace Vocaluxe.Base.Web +{ + /// Starts and stops the embedded webserver (project VocaluxeWeb) and runs its requests on the main thread. + /// The webserver is not available in Linux builds yet. + static class CWebServer + { + private const string _CertificateFileName = "WebServer.pfx"; + private const string _SettingsFileName = "WebServer.json"; + private const string _CacheFolderName = "WebCache"; + private const string _DefaultQueuePlaylistName = "WebApp Queue"; + + public static readonly CRemoteKeyboard Controller = new CRemoteKeyboard(); + +#if WIN + private static CWebHost _Host; +#endif + private static readonly List _PhotosOfThisRound = new List(); + + public static void Init() + { + if (CConfig.Config.Server.ServerActive != EOffOn.TR_CONFIG_ON) + { + return; + } + +#if WIN + var options = new CWebServerOptions + { + Port = CConfig.Config.Server.ServerPort, + UseHttps = CConfig.Config.Server.ServerEncryption == EOffOn.TR_CONFIG_ON, + WebRoot = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameWebsite), + CertificatePath = Path.Combine(CSettings.DataFolder, _CertificateFileName), + SettingsPath = Path.Combine(CSettings.DataFolder, _SettingsFileName), + CachePath = Path.Combine(CSettings.DataFolder, _CacheFolderName), + OnError = e => CLog.Error(e, "Webserver request failed") + }; + + var host = new CWebHost(new CVocaluxeRemote(Controller), options); + try + { + host.Start(); + _Host = host; + CLog.Information("Webserver running at {Address}", new object[] { host.Address }); + } + catch (Exception e) + { + host.Dispose(); + CLog.Error(e, "Could not start the webserver on port {Port}. You may try a different port (change it in config.xml).", new object[] { options.Port }, true); + } +#endif + } + + public static void Close() + { +#if WIN + _Host?.Dispose(); + _Host = null; +#endif + } + + /// Runs pending webserver requests. Called once per frame from the main thread. + public static void ProcessTasks() + { +#if WIN + _Host?.Tick(); +#endif + } + + public static bool IsServerRunning() + { +#if WIN + return _Host != null && _Host.IsRunning; +#else + return false; +#endif + } + + public static string GetServerAddress() + { +#if WIN + return _Host?.Address?.AbsoluteUri ?? ""; +#else + return ""; +#endif + } + + /// Name of the playlist used as WebApp queue; read from the webserver settings also while the server is off. + public static string GetQueuePlaylistName() + { +#if WIN + if (_Host != null) + { + return _Host.QueuePlaylistName; + } + + try + { + var path = Path.Combine(CSettings.DataFolder, _SettingsFileName); + if (File.Exists(path)) + { + var name = (string)JObject.Parse(File.ReadAllText(path))["QueuePlaylistName"]; + if (!string.IsNullOrEmpty(name)) + { + return name; + } + } + } + catch (Exception e) + { + CLog.Warning(e, "Could not read the webserver settings"); + } +#endif + return _DefaultQueuePlaylistName; + } + + /// The queue with requesters and singers, or null if the webserver is not running. + public static IList GetQueueItems() + { +#if WIN + return _Host?.GetQueueForGame().Select(i => new CWebQueue.CItem + { + SongId = i.SongId, + GameMode = (EGameMode)i.GameMode, + AudioMode = (EAudioMode)i.AudioMode, + RequestedBy = i.RequestedBy, + PlayerIds = i.PlayerIds, + PlayerNames = i.PlayerNames + }).ToList(); +#else + return null; +#endif + } + + /// The queue entry at this position was started from the queue screen: it leaves the queue. + public static void MarkQueueEntryStarted(int index) + { +#if WIN + if (_Host != null) + { + _Host.MarkQueueEntryStarted(index); + return; + } +#endif + CWebQueue.Remove(index); + } + + /// Increases whenever a playlist was changed by the webserver or the queue screen, so open views can reload it. + public static int PlaylistVersion { get; private set; } + + public static void NotifyPlaylistChanged() + { + PlaylistVersion++; + } + + /// Photos taken with the WebApp since the last call (shown as slideshow on the score screen). + public static string[] GetPhotosOfThisRound() + { + lock (_PhotosOfThisRound) + { + var result = _PhotosOfThisRound.ToArray(); + _PhotosOfThisRound.Clear(); + return result; + } + } + } +} diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs index 6b7fe26f..d4acaa79 100644 --- a/Vocaluxe/Lib/Draw/CDrawBase.cs +++ b/Vocaluxe/Lib/Draw/CDrawBase.cs @@ -19,7 +19,7 @@ using System; using System.Diagnostics; using System.Threading; using Vocaluxe.Base; -using Vocaluxe.Base.Server; +using Vocaluxe.Base.Web; using VocaluxeLib; using VocaluxeLib.Draw; @@ -451,7 +451,7 @@ namespace Vocaluxe.Lib.Draw while (_Run) { _CheckQueue(); - CVocaluxeServer.ProcessServerTasks(); + CWebServer.ProcessTasks(); //We want to begin drawing _OnBeforeDraw(); diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs index 301f26a9..a8180d5f 100644 --- a/Vocaluxe/Program.cs +++ b/Vocaluxe/Program.cs @@ -27,7 +27,7 @@ using System.Windows.Forms; using SQLitePCL; using Vocaluxe.Base; using Vocaluxe.Base.Fonts; -using Vocaluxe.Base.Server; +using Vocaluxe.Base.Web; using Vocaluxe.Base.ThemeSystem; using Vocaluxe.Reporting; using VocaluxeLib.Log; @@ -284,7 +284,7 @@ namespace Vocaluxe // Init Server using (CBenchmark.Time("Init Server")) { - CVocaluxeServer.Init(); + CWebServer.Init(); } Application.DoEvents(); @@ -360,11 +360,11 @@ namespace Vocaluxe try { - CVocaluxeServer.Close(); + CWebServer.Close(); } catch (Exception e) { - CLog.Error(e, "Error during shutdown! (CVocaluxeServer)"); + CLog.Error(e, "Error during shutdown! (CWebServer)"); } try diff --git a/Vocaluxe/Screens/CPopupScreenServerQR.cs b/Vocaluxe/Screens/CPopupScreenServerQR.cs index 9b6aff30..7bc1da1b 100644 --- a/Vocaluxe/Screens/CPopupScreenServerQR.cs +++ b/Vocaluxe/Screens/CPopupScreenServerQR.cs @@ -18,7 +18,7 @@ using System.Windows.Forms; using QRCoder; using Vocaluxe.Base; -using Vocaluxe.Base.Server; +using Vocaluxe.Base.Web; using VocaluxeLib; using VocaluxeLib.Draw; using VocaluxeLib.Menu; @@ -34,6 +34,7 @@ namespace Vocaluxe.Screens } private CTextureRef _QRServerAddress; + private string _QRAddress; private const string _StaticQRServer = "StaticQRServer"; private const string _TextServerAddress = "TextServerAddress"; @@ -50,16 +51,16 @@ namespace Vocaluxe.Screens public override void OnShow() { base.OnShow(); - if (_QRServerAddress == null) + if (_QRServerAddress == null || _QRAddress != CWebServer.GetServerAddress()) { _GenerateQRs(); _Statics[_StaticQRServer].Texture = _QRServerAddress; - _Texts[_TextServerAddress].Text = CVocaluxeServer.GetServerAddress(); + _Texts[_TextServerAddress].Text = CWebServer.GetServerAddress(); } - _Texts[_TextServerAddress].Visible = CVocaluxeServer.IsServerRunning(); - _Statics[_StaticQRServer].Visible = CVocaluxeServer.IsServerRunning(); - _Texts[_TextServerNotRunning].Visible = !CVocaluxeServer.IsServerRunning(); + _Texts[_TextServerAddress].Visible = CWebServer.IsServerRunning(); + _Statics[_StaticQRServer].Visible = CWebServer.IsServerRunning(); + _Texts[_TextServerNotRunning].Visible = !CWebServer.IsServerRunning(); } public override bool HandleMouse(SMouseEvent mouseEvent) @@ -96,7 +97,9 @@ namespace Vocaluxe.Screens var qr = new QRCodeGenerator(); //ServerAddress - var qrcode = qr.CreateQrCode(CVocaluxeServer.GetServerAddress(), QRCodeGenerator.ECCLevel.H); + CDraw.RemoveTexture(ref _QRServerAddress); + _QRAddress = CWebServer.GetServerAddress(); + var qrcode = qr.CreateQrCode(_QRAddress, QRCodeGenerator.ECCLevel.H); _QRServerAddress = CDraw.AddTexture(qrcode.GetGraphic(20)); } } diff --git a/Vocaluxe/Screens/CScreenHighscore.cs b/Vocaluxe/Screens/CScreenHighscore.cs index 0f9109d8..aa312a99 100644 --- a/Vocaluxe/Screens/CScreenHighscore.cs +++ b/Vocaluxe/Screens/CScreenHighscore.cs @@ -21,6 +21,7 @@ using System.Diagnostics; using System.Linq; using System.Windows.Forms; using Vocaluxe.Base; +using Vocaluxe.Base.Web; using VocaluxeLib; using VocaluxeLib.Draw; using VocaluxeLib.Menu; @@ -510,7 +511,7 @@ namespace Vocaluxe.Screens _HighscoreStream = -1; } - if (!CJukebox.ReturnAfterSinging()) + if (!CJukebox.ReturnAfterSinging() && !CWebQueue.ReturnAfterSinging()) { CParty.LeavingHighscore(); } diff --git a/Vocaluxe/Screens/CScreenNames.cs b/Vocaluxe/Screens/CScreenNames.cs index d2f7aa9a..d67bb5d0 100644 --- a/Vocaluxe/Screens/CScreenNames.cs +++ b/Vocaluxe/Screens/CScreenNames.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Windows.Forms; using Vocaluxe.Base; +using Vocaluxe.Base.Web; using VocaluxeLib; using VocaluxeLib.Draw; using VocaluxeLib.Menu; @@ -954,7 +955,7 @@ namespace Vocaluxe.Screens private static void _FadeBack() { - if (!CJukebox.ReturnAfterSinging()) + if (!CJukebox.ReturnAfterSinging() && !CWebQueue.ReturnAfterSinging()) { CGraphics.FadeTo(EScreen.Song); } diff --git a/Vocaluxe/Screens/CScreenScore.cs b/Vocaluxe/Screens/CScreenScore.cs index 82b12ad8..41fcad1a 100644 --- a/Vocaluxe/Screens/CScreenScore.cs +++ b/Vocaluxe/Screens/CScreenScore.cs @@ -21,7 +21,7 @@ using System.Diagnostics; using System.Linq; using System.Windows.Forms; using Vocaluxe.Base; -using Vocaluxe.Base.Server; +using Vocaluxe.Base.Web; using VocaluxeLib; using VocaluxeLib.Game; using VocaluxeLib.Menu; @@ -205,6 +205,12 @@ namespace Vocaluxe.Screens _SetVisibility(); _UpdateRatings(); _SlideShowBG.Visible = _UpdateBackground(); + + var lastSong = CGame.GetSong(CGame.NumRounds - 1); + if (lastSong != null) + { + CBackgroundMusic.LoadPreview(lastSong); + } } public override void OnClose() @@ -749,7 +755,7 @@ namespace Vocaluxe.Screens private bool _UpdateBackground() { - var photos = CVocaluxeServer.GetPhotosOfThisRound(); + var photos = CWebServer.GetPhotosOfThisRound(); _SlideShowBG.RemoveSlideShowTextures(); foreach (var photo in photos) { @@ -765,7 +771,7 @@ namespace Vocaluxe.Screens if (_IsKaraokeMode(-1)) { - if (!CJukebox.ReturnAfterSinging()) + if (!CJukebox.ReturnAfterSinging() && !CWebQueue.ReturnAfterSinging()) { CGraphics.FadeTo(EScreen.Song); } diff --git a/Vocaluxe/Screens/CScreenSong.cs b/Vocaluxe/Screens/CScreenSong.cs index d803608b..61f1a01a 100644 --- a/Vocaluxe/Screens/CScreenSong.cs +++ b/Vocaluxe/Screens/CScreenSong.cs @@ -21,6 +21,7 @@ using System.Linq; using System.Timers; using System.Windows.Forms; using Vocaluxe.Base; +using Vocaluxe.Base.Web; using VocaluxeLib; using VocaluxeLib.Menu; using VocaluxeLib.Menu.SongMenu; @@ -42,7 +43,7 @@ namespace Vocaluxe.Screens // Version number for theme files. Increment it, if you've changed something on the theme files! protected override int _ScreenVersion { - get { return 16; } + get { return 17; } } private const string _TextCategory = "TextCategory"; @@ -86,6 +87,7 @@ namespace Vocaluxe.Screens private const string _ButtonOptionsSingAllVisible = "ButtonOptionsSingAllVisible"; private const string _ButtonOptionsOpenSelectedItem = "ButtonOptionsOpenSelectedItem"; private const string _ButtonOptionsRandomMedley = "ButtonOptionsRandomMedley"; + private const string _ButtonOptionsWebQueue = "ButtonOptionsWebQueue"; private const string _ButtonOptionsStartMedley = "ButtonOptionsStartMedley"; private const string _ButtonStart = "ButtonStart"; private const string _ButtonOptionsHighscore = "ButtonOptionsHighscore"; @@ -161,6 +163,7 @@ namespace Vocaluxe.Screens private ISongMenu _SongMenu; private CPlaylist _Playlist; + private int _PlaylistVersion; private System.Timers.Timer _TimerShortInfoText; @@ -235,6 +238,7 @@ namespace Vocaluxe.Screens blist.Add(_ButtonOpenOptions); blist.Add(_ButtonStart); blist.Add(_ButtonOptionsRandomMedley); + blist.Add(_ButtonOptionsWebQueue); blist.Add(_ButtonOptionsStartMedley); blist.Add(_ButtonOptionsHighscore); @@ -658,6 +662,11 @@ namespace Vocaluxe.Screens { _ToggleSongOptions(ESongOptionsView.Medley); } + else if (_Buttons[_ButtonOptionsWebQueue].Selected) + { + _ToggleSongOptions(ESongOptionsView.None); + CGraphics.FadeTo(EScreen.WebQueue); + } else if (_Buttons[_ButtonOptionsStartMedley].Selected) { _ToggleSongOptions(ESongOptionsView.None); @@ -878,6 +887,12 @@ namespace Vocaluxe.Screens _ToggleSongOptions(ESongOptionsView.Medley); return true; } + else if (_Buttons[_ButtonOptionsWebQueue].Selected) + { + _ToggleSongOptions(ESongOptionsView.None); + CGraphics.FadeTo(EScreen.WebQueue); + return true; + } else if (_Buttons[_ButtonOptionsStartMedley].Selected) { _ToggleSongOptions(ESongOptionsView.None); @@ -1053,6 +1068,15 @@ namespace Vocaluxe.Screens CSongs.OnCategoryChanged += _OnCategoryChanged; } + private void _UpdatePlaylistIfChanged() + { + if (_PlaylistVersion != CWebServer.PlaylistVersion) + { + _PlaylistVersion = CWebServer.PlaylistVersion; + _Playlist.UpdatePlaylist(); + } + } + private static void _OnCategoryChanged() { CSound.SetGlobalVolume(CSongs.IsInCategory ? CConfig.PreviewMusicVolume : CConfig.BackgroundMusicVolume); @@ -1068,6 +1092,7 @@ namespace Vocaluxe.Screens } else { + _UpdatePlaylistIfChanged(); _Playlist.UpdateGame(); } } @@ -1867,6 +1892,7 @@ namespace Vocaluxe.Screens _Buttons[_ButtonOptionsSingAllVisible].Visible = false; _Buttons[_ButtonOptionsOpenSelectedItem].Visible = false; _Buttons[_ButtonOptionsRandomMedley].Visible = false; + _Buttons[_ButtonOptionsWebQueue].Visible = false; _Buttons[_ButtonOptionsStartMedley].Visible = false; _Buttons[_ButtonOptionsHighscore].Visible = false; _Texts[_TextOptionsTitle].Visible = false; @@ -1956,7 +1982,7 @@ namespace Vocaluxe.Screens }, new[] { _TextOptionsPlayerSelect, _TextOptionsPlaylist }, new[] { _SelectSlideOptionsPlayerSelect, _SelectSlideOptionsPlaylistAdd }, - new[] { _ButtonOptionsPlaylist, _ButtonOptionsHighscore, _ButtonOptionsClose }); + new[] { _ButtonOptionsPlaylist, _ButtonOptionsWebQueue, _ButtonOptionsHighscore, _ButtonOptionsClose }); } private void _SetGeneralOptionsOffsetY(float singAllOffset, float medleyOffset) @@ -2060,6 +2086,7 @@ namespace Vocaluxe.Screens _SelectSlides[_SelectSlideOptionsPlaylistAdd].Visible = true; _Buttons[_ButtonOptionsSing].Visible = true; _Buttons[_ButtonOptionsPlaylist].Visible = true; + _Buttons[_ButtonOptionsWebQueue].Visible = !_Sso.Selection.PartyMode; _Buttons[_ButtonOptionsHighscore].Visible = true; _Texts[_TextOptionsTitle].Visible = false; diff --git a/Vocaluxe/Screens/CScreenWebQueue.cs b/Vocaluxe/Screens/CScreenWebQueue.cs new file mode 100644 index 00000000..275d5dbd --- /dev/null +++ b/Vocaluxe/Screens/CScreenWebQueue.cs @@ -0,0 +1,418 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Windows.Forms; +using Vocaluxe.Base; +using Vocaluxe.Base.Web; +using VocaluxeLib; +using VocaluxeLib.Menu; + +namespace Vocaluxe.Screens +{ + /// The WebApp queue: songs added with the WebApp, shown with the next song, requester and singers. + /// Only the next song can be started (the order is managed in the WebApp); its game mode, audio mode and singers can still be changed. + /// Opened from the general options of the song screen. + public class CScreenWebQueue : CMenu + { + protected override int _ScreenVersion + { + get { return 1; } + } + + private const int _NumRows = 8; + private const long _RefreshIntervalMs = 500; + + private const string _TextInfo = "TextInfo"; + private const string _TextWarning = "TextWarning"; + private const string _TextNextLabel = "TextNextLabel"; + private const string _TextNextSong = "TextNextSong"; + private const string _TextNextDetails = "TextNextDetails"; + private const string _TextNextPlayers = "TextNextPlayers"; + private const string _TextEmpty = "TextEmpty"; + private const string _TextEmpty2 = "TextEmpty2"; + private const string _TextMore = "TextMore"; + private const string _TextMode = "TextMode"; + private const string _TextAudio = "TextAudio"; + + private const string _StaticWarning = "StaticWarning"; + private const string _StaticNextCover = "StaticNextCover"; + private const string _StaticNextPanel = "StaticNextPanel"; + + private const string _SelectSlideMode = "SelectSlideMode"; + private const string _SelectSlideAudio = "SelectSlideAudio"; + + private const string _ButtonBack = "ButtonBack"; + private const string _ButtonServer = "ButtonServer"; + private const string _ButtonPlayers = "ButtonPlayers"; + private const string _ButtonStart = "ButtonStart"; + private const string _ButtonEntryPrefix = "ButtonEntry"; + + private readonly Stopwatch _RefreshTimer = new Stopwatch(); + private IList _Items = new List(); + private int _Offset; + private string _SlidesFor = ""; + private int _PlaylistVersion = -1; + private int _WarningStream = -1; + private bool _HasPlayedWarningSound; + + public override void Init() + { + base.Init(); + + _ThemeTexts = new string[] + { + _TextInfo, _TextWarning, _TextNextLabel, _TextNextSong, _TextNextDetails, _TextNextPlayers, _TextEmpty, _TextEmpty2, _TextMore, _TextMode, _TextAudio + }; + _ThemeStatics = new string[] { _StaticWarning, _StaticNextCover, _StaticNextPanel }; + _ThemeSelectSlides = new string[] { _SelectSlideMode, _SelectSlideAudio }; + _ThemeButtons = new[] { _ButtonBack, _ButtonServer, _ButtonPlayers, _ButtonStart } + .Concat(Enumerable.Range(1, _NumRows).Select(i => _ButtonEntryPrefix + i)).ToArray(); + } + + public override void LoadTheme(string xmlPath) + { + base.LoadTheme(xmlPath); + + //The list only shows the order, the entries can't be selected + for (var row = 1; row <= _NumRows; row++) + { + _Buttons[_ButtonEntryPrefix + row].Selectable = false; + } + } + + public override void OnShow() + { + base.OnShow(); + _HasPlayedWarningSound = false; + _Offset = 0; + _SlidesFor = ""; + _Refresh(); + _SelectElement(_Items.Count > 0 ? _Buttons[_ButtonStart] : _Buttons[_ButtonBack]); + _RefreshTimer.Restart(); + } + + public override void OnClose() + { + base.OnClose(); + if (_WarningStream != -1) + { + CSound.Close(_WarningStream); + _WarningStream = -1; + } + } + + public override bool HandleInput(SKeyEvent keyEvent) + { + base.HandleInput(keyEvent); + + if (keyEvent.KeyPressed) + { + return true; + } + + switch (keyEvent.Key) + { + case Keys.Escape: + case Keys.Back: + CGraphics.FadeTo(EScreen.Song); + break; + + case Keys.Enter: + _HandleEnter(); + break; + + case Keys.PageDown: + _Scroll(_NumRows); + break; + + case Keys.PageUp: + _Scroll(-_NumRows); + break; + + case Keys.Left: + case Keys.Right: + _ReadModes(); + break; + } + + return true; + } + + public override bool HandleMouse(SMouseEvent mouseEvent) + { + base.HandleMouse(mouseEvent); + + if (mouseEvent.Wheel != 0) + { + _Scroll(Math.Sign(mouseEvent.Wheel)); + } + + if (mouseEvent.LB && _IsMouseOverCurSelection(mouseEvent)) + { + if (_SelectSlides[_SelectSlideMode].Selected || _SelectSlides[_SelectSlideAudio].Selected) + { + _ReadModes(); + } + else + { + _HandleEnter(); + } + } + else if (mouseEvent.RB) + { + CGraphics.FadeTo(EScreen.Song); + } + + return true; + } + + public override bool UpdateGame() + { + if (_PlaylistVersion != CWebServer.PlaylistVersion || _RefreshTimer.ElapsedMilliseconds > _RefreshIntervalMs) + { + _Refresh(); + _RefreshTimer.Restart(); + } + + return true; + } + + private void _HandleEnter() + { + if (_Buttons[_ButtonBack].Selected) + { + CGraphics.FadeTo(EScreen.Song); + } + else if (_Buttons[_ButtonServer].Selected) + { + CGraphics.ShowPopup(EPopupScreens.PopupServerQR); + } + else if (_Buttons[_ButtonStart].Selected) + { + _Start(false); + } + else if (_Buttons[_ButtonPlayers].Selected) + { + _Start(true); + } + } + + /// Starts the next song. Directly singing removes it from the queue right away; + /// with the player selection it stays until singing really starts (the selection can be cancelled). + private void _Start(bool showPlayerSelection) + { + if (_Items.Count == 0) + { + return; + } + + var item = _Items[0]; + if (CWebQueue.Start(item.SongId, item.GameMode, item.AudioMode, item.PlayerIds, showPlayerSelection, out var singsNow) && singsNow) + { + CWebServer.MarkQueueEntryStarted(0); + } + } + + private void _Scroll(int rows) + { + var offset = Math.Max(0, Math.Min(_Items.Count - 1 - _NumRows, _Offset + rows)); + if (offset != _Offset) + { + _Offset = offset; + _Refresh(); + } + } + + private void _ReadModes() + { + if (_Items.Count == 0) + { + return; + } + + var item = _Items[0]; + var gameMode = _SelectSlides[_SelectSlideMode].Visible ? (EGameMode)_SelectSlides[_SelectSlideMode].SelectedTag : item.GameMode; + var audioMode = _SelectSlides[_SelectSlideAudio].Visible ? (EAudioMode)_SelectSlides[_SelectSlideAudio].SelectedTag : item.AudioMode; + if (gameMode != item.GameMode || audioMode != item.AudioMode) + { + CWebQueue.SetModes(0, gameMode, audioMode); + _Refresh(); + } + } + + private void _Refresh() + { + _PlaylistVersion = CWebServer.PlaylistVersion; + _Items = CWebQueue.GetItems(); + _Offset = Math.Max(0, Math.Min(_Offset, _Items.Count - 1 - _NumRows)); + + var serverRunning = CWebServer.IsServerRunning(); + _Statics[_StaticWarning].Visible = !serverRunning; + _Texts[_TextWarning].Visible = !serverRunning; + _Texts[_TextInfo].Visible = serverRunning; + if (!serverRunning && !_HasPlayedWarningSound) + { + _WarningStream = CSound.PlaySound(ESounds.Warning, false); + CSound.SetStreamVolume(_WarningStream, CConfig.SoundEffectVolume); + _HasPlayedWarningSound = true; + } + + _UpdateNext(); + _UpdateRows(); + _UpdateSlides(); + + var hasItems = _Items.Count > 0; + _Texts[_TextEmpty].Visible = !hasItems; + _Texts[_TextEmpty2].Visible = !hasItems; + _Buttons[_ButtonStart].Visible = hasItems; + _Buttons[_ButtonPlayers].Visible = hasItems; + if (!hasItems && (_Buttons[_ButtonStart].Selected || _Buttons[_ButtonPlayers].Selected || _SelectSlides[_SelectSlideMode].Selected || + _SelectSlides[_SelectSlideAudio].Selected)) + { + _SelectElement(_Buttons[_ButtonBack]); + } + } + + private void _UpdateNext() + { + var visible = _Items.Count > 0; + foreach (var text in new[] { _TextNextLabel, _TextNextSong, _TextNextDetails, _TextNextPlayers }) + { + _Texts[text].Visible = visible; + } + + _Statics[_StaticNextCover].Visible = visible; + _Statics[_StaticNextPanel].Visible = visible; + if (!visible) + { + return; + } + + var item = _Items[0]; + var song = CSongs.GetSong(item.SongId); + _Statics[_StaticNextCover].Texture = song?.CoverTextureBig ?? CCover.NoCover; + _Texts[_TextNextSong].Text = song == null ? "?" : song.Artist + " - " + song.Title; + _Texts[_TextNextDetails].Text = _GetDetails(item); + _Texts[_TextNextPlayers].Text = _GetPlayers(item); + } + + /// The songs after the next one. + private void _UpdateRows() + { + for (var row = 1; row <= _NumRows; row++) + { + var index = 1 + _Offset + row - 1; + var button = _Buttons[_ButtonEntryPrefix + row]; + button.Visible = index < _Items.Count; + if (!button.Visible) + { + continue; + } + + var item = _Items[index]; + var song = CSongs.GetSong(item.SongId); + var title = song == null ? "?" : song.Artist + " - " + song.Title; + var requester = string.IsNullOrEmpty(item.RequestedBy) ? "" : " (" + item.RequestedBy + ")"; + button.Text.Text = (index + 1) + ". " + title + requester; + } + + var more = _Items.Count - 1 - _Offset - _NumRows; + _Texts[_TextMore].Visible = more > 0; + _Texts[_TextMore].Text = CLanguage.Translate("TR_SCREENWEBQUEUE_MORE").Replace("%d", more.ToString()); + } + + /// Game mode and audio mode of the next song; only modes the song supports. + private void _UpdateSlides() + { + var item = _Items.Count > 0 ? _Items[0] : null; + var song = item == null ? null : CSongs.GetSong(item.SongId); + var key = song == null ? null : item.SongId + ":" + item.GameMode + ":" + item.AudioMode; + if (key == _SlidesFor) + { + return; + } + + _SlidesFor = key; + var modes = song?.AvailableGameModes ?? new List(); + _SelectSlides[_SelectSlideMode].Clear(); + foreach (var mode in modes) + { + _SelectSlides[_SelectSlideMode].AddValue(mode.ToString(), null, (int)mode); + } + + _SelectSlides[_SelectSlideMode].Visible = modes.Count > 1; + _Texts[_TextMode].Visible = modes.Count > 1; + if (item != null && modes.Contains(item.GameMode)) + { + _SelectSlides[_SelectSlideMode].SelectedTag = (int)item.GameMode; + } + + var audioModes = new List(); + if (song != null && song.HasInstrumental()) + { + audioModes.Add(EAudioMode.TR_AUDIOMODE_NORMAL); + audioModes.Add(EAudioMode.TR_AUDIOMODE_INSTRUMENTAL); + if (song.HasVocals()) + { + audioModes.Add(EAudioMode.TR_AUDIOMODE_VOCALS); + } + + audioModes.Add(EAudioMode.TR_AUDIOMODE_KARAOKE); + } + + _SelectSlides[_SelectSlideAudio].Clear(); + foreach (var mode in audioModes) + { + _SelectSlides[_SelectSlideAudio].AddValue(mode.ToString(), null, (int)mode); + } + + _SelectSlides[_SelectSlideAudio].Visible = audioModes.Count > 1; + _Texts[_TextAudio].Visible = audioModes.Count > 1; + if (item != null && audioModes.Contains(item.AudioMode)) + { + _SelectSlides[_SelectSlideAudio].SelectedTag = (int)item.AudioMode; + } + } + + private static string _GetDetails(CWebQueue.CItem item) + { + var parts = new List { CLanguage.Translate(item.GameMode.ToString()) }; + if (item.AudioMode != EAudioMode.TR_AUDIOMODE_NORMAL) + { + parts.Add(CLanguage.Translate(item.AudioMode.ToString())); + } + + if (!string.IsNullOrEmpty(item.RequestedBy)) + { + parts.Add(CLanguage.Translate("TR_SCREENWEBQUEUE_ADDEDBY").Replace("%s", item.RequestedBy)); + } + + return string.Join(" · ", parts); + } + + private static string _GetPlayers(CWebQueue.CItem item) + { + return item.PlayerNames.Count > 0 + ? CLanguage.Translate("TR_SCREENWEBQUEUE_SINGERS").Replace("%s", string.Join(", ", item.PlayerNames)) + : CLanguage.Translate("TR_SCREENWEBQUEUE_NOSINGERS"); + } + } +} diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index dd64b1dd..bd5b9f0a 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -178,8 +178,6 @@ - - @@ -208,13 +206,6 @@ - - - - - - - @@ -272,8 +263,6 @@ - - Form @@ -350,6 +339,7 @@ + @@ -361,151 +351,19 @@ + + + + Designer - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - images - - - PreserveNewest - - - PreserveNewest - images - - - PreserveNewest - images - - - PreserveNewest - images - - - PreserveNewest - images - - - css - PreserveNewest - - - css - PreserveNewest - - - css - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - img - - - PreserveNewest - img - - - PreserveNewest - img - - - PreserveNewest - img - - - PreserveNewest - img - - - PreserveNewest - - - PreserveNewest - js - - - PreserveNewest - - - js - PreserveNewest - - - PreserveNewest - - - js - PreserveNewest - @@ -524,12 +382,10 @@ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} VocaluxeLib - - - - - - + + {4E2C9A71-6B3D-4F85-9C1E-8A7D5B2F3C60} + VocaluxeWeb + @@ -538,10 +394,8 @@ - xcopy /E /D /Y "$(ProjectDir)\Website" "$(SolutionDir)\PhoneGap" -powershell -ExecutionPolicy Bypass -Command "& '$(SolutionDir)\.build\winPostBuild.ps1' -ProjectDir '$(ProjectDir)'" - cp -ruT "$(ProjectDir)Website" "$(SolutionDir)/PhoneGap" -$(SolutionDir)/.build/linuxPostBuildEvent.sh $(ProjectDir) + powershell -ExecutionPolicy Bypass -Command "& '$(SolutionDir)\.build\winPostBuild.ps1' -ProjectDir '$(ProjectDir)'" + $(SolutionDir)/.build/linuxPostBuildEvent.sh $(ProjectDir) powershell -ExecutionPolicy Bypass -Command "& '$(SolutionDir)\.build\winPreBuild.ps1' -ProjectDir '$(ProjectDir)' -Arch '$(Platform)'" @@ -568,11 +422,23 @@ $(SolutionDir)/.build/linuxPostBuildEvent.sh $(ProjectDir) PostBuildMacros; + + + + + + + + + + + + diff --git a/Vocaluxe/Website/css/images/ajax-loader.gif b/Vocaluxe/Website/css/images/ajax-loader.gif deleted file mode 100644 index fd1a189c..00000000 Binary files a/Vocaluxe/Website/css/images/ajax-loader.gif and /dev/null differ diff --git a/Vocaluxe/Website/css/images/alert.png b/Vocaluxe/Website/css/images/alert.png deleted file mode 100644 index dd0e2afc..00000000 Binary files a/Vocaluxe/Website/css/images/alert.png and /dev/null differ diff --git a/Vocaluxe/Website/css/images/icons-18-black.png b/Vocaluxe/Website/css/images/icons-18-black.png deleted file mode 100644 index 79164638..00000000 Binary files a/Vocaluxe/Website/css/images/icons-18-black.png and /dev/null differ diff --git a/Vocaluxe/Website/css/images/icons-18-white.png b/Vocaluxe/Website/css/images/icons-18-white.png deleted file mode 100644 index 3419b81f..00000000 Binary files a/Vocaluxe/Website/css/images/icons-18-white.png and /dev/null differ diff --git a/Vocaluxe/Website/css/images/icons-36-black.png b/Vocaluxe/Website/css/images/icons-36-black.png deleted file mode 100644 index 043bfcd5..00000000 Binary files a/Vocaluxe/Website/css/images/icons-36-black.png and /dev/null differ diff --git a/Vocaluxe/Website/css/images/icons-36-white.png b/Vocaluxe/Website/css/images/icons-36-white.png deleted file mode 100644 index 12455c90..00000000 Binary files a/Vocaluxe/Website/css/images/icons-36-white.png and /dev/null differ diff --git a/Vocaluxe/Website/css/jquery.mobile-1.3.2.min.css b/Vocaluxe/Website/css/jquery.mobile-1.3.2.min.css deleted file mode 100644 index 0975cbc5..00000000 --- a/Vocaluxe/Website/css/jquery.mobile-1.3.2.min.css +++ /dev/null @@ -1,12 +0,0 @@ -/*! jQuery Mobile 1.3.2 | Git HEAD hash: 528cf0e <> 2013-07-19T22:17:57Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */ - -/*! -* jQuery Mobile 1.3.2 -* Git HEAD hash: 528cf0e96940644ea644096bfeb913ed920ffaef <> Date: Fri Jul 19 2013 22:17:57 UTC -* http://jquerymobile.com -* -* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors -* Released under the MIT license. -* http://jquery.org/license -* -*/.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:700;text-shadow:0 -1px 0 #000;background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#111));background-image:-webkit-linear-gradient(#3c3c3c,#111);background-image:-moz-linear-gradient(#3c3c3c,#111);background-image:-ms-linear-gradient(#3c3c3c,#111);background-image:-o-linear-gradient(#3c3c3c,#111);background-image:linear-gradient(#3c3c3c,#111)}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-a a.ui-link:visited{color:#2489ce}.ui-bar-a a.ui-link:hover{color:#2489ce}.ui-bar-a a.ui-link:active{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 0 #111;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#222));background-image:-webkit-linear-gradient(#444,#222);background-image:-moz-linear-gradient(#444,#222);background-image:-ms-linear-gradient(#444,#222);background-image:-o-linear-gradient(#444,#222);background-image:linear-gradient(#444,#222)}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:700}.ui-body-a .ui-link:visited{color:#2489ce}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#2d2d2d));background-image:-webkit-linear-gradient(#444,#2d2d2d);background-image:-moz-linear-gradient(#444,#2d2d2d);background-image:-ms-linear-gradient(#444,#2d2d2d);background-image:-o-linear-gradient(#444,#2d2d2d);background-image:linear-gradient(#444,#2d2d2d)}.ui-btn-up-a:visited,.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#555),to(#383838));background-image:-webkit-linear-gradient(#555,#383838);background-image:-moz-linear-gradient(#555,#383838);background-image:-ms-linear-gradient(#555,#383838);background-image:-o-linear-gradient(#555,#383838);background-image:linear-gradient(#555,#383838)}.ui-btn-hover-a:visited,.ui-btn-hover-a:hover,.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#202020),to(#2c2c2c));background-image:-webkit-linear-gradient(#202020,#2c2c2c);background-image:-moz-linear-gradient(#202020,#2c2c2c);background-image:-ms-linear-gradient(#202020,#2c2c2c);background-image:-o-linear-gradient(#202020,#2c2c2c);background-image:linear-gradient(#202020,#2c2c2c)}.ui-btn-down-a:visited,.ui-btn-down-a:hover,.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:700;text-shadow:0 1px 0 #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#497bae));background-image:-webkit-linear-gradient(#6facd5,#497bae);background-image:-moz-linear-gradient(#6facd5,#497bae);background-image:-ms-linear-gradient(#6facd5,#497bae);background-image:-o-linear-gradient(#6facd5,#497bae);background-image:linear-gradient(#6facd5,#497bae)}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b a.ui-link{color:#ddf0f8;font-weight:700}.ui-bar-b a.ui-link:visited{color:#ddf0f8}.ui-bar-b a.ui-link:hover{color:#ddf0f8}.ui-bar-b a.ui-link:active{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#ccc));background-image:-webkit-linear-gradient(#ddd,#ccc);background-image:-moz-linear-gradient(#ddd,#ccc);background-image:-ms-linear-gradient(#ddd,#ccc);background-image:-o-linear-gradient(#ddd,#ccc);background-image:linear-gradient(#ddd,#ccc)}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:700}.ui-body-b .ui-link:visited{color:#2489ce}.ui-body-b .ui-link:hover{color:#2489ce}.ui-body-b .ui-link:active{color:#2489ce}.ui-btn-up-b{border:1px solid #044062;background:#396b9e;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#5f9cc5),to(#396b9e));background-image:-webkit-linear-gradient(#5f9cc5,#396b9e);background-image:-moz-linear-gradient(#5f9cc5,#396b9e);background-image:-ms-linear-gradient(#5f9cc5,#396b9e);background-image:-o-linear-gradient(#5f9cc5,#396b9e);background-image:linear-gradient(#5f9cc5,#396b9e)}.ui-btn-up-b:visited,.ui-btn-up-b a.ui-link-inherit{color:#fff}.ui-btn-hover-b{border:1px solid #00415e;background:#4b88b6;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#4272a4));background-image:-webkit-linear-gradient(#6facd5,#4272a4);background-image:-moz-linear-gradient(#6facd5,#4272a4);background-image:-ms-linear-gradient(#6facd5,#4272a4);background-image:-o-linear-gradient(#6facd5,#4272a4);background-image:linear-gradient(#6facd5,#4272a4)}.ui-btn-hover-b:visited,.ui-btn-hover-b:hover,.ui-btn-hover-b a.ui-link-inherit{color:#fff}.ui-btn-down-b{border:1px solid #225377;background:#4e89c5;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#295b8e),to(#3e79b5));background-image:-webkit-linear-gradient(#295b8e,#3e79b5);background-image:-moz-linear-gradient(#295b8e,#3e79b5);background-image:-ms-linear-gradient(#295b8e,#3e79b5);background-image:-o-linear-gradient(#295b8e,#3e79b5);background-image:linear-gradient(#295b8e,#3e79b5)}.ui-btn-down-b:visited,.ui-btn-down-b:hover,.ui-btn-down-b a.ui-link-inherit{color:#fff}.ui-btn-up-b,.ui-btn-hover-b,.ui-btn-down-b{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-c{border:1px solid #b3b3b3;background:#eee;color:#3e3e3e;font-weight:700;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#ddd));background-image:-webkit-linear-gradient(#f0f0f0,#ddd);background-image:-moz-linear-gradient(#f0f0f0,#ddd);background-image:-ms-linear-gradient(#f0f0f0,#ddd);background-image:-o-linear-gradient(#f0f0f0,#ddd);background-image:linear-gradient(#f0f0f0,#ddd)}.ui-bar-c .ui-link-inherit{color:#3e3e3e}.ui-bar-c a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-c a.ui-link:visited{color:#2489ce}.ui-bar-c a.ui-link:hover{color:#2489ce}.ui-bar-c a.ui-link:active{color:#2489ce}.ui-bar-c,.ui-bar-c input,.ui-bar-c select,.ui-bar-c textarea,.ui-bar-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c,.ui-overlay-c{border:1px solid #aaa;color:#333;text-shadow:0 1px 0 #fff;background:#f9f9f9;background-image:-webkit-gradient(linear,left top,left bottom,from(#f9f9f9),to(#eee));background-image:-webkit-linear-gradient(#f9f9f9,#eee);background-image:-moz-linear-gradient(#f9f9f9,#eee);background-image:-ms-linear-gradient(#f9f9f9,#eee);background-image:-o-linear-gradient(#f9f9f9,#eee);background-image:linear-gradient(#f9f9f9,#eee)}.ui-overlay-c{background-image:none;border-width:0}.ui-body-c,.ui-body-c input,.ui-body-c select,.ui-body-c textarea,.ui-body-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c .ui-link-inherit{color:#333}.ui-body-c .ui-link{color:#2489ce;font-weight:700}.ui-body-c .ui-link:visited{color:#2489ce}.ui-body-c .ui-link:hover{color:#2489ce}.ui-body-c .ui-link:active{color:#2489ce}.ui-btn-up-c{border:1px solid #ccc;background:#eee;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f1f1f1));background-image:-webkit-linear-gradient(#fff,#f1f1f1);background-image:-moz-linear-gradient(#fff,#f1f1f1);background-image:-ms-linear-gradient(#fff,#f1f1f1);background-image:-o-linear-gradient(#fff,#f1f1f1);background-image:linear-gradient(#fff,#f1f1f1)}.ui-btn-up-c:visited,.ui-btn-up-c a.ui-link-inherit{color:#2f3e46}.ui-btn-hover-c{border:1px solid #bbb;background:#dfdfdf;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f6f6f6),to(#e0e0e0));background-image:-webkit-linear-gradient(#f6f6f6,#e0e0e0);background-image:-moz-linear-gradient(#f6f6f6,#e0e0e0);background-image:-ms-linear-gradient(#f6f6f6,#e0e0e0);background-image:-o-linear-gradient(#f6f6f6,#e0e0e0);background-image:linear-gradient(#f6f6f6,#e0e0e0)}.ui-btn-hover-c:visited,.ui-btn-hover-c:hover,.ui-btn-hover-c a.ui-link-inherit{color:#2f3e46}.ui-btn-down-c{border:1px solid #bbb;background:#d6d6d6;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#d0d0d0),to(#dfdfdf));background-image:-webkit-linear-gradient(#d0d0d0,#dfdfdf);background-image:-moz-linear-gradient(#d0d0d0,#dfdfdf);background-image:-ms-linear-gradient(#d0d0d0,#dfdfdf);background-image:-o-linear-gradient(#d0d0d0,#dfdfdf);background-image:linear-gradient(#d0d0d0,#dfdfdf)}.ui-btn-down-c:visited,.ui-btn-down-c:hover,.ui-btn-down-c a.ui-link-inherit{color:#2f3e46}.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-d{border:1px solid #bbb;background:#bbb;color:#333;font-weight:700;text-shadow:0 1px 0 #eee;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#bbb));background-image:-webkit-linear-gradient(#ddd,#bbb);background-image:-moz-linear-gradient(#ddd,#bbb);background-image:-ms-linear-gradient(#ddd,#bbb);background-image:-o-linear-gradient(#ddd,#bbb);background-image:linear-gradient(#ddd,#bbb)}.ui-bar-d,.ui-bar-d input,.ui-bar-d select,.ui-bar-d textarea,.ui-bar-d button{font-family:Helvetica,Arial,sans-serif}.ui-bar-d .ui-link-inherit{color:#333}.ui-bar-d a.ui-link{color:#2489ce;font-weight:700}.ui-bar-d a.ui-link:visited{color:#2489ce}.ui-bar-d a.ui-link:hover{color:#2489ce}.ui-bar-d a.ui-link:active{color:#2489ce}.ui-body-d,.ui-overlay-d{border:1px solid #bbb;color:#333;text-shadow:0 1px 0 #fff;background:#fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#fff));background-image:-webkit-linear-gradient(#fff,#fff);background-image:-moz-linear-gradient(#fff,#fff);background-image:-ms-linear-gradient(#fff,#fff);background-image:-o-linear-gradient(#fff,#fff);background-image:linear-gradient(#fff,#fff)}.ui-overlay-d{background-image:none;border-width:0}.ui-body-d,.ui-body-d input,.ui-body-d select,.ui-body-d textarea,.ui-body-d button{font-family:Helvetica,Arial,sans-serif}.ui-body-d .ui-link-inherit{color:#333}.ui-body-d .ui-link{color:#2489ce;font-weight:700}.ui-body-d .ui-link:visited{color:#2489ce}.ui-body-d .ui-link:hover{color:#2489ce}.ui-body-d .ui-link:active{color:#2489ce}.ui-btn-up-d{border:1px solid #bbb;background:#fff;font-weight:700;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#f6f6f6));background-image:-webkit-linear-gradient(#fafafa,#f6f6f6);background-image:-moz-linear-gradient(#fafafa,#f6f6f6);background-image:-ms-linear-gradient(#fafafa,#f6f6f6);background-image:-o-linear-gradient(#fafafa,#f6f6f6);background-image:linear-gradient(#fafafa,#f6f6f6)}.ui-btn-up-d:visited,.ui-btn-up-d a.ui-link-inherit{color:#333}.ui-btn-hover-d{border:1px solid #aaa;background:#eee;font-weight:700;color:#333;cursor:pointer;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#eee),to(#fff));background-image:-webkit-linear-gradient(#eee,#fff);background-image:-moz-linear-gradient(#eee,#fff);background-image:-ms-linear-gradient(#eee,#fff);background-image:-o-linear-gradient(#eee,#fff);background-image:linear-gradient(#eee,#fff)}.ui-btn-hover-d:visited,.ui-btn-hover-d:hover,.ui-btn-hover-d a.ui-link-inherit{color:#333}.ui-btn-down-d{border:1px solid #aaa;background:#eee;font-weight:700;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#e5e5e5),to(#f2f2f2));background-image:-webkit-linear-gradient(#e5e5e5,#f2f2f2);background-image:-moz-linear-gradient(#e5e5e5,#f2f2f2);background-image:-ms-linear-gradient(#e5e5e5,#f2f2f2);background-image:-o-linear-gradient(#e5e5e5,#f2f2f2);background-image:linear-gradient(#e5e5e5,#f2f2f2)}.ui-btn-down-d:visited,.ui-btn-down-d:hover,.ui-btn-down-d a.ui-link-inherit{color:#333}.ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-e{border:1px solid #f7c942;background:#fadb4e;color:#333;font-weight:700;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fceda7),to(#fbef7e));background-image:-webkit-linear-gradient(#fceda7,#fbef7e);background-image:-moz-linear-gradient(#fceda7,#fbef7e);background-image:-ms-linear-gradient(#fceda7,#fbef7e);background-image:-o-linear-gradient(#fceda7,#fbef7e);background-image:linear-gradient(#fceda7,#fbef7e)}.ui-bar-e,.ui-bar-e input,.ui-bar-e select,.ui-bar-e textarea,.ui-bar-e button{font-family:Helvetica,Arial,sans-serif}.ui-bar-e .ui-link-inherit{color:#333}.ui-bar-e a.ui-link{color:#2489ce;font-weight:700}.ui-bar-e a.ui-link:visited{color:#2489ce}.ui-bar-e a.ui-link:hover{color:#2489ce}.ui-bar-e a.ui-link:active{color:#2489ce}.ui-body-e,.ui-overlay-e{border:1px solid #f7c942;color:#222;text-shadow:0 1px 0 #fff;background:#fff9df;background-image:-webkit-gradient(linear,left top,left bottom,from(#fffadf),to(#fff3a5));background-image:-webkit-linear-gradient(#fffadf,#fff3a5);background-image:-moz-linear-gradient(#fffadf,#fff3a5);background-image:-ms-linear-gradient(#fffadf,#fff3a5);background-image:-o-linear-gradient(#fffadf,#fff3a5);background-image:linear-gradient(#fffadf,#fff3a5)}.ui-overlay-e{background-image:none;border-width:0}.ui-body-e,.ui-body-e input,.ui-body-e select,.ui-body-e textarea,.ui-body-e button{font-family:Helvetica,Arial,sans-serif}.ui-body-e .ui-link-inherit{color:#222}.ui-body-e .ui-link{color:#2489ce;font-weight:700}.ui-body-e .ui-link:visited{color:#2489ce}.ui-body-e .ui-link:hover{color:#2489ce}.ui-body-e .ui-link:active{color:#2489ce}.ui-btn-up-e{border:1px solid #f4c63f;background:#fadb4e;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#ffefaa),to(#ffe155));background-image:-webkit-linear-gradient(#ffefaa,#ffe155);background-image:-moz-linear-gradient(#ffefaa,#ffe155);background-image:-ms-linear-gradient(#ffefaa,#ffe155);background-image:-o-linear-gradient(#ffefaa,#ffe155);background-image:linear-gradient(#ffefaa,#ffe155)}.ui-btn-up-e:visited,.ui-btn-up-e a.ui-link-inherit{color:#222}.ui-btn-hover-e{border:1px solid #f2c43d;background:#fbe26f;font-weight:700;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff5ba),to(#fbdd52));background-image:-webkit-linear-gradient(#fff5ba,#fbdd52);background-image:-moz-linear-gradient(#fff5ba,#fbdd52);background-image:-ms-linear-gradient(#fff5ba,#fbdd52);background-image:-o-linear-gradient(#fff5ba,#fbdd52);background-image:linear-gradient(#fff5ba,#fbdd52)}.ui-btn-hover-e:visited,.ui-btn-hover-e:hover,.ui-btn-hover-e a.ui-link-inherit{color:#333}.ui-btn-down-e{border:1px solid #f2c43d;background:#fceda7;font-weight:700;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f8d94c),to(#fadb4e));background-image:-webkit-linear-gradient(#f8d94c,#fadb4e);background-image:-moz-linear-gradient(#f8d94c,#fadb4e);background-image:-ms-linear-gradient(#f8d94c,#fadb4e);background-image:-o-linear-gradient(#f8d94c,#fadb4e);background-image:linear-gradient(#f8d94c,#fadb4e)}.ui-btn-down-e:visited,.ui-btn-down-e:hover,.ui-btn-down-e a.ui-link-inherit{color:#333}.ui-btn-up-e,.ui-btn-hover-e,.ui-btn-down-e{font-family:Helvetica,Arial,sans-serif;text-decoration:none}a.ui-link-inherit{text-decoration:none!important}.ui-btn-active{border:1px solid #2373a5;background:#5393c5;font-weight:700;color:#fff;cursor:pointer;text-shadow:0 1px 0 #3373a5;text-decoration:none;background-image:-webkit-gradient(linear,left top,left bottom,from(#5393c5),to(#6facd5));background-image:-webkit-linear-gradient(#5393c5,#6facd5);background-image:-moz-linear-gradient(#5393c5,#6facd5);background-image:-ms-linear-gradient(#5393c5,#6facd5);background-image:-o-linear-gradient(#5393c5,#6facd5);background-image:linear-gradient(#5393c5,#6facd5);font-family:Helvetica,Arial,sans-serif}.ui-btn-active:visited,.ui-btn-active:hover,.ui-btn-active a.ui-link-inherit{color:#fff}.ui-btn-inner{border-top:1px solid #fff;border-color:rgba(255,255,255,.3)}.ui-corner-all{-webkit-border-radius:.6em;border-radius:.6em}.ui-br{border-color:#828282;border-color:rgba(130,130,130,.3);border-style:solid}.ui-disabled{filter:Alpha(Opacity=30);opacity:.3;zoom:1}.ui-disabled,.ui-disabled a{cursor:default!important;pointer-events:none}.ui-icon,.ui-icon-searchfield:after{background:#666;background:rgba(0,0,0,.4);background-image:url(images/icons-18-white.png);background-repeat:no-repeat;-webkit-border-radius:9px;border-radius:9px}.ui-icon-alt .ui-icon,.ui-icon-alt .ui-icon-searchfield:after{background-color:#fff;background-color:rgba(255,255,255,.3);background-image:url(images/icons-18-black.png);background-repeat:no-repeat}.ui-icon-nodisc .ui-icon,.ui-icon-nodisc .ui-icon-searchfield:after,.ui-icon-nodisc .ui-icon-alt .ui-icon,.ui-icon-nodisc .ui-icon-alt .ui-icon-searchfield:after{background-color:transparent}.ui-icon-plus{background-position:-1px -1px}.ui-icon-minus{background-position:-37px -1px}.ui-icon-delete{background-position:-73px -1px}.ui-icon-arrow-r{background-position:-108px -1px}.ui-icon-arrow-l{background-position:-144px -1px}.ui-icon-arrow-u{background-position:-180px -1px}.ui-icon-arrow-d{background-position:-216px -1px}.ui-icon-check{background-position:-252px -1px}.ui-icon-gear{background-position:-288px -1px}.ui-icon-refresh{background-position:-323px -1px}.ui-icon-forward{background-position:-360px -1px}.ui-icon-back{background-position:-396px -1px}.ui-icon-grid{background-position:-432px -1px}.ui-icon-star{background-position:-467px -1px}.ui-icon-alert{background-position:-503px -1px}.ui-icon-info{background-position:-539px -1px}.ui-icon-home{background-position:-575px -1px}.ui-icon-search,.ui-icon-searchfield:after{background-position:-611px -1px}.ui-icon-checkbox-on{background-position:-647px -1px}.ui-icon-checkbox-off{background-position:-683px -1px}.ui-icon-radio-on{background-position:-718px -1px}.ui-icon-radio-off{background-position:-754px -1px}.ui-icon-bars{background-position:-788px -1px}.ui-icon-edit{background-position:-824px -1px}@media only screen and (-webkit-min-device-pixel-ratio:1.3),only screen and (min--moz-device-pixel-ratio:1.3),only screen and (min-resolution:200dpi){.ui-icon-plus,.ui-icon-minus,.ui-icon-delete,.ui-icon-arrow-r,.ui-icon-arrow-l,.ui-icon-arrow-u,.ui-icon-arrow-d,.ui-icon-check,.ui-icon-gear,.ui-icon-refresh,.ui-icon-forward,.ui-icon-back,.ui-icon-grid,.ui-icon-star,.ui-icon-alert,.ui-icon-info,.ui-icon-home,.ui-icon-bars,.ui-icon-edit,.ui-icon-search,.ui-icon-searchfield:after,.ui-icon-checkbox-off,.ui-icon-checkbox-on,.ui-icon-radio-off,.ui-icon-radio-on{background-image:url(images/icons-36-white.png);-moz-background-size:864px 18px;-o-background-size:864px 18px;-webkit-background-size:864px 18px;background-size:864px 18px}.ui-icon-alt .ui-icon{background-image:url(images/icons-36-black.png)}.ui-icon-plus{background-position:0 50%}.ui-icon-minus{background-position:-36px 50%}.ui-icon-delete{background-position:-72px 50%}.ui-icon-arrow-r{background-position:-108px 50%}.ui-icon-arrow-l{background-position:-144px 50%}.ui-icon-arrow-u{background-position:-179px 50%}.ui-icon-arrow-d{background-position:-215px 50%}.ui-icon-check{background-position:-252px 50%}.ui-icon-gear{background-position:-287px 50%}.ui-icon-refresh{background-position:-323px 50%}.ui-icon-forward{background-position:-360px 50%}.ui-icon-back{background-position:-395px 50%}.ui-icon-grid{background-position:-431px 50%}.ui-icon-star{background-position:-467px 50%}.ui-icon-alert{background-position:-503px 50%}.ui-icon-info{background-position:-538px 50%}.ui-icon-home{background-position:-575px 50%}.ui-icon-search,.ui-icon-searchfield:after{background-position:-611px 50%}.ui-icon-checkbox-on{background-position:-647px 50%}.ui-icon-checkbox-off{background-position:-683px 50%}.ui-icon-radio-on{background-position:-718px 50%}.ui-icon-radio-off{background-position:-754px 50%}.ui-icon-bars{background-position:-788px 50%}.ui-icon-edit{background-position:-824px 50%}}.ui-checkbox .ui-icon,.ui-selectmenu-list .ui-icon{-webkit-border-radius:3px;border-radius:3px}.ui-icon-checkbox-off,.ui-icon-radio-off{background-color:transparent}.ui-checkbox-on .ui-icon,.ui-radio-on .ui-icon{background-color:#4596ce}.ui-icon-loading{background:url(images/ajax-loader.gif);background-size:46px 46px}.ui-btn-corner-all{-webkit-border-radius:1em;border-radius:1em}.ui-corner-all,.ui-btn-corner-all{-webkit-background-clip:padding;background-clip:padding-box}.ui-overlay{background:#666;filter:Alpha(Opacity=50);opacity:.5;position:absolute;width:100%;height:100%}.ui-overlay-shadow{-moz-box-shadow:0 0 12px rgba(0,0,0,.6);-webkit-box-shadow:0 0 12px rgba(0,0,0,.6);box-shadow:0 0 12px rgba(0,0,0,.6)}.ui-shadow{-moz-box-shadow:0 1px 3px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,.2);box-shadow:0 1px 3px rgba(0,0,0,.2)}.ui-bar-a .ui-shadow,.ui-bar-b .ui-shadow,.ui-bar-c .ui-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.ui-shadow-inset{-moz-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);box-shadow:inset 0 1px 4px rgba(0,0,0,.2)}.ui-icon-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.4);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.4);box-shadow:0 1px 0 rgba(255,255,255,.4)}.ui-btn:focus,.ui-link-inherit:focus{outline:0}.ui-btn.ui-focus{z-index:1}.ui-focus,.ui-btn:focus{-moz-box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe;-webkit-box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe;box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe}.ui-input-text.ui-focus,.ui-input-search.ui-focus{-moz-box-shadow:0 0 12px #387bbe;-webkit-box-shadow:0 0 12px #387bbe;box-shadow:0 0 12px #387bbe}.ui-mobile-nosupport-boxshadow *{-moz-box-shadow:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui-mobile-nosupport-boxshadow .ui-focus,.ui-mobile-nosupport-boxshadow .ui-btn:focus,.ui-mobile-nosupport-boxshadow .ui-link-inherit:focus{outline-width:1px;outline-style:auto}.ui-mobile,.ui-mobile body{height:99.9%}.ui-mobile fieldset,.ui-page{padding:0;margin:0}.ui-mobile a img,.ui-mobile fieldset{border-width:0}.ui-mobile fieldset{min-width:0}.ui-mobile-viewport{margin:0;overflow-x:visible;-webkit-text-size-adjust:100%;-ms-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}body.ui-mobile-viewport,div.ui-mobile-viewport{overflow-x:hidden}.ui-mobile [data-role=page],.ui-mobile [data-role=dialog],.ui-page{top:0;left:0;width:100%;min-height:100%;position:absolute;display:none;border:0}.ui-mobile .ui-page-active{display:block;overflow:visible}.ui-page{outline:0}@media screen and (orientation:portrait){.ui-mobile .ui-page{min-height:420px}}@media screen and (orientation:landscape){.ui-mobile .ui-page{min-height:300px}}.ui-loading .ui-loader{display:block}.ui-loader{display:none;z-index:9999999;position:fixed;top:50%;left:50%;border:0}.ui-loader-default{background:0;filter:Alpha(Opacity=18);opacity:.18;width:46px;height:46px;margin-left:-23px;margin-top:-23px}.ui-loader-verbose{width:200px;filter:Alpha(Opacity=88);opacity:.88;box-shadow:0 1px 1px -1px #fff;height:auto;margin-left:-110px;margin-top:-43px;padding:10px}.ui-loader-default h1{font-size:0;width:0;height:0;overflow:hidden}.ui-loader-verbose h1{font-size:16px;margin:0;text-align:center}.ui-loader .ui-icon{background-color:#000;display:block;margin:0;width:44px;height:44px;padding:1px;-webkit-border-radius:36px;border-radius:36px}.ui-loader-verbose .ui-icon{margin:0 auto 10px;filter:Alpha(Opacity=75);opacity:.75}.ui-loader-textonly{padding:15px;margin-left:-115px}.ui-loader-textonly .ui-icon{display:none}.ui-loader-fakefix{position:absolute}.ui-mobile-rendering>*{visibility:hidden}.ui-bar,.ui-body{position:relative;padding:.4em 15px;overflow:hidden;display:block;clear:both}.ui-bar{font-size:16px;margin:0}.ui-bar h1,.ui-bar h2,.ui-bar h3,.ui-bar h4,.ui-bar h5,.ui-bar h6{margin:0;padding:0;font-size:16px;display:inline-block}.ui-header,.ui-footer{position:relative;zoom:1}.ui-mobile .ui-header,.ui-mobile .ui-footer{border-left-width:0;border-right-width:0}.ui-header .ui-btn-left,.ui-header .ui-btn-right,.ui-footer .ui-btn-left,.ui-footer .ui-btn-right,.ui-header-fixed.ui-fixed-hidden .ui-btn-left,.ui-header-fixed.ui-fixed-hidden .ui-btn-right{position:absolute;top:3px}.ui-header-fixed .ui-btn-left,.ui-header-fixed .ui-btn-right{top:4px}.ui-header .ui-btn-left,.ui-footer .ui-btn-left{left:5px}.ui-header .ui-btn-right,.ui-footer .ui-btn-right{right:5px}.ui-footer>.ui-btn-icon-notext,.ui-header>.ui-btn-icon-notext,.ui-header-fixed.ui-fixed-hidden>.ui-btn-icon-notext{top:6px}.ui-header-fixed>.ui-btn-icon-notext{top:7px}.ui-header .ui-title,.ui-footer .ui-title{min-height:1.1em;text-align:center;font-size:16px;display:block;margin:.6em 30% .8em;padding:0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;outline:0!important}.ui-footer .ui-title{margin:.6em 15px .8em}.ui-content{border-width:0;overflow:visible;overflow-x:hidden;padding:15px}.ui-corner-all>.ui-header:first-child,.ui-corner-all>.ui-content:first-child,.ui-corner-all>.ui-footer:first-child{-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit;-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit}.ui-corner-all>.ui-header:last-child,.ui-corner-all>.ui-content:last-child,.ui-corner-all>.ui-footer:last-child{-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit;-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-icon{width:18px;height:18px}.ui-nojs{position:absolute;left:-9999px}.ui-hide-label label.ui-input-text,.ui-hide-label label.ui-select,.ui-hide-label label.ui-slider,.ui-hide-label label.ui-submit,.ui-hide-label .ui-controlgroup-label,.ui-hidden-accessible{position:absolute!important;left:-9999px;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .ui-page{width:100%;height:100%;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.ui-page-pre-in{opacity:0}.in{-webkit-animation-timing-function:ease-out;-webkit-animation-duration:350ms;-moz-animation-timing-function:ease-out;-moz-animation-duration:350ms;animation-timing-function:ease-out;animation-duration:350ms}.out{-webkit-animation-timing-function:ease-in;-webkit-animation-duration:225ms;-moz-animation-timing-function:ease-in;-moz-animation-duration:225ms;animation-timing-function:ease-in;animation-duration:225ms}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@-moz-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes fadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeout{from{opacity:1}to{opacity:0}}@-moz-keyframes fadeout{from{opacity:1}to{opacity:0}}@keyframes fadeout{from{opacity:1}to{opacity:0}}.fade.out{opacity:0;-webkit-animation-duration:125ms;-webkit-animation-name:fadeout;-moz-animation-duration:125ms;-moz-animation-name:fadeout;animation-duration:125ms;animation-name:fadeout}.fade.in{opacity:1;-webkit-animation-duration:225ms;-webkit-animation-name:fadein;-moz-animation-duration:225ms;-moz-animation-name:fadein;animation-duration:225ms;animation-name:fadein}.pop{-webkit-transform-origin:50% 50%;-moz-transform-origin:50% 50%;transform-origin:50% 50%}.pop.in{-webkit-transform:scale(1);-webkit-animation-name:popin;-webkit-animation-duration:350ms;-moz-transform:scale(1);-moz-animation-name:popin;-moz-animation-duration:350ms;transform:scale(1);animation-name:popin;animation-duration:350ms;opacity:1}.pop.out{-webkit-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-name:fadeout;-moz-animation-duration:100ms;animation-name:fadeout;animation-duration:100ms;opacity:0}.pop.in.reverse{-webkit-animation-name:fadein;-moz-animation-name:fadein;animation-name:fadein}.pop.out.reverse{-webkit-transform:scale(.8);-webkit-animation-name:popout;-moz-transform:scale(.8);-moz-animation-name:popout;transform:scale(.8);animation-name:popout}@-webkit-keyframes popin{from{-webkit-transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);opacity:1}}@-moz-keyframes popin{from{-moz-transform:scale(.8);opacity:0}to{-moz-transform:scale(1);opacity:1}}@keyframes popin{from{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}@-webkit-keyframes popout{from{-webkit-transform:scale(1);opacity:1}to{-webkit-transform:scale(.8);opacity:0}}@-moz-keyframes popout{from{-moz-transform:scale(1);opacity:1}to{-moz-transform:scale(.8);opacity:0}}@keyframes popout{from{transform:scale(1);opacity:1}to{transform:scale(.8);opacity:0}}@-webkit-keyframes slideinfromright{from{-webkit-transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0)}}@-moz-keyframes slideinfromright{from{-moz-transform:translateX(100%)}to{-moz-transform:translateX(0)}}@keyframes slideinfromright{from{transform:translateX(100%)}to{transform:translateX(0)}}@-webkit-keyframes slideinfromleft{from{-webkit-transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0)}}@-moz-keyframes slideinfromleft{from{-moz-transform:translateX(-100%)}to{-moz-transform:translateX(0)}}@keyframes slideinfromleft{from{transform:translateX(-100%)}to{transform:translateX(0)}}@-webkit-keyframes slideouttoleft{from{-webkit-transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0)}}@-moz-keyframes slideouttoleft{from{-moz-transform:translateX(0)}to{-moz-transform:translateX(-100%)}}@keyframes slideouttoleft{from{transform:translateX(0)}to{transform:translateX(-100%)}}@-webkit-keyframes slideouttoright{from{-webkit-transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0)}}@-moz-keyframes slideouttoright{from{-moz-transform:translateX(0)}to{-moz-transform:translateX(100%)}}@keyframes slideouttoright{from{transform:translateX(0)}to{transform:translateX(100%)}}.slide.out,.slide.in{-webkit-animation-timing-function:ease-out;-webkit-animation-duration:350ms;-moz-animation-timing-function:ease-out;-moz-animation-duration:350ms;animation-timing-function:ease-out;animation-duration:350ms}.slide.out{-webkit-transform:translate3d(-100%,0,0);-webkit-animation-name:slideouttoleft;-moz-transform:translateX(-100%);-moz-animation-name:slideouttoleft;transform:translateX(-100%);animation-name:slideouttoleft}.slide.in{-webkit-transform:translate3d(0,0,0);-webkit-animation-name:slideinfromright;-moz-transform:translateX(0);-moz-animation-name:slideinfromright;transform:translateX(0);animation-name:slideinfromright}.slide.out.reverse{-webkit-transform:translate3d(100%,0,0);-webkit-animation-name:slideouttoright;-moz-transform:translateX(100%);-moz-animation-name:slideouttoright;transform:translateX(100%);animation-name:slideouttoright}.slide.in.reverse{-webkit-transform:translate3d(0,0,0);-webkit-animation-name:slideinfromleft;-moz-transform:translateX(0);-moz-animation-name:slideinfromleft;transform:translateX(0);animation-name:slideinfromleft}.slidefade.out{-webkit-transform:translateX(-100%);-webkit-animation-name:slideouttoleft;-webkit-animation-duration:225ms;-moz-transform:translateX(-100%);-moz-animation-name:slideouttoleft;-moz-animation-duration:225ms;transform:translateX(-100%);animation-name:slideouttoleft;animation-duration:225ms}.slidefade.in{-webkit-transform:translateX(0);-webkit-animation-name:fadein;-webkit-animation-duration:200ms;-moz-transform:translateX(0);-moz-animation-name:fadein;-moz-animation-duration:200ms;transform:translateX(0);animation-name:fadein;animation-duration:200ms}.slidefade.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:slideouttoright;-webkit-animation-duration:200ms;-moz-transform:translateX(100%);-moz-animation-name:slideouttoright;-moz-animation-duration:200ms;transform:translateX(100%);animation-name:slideouttoright;animation-duration:200ms}.slidefade.in.reverse{-webkit-transform:translateX(0);-webkit-animation-name:fadein;-webkit-animation-duration:200ms;-moz-transform:translateX(0);-moz-animation-name:fadein;-moz-animation-duration:200ms;transform:translateX(0);animation-name:fadein;animation-duration:200ms}.slidedown.out{-webkit-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-name:fadeout;-moz-animation-duration:100ms;animation-name:fadeout;animation-duration:100ms}.slidedown.in{-webkit-transform:translateY(0);-webkit-animation-name:slideinfromtop;-webkit-animation-duration:250ms;-moz-transform:translateY(0);-moz-animation-name:slideinfromtop;-moz-animation-duration:250ms;transform:translateY(0);animation-name:slideinfromtop;animation-duration:250ms}.slidedown.in.reverse{-webkit-animation-name:fadein;-webkit-animation-duration:150ms;-moz-animation-name:fadein;-moz-animation-duration:150ms;animation-name:fadein;animation-duration:150ms}.slidedown.out.reverse{-webkit-transform:translateY(-100%);-webkit-animation-name:slideouttotop;-webkit-animation-duration:200ms;-moz-transform:translateY(-100%);-moz-animation-name:slideouttotop;-moz-animation-duration:200ms;transform:translateY(-100%);animation-name:slideouttotop;animation-duration:200ms}@-webkit-keyframes slideinfromtop{from{-webkit-transform:translateY(-100%)}to{-webkit-transform:translateY(0)}}@-moz-keyframes slideinfromtop{from{-moz-transform:translateY(-100%)}to{-moz-transform:translateY(0)}}@keyframes slideinfromtop{from{transform:translateY(-100%)}to{transform:translateY(0)}}@-webkit-keyframes slideouttotop{from{-webkit-transform:translateY(0)}to{-webkit-transform:translateY(-100%)}}@-moz-keyframes slideouttotop{from{-moz-transform:translateY(0)}to{-moz-transform:translateY(-100%)}}@keyframes slideouttotop{from{transform:translateY(0)}to{transform:translateY(-100%)}}.slideup.out{-webkit-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-name:fadeout;-moz-animation-duration:100ms;animation-name:fadeout;animation-duration:100ms}.slideup.in{-webkit-transform:translateY(0);-webkit-animation-name:slideinfrombottom;-webkit-animation-duration:250ms;-moz-transform:translateY(0);-moz-animation-name:slideinfrombottom;-moz-animation-duration:250ms;transform:translateY(0);animation-name:slideinfrombottom;animation-duration:250ms}.slideup.in.reverse{-webkit-animation-name:fadein;-webkit-animation-duration:150ms;-moz-animation-name:fadein;-moz-animation-duration:150ms;animation-name:fadein;animation-duration:150ms}.slideup.out.reverse{-webkit-transform:translateY(100%);-webkit-animation-name:slideouttobottom;-webkit-animation-duration:200ms;-moz-transform:translateY(100%);-moz-animation-name:slideouttobottom;-moz-animation-duration:200ms;transform:translateY(100%);animation-name:slideouttobottom;animation-duration:200ms}@-webkit-keyframes slideinfrombottom{from{-webkit-transform:translateY(100%)}to{-webkit-transform:translateY(0)}}@-moz-keyframes slideinfrombottom{from{-moz-transform:translateY(100%)}to{-moz-transform:translateY(0)}}@keyframes slideinfrombottom{from{transform:translateY(100%)}to{transform:translateY(0)}}@-webkit-keyframes slideouttobottom{from{-webkit-transform:translateY(0)}to{-webkit-transform:translateY(100%)}}@-moz-keyframes slideouttobottom{from{-moz-transform:translateY(0)}to{-moz-transform:translateY(100%)}}@keyframes slideouttobottom{from{transform:translateY(0)}to{transform:translateY(100%)}}.viewport-flip{-webkit-perspective:1000;-moz-perspective:1000;perspective:1000;position:absolute}.flip{-webkit-backface-visibility:hidden;-webkit-transform:translateX(0);-moz-backface-visibility:hidden;-moz-transform:translateX(0);backface-visibility:hidden;transform:translateX(0)}.flip.out{-webkit-transform:rotateY(-90deg) scale(.9);-webkit-animation-name:flipouttoleft;-webkit-animation-duration:175ms;-moz-transform:rotateY(-90deg) scale(.9);-moz-animation-name:flipouttoleft;-moz-animation-duration:175ms;transform:rotateY(-90deg) scale(.9);animation-name:flipouttoleft;animation-duration:175ms}.flip.in{-webkit-animation-name:flipintoright;-webkit-animation-duration:225ms;-moz-animation-name:flipintoright;-moz-animation-duration:225ms;animation-name:flipintoright;animation-duration:225ms}.flip.out.reverse{-webkit-transform:rotateY(90deg) scale(.9);-webkit-animation-name:flipouttoright;-moz-transform:rotateY(90deg) scale(.9);-moz-animation-name:flipouttoright;transform:rotateY(90deg) scale(.9);animation-name:flipouttoright}.flip.in.reverse{-webkit-animation-name:flipintoleft;-moz-animation-name:flipintoleft;animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(.9)}}@-moz-keyframes flipouttoleft{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(-90deg) scale(.9)}}@keyframes flipouttoleft{from{transform:rotateY(0)}to{transform:rotateY(-90deg) scale(.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(.9)}}@-moz-keyframes flipouttoright{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(90deg) scale(.9)}}@keyframes flipouttoright{from{transform:rotateY(0)}to{transform:rotateY(90deg) scale(.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoleft{from{-moz-transform:rotateY(-90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@keyframes flipintoleft{from{transform:rotateY(-90deg) scale(.9)}to{transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoright{from{-moz-transform:rotateY(90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@keyframes flipintoright{from{transform:rotateY(90deg) scale(.9)}to{transform:rotateY(0)}}.viewport-turn{-webkit-perspective:200px;-moz-perspective:200px;-ms-perspective:200px;perspective:200px;position:absolute}.turn{-webkit-backface-visibility:hidden;-webkit-transform:translateX(0);-webkit-transform-origin:0;-moz-backface-visibility:hidden;-moz-transform:translateX(0);-moz-transform-origin:0;backface-visibility :hidden;transform:translateX(0);transform-origin:0}.turn.out{-webkit-transform:rotateY(-90deg) scale(.9);-webkit-animation-name:flipouttoleft;-webkit-animation-duration:125ms;-moz-transform:rotateY(-90deg) scale(.9);-moz-animation-name:flipouttoleft;-moz-animation-duration:125ms;transform:rotateY(-90deg) scale(.9);animation-name:flipouttoleft;animation-duration:125ms}.turn.in{-webkit-animation-name:flipintoright;-webkit-animation-duration:250ms;-moz-animation-name:flipintoright;-moz-animation-duration:250ms;animation-name:flipintoright;animation-duration:250ms}.turn.out.reverse{-webkit-transform:rotateY(90deg) scale(.9);-webkit-animation-name:flipouttoright;-moz-transform:rotateY(90deg) scale(.9);-moz-animation-name:flipouttoright;transform:rotateY(90deg) scale(.9);animation-name:flipouttoright}.turn.in.reverse{-webkit-animation-name:flipintoleft;-moz-animation-name:flipintoleft;animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(.9)}}@-moz-keyframes flipouttoleft{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(-90deg) scale(.9)}}@keyframes flipouttoleft{from{transform:rotateY(0)}to{transform:rotateY(-90deg) scale(.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(.9)}}@-moz-keyframes flipouttoright{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(90deg) scale(.9)}}@keyframes flipouttoright{from{transform:rotateY(0)}to{transform:rotateY(90deg) scale(.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoleft{from{-moz-transform:rotateY(-90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@keyframes flipintoleft{from{transform:rotateY(-90deg) scale(.9)}to{transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoright{from{-moz-transform:rotateY(90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@keyframes flipintoright{from{transform:rotateY(90deg) scale(.9)}to{transform:rotateY(0)}}.flow{-webkit-transform-origin:50% 30%;-webkit-box-shadow:0 0 20px rgba(0,0,0,.4);-moz-transform-origin:50% 30%;-moz-box-shadow:0 0 20px rgba(0,0,0,.4);transform-origin:50% 30%;box-shadow:0 0 20px rgba(0,0,0,.4)}.ui-dialog.flow{-webkit-transform-origin:none;-webkit-box-shadow:none;-moz-transform-origin:none;-moz-box-shadow:none;transform-origin:none;box-shadow:none}.flow.out{-webkit-transform:translateX(-100%) scale(.7);-webkit-animation-name:flowouttoleft;-webkit-animation-timing-function:ease;-webkit-animation-duration:350ms;-moz-transform:translateX(-100%) scale(.7);-moz-animation-name:flowouttoleft;-moz-animation-timing-function:ease;-moz-animation-duration:350ms;transform:translateX(-100%) scale(.7);animation-name:flowouttoleft;animation-timing-function:ease;animation-duration:350ms}.flow.in{-webkit-transform:translateX(0) scale(1);-webkit-animation-name:flowinfromright;-webkit-animation-timing-function:ease;-webkit-animation-duration:350ms;-moz-transform:translateX(0) scale(1);-moz-animation-name:flowinfromright;-moz-animation-timing-function:ease;-moz-animation-duration:350ms;transform:translateX(0) scale(1);animation-name:flowinfromright;animation-timing-function:ease;animation-duration:350ms}.flow.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:flowouttoright;-moz-transform:translateX(100%);-moz-animation-name:flowouttoright;transform:translateX(100%);animation-name:flowouttoright}.flow.in.reverse{-webkit-animation-name:flowinfromleft;-moz-animation-name:flowinfromleft;animation-name:flowinfromleft}@-webkit-keyframes flowouttoleft{0%{-webkit-transform:translateX(0) scale(1)}60%,70%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(-100%) scale(.7)}}@-moz-keyframes flowouttoleft{0%{-moz-transform:translateX(0) scale(1)}60%,70%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(-100%) scale(.7)}}@keyframes flowouttoleft{0%{transform:translateX(0) scale(1)}60%,70%{transform:translateX(0) scale(.7)}100%{transform:translateX(-100%) scale(.7)}}@-webkit-keyframes flowouttoright{0%{-webkit-transform:translateX(0) scale(1)}60%,70%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(100%) scale(.7)}}@-moz-keyframes flowouttoright{0%{-moz-transform:translateX(0) scale(1)}60%,70%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(100%) scale(.7)}}@keyframes flowouttoright{0%{transform:translateX(0) scale(1)}60%,70%{transform:translateX(0) scale(.7)}100%{transform:translateX(100%) scale(.7)}}@-webkit-keyframes flowinfromleft{0%{-webkit-transform:translateX(-100%) scale(.7)}30%,40%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(0) scale(1)}}@-moz-keyframes flowinfromleft{0%{-moz-transform:translateX(-100%) scale(.7)}30%,40%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(0) scale(1)}}@keyframes flowinfromleft{0%{transform:translateX(-100%) scale(.7)}30%,40%{transform:translateX(0) scale(.7)}100%{transform:translateX(0) scale(1)}}@-webkit-keyframes flowinfromright{0%{-webkit-transform:translateX(100%) scale(.7)}30%,40%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(0) scale(1)}}@-moz-keyframes flowinfromright{0%{-moz-transform:translateX(100%) scale(.7)}30%,40%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(0) scale(1)}}@keyframes flowinfromright{0%{transform:translateX(100%) scale(.7)}30%,40%{transform:translateX(0) scale(.7)}100%{transform:translateX(0) scale(1)}}.ui-grid-a,.ui-grid-b,.ui-grid-c,.ui-grid-d{overflow:hidden}.ui-block-a,.ui-block-b,.ui-block-c,.ui-block-d,.ui-block-e{margin:0;padding:0;border:0;float:left;min-height:1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.ui-grid-solo .ui-block-a{display:block;float:none}.ui-grid-a .ui-block-a,.ui-grid-a .ui-block-b{width:49.95%}.ui-grid-a>:nth-child(n){width:50%;margin-right:-.5px}.ui-grid-a .ui-block-a{clear:left}.ui-grid-b .ui-block-a,.ui-grid-b .ui-block-b,.ui-grid-b .ui-block-c{width:33.25%}.ui-grid-b>:nth-child(n){width:33.333%;margin-right:-.5px}.ui-grid-b .ui-block-a{clear:left}.ui-grid-c .ui-block-a,.ui-grid-c .ui-block-b,.ui-grid-c .ui-block-c,.ui-grid-c .ui-block-d{width:24.925%}.ui-grid-c>:nth-child(n){width:25%;margin-right:-.5px}.ui-grid-c .ui-block-a{clear:left}.ui-grid-d .ui-block-a,.ui-grid-d .ui-block-b,.ui-grid-d .ui-block-c,.ui-grid-d .ui-block-d,.ui-grid-d .ui-block-e{width:19.925%}.ui-grid-d>:nth-child(n){width:20%}.ui-grid-d .ui-block-a{clear:left}@media all and (max-width:35em){.ui-responsive .ui-block-a,.ui-responsive .ui-block-b,.ui-responsive .ui-block-c,.ui-responsive .ui-block-d,.ui-responsive .ui-block-e{width:100%;float:none}}.ui-header-fixed,.ui-footer-fixed{left:0;right:0;width:100%;position:fixed;z-index:1000}.ui-header-fixed{top:-1px;padding-top:1px}.ui-header-fixed.ui-fixed-hidden{top:0;padding-top:0}.ui-footer-fixed{bottom:-1px;padding-bottom:1px}.ui-footer-fixed.ui-fixed-hidden{bottom:0;padding-bottom:0}.ui-header-fullscreen,.ui-footer-fullscreen{filter:Alpha(Opacity=90);opacity:.9}.ui-page-header-fixed{padding-top:2.6875em}.ui-page-footer-fixed{padding-bottom:2.6875em}.ui-page-header-fullscreen>.ui-content,.ui-page-footer-fullscreen>.ui-content{padding:0}.ui-fixed-hidden{position:absolute}.ui-page-header-fullscreen .ui-fixed-hidden,.ui-page-footer-fullscreen .ui-fixed-hidden{left:-9999px}.ui-header-fixed .ui-btn,.ui-footer-fixed .ui-btn{z-index:10}.ui-android-2x-fixed .ui-li-has-thumb{-webkit-transform:translate3d(0,0,0)}.ui-navbar{max-width:100%}.ui-navbar.ui-mini{margin:0}.ui-navbar ul:before,.ui-navbar ul:after{content:" ";display:table}.ui-navbar ul:after{clear:both}.ui-navbar ul{list-style:none;margin:0;padding:0;position:relative;display:block;border:0;max-width:100%;overflow:visible;zoom:1}.ui-navbar li .ui-btn{display:block;text-align:center;margin:0 -1px 0 0;border-right-width:0}.ui-navbar li .ui-btn-icon-right .ui-icon{right:6px}.ui-navbar li:last-child .ui-btn,.ui-navbar .ui-grid-duo .ui-block-b .ui-btn{margin-right:0;border-right-width:1px}.ui-header .ui-navbar li:last-child .ui-btn,.ui-footer .ui-navbar li:last-child .ui-btn,.ui-header .ui-navbar .ui-grid-duo .ui-block-b .ui-btn,.ui-footer .ui-navbar .ui-grid-duo .ui-block-b .ui-btn{margin-right:-1px;border-right-width:0}.ui-navbar .ui-grid-duo li.ui-block-a:last-child .ui-btn{margin-right:-1px;border-right-width:1px}.ui-header .ui-navbar li .ui-btn,.ui-footer .ui-navbar li .ui-btn{border-top-width:0;border-bottom-width:0}.ui-header .ui-navbar .ui-grid-b li.ui-block-c .ui-btn,.ui-footer .ui-navbar .ui-grid-b li.ui-block-c .ui-btn{margin-right:-5px}.ui-header .ui-navbar .ui-grid-c li.ui-block-d .ui-btn,.ui-footer .ui-navbar .ui-grid-c li.ui-block-d .ui-btn,.ui-header .ui-navbar .ui-grid-d li.ui-block-e .ui-btn,.ui-footer .ui-navbar .ui-grid-d li.ui-block-e .ui-btn{margin-right:-4px}.ui-header .ui-navbar .ui-grid-b li.ui-block-c .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-b li.ui-block-c .ui-btn-icon-right .ui-icon,.ui-header .ui-navbar .ui-grid-c li.ui-block-d .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-c li.ui-block-d .ui-btn-icon-right .ui-icon,.ui-header .ui-navbar .ui-grid-d li.ui-block-e .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-d li.ui-block-e .ui-btn-icon-right .ui-icon{right:8px}.ui-navbar li .ui-btn .ui-btn-inner{padding-top:.7em;padding-bottom:.8em}.ui-navbar li .ui-btn-icon-top .ui-btn-inner{padding-top:30px}.ui-navbar li .ui-btn-icon-bottom .ui-btn-inner{padding-bottom:30px}.ui-btn{display:block;text-align:center;cursor:pointer;position:relative;margin:.5em 0;padding:0}.ui-mini{margin-top:.25em;margin-bottom:.25em}.ui-btn-left,.ui-btn-right,.ui-input-clear,.ui-btn-inline,.ui-grid-a .ui-btn,.ui-grid-b .ui-btn,.ui-grid-c .ui-btn,.ui-grid-d .ui-btn,.ui-grid-e .ui-btn,.ui-grid-solo .ui-btn{margin-right:5px;margin-left:5px}.ui-btn-inner{font-size:16px;padding:.6em 20px;min-width:.75em;display:block;position:relative;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;zoom:1}.ui-btn input,.ui-btn button{z-index:2}.ui-btn-left,.ui-btn-right,.ui-btn-inline{display:inline-block;vertical-align:middle}.ui-mobile .ui-btn-left,.ui-mobile .ui-btn-right,.ui-btn-left>.ui-btn,.ui-btn-right>.ui-btn{margin:0}.ui-btn-block{display:block}.ui-header>.ui-btn,.ui-footer>.ui-btn{display:inline-block;margin:0}.ui-header .ui-btn-block,.ui-footer .ui-btn-block{display:block}.ui-header .ui-btn-inner,.ui-footer .ui-btn-inner,.ui-mini .ui-btn-inner{font-size:12.5px;padding:.55em 11px .5em}.ui-fullsize .ui-btn-inner,.ui-fullsize .ui-btn-inner{font-size:16px;padding:.6em 20px}.ui-btn-icon-notext{width:24px;height:24px}.ui-btn-icon-notext .ui-btn-inner{padding:0;height:100%}.ui-btn-icon-notext .ui-btn-inner .ui-icon{margin:2px 1px 2px 3px;float:left}.ui-btn-text{position:relative;z-index:1;width:100%;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}div.ui-btn-text{width:auto}.ui-btn-icon-notext .ui-btn-text{position:absolute;left:-9999px}.ui-btn-icon-left .ui-btn-inner{padding-left:40px}.ui-btn-icon-right .ui-btn-inner{padding-right:40px}.ui-btn-icon-top .ui-btn-inner{padding-top:40px}.ui-btn-icon-bottom .ui-btn-inner{padding-bottom:40px}.ui-header .ui-btn-icon-left .ui-btn-inner,.ui-footer .ui-btn-icon-left .ui-btn-inner,.ui-mini.ui-btn-icon-left .ui-btn-inner,.ui-mini .ui-btn-icon-left .ui-btn-inner{padding-left:30px}.ui-header .ui-btn-icon-right .ui-btn-inner,.ui-footer .ui-btn-icon-right .ui-btn-inner,.ui-mini.ui-btn-icon-right .ui-btn-inner,.ui-mini .ui-btn-icon-right .ui-btn-inner{padding-right:30px}.ui-header .ui-btn-icon-top .ui-btn-inner,.ui-footer .ui-btn-icon-top .ui-btn-inner{padding:30px 3px .5em}.ui-mini.ui-btn-icon-top .ui-btn-inner,.ui-mini .ui-btn-icon-top .ui-btn-inner{padding-top:30px}.ui-header .ui-btn-icon-bottom .ui-btn-inner,.ui-footer .ui-btn-icon-bottom .ui-btn-inner{padding:.55em 3px 30px}.ui-mini.ui-btn-icon-bottom .ui-btn-inner,.ui-mini .ui-btn-icon-bottom .ui-btn-inner{padding-bottom:30px}.ui-btn-inner{-webkit-border-radius:inherit;border-radius:inherit}.ui-btn-icon-notext .ui-icon{display:block;z-index:0}.ui-btn-icon-left>.ui-btn-inner>.ui-icon,.ui-btn-icon-right>.ui-btn-inner>.ui-icon{position:absolute;top:50%;margin-top:-9px}.ui-btn-icon-top .ui-btn-inner .ui-icon,.ui-btn-icon-bottom .ui-btn-inner .ui-icon{position:absolute;left:50%;margin-left:-9px}.ui-btn-icon-left .ui-icon{left:10px}.ui-btn-icon-right .ui-icon{right:10px}.ui-btn-icon-top .ui-icon{top:10px}.ui-btn-icon-bottom .ui-icon{top:auto;bottom:10px}.ui-header .ui-btn-icon-left .ui-icon,.ui-footer .ui-btn-icon-left .ui-icon,.ui-mini.ui-btn-icon-left .ui-icon,.ui-mini .ui-btn-icon-left .ui-icon{left:5px}.ui-header .ui-btn-icon-right .ui-icon,.ui-footer .ui-btn-icon-right .ui-icon,.ui-mini.ui-btn-icon-right .ui-icon,.ui-mini .ui-btn-icon-right .ui-icon{right:5px}.ui-header .ui-btn-icon-top .ui-icon,.ui-footer .ui-btn-icon-top .ui-icon,.ui-mini.ui-btn-icon-top .ui-icon,.ui-mini .ui-btn-icon-top .ui-icon{top:5px}.ui-header .ui-btn-icon-bottom .ui-icon,.ui-footer .ui-btn-icon-bottom .ui-icon,.ui-mini.ui-btn-icon-bottom .ui-icon,.ui-mini .ui-btn-icon-bottom .ui-icon{bottom:5px}.ui-btn-hidden{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-appearance:none;cursor:pointer;background:#fff;background:rgba(255,255,255,0);filter:Alpha(Opacity=0);opacity:.1;font-size:1px;border:0;text-indent:-9999px}.ui-disabled .ui-btn-hidden{display:none}.ui-disabled{z-index:1}.ui-field-contain .ui-btn.ui-submit{margin:0}label.ui-submit{font-size:16px;line-height:1.4;font-weight:400;margin:0 0 .3em;display:block}@media all and (min-width:28em){.ui-field-contain label.ui-submit{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-btn.ui-submit{width:78%;display:inline-block;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.ui-hide-label .ui-btn.ui-submit{width:auto;display:block}}.ui-collapsible-inset{margin:.5em 0}.ui-collapsible-heading{font-size:16px;display:block;margin:0 -15px;padding:0;position:relative}.ui-collapsible-inset .ui-collapsible-heading{margin:0}.ui-collapsible-heading .ui-btn{text-align:left;margin:0;border-left-width:0;border-right-width:0}.ui-collapsible-inset .ui-collapsible-heading .ui-btn{border-right-width:1px;border-left-width:1px}.ui-collapsible-collapsed+.ui-collapsible:not(.ui-collapsible-inset) .ui-collapsible-heading .ui-btn{border-top-width:0}.ui-collapsible-set .ui-collapsible:not(.ui-collapsible-inset) .ui-collapsible-heading .ui-btn{border-top-width:1px}.ui-collapsible-heading .ui-btn-inner{padding-left:12px;padding-right:12px}.ui-collapsible-heading .ui-btn-icon-left .ui-btn-inner{padding-left:40px}.ui-collapsible-heading .ui-btn-icon-right .ui-btn-inner{padding-right:40px}.ui-collapsible-heading .ui-btn-icon-top .ui-btn-inner,.ui-collapsible-heading .ui-btn-icon-bottom .ui-btn-inner{text-align:center}.ui-collapsible-heading .ui-btn-icon-left.ui-mini .ui-btn-inner{padding-left:30px}.ui-collapsible-heading .ui-btn-icon-right.ui-mini .ui-btn-inner{padding-right:30px}.ui-collapsible-heading .ui-btn span.ui-btn{position:absolute;left:6px;top:50%;margin:-12px 0 0 0;width:20px;height:20px;padding:1px 0 1px 2px;text-indent:-9999px}.ui-collapsible-heading .ui-btn span.ui-btn .ui-btn-inner{padding:10px 0}.ui-collapsible-heading .ui-btn span.ui-btn .ui-icon{left:0;margin-top:-10px}.ui-collapsible-heading-status{position:absolute;top:-9999px;left:0}.ui-collapsible-content{display:block;margin:0 -15px;padding:10px 15px;border-left-width:0;border-right-width:0;border-top:0;background-image:none}.ui-collapsible-inset .ui-collapsible-content{margin:0;border-right-width:1px;border-left-width:1px}.ui-collapsible-content-collapsed{display:none}.ui-collapsible-set>.ui-collapsible.ui-corner-all{-webkit-border-radius:0;border-radius:0}.ui-collapsible-heading,.ui-collapsible-heading>.ui-btn{-webkit-border-radius:inherit;border-radius:inherit}.ui-collapsible-set .ui-collapsible.ui-first-child{-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit;-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit}.ui-collapsible-content,.ui-collapsible-set .ui-collapsible.ui-last-child{-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit;-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit}.ui-collapsible-themed-content:not(.ui-collapsible-collapsed)>.ui-collapsible-heading{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0}.ui-collapsible-set{margin:.5em 0}.ui-collapsible-set .ui-collapsible{margin:-1px 0 0}.ui-collapsible-set .ui-collapsible.ui-first-child{margin-top:0}.ui-controlgroup,fieldset.ui-controlgroup{padding:0;margin:.5em 0;zoom:1}.ui-controlgroup.ui-mini,fieldset.ui-controlgroup.ui-mini{margin:.25em 0}.ui-field-contain .ui-controlgroup,.ui-field-contain fieldset.ui-controlgroup{margin:0}.ui-bar .ui-controlgroup{margin:0 5px}.ui-controlgroup-label{font-size:16px;line-height:1.4;font-weight:400;margin:0 0 .4em}.ui-controlgroup-label legend{max-width:100%}.ui-controlgroup-controls label.ui-select,.ui-controlgroup-controls label.ui-submit{position:absolute;left:-9999px}.ui-controlgroup li{list-style:none}.ui-controlgroup .ui-btn{margin:0}.ui-controlgroup .ui-btn-icon-notext{width:auto;height:auto;top:auto}.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner{height:20px;padding:.6em 20px}.ui-controlgroup-horizontal .ui-btn-icon-notext .ui-btn-inner{width:18px}.ui-controlgroup.ui-mini .ui-btn-icon-notext .ui-btn-inner,.ui-header .ui-controlgroup .ui-btn-icon-notext .ui-btn-inner,.ui-footer .ui-controlgroup .ui-btn-icon-notext .ui-btn-inner{height:16px;padding:.55em 11px .5em}.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner .ui-icon{position:absolute;top:50%;right:50%;margin:-9px -9px 0 0}.ui-controlgroup-horizontal .ui-btn-inner{text-align:center}.ui-controlgroup-horizontal.ui-mini .ui-btn-inner{height:16px;line-height:16px}.ui-controlgroup .ui-checkbox label,.ui-controlgroup .ui-radio label{font-size:16px}.ui-controlgroup-horizontal .ui-controlgroup-controls:before,.ui-controlgroup-horizontal .ui-controlgroup-controls:after{content:"";display:table}.ui-controlgroup-horizontal .ui-controlgroup-controls:after{clear:both}.ui-controlgroup-horizontal .ui-controlgroup-controls{display:inline-block;vertical-align:middle;zoom:1}.ui-controlgroup-horizontal .ui-controlgroup-controls>.ui-btn,.ui-controlgroup-horizontal .ui-controlgroup-controls li>.ui-btn,.ui-controlgroup-horizontal .ui-checkbox,.ui-controlgroup-horizontal .ui-radio,.ui-controlgroup-horizontal .ui-select{float:left;clear:none;margin:0}.ui-controlgroup-horizontal .ui-select .ui-btn-text{width:auto}.ui-controlgroup-vertical .ui-btn{border-bottom-width:0}.ui-controlgroup-vertical .ui-btn.ui-last-child{border-bottom-width:1px}.ui-controlgroup-horizontal .ui-btn{border-right-width:0}.ui-controlgroup-horizontal .ui-btn.ui-last-child{border-right-width:1px}.ui-controlgroup .ui-btn-corner-all{-webkit-border-radius:0;border-radius:0}.ui-controlgroup .ui-controlgroup-controls,.ui-controlgroup .ui-radio,.ui-controlgroup .ui-checkbox,.ui-controlgroup .ui-select,.ui-controlgroup li{-webkit-border-radius:inherit;border-radius:inherit}.ui-controlgroup-vertical .ui-btn.ui-first-child{-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit;-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit}.ui-controlgroup-vertical .ui-btn.ui-last-child{-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit;-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-controlgroup-horizontal .ui-btn.ui-first-child{-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit;-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit}.ui-controlgroup-horizontal .ui-btn.ui-last-child{-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit;-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-controlgroup .ui-shadow:not(.ui-focus){-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}@media all and (min-width:28em){.ui-field-contain .ui-controlgroup-label{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-controlgroup-controls{width:78%;display:inline-block}.ui-field-contain .ui-controlgroup .ui-select{width:100%;display:block}.ui-field-contain .ui-controlgroup-horizontal .ui-select{width:auto}.ui-hide-label .ui-controlgroup-controls{width:100%}}.ui-dialog{background:none!important}.ui-dialog-contain{width:92.5%;max-width:500px;margin:10% auto 15px;padding:0;position:relative;top:-15px}.ui-dialog-contain>.ui-header,.ui-dialog-contain>.ui-content,.ui-dialog-contain>.ui-footer{display:block;position:relative;width:auto;margin:0}.ui-dialog-contain>.ui-header{border:0;overflow:hidden;z-index:10;padding:0}.ui-dialog-contain>.ui-content{padding:15px}.ui-dialog-contain>.ui-footer{z-index:10;padding:0 15px}.ui-popup-open .ui-header-fixed,.ui-popup-open .ui-footer-fixed{position:absolute!important}.ui-popup-screen{background-image:url(data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==);top:0;left:0;right:0;bottom:1px;position:absolute;filter:Alpha(Opacity=0);opacity:0;z-index:1099}.ui-popup-screen.in{opacity:.5;filter:Alpha(Opacity=50)}.ui-popup-screen.out{opacity:0;filter:Alpha(Opacity=0)}.ui-popup-container{z-index:1100;display:inline-block;position:absolute;padding:0;outline:0}.ui-popup{position:relative}.ui-popup.ui-content,.ui-popup .ui-content{overflow:visible}.ui-popup>p,.ui-popup>h1,.ui-popup>h2,.ui-popup>h3,.ui-popup>h4,.ui-popup>h5,.ui-popup>h6{margin:.5em 7px}.ui-popup>span{display:block;margin:.5em 7px}.ui-popup .ui-title{font-size:16px;font-weight:700;margin-top:.5em;margin-bottom:.5em}.ui-popup-container .ui-content>p,.ui-popup-container .ui-content>h1,.ui-popup-container .ui-content>h2,.ui-popup-container .ui-content>h3,.ui-popup-container .ui-content>h4,.ui-popup-container .ui-content>h5,.ui-popup-container .ui-content>h6{margin:.5em 0}.ui-popup-container .ui-content>span{margin:0}.ui-popup-container .ui-content>p:first-child,.ui-popup-container .ui-content>h1:first-child,.ui-popup-container .ui-content>h2:first-child,.ui-popup-container .ui-content>h3:first-child,.ui-popup-container .ui-content>h4:first-child,.ui-popup-container .ui-content>h5:first-child,.ui-popup-container .ui-content>h6:first-child{margin-top:0}.ui-popup-container .ui-content>p:last-child,.ui-popup-container .ui-content>h1:last-child,.ui-popup-container .ui-content>h2:last-child,.ui-popup-container .ui-content>h3:last-child,.ui-popup-container .ui-content>h4:last-child,.ui-popup-container .ui-content>h5:last-child,.ui-popup-container .ui-content>h6:last-child{margin-bottom:0}.ui-popup>img{width:auto;height:auto;max-width:100%;max-height:100%;vertical-align:middle}.ui-popup:not(.ui-content)>img:only-child,.ui-popup:not(.ui-content)>.ui-btn-left:first-child+img:last-child,.ui-popup:not(.ui-content)>.ui-btn-right:first-child+img:last-child{-webkit-border-radius:inherit;border-radius:inherit}.ui-popup iframe{vertical-align:middle}@media all and (min-width:28em){.ui-popup .ui-field-contain label.ui-submit,.ui-popup .ui-field-contain .ui-controlgroup-label,.ui-popup .ui-field-contain label.ui-select,.ui-popup .ui-field-contain label.ui-input-text{font-size:16px;line-height:1.4;display:block;font-weight:400;margin:0 0 .3em}.ui-popup .ui-field-contain .ui-btn.ui-submit,.ui-popup .ui-field-contain .ui-controlgroup-controls,.ui-popup .ui-field-contain .ui-select,.ui-popup .ui-field-contain input.ui-input-text,.ui-popup .ui-field-contain textarea.ui-input-text,.ui-popup .ui-field-contain .ui-input-search{width:100%;display:block}}.ui-popup>.ui-btn-left,.ui-popup>.ui-btn-right{position:absolute;top:-9px;margin:0;z-index:1101}.ui-popup>.ui-btn-left{left:-9px}.ui-popup>.ui-btn-right{right:-9px}.ui-popup-hidden{top:-99999px;left:-9999px;visibility:hidden}.ui-checkbox,.ui-radio{position:relative;clear:both;margin:0;z-index:1}.ui-checkbox .ui-btn,.ui-radio .ui-btn{text-align:left;z-index:2}.ui-controlgroup .ui-checkbox .ui-btn,.ui-controlgroup .ui-radio .ui-btn{margin:0}.ui-checkbox .ui-btn-inner,.ui-radio .ui-btn-inner{white-space:normal}.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner{padding-left:45px}.ui-checkbox .ui-mini.ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-mini.ui-btn-icon-left .ui-btn-inner{padding-left:36px}.ui-checkbox .ui-btn-icon-right .ui-btn-inner,.ui-radio .ui-btn-icon-right .ui-btn-inner{padding-right:45px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-btn-inner,.ui-radio .ui-mini.ui-btn-icon-right .ui-btn-inner{padding-right:36px}.ui-checkbox .ui-btn-icon-top .ui-btn-inner,.ui-radio .ui-btn-icon-top .ui-btn-inner{padding-right:0;padding-left:0;text-align:center}.ui-checkbox .ui-btn-icon-bottom .ui-btn-inner,.ui-radio .ui-btn-icon-bottom .ui-btn-inner{padding-right:0;padding-left:0;text-align:center}.ui-checkbox .ui-icon,.ui-radio .ui-icon{top:1.1em}.ui-checkbox .ui-btn-icon-left .ui-icon,.ui-radio .ui-btn-icon-left .ui-icon{left:15px}.ui-checkbox .ui-mini.ui-btn-icon-left .ui-icon,.ui-radio .ui-mini.ui-btn-icon-left .ui-icon{left:9px}.ui-checkbox .ui-btn-icon-right .ui-icon,.ui-radio .ui-btn-icon-right .ui-icon{right:15px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-icon,.ui-radio .ui-mini.ui-btn-icon-right .ui-icon{right:9px}.ui-checkbox .ui-btn-icon-top .ui-icon,.ui-radio .ui-btn-icon-top .ui-icon{top:10px}.ui-checkbox .ui-btn-icon-bottom .ui-icon,.ui-radio .ui-btn-icon-bottom .ui-icon{top:auto;bottom:10px}.ui-checkbox .ui-btn-icon-right .ui-icon,.ui-radio .ui-btn-icon-right .ui-icon{right:15px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-icon,.ui-radio .ui-mini.ui-btn-icon-right .ui-icon{right:9px}.ui-controlgroup-horizontal .ui-checkbox .ui-icon,.ui-controlgroup-horizontal .ui-radio .ui-icon{display:none}.ui-controlgroup-horizontal .ui-checkbox .ui-btn-inner,.ui-controlgroup-horizontal .ui-radio .ui-btn-inner{padding:.6em 20px}.ui-controlgroup-horizontal .ui-checkbox .ui-mini .ui-btn-inner,.ui-controlgroup-horizontal .ui-radio .ui-mini .ui-btn-inner{padding:.55em 11px .5em}.ui-checkbox input,.ui-radio input{position:absolute;left:20px;top:50%;width:10px;height:10px;margin:-5px 0 0 0;outline:0!important;z-index:1}.ui-field-contain,fieldset.ui-field-contain{padding:.8em 0;margin:0;border-width:0 0 1px;overflow:visible}.ui-field-contain:last-child{border-bottom-width:0}.ui-field-contain{max-width:100%}@media all and (min-width:28em){.ui-field-contain,.ui-mobile fieldset.ui-field-contain{border-width:0;padding:0;margin:1em 0}}.ui-select{display:block;position:relative}.ui-select select{position:absolute;left:-9999px;top:-9999px}.ui-select .ui-btn{opacity:1}.ui-field-contain .ui-select .ui-btn{margin:0}.ui-select .ui-btn select{cursor:pointer;-webkit-appearance:none;left:0;top:0;width:100%;min-height:1.5em;min-height:100%;height:3em;max-height:100%;filter:Alpha(Opacity=0);opacity:0;z-index:2}.ui-select .ui-disabled{opacity:.3}.ui-select .ui-disabled select{display:none}@-moz-document url-prefix(){.ui-select .ui-btn select{opacity:.0001}}.ui-select .ui-btn.ui-select-nativeonly{border-radius:0;border:0}.ui-select .ui-btn.ui-select-nativeonly select{opacity:1;text-indent:0;display:block}.ui-select .ui-disabled.ui-select-nativeonly .ui-btn-inner{opacity:0}.ui-select .ui-btn-icon-right .ui-btn-inner,.ui-select .ui-li-has-count .ui-btn-inner{padding-right:45px}.ui-select .ui-mini.ui-btn-icon-right .ui-btn-inner{padding-right:32px}.ui-select .ui-btn-icon-right.ui-li-has-count .ui-btn-inner{padding-right:80px}.ui-select .ui-mini.ui-btn-icon-right.ui-li-has-count .ui-btn-inner{padding-right:67px}.ui-select .ui-btn-icon-right .ui-icon{right:15px}.ui-select .ui-mini.ui-btn-icon-right .ui-icon{right:7px}.ui-select .ui-btn-icon-right.ui-li-has-count .ui-li-count{right:45px}.ui-select .ui-mini.ui-btn-icon-right.ui-li-has-count .ui-li-count{right:32px}label.ui-select{font-size:16px;line-height:1.4;font-weight:400;margin:0 0 .3em;display:block}.ui-select .ui-btn-text,.ui-selectmenu .ui-btn-text{display:block;min-height:1em;overflow:hidden!important}.ui-select .ui-btn-text{text-overflow:ellipsis}.ui-selectmenu{padding:6px;min-width:160px}.ui-selectmenu .ui-listview{margin:0}.ui-selectmenu .ui-btn.ui-li-divider{cursor:default}.ui-screen-hidden,.ui-selectmenu-list .ui-li .ui-icon{display:none}.ui-selectmenu-list .ui-li .ui-icon{display:block}.ui-li.ui-selectmenu-placeholder{display:none}.ui-selectmenu .ui-header{margin:0;padding:0}.ui-selectmenu.ui-popup .ui-header{-webkit-border-top-left-radius:0;border-top-left-radius:0;-webkit-border-top-right-radius:0;border-top-right-radius:0}.ui-selectmenu .ui-header .ui-title{margin:.6em 46px .8em}@media all and (min-width:28em){.ui-field-contain label.ui-select{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-select{width:78%;display:inline-block}.ui-hide-label .ui-select{width:100%}}.ui-selectmenu .ui-header h1:after{content:'.';visibility:hidden}label.ui-input-text{font-size:16px;line-height:1.4;display:block;font-weight:400;margin:0 0 .3em}input.ui-input-text,textarea.ui-input-text{background-image:none;padding:.4em;margin:.5em 0;min-height:1.4em;line-height:1.4em;font-size:16px;display:block;width:100%;outline:0}input.ui-mini,.ui-mini input,textarea.ui-mini{font-size:14px}div.ui-input-text input.ui-input-text,div.ui-input-text textarea.ui-input-text,.ui-input-search input.ui-input-text{border:0;width:100%;padding:.4em 0;margin:0;display:block;background:transparent none;outline:0!important}.ui-input-search,div.ui-input-text{margin:.5em 0;background-image:none;position:relative}.ui-input-search{padding:0 30px}div.ui-input-text{padding:0 .4em}div.ui-input-has-clear{padding:0 30px 0 .4em}input.ui-input-text.ui-mini,textarea.ui-input-text.ui-mini,.ui-input-search.ui-mini,div.ui-input-text.ui-mini{margin:.25em 0}.ui-field-contain input.ui-input-text,.ui-field-contain textarea.ui-input-text,.ui-field-contain .ui-input-search,.ui-field-contain div.ui-input-text{margin:0}textarea.ui-input-text{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}input.ui-input-text{-webkit-appearance:none}textarea.ui-input-text{height:50px;-webkit-transition:height 200ms linear;-moz-transition:height 200ms linear;-o-transition:height 200ms linear;transition:height 200ms linear}textarea.ui-mini{height:45px}.ui-icon-searchfield:after{position:absolute;left:7px;top:50%;margin-top:-9px;content:"";width:18px;height:18px;opacity:.5}.ui-input-search .ui-input-clear,.ui-input-text .ui-input-clear{position:absolute;right:0;top:50%;margin-top:-13px}.ui-mini .ui-input-clear{right:-3px}.ui-input-search .ui-input-clear-hidden,.ui-input-text .ui-input-clear-hidden{display:none}input::-moz-placeholder,textarea::-moz-placeholder{color:#aaa}:-ms-input-placeholder{color:#aaa}input[type=number]::-webkit-outer-spin-button{margin:0}@media all and (min-width:28em){.ui-field-contain label.ui-input-text{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain input.ui-input-text,.ui-field-contain textarea.ui-input-text,.ui-field-contain .ui-input-search,.ui-field-contain div.ui-input-text{width:78%;display:inline-block}.ui-field-contain .ui-input-search,.ui-field-contain div.ui-input-text{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.ui-hide-label input.ui-input-text,.ui-hide-label textarea.ui-input-text,.ui-hide-label .ui-input-search,.ui-hide-label div.ui-input-text,.ui-input-search input.ui-input-text,div.ui-input-text input.ui-input-text{width:100%}}.ui-rangeslider{zoom:1;margin:0}.ui-rangeslider:before,.ui-rangeslider:after{content:"";display:table}.ui-rangeslider:after{clear:both}.ui-rangeslider input.ui-input-text.ui-slider-input{margin:.57143em 0}.ui-rangeslider.ui-mini input.ui-slider-input{margin:.28571em 0}.ui-rangeslider input.ui-slider-input.ui-rangeslider-last{float:right}.ui-rangeslider .ui-rangeslider-sliders{position:relative;overflow:visible;height:30px;margin:.5em 68px}.ui-rangeslider.ui-mini .ui-rangeslider-sliders{margin:.25em 68px}.ui-field-contain .ui-rangeslider input.ui-slider-input,.ui-field-contain .ui-rangeslider.ui-mini input.ui-slider-input,.ui-field-contain .ui-rangeslider .ui-rangeslider-sliders,.ui-field-contain .ui-rangeslider.ui-mini .ui-rangeslider-sliders{margin-top:0;margin-bottom:0}.ui-rangeslider .ui-rangeslider-sliders .ui-slider-track{position:absolute;top:6px;right:0;left:0;margin:0}.ui-rangeslider.ui-mini .ui-rangeslider-sliders .ui-slider-track{top:8px}.ui-rangeslider .ui-slider-track:first-child .ui-slider-bg{display:none}.ui-rangeslider .ui-rangeslider-sliders .ui-slider-track:first-child{background-color:transparent;background:0;border-width:0;height:0}html >body .ui-rangeslider .ui-rangeslider-sliders .ui-slider-track:first-child{height:15px;border-width:1px}html >body .ui-rangeslider.ui-mini .ui-rangeslider-sliders .ui-slider-track:first-child{height:12px}@media all and (min-width:28em){.ui-field-contain .ui-rangeslider label.ui-slider{float:left}.ui-field-contain .ui-rangeslider input.ui-slider-input{position:relative;z-index:1}.ui-field-contain .ui-rangeslider input.ui-slider-input.ui-rangeslider-first,.ui-field-contain .ui-rangeslider.ui-mini input.ui-slider-input.ui-rangeslider-first{margin-right:17px}.ui-field-contain .ui-rangeslider .ui-rangeslider-sliders,.ui-field-contain .ui-rangeslider.ui-mini .ui-rangeslider-sliders{float:left;width:78%;margin:0 -68px}.ui-field-contain .ui-rangeslider .ui-slider-track,.ui-field-contain .ui-rangeslider.ui-mini .ui-slider-track{right:68px;left:68px}.ui-field-contain.ui-hide-label .ui-rangeslider input.ui-slider-input.ui-rangeslider-first{margin:0}.ui-field-contain.ui-hide-label .ui-rangeslider .ui-rangeslider-sliders,.ui-field-contain.ui-hide-label .ui-rangeslider.ui-mini .ui-rangeslider-sliders{width:auto;float:none;margin:0 68px}.ui-field-contain.ui-hide-label .ui-rangeslider .ui-slider-track,.ui-field-contain.ui-hide-label .ui-rangeslider.ui-mini .ui-slider-track{right:0;left:0}}.ui-listview{margin:0}ol.ui-listview,ol.ui-listview .ui-li-divider{counter-reset:listnumbering}.ui-content .ui-listview,.ui-panel-inner>.ui-listview{margin:-15px}.ui-collapsible-content>.ui-listview{margin:-10px -15px}.ui-content .ui-listview-inset,.ui-panel-inner .ui-listview-inset{margin:1em 0}.ui-collapsible-content .ui-listview-inset{margin:.5em 0}.ui-listview,.ui-li{list-style:none;padding:0}.ui-li,.ui-li.ui-field-contain{display:block;margin:0;position:relative;overflow:visible;text-align:left;border-width:0;border-top-width:1px}.ui-li.ui-btn,.ui-li.ui-field-contain,.ui-li-divider,.ui-li-static{margin:0}.ui-listview-inset .ui-li{border-right-width:1px;border-left-width:1px}.ui-li.ui-last-child,.ui-li.ui-field-contain.ui-last-child{border-bottom-width:1px}.ui-collapsible-content>.ui-listview:not(.ui-listview-inset)>.ui-li.ui-first-child{border-top-width:0}.ui-collapsible-themed-content .ui-listview:not(.ui-listview-inset)>.ui-li.ui-last-child{border-bottom-width:0}.ui-li .ui-btn-text a.ui-link-inherit{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-static{background-image:none}.ui-li-divider{padding:.5em 15px;font-size:14px;font-weight:700}ol.ui-listview .ui-link-inherit:before,ol.ui-listview .ui-li-static:before,.ui-li-dec{font-size:.8em;display:inline-block;padding-right:.3em;font-weight:400;counter-increment:listnumbering;content:counter(listnumbering) ". "}ol.ui-listview .ui-li-jsnumbering:before{content:""!important}.ui-listview .ui-li>.ui-btn-text{-webkit-border-radius:inherit;border-radius:inherit}.ui-listview>.ui-li.ui-first-child,.ui-listview .ui-btn.ui-first-child>.ui-li>.ui-btn-text>.ui-link-inherit{-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit;-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit}.ui-listview>.ui-li.ui-last-child,.ui-listview .ui-btn.ui-last-child>.ui-li>.ui-btn-text>.ui-link-inherit,.ui-collapsible-content>.ui-listview:not(.ui-listview-inset),.ui-collapsible-content>.ui-listview:not(.ui-listview-inset) .ui-li.ui-last-child{-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit;-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit}.ui-listview>.ui-li.ui-first-child .ui-li-link-alt{-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit}.ui-listview>.ui-li.ui-last-child .ui-li-link-alt{-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-listview>.ui-li.ui-first-child .ui-li-thumb:not(.ui-li-icon){-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit}.ui-listview>.ui-li.ui-last-child .ui-li-thumb:not(.ui-li-icon){-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit}.ui-li>.ui-btn-inner{display:block;position:relative;padding:0}.ui-li .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li{padding:.7em 15px;display:block}.ui-li-has-thumb .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-thumb{min-height:59px;padding-left:100px}.ui-li-has-icon .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-icon{min-height:20px;padding-left:40px}.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-count,.ui-li-divider.ui-li-has-count{padding-right:45px}.ui-li-has-arrow .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-arrow{padding-right:40px}.ui-li-has-arrow.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-arrow.ui-li-has-count{padding-right:75px}.ui-li-heading{font-size:16px;font-weight:700;display:block;margin:.6em 0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-desc{font-size:12px;font-weight:400;display:block;margin:-.5em 0 .6em;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}ol.ui-listview>.ui-li .ui-li-heading{display:inline-block;width:100%;margin-left:-1.3em;text-indent:1.3em;vertical-align:middle}ol.ui-listview>.ui-li .ui-li-desc:not(.ui-li-aside){text-indent:1.55em}.ui-li-thumb,.ui-listview .ui-li-icon{position:absolute;left:1px;top:0;max-height:80px;max-width:80px}.ui-listview .ui-li-icon{max-height:16px;max-width:16px;left:10px;top:.9em}.ui-li-thumb,.ui-listview .ui-li-icon,.ui-li-content{float:left;margin-right:10px}.ui-li-aside{float:right;width:50%;text-align:right;margin:.3em 0}@media all and (min-width:480px){.ui-li-aside{width:45%}}.ui-li-divider{cursor:default}.ui-li-has-alt .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-alt{padding-right:53px}.ui-li-has-alt.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-alt.ui-li-has-count{padding-right:88px}.ui-li-has-count .ui-li-count{position:absolute;font-size:11px;font-weight:700;padding:.2em .5em;top:50%;margin-top:-.9em;right:10px}.ui-li-has-count.ui-li-divider .ui-li-count,.ui-li-has-count .ui-link-inherit .ui-li-count{margin-top:-.95em}.ui-li-has-arrow.ui-li-has-count .ui-li-count{right:40px}.ui-li-has-alt.ui-li-has-count .ui-li-count{right:53px}.ui-li-link-alt{position:absolute;width:40px;height:100%;border-width:0;border-left-width:1px;top:0;right:0;margin:0;padding:0;z-index:2}.ui-li-link-alt .ui-btn{overflow:hidden;position:absolute;right:8px;top:50%;margin:-13px 0 0 0;border-bottom-width:1px;z-index:-1}.ui-li-link-alt .ui-btn-inner{padding:0;height:100%;position:absolute;width:100%;top:0;left:0}.ui-li-link-alt .ui-btn .ui-icon{right:50%;margin-right:-9px}.ui-li-link-alt .ui-btn-icon-notext .ui-btn-inner .ui-icon{position:absolute;top:50%;margin-top:-9px}.ui-listview * .ui-btn-inner>.ui-btn>.ui-btn-inner{border-top:0}.ui-listview-filter{border-width:0;overflow:hidden;margin:-15px -15px 15px -15px}.ui-collapsible-content .ui-listview-filter{margin:-10px -15px 10px -15px;border-bottom:inherit}.ui-listview-filter-inset{margin:-15px -5px;background:transparent}.ui-collapsible-content .ui-listview-filter-inset{margin:-5px;border-bottom-width:0}.ui-listview-filter .ui-input-search{margin:5px;width:auto;display:block}.ui-li.ui-screen-hidden{display:none}@media only screen and (min-device-width:768px) and (max-device-width:1024px){.ui-li .ui-btn-text{overflow:visible}}label.ui-slider{font-size:16px;line-height:1.4;font-weight:400;margin:0;display:block}.ui-field-contain label.ui-slider{margin-bottom:.4em}div.ui-slider{height:30px;margin:.5em 0;zoom:1}div.ui-slider.ui-mini{margin:.25em 0}.ui-field-contain div.ui-slider,.ui-field-contain div.ui-slider.ui-mini{margin:0}div.ui-slider:before,div.ui-slider:after{content:"";display:table}div.ui-slider:after{clear:both}input.ui-input-text.ui-slider-input{display:block;float:left;margin:0;padding:4px;width:40px;height:22px;line-height:22px;font-size:14px;border-width:0;background-image:none;font-weight:700;text-align:center;vertical-align:text-bottom;outline:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;-ms-box-sizing:content-box;box-sizing:content-box}.ui-slider-input::-webkit-outer-spin-button,.ui-slider-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.ui-slider-track,.ui-slider-switch{position:relative;overflow:visible;height:15px;margin:0 15px 0 68px;top:6px}.ui-slider-track.ui-mini{height:12px;top:8px}.ui-slider-bg{border:0;height:100%}.ui-slider-track .ui-btn.ui-slider-handle,.ui-slider-switch .ui-btn.ui-slider-handle{position:absolute;z-index:1;top:50%;width:28px;height:28px;margin:-15px 0 0 -15px;outline:0}.ui-slider-track.ui-mini .ui-slider-handle{height:14px;width:14px;margin:-8px 0 0 -7px}.ui-slider-handle .ui-btn-inner{padding:0;height:100%}.ui-slider-track.ui-mini .ui-slider-handle .ui-btn-inner{height:30px;width:30px;padding:0;margin:-9px 0 0 -9px;border-top:0}select.ui-slider-switch{display:none}div.ui-slider-switch{display:inline-block;height:32px;width:5.8em;margin:.5em 0;top:0}div.ui-slider-switch:before,div.ui-slider-switch:after{display:none;clear:none}div.ui-slider-switch.ui-mini{width:5em;height:29px;margin:.25em 0;top:0}.ui-field-contain .ui-slider-switch,.ui-field-contain .ui-slider-switch.ui-mini{margin:0}.ui-slider-inneroffset{margin:0 16px;position:relative;z-index:1}.ui-slider-switch.ui-mini .ui-slider-inneroffset{margin:0 15px 0 14px}.ui-slider-switch .ui-btn.ui-slider-handle{margin:1px 0 0 -15px}.ui-slider-switch.ui-mini .ui-slider-handle{width:25px;height:25px;margin:1px 0 0 -13px;padding:0}.ui-slider-handle-snapping{-webkit-transition:left 70ms linear;-moz-transition:left 70ms linear}.ui-slider-switch.ui-mini .ui-slider-handle .ui-btn-inner{height:30px;width:30px;padding:0;margin:0;border-top:0}.ui-slider-switch .ui-slider-label{position:absolute;text-align:center;width:100%;overflow:hidden;font-size:16px;top:0;line-height:2;min-height:100%;border-width:0;white-space:nowrap;cursor:pointer}.ui-slider-switch.ui-mini .ui-slider-label{font-size:14px}.ui-slider-switch .ui-slider-label-a{z-index:1;left:0;text-indent:-1.5em}.ui-slider-switch .ui-slider-label-b{z-index:0;right:0;text-indent:1.5em}@media all and (min-width:28em){.ui-field-contain label.ui-slider{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain div.ui-slider{display:inline-block;width:78%}.ui-field-contain.ui-hide-label div.ui-slider{display:block;width:auto}.ui-field-contain div.ui-slider-switch,.ui-field-contain.ui-hide-label div.ui-slider-switch{display:inline-block;width:5.8em}.ui-field-contain div.ui-slider-switch.ui-mini{width:5em}}.ui-table{border:0;border-collapse:collapse;padding:0;width:100%}.ui-table th,.ui-table td{line-height:1.5em;text-align:left;padding:.4em .5em;vertical-align:top}.ui-table th .ui-btn,.ui-table td .ui-btn{line-height:normal}.ui-table th{font-weight:700}.ui-table caption{text-align:left;margin-bottom:1.4em;opacity:.5}.table-stroke thead th{border-bottom:1px solid #d6d6d6;border-bottom:1px solid rgba(0,0,0,.1)}.table-stroke tbody th,.table-stroke tbody td{border-bottom:1px solid #e6e6e6;border-bottom:1px solid rgba(0,0,0,.05)}.table-stripe tbody tr:nth-child(odd) td,.table-stripe tbody tr:nth-child(odd) th{background-color:#eee;background-color:rgba(0,0,0,.04)}.table-stripe thead th,.table-stripe tbody tr:last-child{border-bottom:1px solid #d6d6d6;border-bottom:1px solid rgba(0,0,0,.1)}.ui-table-columntoggle-btn{float:right;margin-bottom:.8em}.ui-table-columntoggle-popup fieldset{margin:0}@media only all{th.ui-table-priority-6,td.ui-table-priority-6,th.ui-table-priority-5,td.ui-table-priority-5,th.ui-table-priority-4,td.ui-table-priority-4,th.ui-table-priority-3,td.ui-table-priority-3,th.ui-table-priority-2,td.ui-table-priority-2,th.ui-table-priority-1,td.ui-table-priority-1{display:none}}@media screen and (min-width:20em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-1,.ui-table-columntoggle.ui-responsive td.ui-table-priority-1{display:table-cell}}@media screen and (min-width:30em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-2,.ui-table-columntoggle.ui-responsive td.ui-table-priority-2{display:table-cell}}@media screen and (min-width:40em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-3,.ui-table-columntoggle.ui-responsive td.ui-table-priority-3{display:table-cell}}@media screen and (min-width:50em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-4,.ui-table-columntoggle.ui-responsive td.ui-table-priority-4{display:table-cell}}@media screen and (min-width:60em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-5,.ui-table-columntoggle.ui-responsive td.ui-table-priority-5{display:table-cell}}@media screen and (min-width:70em){.ui-table-columntoggle.ui-responsive th.ui-table-priority-6,.ui-table-columntoggle.ui-responsive td.ui-table-priority-6{display:table-cell}}.ui-table-columntoggle th.ui-table-cell-hidden,.ui-table-columntoggle td.ui-table-cell-hidden,.ui-table-columntoggle.ui-responsive th.ui-table-cell-hidden,.ui-table-columntoggle.ui-responsive td.ui-table-cell-hidden{display:none}.ui-table-columntoggle th.ui-table-cell-visible,.ui-table-columntoggle td.ui-table-cell-visible,.ui-table-columntoggle.ui-responsive th.ui-table-cell-visible,.ui-table-columntoggle.ui-responsive td.ui-table-cell-visible{display:table-cell}.ui-table-reflow td .ui-table-cell-label,.ui-table-reflow th .ui-table-cell-label{display:none}@media only all{.ui-table-reflow thead td,.ui-table-reflow thead th{display:none}.ui-table-reflow td,.ui-table-reflow th{text-align:left;display:block}.ui-table-reflow tbody th{margin-top:3em}.ui-table-reflow td .ui-table-cell-label,.ui-table-reflow th .ui-table-cell-label{padding:.4em;min-width:30%;display:inline-block;margin:-.4em 1em -.4em -.4em}.ui-table-reflow th .ui-table-cell-label-top,.ui-table-reflow td .ui-table-cell-label-top{display:block;padding:.4em 0;margin:.4em 0;text-transform:uppercase;font-size:.9em;font-weight:400}}@media (min-width:35em){.ui-table-reflow.ui-responsive{display:table-row-group}.ui-table-reflow.ui-responsive td,.ui-table-reflow.ui-responsive th,.ui-table-reflow.ui-responsive tbody th,.ui-table-reflow.ui-responsive tbody td,.ui-table-reflow.ui-responsive thead td,.ui-table-reflow.ui-responsive thead th{display:table-cell;margin:0}.ui-table-reflow.ui-responsive td .ui-table-cell-label,.ui-table-reflow.ui-responsive th .ui-table-cell-label{display:none}}@media (max-width:35em){.ui-table-reflow.ui-responsive td,.ui-table-reflow.ui-responsive th{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;clear:left}}.ui-panel{width:17em;min-height:100%;max-height:none;border-width:0;position:absolute;top:0;display:block}.ui-panel-closed{width:0;max-height:100%;overflow:hidden;visibility:hidden}.ui-panel-fixed{position:fixed;bottom:-1px;padding-bottom:1px}.ui-panel-display-overlay{z-index:1001}.ui-panel-display-reveal{z-index:0}.ui-panel-display-push{z-index:999}.ui-panel-inner{padding:15px}.ui-panel-content-wrap{position:relative;left:0;min-height:inherit;border:0;z-index:999}.ui-panel-content-wrap-display-overlay,.ui-panel-animate.ui-panel-content-wrap>.ui-header,.ui-panel-content-wrap-closed{position:static}.ui-panel-dismiss{position:absolute;top:0;left:0;height:100%;width:100%;z-index:1002;display:none}.ui-panel-dismiss-open{display:block}.ui-panel-animate{-webkit-transition:-webkit-transform 350ms ease;-moz-transition:-moz-transform 350ms ease;transition:transform 350ms ease}.ui-panel-animate.ui-panel:not(.ui-panel-display-reveal),.ui-panel-animate.ui-panel:not(.ui-panel-display-reveal)>div,.ui-panel-animate.ui-panel-closed.ui-panel-display-reveal>div,.ui-panel-animate.ui-panel-content-wrap,.ui-panel-animate.ui-panel-content-fixed-toolbar{-webkit-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0)}.ui-panel-position-left{left:-17em}.ui-panel-animate.ui-panel-position-left.ui-panel-display-overlay,.ui-panel-animate.ui-panel-position-left.ui-panel-display-push{left:0;-webkit-transform:translate3d(-17em,0,0);-moz-transform:translate3d(-17em,0,0);transform:translate3d(-17em,0,0)}.ui-panel-position-left.ui-panel-display-reveal,.ui-panel-position-left.ui-panel-open{left:0}.ui-panel-animate.ui-panel-position-left.ui-panel-open.ui-panel-display-overlay,.ui-panel-animate.ui-panel-position-left.ui-panel-open.ui-panel-display-push{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-moz-transform:none}.ui-panel-position-right{right:-17em}.ui-panel-animate.ui-panel-position-right.ui-panel-display-overlay,.ui-panel-animate.ui-panel-position-right.ui-panel-display-push{right:0;-webkit-transform:translate3d(17em,0,0);-moz-transform:translate3d(17em,0,0);transform:translate3d(17em,0,0)}.ui-panel-position-right.ui-panel-display-reveal,.ui-panel-position-right.ui-panel-open{right:0}.ui-panel-animate.ui-panel-position-right.ui-panel-open.ui-panel-display-overlay,.ui-panel-animate.ui-panel-position-right.ui-panel-open.ui-panel-display-push{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-moz-transform:none}.ui-panel-content-fixed-toolbar-position-left.ui-panel-content-fixed-toolbar-open,.ui-panel-content-wrap-position-left.ui-panel-content-wrap-open,.ui-panel-dismiss-position-left.ui-panel-dismiss-open{left:17em;right:-17em}.ui-panel-animate.ui-panel-content-fixed-toolbar-position-left.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-reveal,.ui-panel-animate.ui-panel-content-fixed-toolbar-position-left.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-push,.ui-panel-animate.ui-panel-content-wrap-position-left.ui-panel-content-wrap-open.ui-panel-content-wrap-display-reveal,.ui-panel-animate.ui-panel-content-wrap-position-left.ui-panel-content-wrap-open.ui-panel-content-wrap-display-push{left:0;right:0;-webkit-transform:translate3d(17em,0,0);-moz-transform:translate3d(17em,0,0);transform:translate3d(17em,0,0)}.ui-panel-content-fixed-toolbar-position-right.ui-panel-content-fixed-toolbar-open,.ui-panel-content-wrap-position-right.ui-panel-content-wrap-open,.ui-panel-dismiss-position-right.ui-panel-dismiss-open{left:-17em;right:17em}.ui-panel-animate.ui-panel-content-fixed-toolbar-position-right.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-reveal,.ui-panel-animate.ui-panel-content-fixed-toolbar-position-right.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-push,.ui-panel-animate.ui-panel-content-wrap-position-right.ui-panel-content-wrap-open.ui-panel-content-wrap-display-reveal,.ui-panel-animate.ui-panel-content-wrap-position-right.ui-panel-content-wrap-open.ui-panel-content-wrap-display-push{left:0;right:0;-webkit-transform:translate3d(-17em,0,0);-moz-transform:translate3d(-17em,0,0);transform:translate3d(-17em,0,0)}.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-overlay,.ui-panel-content-wrap-open.ui-panel-content-wrap-display-overlay{left:0}.ui-page-active.ui-page-panel{overflow-x:hidden}.ui-panel-display-reveal{-webkit-box-shadow:inset -5px 0 5px rgba(0,0,0,.15);-moz-box-shadow:inset -5px 0 5px rgba(0,0,0,.15);box-shadow:inset -5px 0 5px rgba(0,0,0,.15)}.ui-panel-position-right.ui-panel-display-reveal{-webkit-box-shadow:inset 5px 0 5px rgba(0,0,0,.15);-moz-box-shadow:inset 5px 0 5px rgba(0,0,0,.15);box-shadow:inset 5px 0 5px rgba(0,0,0,.15)}.ui-panel-display-overlay{-webkit-box-shadow:5px 0 5px rgba(0,0,0,.15);-moz-box-shadow:5px 0 5px rgba(0,0,0,.15);box-shadow:5px 0 5px rgba(0,0,0,.15)}.ui-panel-position-right.ui-panel-display-overlay{-webkit-box-shadow:-5px 0 5px rgba(0,0,0,.15);-moz-box-shadow:-5px 0 5px rgba(0,0,0,.15);box-shadow:-5px 0 5px rgba(0,0,0,.15)}.ui-panel-display-push.ui-panel-open.ui-panel-position-left{border-right-width:1px;margin-right:-1px}.ui-panel-animate.ui-panel-content-fixed-toolbar-position-left.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-push{margin-left:1px}.ui-panel-display-push.ui-panel-open.ui-panel-position-right{border-left-width:1px;margin-left:-1px}.ui-panel-animate.ui-panel-content-fixed-toolbar-position-right.ui-panel-content-fixed-toolbar-open.ui-panel-content-fixed-toolbar-display-push{margin-right:1px}@media (min-width:55em){.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-push.ui-panel-content-fixed-toolbar-position-left,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-reveal.ui-panel-content-fixed-toolbar-position-left,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-display-push.ui-panel-content-wrap-position-left,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-display-reveal.ui-panel-content-wrap-position-left{margin-right:17em}.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-push.ui-panel-content-fixed-toolbar-position-right,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-reveal.ui-panel-content-fixed-toolbar-position-right,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-display-push.ui-panel-content-wrap-position-right,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-wrap-display-reveal.ui-panel-content-wrap-position-right{margin-left:17em}.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-push,.ui-responsive-panel.ui-page-panel-open .ui-panel-content-fixed-toolbar-display-reveal{width:auto}.ui-responsive-panel .ui-panel-dismiss-display-push{display:none}} \ No newline at end of file diff --git a/Vocaluxe/Website/css/jquery.mobile.theme-1.3.2.min.css b/Vocaluxe/Website/css/jquery.mobile.theme-1.3.2.min.css deleted file mode 100644 index 229e0adc..00000000 --- a/Vocaluxe/Website/css/jquery.mobile.theme-1.3.2.min.css +++ /dev/null @@ -1,12 +0,0 @@ -/*! jQuery Mobile 1.3.2 | Git HEAD hash: 528cf0e <> 2013-07-19T22:17:57Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */ - -/*! -* jQuery Mobile 1.3.2 -* Git HEAD hash: 528cf0e96940644ea644096bfeb913ed920ffaef <> Date: Fri Jul 19 2013 22:17:57 UTC -* http://jquerymobile.com -* -* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors -* Released under the MIT license. -* http://jquery.org/license -* -*/.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:700;text-shadow:0 -1px 0 #000;background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#111));background-image:-webkit-linear-gradient(#3c3c3c,#111);background-image:-moz-linear-gradient(#3c3c3c,#111);background-image:-ms-linear-gradient(#3c3c3c,#111);background-image:-o-linear-gradient(#3c3c3c,#111);background-image:linear-gradient(#3c3c3c,#111)}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-a a.ui-link:visited{color:#2489ce}.ui-bar-a a.ui-link:hover{color:#2489ce}.ui-bar-a a.ui-link:active{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 0 #111;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#222));background-image:-webkit-linear-gradient(#444,#222);background-image:-moz-linear-gradient(#444,#222);background-image:-ms-linear-gradient(#444,#222);background-image:-o-linear-gradient(#444,#222);background-image:linear-gradient(#444,#222)}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:700}.ui-body-a .ui-link:visited{color:#2489ce}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#2d2d2d));background-image:-webkit-linear-gradient(#444,#2d2d2d);background-image:-moz-linear-gradient(#444,#2d2d2d);background-image:-ms-linear-gradient(#444,#2d2d2d);background-image:-o-linear-gradient(#444,#2d2d2d);background-image:linear-gradient(#444,#2d2d2d)}.ui-btn-up-a:visited,.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#555),to(#383838));background-image:-webkit-linear-gradient(#555,#383838);background-image:-moz-linear-gradient(#555,#383838);background-image:-ms-linear-gradient(#555,#383838);background-image:-o-linear-gradient(#555,#383838);background-image:linear-gradient(#555,#383838)}.ui-btn-hover-a:visited,.ui-btn-hover-a:hover,.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#202020),to(#2c2c2c));background-image:-webkit-linear-gradient(#202020,#2c2c2c);background-image:-moz-linear-gradient(#202020,#2c2c2c);background-image:-ms-linear-gradient(#202020,#2c2c2c);background-image:-o-linear-gradient(#202020,#2c2c2c);background-image:linear-gradient(#202020,#2c2c2c)}.ui-btn-down-a:visited,.ui-btn-down-a:hover,.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:700;text-shadow:0 1px 0 #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#497bae));background-image:-webkit-linear-gradient(#6facd5,#497bae);background-image:-moz-linear-gradient(#6facd5,#497bae);background-image:-ms-linear-gradient(#6facd5,#497bae);background-image:-o-linear-gradient(#6facd5,#497bae);background-image:linear-gradient(#6facd5,#497bae)}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b a.ui-link{color:#ddf0f8;font-weight:700}.ui-bar-b a.ui-link:visited{color:#ddf0f8}.ui-bar-b a.ui-link:hover{color:#ddf0f8}.ui-bar-b a.ui-link:active{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#ccc));background-image:-webkit-linear-gradient(#ddd,#ccc);background-image:-moz-linear-gradient(#ddd,#ccc);background-image:-ms-linear-gradient(#ddd,#ccc);background-image:-o-linear-gradient(#ddd,#ccc);background-image:linear-gradient(#ddd,#ccc)}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:700}.ui-body-b .ui-link:visited{color:#2489ce}.ui-body-b .ui-link:hover{color:#2489ce}.ui-body-b .ui-link:active{color:#2489ce}.ui-btn-up-b{border:1px solid #044062;background:#396b9e;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#5f9cc5),to(#396b9e));background-image:-webkit-linear-gradient(#5f9cc5,#396b9e);background-image:-moz-linear-gradient(#5f9cc5,#396b9e);background-image:-ms-linear-gradient(#5f9cc5,#396b9e);background-image:-o-linear-gradient(#5f9cc5,#396b9e);background-image:linear-gradient(#5f9cc5,#396b9e)}.ui-btn-up-b:visited,.ui-btn-up-b a.ui-link-inherit{color:#fff}.ui-btn-hover-b{border:1px solid #00415e;background:#4b88b6;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#4272a4));background-image:-webkit-linear-gradient(#6facd5,#4272a4);background-image:-moz-linear-gradient(#6facd5,#4272a4);background-image:-ms-linear-gradient(#6facd5,#4272a4);background-image:-o-linear-gradient(#6facd5,#4272a4);background-image:linear-gradient(#6facd5,#4272a4)}.ui-btn-hover-b:visited,.ui-btn-hover-b:hover,.ui-btn-hover-b a.ui-link-inherit{color:#fff}.ui-btn-down-b{border:1px solid #225377;background:#4e89c5;font-weight:700;color:#fff;text-shadow:0 1px 0 #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#295b8e),to(#3e79b5));background-image:-webkit-linear-gradient(#295b8e,#3e79b5);background-image:-moz-linear-gradient(#295b8e,#3e79b5);background-image:-ms-linear-gradient(#295b8e,#3e79b5);background-image:-o-linear-gradient(#295b8e,#3e79b5);background-image:linear-gradient(#295b8e,#3e79b5)}.ui-btn-down-b:visited,.ui-btn-down-b:hover,.ui-btn-down-b a.ui-link-inherit{color:#fff}.ui-btn-up-b,.ui-btn-hover-b,.ui-btn-down-b{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-c{border:1px solid #b3b3b3;background:#eee;color:#3e3e3e;font-weight:700;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#ddd));background-image:-webkit-linear-gradient(#f0f0f0,#ddd);background-image:-moz-linear-gradient(#f0f0f0,#ddd);background-image:-ms-linear-gradient(#f0f0f0,#ddd);background-image:-o-linear-gradient(#f0f0f0,#ddd);background-image:linear-gradient(#f0f0f0,#ddd)}.ui-bar-c .ui-link-inherit{color:#3e3e3e}.ui-bar-c a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-c a.ui-link:visited{color:#2489ce}.ui-bar-c a.ui-link:hover{color:#2489ce}.ui-bar-c a.ui-link:active{color:#2489ce}.ui-bar-c,.ui-bar-c input,.ui-bar-c select,.ui-bar-c textarea,.ui-bar-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c,.ui-overlay-c{border:1px solid #aaa;color:#333;text-shadow:0 1px 0 #fff;background:#f9f9f9;background-image:-webkit-gradient(linear,left top,left bottom,from(#f9f9f9),to(#eee));background-image:-webkit-linear-gradient(#f9f9f9,#eee);background-image:-moz-linear-gradient(#f9f9f9,#eee);background-image:-ms-linear-gradient(#f9f9f9,#eee);background-image:-o-linear-gradient(#f9f9f9,#eee);background-image:linear-gradient(#f9f9f9,#eee)}.ui-overlay-c{background-image:none;border-width:0}.ui-body-c,.ui-body-c input,.ui-body-c select,.ui-body-c textarea,.ui-body-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c .ui-link-inherit{color:#333}.ui-body-c .ui-link{color:#2489ce;font-weight:700}.ui-body-c .ui-link:visited{color:#2489ce}.ui-body-c .ui-link:hover{color:#2489ce}.ui-body-c .ui-link:active{color:#2489ce}.ui-btn-up-c{border:1px solid #ccc;background:#eee;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f1f1f1));background-image:-webkit-linear-gradient(#fff,#f1f1f1);background-image:-moz-linear-gradient(#fff,#f1f1f1);background-image:-ms-linear-gradient(#fff,#f1f1f1);background-image:-o-linear-gradient(#fff,#f1f1f1);background-image:linear-gradient(#fff,#f1f1f1)}.ui-btn-up-c:visited,.ui-btn-up-c a.ui-link-inherit{color:#2f3e46}.ui-btn-hover-c{border:1px solid #bbb;background:#dfdfdf;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f6f6f6),to(#e0e0e0));background-image:-webkit-linear-gradient(#f6f6f6,#e0e0e0);background-image:-moz-linear-gradient(#f6f6f6,#e0e0e0);background-image:-ms-linear-gradient(#f6f6f6,#e0e0e0);background-image:-o-linear-gradient(#f6f6f6,#e0e0e0);background-image:linear-gradient(#f6f6f6,#e0e0e0)}.ui-btn-hover-c:visited,.ui-btn-hover-c:hover,.ui-btn-hover-c a.ui-link-inherit{color:#2f3e46}.ui-btn-down-c{border:1px solid #bbb;background:#d6d6d6;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#d0d0d0),to(#dfdfdf));background-image:-webkit-linear-gradient(#d0d0d0,#dfdfdf);background-image:-moz-linear-gradient(#d0d0d0,#dfdfdf);background-image:-ms-linear-gradient(#d0d0d0,#dfdfdf);background-image:-o-linear-gradient(#d0d0d0,#dfdfdf);background-image:linear-gradient(#d0d0d0,#dfdfdf)}.ui-btn-down-c:visited,.ui-btn-down-c:hover,.ui-btn-down-c a.ui-link-inherit{color:#2f3e46}.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-d{border:1px solid #bbb;background:#bbb;color:#333;font-weight:700;text-shadow:0 1px 0 #eee;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#bbb));background-image:-webkit-linear-gradient(#ddd,#bbb);background-image:-moz-linear-gradient(#ddd,#bbb);background-image:-ms-linear-gradient(#ddd,#bbb);background-image:-o-linear-gradient(#ddd,#bbb);background-image:linear-gradient(#ddd,#bbb)}.ui-bar-d,.ui-bar-d input,.ui-bar-d select,.ui-bar-d textarea,.ui-bar-d button{font-family:Helvetica,Arial,sans-serif}.ui-bar-d .ui-link-inherit{color:#333}.ui-bar-d a.ui-link{color:#2489ce;font-weight:700}.ui-bar-d a.ui-link:visited{color:#2489ce}.ui-bar-d a.ui-link:hover{color:#2489ce}.ui-bar-d a.ui-link:active{color:#2489ce}.ui-body-d,.ui-overlay-d{border:1px solid #bbb;color:#333;text-shadow:0 1px 0 #fff;background:#fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#fff));background-image:-webkit-linear-gradient(#fff,#fff);background-image:-moz-linear-gradient(#fff,#fff);background-image:-ms-linear-gradient(#fff,#fff);background-image:-o-linear-gradient(#fff,#fff);background-image:linear-gradient(#fff,#fff)}.ui-overlay-d{background-image:none;border-width:0}.ui-body-d,.ui-body-d input,.ui-body-d select,.ui-body-d textarea,.ui-body-d button{font-family:Helvetica,Arial,sans-serif}.ui-body-d .ui-link-inherit{color:#333}.ui-body-d .ui-link{color:#2489ce;font-weight:700}.ui-body-d .ui-link:visited{color:#2489ce}.ui-body-d .ui-link:hover{color:#2489ce}.ui-body-d .ui-link:active{color:#2489ce}.ui-btn-up-d{border:1px solid #bbb;background:#fff;font-weight:700;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#f6f6f6));background-image:-webkit-linear-gradient(#fafafa,#f6f6f6);background-image:-moz-linear-gradient(#fafafa,#f6f6f6);background-image:-ms-linear-gradient(#fafafa,#f6f6f6);background-image:-o-linear-gradient(#fafafa,#f6f6f6);background-image:linear-gradient(#fafafa,#f6f6f6)}.ui-btn-up-d:visited,.ui-btn-up-d a.ui-link-inherit{color:#333}.ui-btn-hover-d{border:1px solid #aaa;background:#eee;font-weight:700;color:#333;cursor:pointer;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#eee),to(#fff));background-image:-webkit-linear-gradient(#eee,#fff);background-image:-moz-linear-gradient(#eee,#fff);background-image:-ms-linear-gradient(#eee,#fff);background-image:-o-linear-gradient(#eee,#fff);background-image:linear-gradient(#eee,#fff)}.ui-btn-hover-d:visited,.ui-btn-hover-d:hover,.ui-btn-hover-d a.ui-link-inherit{color:#333}.ui-btn-down-d{border:1px solid #aaa;background:#eee;font-weight:700;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#e5e5e5),to(#f2f2f2));background-image:-webkit-linear-gradient(#e5e5e5,#f2f2f2);background-image:-moz-linear-gradient(#e5e5e5,#f2f2f2);background-image:-ms-linear-gradient(#e5e5e5,#f2f2f2);background-image:-o-linear-gradient(#e5e5e5,#f2f2f2);background-image:linear-gradient(#e5e5e5,#f2f2f2)}.ui-btn-down-d:visited,.ui-btn-down-d:hover,.ui-btn-down-d a.ui-link-inherit{color:#333}.ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-e{border:1px solid #f7c942;background:#fadb4e;color:#333;font-weight:700;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fceda7),to(#fbef7e));background-image:-webkit-linear-gradient(#fceda7,#fbef7e);background-image:-moz-linear-gradient(#fceda7,#fbef7e);background-image:-ms-linear-gradient(#fceda7,#fbef7e);background-image:-o-linear-gradient(#fceda7,#fbef7e);background-image:linear-gradient(#fceda7,#fbef7e)}.ui-bar-e,.ui-bar-e input,.ui-bar-e select,.ui-bar-e textarea,.ui-bar-e button{font-family:Helvetica,Arial,sans-serif}.ui-bar-e .ui-link-inherit{color:#333}.ui-bar-e a.ui-link{color:#2489ce;font-weight:700}.ui-bar-e a.ui-link:visited{color:#2489ce}.ui-bar-e a.ui-link:hover{color:#2489ce}.ui-bar-e a.ui-link:active{color:#2489ce}.ui-body-e,.ui-overlay-e{border:1px solid #f7c942;color:#222;text-shadow:0 1px 0 #fff;background:#fff9df;background-image:-webkit-gradient(linear,left top,left bottom,from(#fffadf),to(#fff3a5));background-image:-webkit-linear-gradient(#fffadf,#fff3a5);background-image:-moz-linear-gradient(#fffadf,#fff3a5);background-image:-ms-linear-gradient(#fffadf,#fff3a5);background-image:-o-linear-gradient(#fffadf,#fff3a5);background-image:linear-gradient(#fffadf,#fff3a5)}.ui-overlay-e{background-image:none;border-width:0}.ui-body-e,.ui-body-e input,.ui-body-e select,.ui-body-e textarea,.ui-body-e button{font-family:Helvetica,Arial,sans-serif}.ui-body-e .ui-link-inherit{color:#222}.ui-body-e .ui-link{color:#2489ce;font-weight:700}.ui-body-e .ui-link:visited{color:#2489ce}.ui-body-e .ui-link:hover{color:#2489ce}.ui-body-e .ui-link:active{color:#2489ce}.ui-btn-up-e{border:1px solid #f4c63f;background:#fadb4e;font-weight:700;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#ffefaa),to(#ffe155));background-image:-webkit-linear-gradient(#ffefaa,#ffe155);background-image:-moz-linear-gradient(#ffefaa,#ffe155);background-image:-ms-linear-gradient(#ffefaa,#ffe155);background-image:-o-linear-gradient(#ffefaa,#ffe155);background-image:linear-gradient(#ffefaa,#ffe155)}.ui-btn-up-e:visited,.ui-btn-up-e a.ui-link-inherit{color:#222}.ui-btn-hover-e{border:1px solid #f2c43d;background:#fbe26f;font-weight:700;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff5ba),to(#fbdd52));background-image:-webkit-linear-gradient(#fff5ba,#fbdd52);background-image:-moz-linear-gradient(#fff5ba,#fbdd52);background-image:-ms-linear-gradient(#fff5ba,#fbdd52);background-image:-o-linear-gradient(#fff5ba,#fbdd52);background-image:linear-gradient(#fff5ba,#fbdd52)}.ui-btn-hover-e:visited,.ui-btn-hover-e:hover,.ui-btn-hover-e a.ui-link-inherit{color:#333}.ui-btn-down-e{border:1px solid #f2c43d;background:#fceda7;font-weight:700;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f8d94c),to(#fadb4e));background-image:-webkit-linear-gradient(#f8d94c,#fadb4e);background-image:-moz-linear-gradient(#f8d94c,#fadb4e);background-image:-ms-linear-gradient(#f8d94c,#fadb4e);background-image:-o-linear-gradient(#f8d94c,#fadb4e);background-image:linear-gradient(#f8d94c,#fadb4e)}.ui-btn-down-e:visited,.ui-btn-down-e:hover,.ui-btn-down-e a.ui-link-inherit{color:#333}.ui-btn-up-e,.ui-btn-hover-e,.ui-btn-down-e{font-family:Helvetica,Arial,sans-serif;text-decoration:none}a.ui-link-inherit{text-decoration:none!important}.ui-btn-active{border:1px solid #2373a5;background:#5393c5;font-weight:700;color:#fff;cursor:pointer;text-shadow:0 1px 0 #3373a5;text-decoration:none;background-image:-webkit-gradient(linear,left top,left bottom,from(#5393c5),to(#6facd5));background-image:-webkit-linear-gradient(#5393c5,#6facd5);background-image:-moz-linear-gradient(#5393c5,#6facd5);background-image:-ms-linear-gradient(#5393c5,#6facd5);background-image:-o-linear-gradient(#5393c5,#6facd5);background-image:linear-gradient(#5393c5,#6facd5);font-family:Helvetica,Arial,sans-serif}.ui-btn-active:visited,.ui-btn-active:hover,.ui-btn-active a.ui-link-inherit{color:#fff}.ui-btn-inner{border-top:1px solid #fff;border-color:rgba(255,255,255,.3)}.ui-corner-all{-webkit-border-radius:.6em;border-radius:.6em}.ui-br{border-color:#828282;border-color:rgba(130,130,130,.3);border-style:solid}.ui-disabled{filter:Alpha(Opacity=30);opacity:.3;zoom:1}.ui-disabled,.ui-disabled a{cursor:default!important;pointer-events:none}.ui-icon,.ui-icon-searchfield:after{background:#666;background:rgba(0,0,0,.4);background-image:url(images/icons-18-white.png);background-repeat:no-repeat;-webkit-border-radius:9px;border-radius:9px}.ui-icon-alt .ui-icon,.ui-icon-alt .ui-icon-searchfield:after{background-color:#fff;background-color:rgba(255,255,255,.3);background-image:url(images/icons-18-black.png);background-repeat:no-repeat}.ui-icon-nodisc .ui-icon,.ui-icon-nodisc .ui-icon-searchfield:after,.ui-icon-nodisc .ui-icon-alt .ui-icon,.ui-icon-nodisc .ui-icon-alt .ui-icon-searchfield:after{background-color:transparent}.ui-icon-plus{background-position:-1px -1px}.ui-icon-minus{background-position:-37px -1px}.ui-icon-delete{background-position:-73px -1px}.ui-icon-arrow-r{background-position:-108px -1px}.ui-icon-arrow-l{background-position:-144px -1px}.ui-icon-arrow-u{background-position:-180px -1px}.ui-icon-arrow-d{background-position:-216px -1px}.ui-icon-check{background-position:-252px -1px}.ui-icon-gear{background-position:-288px -1px}.ui-icon-refresh{background-position:-323px -1px}.ui-icon-forward{background-position:-360px -1px}.ui-icon-back{background-position:-396px -1px}.ui-icon-grid{background-position:-432px -1px}.ui-icon-star{background-position:-467px -1px}.ui-icon-alert{background-position:-503px -1px}.ui-icon-info{background-position:-539px -1px}.ui-icon-home{background-position:-575px -1px}.ui-icon-search,.ui-icon-searchfield:after{background-position:-611px -1px}.ui-icon-checkbox-on{background-position:-647px -1px}.ui-icon-checkbox-off{background-position:-683px -1px}.ui-icon-radio-on{background-position:-718px -1px}.ui-icon-radio-off{background-position:-754px -1px}.ui-icon-bars{background-position:-788px -1px}.ui-icon-edit{background-position:-824px -1px}@media only screen and (-webkit-min-device-pixel-ratio:1.3),only screen and (min--moz-device-pixel-ratio:1.3),only screen and (min-resolution:200dpi){.ui-icon-plus,.ui-icon-minus,.ui-icon-delete,.ui-icon-arrow-r,.ui-icon-arrow-l,.ui-icon-arrow-u,.ui-icon-arrow-d,.ui-icon-check,.ui-icon-gear,.ui-icon-refresh,.ui-icon-forward,.ui-icon-back,.ui-icon-grid,.ui-icon-star,.ui-icon-alert,.ui-icon-info,.ui-icon-home,.ui-icon-bars,.ui-icon-edit,.ui-icon-search,.ui-icon-searchfield:after,.ui-icon-checkbox-off,.ui-icon-checkbox-on,.ui-icon-radio-off,.ui-icon-radio-on{background-image:url(images/icons-36-white.png);-moz-background-size:864px 18px;-o-background-size:864px 18px;-webkit-background-size:864px 18px;background-size:864px 18px}.ui-icon-alt .ui-icon{background-image:url(images/icons-36-black.png)}.ui-icon-plus{background-position:0 50%}.ui-icon-minus{background-position:-36px 50%}.ui-icon-delete{background-position:-72px 50%}.ui-icon-arrow-r{background-position:-108px 50%}.ui-icon-arrow-l{background-position:-144px 50%}.ui-icon-arrow-u{background-position:-179px 50%}.ui-icon-arrow-d{background-position:-215px 50%}.ui-icon-check{background-position:-252px 50%}.ui-icon-gear{background-position:-287px 50%}.ui-icon-refresh{background-position:-323px 50%}.ui-icon-forward{background-position:-360px 50%}.ui-icon-back{background-position:-395px 50%}.ui-icon-grid{background-position:-431px 50%}.ui-icon-star{background-position:-467px 50%}.ui-icon-alert{background-position:-503px 50%}.ui-icon-info{background-position:-538px 50%}.ui-icon-home{background-position:-575px 50%}.ui-icon-search,.ui-icon-searchfield:after{background-position:-611px 50%}.ui-icon-checkbox-on{background-position:-647px 50%}.ui-icon-checkbox-off{background-position:-683px 50%}.ui-icon-radio-on{background-position:-718px 50%}.ui-icon-radio-off{background-position:-754px 50%}.ui-icon-bars{background-position:-788px 50%}.ui-icon-edit{background-position:-824px 50%}}.ui-checkbox .ui-icon,.ui-selectmenu-list .ui-icon{-webkit-border-radius:3px;border-radius:3px}.ui-icon-checkbox-off,.ui-icon-radio-off{background-color:transparent}.ui-checkbox-on .ui-icon,.ui-radio-on .ui-icon{background-color:#4596ce}.ui-icon-loading{background:url(images/ajax-loader.gif);background-size:46px 46px}.ui-btn-corner-all{-webkit-border-radius:1em;border-radius:1em}.ui-corner-all,.ui-btn-corner-all{-webkit-background-clip:padding;background-clip:padding-box}.ui-overlay{background:#666;filter:Alpha(Opacity=50);opacity:.5;position:absolute;width:100%;height:100%}.ui-overlay-shadow{-moz-box-shadow:0 0 12px rgba(0,0,0,.6);-webkit-box-shadow:0 0 12px rgba(0,0,0,.6);box-shadow:0 0 12px rgba(0,0,0,.6)}.ui-shadow{-moz-box-shadow:0 1px 3px rgba(0,0,0,.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,.2);box-shadow:0 1px 3px rgba(0,0,0,.2)}.ui-bar-a .ui-shadow,.ui-bar-b .ui-shadow,.ui-bar-c .ui-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.ui-shadow-inset{-moz-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);box-shadow:inset 0 1px 4px rgba(0,0,0,.2)}.ui-icon-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.4);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.4);box-shadow:0 1px 0 rgba(255,255,255,.4)}.ui-btn:focus,.ui-link-inherit:focus{outline:0}.ui-btn.ui-focus{z-index:1}.ui-focus,.ui-btn:focus{-moz-box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe;-webkit-box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe;box-shadow:inset 0 0 3px #387bbe,0 0 9px #387bbe}.ui-input-text.ui-focus,.ui-input-search.ui-focus{-moz-box-shadow:0 0 12px #387bbe;-webkit-box-shadow:0 0 12px #387bbe;box-shadow:0 0 12px #387bbe}.ui-mobile-nosupport-boxshadow *{-moz-box-shadow:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui-mobile-nosupport-boxshadow .ui-focus,.ui-mobile-nosupport-boxshadow .ui-btn:focus,.ui-mobile-nosupport-boxshadow .ui-link-inherit:focus{outline-width:1px;outline-style:auto} \ No newline at end of file diff --git a/Vocaluxe/Website/css/style.css b/Vocaluxe/Website/css/style.css deleted file mode 100644 index 19f6762c..00000000 --- a/Vocaluxe/Website/css/style.css +++ /dev/null @@ -1,121 +0,0 @@ -#playerAvatar { - height: 75%; - max-height: 250px; - width: auto; -} - -#playerName { - text-align: center; - font-size: 20px; - font-weight: bold; -} - -#displayProfileContent { - text-align: center; -} - -#keyboardContent { - text-align: center; -} - -.overlay { - position: relative; - height: 100%; - width: 100%; - background-color: #000000; - background-color: rgba(0,0,0,0.7); -} - -.ui-loader-background { - width: 100%; - height: 100%; - top: 0; - margin: 0; - background: #000000; - background: rgba(0, 0, 0, 0.3); - display: none; - position: fixed; - z-index: 100; -} - -.ui-loading .ui-loader-background { - display: block; -} - -#displaySongCover { - height: 75%; - max-height: 250px; - width: auto; -} - -#displaySongContent { - text-align: center; -} - - #displaySongContent span { - font-size: 18px; - font-weight: bold; - } - -.imageLoaderImg { - height: 100%; - width: 100%; - background: url(images/ajax-loader.gif); - background-size: 45px; - border: #000000 solid 0px; - content: ''; - background-repeat: no-repeat; - background-position: center; -} - -.ui-body-c, .ui-overlay-c { - background: #000000; -} - -.ui-input-search { - background: #6E6E6E !important; -} - -.ui-listview-filter { - background: #000000 !important; -} - -.ui-custom-errorIcon { - background: url(images/alert.png) !important; - background-size: 42px 42px; - -webkit-border-radius: 0px !important; - border-radius: 0px !important; -} - -.cursorStyleClickable { - cursor: pointer; -} - -#logo { - display: block; - margin-left: auto; - margin-right: auto; - margin-top: 10px; - margin-bottom: 10px; - width: 219px; - height:40px; -} - -.ui-bar-b { - border: 1px solid #000; - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - background: #000; - background-image: none; - color: #fff; - font-weight: 700; - text-shadow: 0 1px 0 #3e6790; - background-image: -webkit-gradient(linear,left top,left bottom,from(#000000),to(#000000)); - background-image: -webkit-linear-gradient(#000000,#000000); - background-image: -moz-linear-gradient(#000000,#000000); - background-image: -ms-linear-gradient(#000000,#000000); - background-image: -o-linear-gradient(#000000,#000000); - background-image: linear-gradient(#000000,#000000); -} diff --git a/Vocaluxe/Website/img/addPlaylist.png b/Vocaluxe/Website/img/addPlaylist.png deleted file mode 100644 index e7fc93ab..00000000 Binary files a/Vocaluxe/Website/img/addPlaylist.png and /dev/null differ diff --git a/Vocaluxe/Website/img/admin.png b/Vocaluxe/Website/img/admin.png deleted file mode 100644 index 9919e6d6..00000000 Binary files a/Vocaluxe/Website/img/admin.png and /dev/null differ diff --git a/Vocaluxe/Website/img/keyboard.png b/Vocaluxe/Website/img/keyboard.png deleted file mode 100644 index 7d13c796..00000000 Binary files a/Vocaluxe/Website/img/keyboard.png and /dev/null differ diff --git a/Vocaluxe/Website/img/license.txt b/Vocaluxe/Website/img/license.txt deleted file mode 100644 index b2321349..00000000 --- a/Vocaluxe/Website/img/license.txt +++ /dev/null @@ -1,5 +0,0 @@ -100% royalty-free icons from flaticons.net - -https://flaticons.net - -For: personal, commercial use, without attribution \ No newline at end of file diff --git a/Vocaluxe/Website/img/logo.png b/Vocaluxe/Website/img/logo.png deleted file mode 100644 index 82d8afef..00000000 Binary files a/Vocaluxe/Website/img/logo.png and /dev/null differ diff --git a/Vocaluxe/Website/img/logout.png b/Vocaluxe/Website/img/logout.png deleted file mode 100644 index 68c7876c..00000000 Binary files a/Vocaluxe/Website/img/logout.png and /dev/null differ diff --git a/Vocaluxe/Website/img/music.png b/Vocaluxe/Website/img/music.png deleted file mode 100644 index 2d068da7..00000000 Binary files a/Vocaluxe/Website/img/music.png and /dev/null differ diff --git a/Vocaluxe/Website/img/noCover.png b/Vocaluxe/Website/img/noCover.png deleted file mode 100644 index 4df4d9b8..00000000 Binary files a/Vocaluxe/Website/img/noCover.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/addPlaylist.png b/Vocaluxe/Website/img/original icons/addPlaylist.png deleted file mode 100644 index acdfe91c..00000000 Binary files a/Vocaluxe/Website/img/original icons/addPlaylist.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/admin.png b/Vocaluxe/Website/img/original icons/admin.png deleted file mode 100644 index d13ecdd6..00000000 Binary files a/Vocaluxe/Website/img/original icons/admin.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/keyboard.png b/Vocaluxe/Website/img/original icons/keyboard.png deleted file mode 100644 index 4c1fc687..00000000 Binary files a/Vocaluxe/Website/img/original icons/keyboard.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/logout.png b/Vocaluxe/Website/img/original icons/logout.png deleted file mode 100644 index 28480926..00000000 Binary files a/Vocaluxe/Website/img/original icons/logout.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/music.png b/Vocaluxe/Website/img/original icons/music.png deleted file mode 100644 index 3c4d28fd..00000000 Binary files a/Vocaluxe/Website/img/original icons/music.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/noCover.png b/Vocaluxe/Website/img/original icons/noCover.png deleted file mode 100644 index d57d9e73..00000000 Binary files a/Vocaluxe/Website/img/original icons/noCover.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/photo.png b/Vocaluxe/Website/img/original icons/photo.png deleted file mode 100644 index d0550339..00000000 Binary files a/Vocaluxe/Website/img/original icons/photo.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/playlist.png b/Vocaluxe/Website/img/original icons/playlist.png deleted file mode 100644 index 370a115e..00000000 Binary files a/Vocaluxe/Website/img/original icons/playlist.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/playlists.png b/Vocaluxe/Website/img/original icons/playlists.png deleted file mode 100644 index d259e728..00000000 Binary files a/Vocaluxe/Website/img/original icons/playlists.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/profile.png b/Vocaluxe/Website/img/original icons/profile.png deleted file mode 100644 index ba12a407..00000000 Binary files a/Vocaluxe/Website/img/original icons/profile.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/profiles.png b/Vocaluxe/Website/img/original icons/profiles.png deleted file mode 100644 index dc385bda..00000000 Binary files a/Vocaluxe/Website/img/original icons/profiles.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/spotify.png b/Vocaluxe/Website/img/original icons/spotify.png deleted file mode 100644 index 0be1cd79..00000000 Binary files a/Vocaluxe/Website/img/original icons/spotify.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/wikipedia.png b/Vocaluxe/Website/img/original icons/wikipedia.png deleted file mode 100644 index 52f87393..00000000 Binary files a/Vocaluxe/Website/img/original icons/wikipedia.png and /dev/null differ diff --git a/Vocaluxe/Website/img/original icons/youtube.png b/Vocaluxe/Website/img/original icons/youtube.png deleted file mode 100644 index 0241b05f..00000000 Binary files a/Vocaluxe/Website/img/original icons/youtube.png and /dev/null differ diff --git a/Vocaluxe/Website/img/photo.png b/Vocaluxe/Website/img/photo.png deleted file mode 100644 index 37cfec10..00000000 Binary files a/Vocaluxe/Website/img/photo.png and /dev/null differ diff --git a/Vocaluxe/Website/img/playlist.png b/Vocaluxe/Website/img/playlist.png deleted file mode 100644 index fa1c0910..00000000 Binary files a/Vocaluxe/Website/img/playlist.png and /dev/null differ diff --git a/Vocaluxe/Website/img/playlists.png b/Vocaluxe/Website/img/playlists.png deleted file mode 100644 index 914f2bf4..00000000 Binary files a/Vocaluxe/Website/img/playlists.png and /dev/null differ diff --git a/Vocaluxe/Website/img/profile.png b/Vocaluxe/Website/img/profile.png deleted file mode 100644 index 06ab7e03..00000000 Binary files a/Vocaluxe/Website/img/profile.png and /dev/null differ diff --git a/Vocaluxe/Website/img/profiles.png b/Vocaluxe/Website/img/profiles.png deleted file mode 100644 index f1960f5d..00000000 Binary files a/Vocaluxe/Website/img/profiles.png and /dev/null differ diff --git a/Vocaluxe/Website/img/spotify.png b/Vocaluxe/Website/img/spotify.png deleted file mode 100644 index d259a3a8..00000000 Binary files a/Vocaluxe/Website/img/spotify.png and /dev/null differ diff --git a/Vocaluxe/Website/img/wikipedia.png b/Vocaluxe/Website/img/wikipedia.png deleted file mode 100644 index 52f87393..00000000 Binary files a/Vocaluxe/Website/img/wikipedia.png and /dev/null differ diff --git a/Vocaluxe/Website/img/youtube.png b/Vocaluxe/Website/img/youtube.png deleted file mode 100644 index d720a717..00000000 Binary files a/Vocaluxe/Website/img/youtube.png and /dev/null differ diff --git a/Vocaluxe/Website/index.html b/Vocaluxe/Website/index.html deleted file mode 100644 index 633c409f..00000000 --- a/Vocaluxe/Website/index.html +++ /dev/null @@ -1,381 +0,0 @@ - - - - Vocaluxe - - - - - - - - - - - - -
-
-

Login

-
- - -
- - - - -
- -
-
-
- -
- -
- - -
-
- -
- - - - -
- - -
-
-

-
- - -
-
    -
    - -
    - - -
    -
    -

    Profile

    -
    - - -
    - Avatar - - - - - - - - - - - -
    - -
    - -
    - - -
    -
    -

    -
    - - -
    - Cover -
    -
    -
    - - - -
    - - - -
    - - - -
    - - - -
    - - - -
    -
    - - -
    - -
    - - -
    - -
    - - -
    -
    -

    -
    - - -
    -
      -
      - -
      - - -
      -
      -

      -
      - - -
      -
      -
      -
      - -
      -
      -
      - -
      -
      -
      -
      - -
      -
      -
      - -
      -
      -
      -
      -
      - -
      -
      - -
      -
      - -
      -
      - -
      -
      -
      - - - - - - -
      -
      -
      - -
      -
      -
      -
      - - -
      - - - -
      -
      - -
      - - -
      -
      -

      -
      - - -
      -
        -
        - -
        - - -
        -
        -

        -
        - - -
        -
        - - - - - - - - - - - -
        - -
        - -
        - - -
        -
        -

        - -
        - - -
        -
          -
          - -
          - - -
          -
          -

          - -
          - - -
          -
            -
            - -
            - - -
            - - diff --git a/Vocaluxe/Website/js/i18next-1.7.1.min.js b/Vocaluxe/Website/js/i18next-1.7.1.min.js deleted file mode 100644 index 7cf162f8..00000000 --- a/Vocaluxe/Website/js/i18next-1.7.1.min.js +++ /dev/null @@ -1,5 +0,0 @@ -// i18next, v1.7.1 -// Copyright (c)2013 Jan Mühlemann (jamuhl). -// Distributed under MIT license -// http://i18next.com -!function(){function a(a,b){if(!b||"function"==typeof b)return a;for(var c in b)a[c]=b[c];return a}function b(a,b,c){var d,e=0,f=a.length,g=void 0===f||"function"==typeof a;if(c)if(g){for(d in a)if(b.apply(a[d],c)===!1)break}else for(;f>e&&b.apply(a[e++],c)!==!1;);else if(g){for(d in a)if(b.call(a[d],d,a[d])===!1)break}else for(;f>e&&b.call(a[e],e,a[e++])!==!1;);return a}function c(a){return"string"==typeof a?a.replace(/[&<>"'\/]/g,function(a){return H[a]}):a}function d(a){var b=function(a){if(window.XMLHttpRequest)return a(null,new XMLHttpRequest);if(window.ActiveXObject)try{return a(null,new ActiveXObject("Msxml2.XMLHTTP"))}catch(b){return a(null,new ActiveXObject("Microsoft.XMLHTTP"))}return a(new Error)},c=function(a){if("string"==typeof a)return a;var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")},d=function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;cd?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(192|d>>6),b+=String.fromCharCode(128|63&d)):(b+=String.fromCharCode(224|d>>12),b+=String.fromCharCode(128|63&d>>6),b+=String.fromCharCode(128|63&d))}return b},e=function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a=d(a);var c,e,f,g,h,i,j,k="",l=0;do c=a.charCodeAt(l++),e=a.charCodeAt(l++),f=a.charCodeAt(l++),g=c>>2,h=(3&c)<<4|e>>4,i=(15&e)<<2|f>>6,j=63&f,isNaN(e)?i=j=64:isNaN(f)&&(j=64),k+=b.charAt(g)+b.charAt(h)+b.charAt(i)+b.charAt(j),c=e=f="",g=h=i=j="";while(l1&&(d+=d.indexOf("?")>-1?"&"+k:"?"+k),e.jsonp){var l=document.getElementsByTagName("head")[0],m=document.createElement("script");return m.type="text/javascript",m.src=d,l.appendChild(m),void 0}}b(function(b,c){if(b)return h(b);c.open(a,d,e.async);for(var f in j)j.hasOwnProperty(f)&&c.setRequestHeader(f,j[f]);c.onreadystatechange=function(){if(4===c.readyState){var a=c.responseText||"";if(!h)return;h(c.status,{text:function(){return a},json:function(){return JSON.parse(a)}})}},c.send(i)})},h={authBasic:function(a,b){g.headers.Authorization="Basic "+e(a+":"+b)},connect:function(a,b,c){return g("CONNECT",a,b,c)},del:function(a,b,c){return g("DELETE",a,b,c)},get:function(a,b,c){return g("GET",a,b,c)},head:function(a,b,c){return g("HEAD",a,b,c)},headers:function(a){g.headers=a||{}},isAllowed:function(a,b,c){this.options(a,function(a,d){c(-1!==d.text().indexOf(b))})},options:function(a,b,c){return g("OPTIONS",a,b,c)},patch:function(a,b,c){return g("PATCH",a,b,c)},post:function(a,b,c){return g("POST",a,b,c)},put:function(a,b,c){return g("PUT",a,b,c)},trace:function(a,b,c){return g("TRACE",a,b,c)}},i=a.type?a.type.toLowerCase():"get";h[i](a.url,a,function(b,c){200===b?a.success(c.json(),b,null):a.error(c.text(),b,null)})}function e(a,b){"function"==typeof a&&(b=a,a={}),a=a||{},K.extend(G,a),delete G.fixLng,"string"==typeof G.ns&&(G.ns={namespaces:[G.ns],defaultNs:G.ns}),"string"==typeof G.fallbackNS&&(G.fallbackNS=[G.fallbackNS]),G.interpolationPrefixEscaped=K.regexEscape(G.interpolationPrefix),G.interpolationSuffixEscaped=K.regexEscape(G.interpolationSuffix),G.lng||(G.lng=K.detectLanguage()),G.lng?G.useCookie&&K.cookie.create(G.cookieName,G.lng,G.cookieExpirationTime,G.cookieDomain):(G.lng=G.fallbackLng,G.useCookie&&K.cookie.remove(G.cookieName)),E=K.toLanguages(G.lng),y=E[0],K.log("currentLng set to: "+y);var c=s;a.fixLng&&(c=function(a,b){return b=b||{},b.lng=b.lng||c.lng,s(a,b)},c.lng=y),M.setCurrentLng(y),A&&G.setJqueryExt&&m();var d;if(A&&A.Deferred&&(d=A.Deferred()),!G.resStore){var e=K.toLanguages(G.lng);"string"==typeof G.preload&&(G.preload=[G.preload]);for(var f=0,g=G.preload.length;g>f;f++)for(var h=K.toLanguages(G.preload[f]),i=0,j=h.length;j>i;i++)e.indexOf(h[i])<0&&e.push(h[i]);return B.sync.load(e,G,function(a,e){C=e,F=!0,b&&b(c),d&&d.resolve(c)}),d?d.promise():void 0}return C=G.resStore,F=!0,b&&b(c),d&&d.resolve(c),d?d.promise():void 0}function f(a,b){"string"==typeof a&&(a=[a]);for(var c=0,d=a.length;d>c;c++)G.preload.indexOf(a[c])<0&&G.preload.push(a[c]);return e(b)}function g(a,b,c){"string"!=typeof b?(c=b,b=G.ns.defaultNs):G.ns.namespaces.indexOf(b)<0&&G.ns.namespaces.push(b),C[a]=C[a]||{},C[a][b]=C[a][b]||{},K.extend(C[a][b],c)}function h(a){G.ns.defaultNs=a}function i(a,b){j([a],b)}function j(a,b){var c={dynamicLoad:G.dynamicLoad,resGetPath:G.resGetPath,getAsync:G.getAsync,customLoad:G.customLoad,ns:{namespaces:a,defaultNs:""}},d=K.toLanguages(G.lng);"string"==typeof G.preload&&(G.preload=[G.preload]);for(var e=0,f=G.preload.length;f>e;e++)for(var g=K.toLanguages(G.preload[e]),h=0,i=g.length;i>h;h++)d.indexOf(g[h])<0&&d.push(g[h]);for(var j=[],k=0,l=d.length;l>k;k++){var m=!1,n=C[d[k]];if(n)for(var o=0,p=a.length;p>o;o++)n[a[o]]||(m=!0);else m=!0;m&&j.push(d[k])}j.length?B.sync._fetch(j,c,function(c,d){var e=a.length*j.length;K.each(a,function(a,c){G.ns.namespaces.indexOf(c)<0&&G.ns.namespaces.push(c),K.each(j,function(a,f){C[f]=C[f]||{},C[f][c]=d[f][c],e--,0===e&&b&&(G.useLocalStorage&&B.sync._storeLocal(C),b())})})}):b&&b()}function k(a,b,c){return"function"==typeof b&&(c=b,b={}),b.lng=a,e(b,c)}function l(){return y}function m(){function a(a,b,c){if(0!==b.length){var d="text";if(0===b.indexOf("[")){var e=b.split("]");b=e[1],d=e[0].substr(1,e[0].length-1)}b.indexOf(";")===b.length-1&&(b=b.substr(0,b.length-2));var f;"html"===d?(f=G.defaultValueFromContent?A.extend({defaultValue:a.html()},c):c,a.html(A.t(b,f))):"text"===d?(f=G.defaultValueFromContent?A.extend({defaultValue:a.text()},c):c,a.text(A.t(b,f))):(f=G.defaultValueFromContent?A.extend({defaultValue:a.attr(d)},c):c,a.attr(d,A.t(b,f)))}}function b(b,c){var d=b.attr(G.selectorAttr);if(d||"undefined"==typeof d||d===!1||(d=b.text()||b.val()),d){var e=b,f=b.data("i18n-target");if(f&&(e=b.find(f)||b),c||G.useDataAttrOptions!==!0||(c=b.data("i18n-options")),c=c||{},d.indexOf(";")>=0){var g=d.split(";");A.each(g,function(b,d){""!==d&&a(e,d,c)})}else a(e,d,c);G.useDataAttrOptions===!0&&b.data("i18n-options",c)}}A.t=A.t||s,A.fn.i18n=function(a){return this.each(function(){b(A(this),a);var c=A(this).find("["+G.selectorAttr+"]");c.each(function(){b(A(this),a)})})}}function n(a,b,c,d){if(!a)return a;if(d=d||b,a.indexOf(d.interpolationPrefix||G.interpolationPrefix)<0)return a;var e=d.interpolationPrefix?K.regexEscape(d.interpolationPrefix):G.interpolationPrefixEscaped,f=d.interpolationSuffix?K.regexEscape(d.interpolationSuffix):G.interpolationSuffixEscaped,g="HTML"+f;return K.each(b,function(b,h){var i=c?c+G.keyseparator+b:b;"object"==typeof h&&null!==h?a=n(a,h,i,d):d.escapeInterpolation||G.escapeInterpolation?(a=a.replace(new RegExp([e,i,g].join(""),"g"),h),a=a.replace(new RegExp([e,i,f].join(""),"g"),K.escape(h))):a=a.replace(new RegExp([e,i,f].join(""),"g"),h)}),a}function o(a,b){var c=",",d="{",e="}",f=K.extend({},b);for(delete f.postProcess;-1!=a.indexOf(G.reusePrefix)&&(D++,!(D>G.maxRecursion));){var g=a.lastIndexOf(G.reusePrefix),h=a.indexOf(G.reuseSuffix,g)+G.reuseSuffix.length,i=a.substring(g,h),j=i.replace(G.reusePrefix,"").replace(G.reuseSuffix,"");if(-1!=j.indexOf(c)){var k=j.indexOf(c);if(-1!=j.indexOf(d,k)&&-1!=j.indexOf(e,k)){var l=j.indexOf(d,k),m=j.indexOf(e,l)+e.length;try{f=K.extend(f,JSON.parse(j.substring(l,m))),j=j.substring(0,k)}catch(n){}}}var o=v(j,f);a=a.replace(i,o)}return a}function p(a){return a.context&&"string"==typeof a.context}function q(a){return void 0!==a.count&&"string"!=typeof a.count&&1!==a.count}function r(a,b){b=b||{};var c=t(a,b),d=w(a,b);return void 0!==d||d===c}function s(a,b){return F?(D=0,v.apply(null,arguments)):(K.log("i18next not finished initialization. you might have called t function before loading resources finished."),b.defaultValue||"")}function t(a,b){return void 0!==b.defaultValue?b.defaultValue:a}function u(){for(var a=[],b=1;b-1&&(e=c.split(G.nsseparator),i=e[0],c=e[1]),void 0===g&&G.sendMissing&&(b.lng?L.postMissing(h[0],i,c,f,h):L.postMissing(G.lng,i,c,f,h));var j=b.postProcess||G.postProcess;void 0!==g&&j&&N[j]&&(g=N[j](g,c,b));var k=f;if(f.indexOf(G.nsseparator)>-1&&(e=f.split(G.nsseparator),k=e[1]),k===c&&G.parseMissingKey&&(f=G.parseMissingKey(f)),void 0===g&&(f=n(f,b),f=o(f,b),j&&N[j])){var l=t(c,b);g=N[j](l,c,b)}return void 0!==g?g:f}function w(a,b){b=b||{};var c,d,e=t(a,b),f=E;if(!C)return e;if(b.lng&&(f=K.toLanguages(b.lng),!C[f[0]])){var g=G.getAsync;G.getAsync=!1,B.sync.load(f,G,function(a,b){K.extend(C,b),G.getAsync=g})}var h=b.ns||G.ns.defaultNs;if(a.indexOf(G.nsseparator)>-1){var i=a.split(G.nsseparator);h=i[0],a=i[1]}if(p(b)){c=K.extend({},b),delete c.context,c.defaultValue=G.contextNotFound;var j=h+G.nsseparator+a+"_"+b.context;if(d=s(j,c),d!=G.contextNotFound)return n(d,{context:b.context})}if(q(b)){c=K.extend({},b),delete c.count,c.defaultValue=G.pluralNotFound;var k=h+G.nsseparator+a+G.pluralSuffix,l=M.get(f[0],b.count);if(l>=0?k=k+"_"+l:1===l&&(k=h+G.nsseparator+a),d=s(k,c),d!=G.pluralNotFound)return n(d,{count:b.count,interpolationPrefix:b.interpolationPrefix,interpolationSuffix:b.interpolationSuffix})}for(var m,r=a.split(G.keyseparator),u=0,x=f.length;x>u&&void 0===m;u++){for(var y=f[u],z=0,A=C[y]&&C[y][h];r[z];)A=A&&A[r[z]],z++;if(void 0!==A){if("string"==typeof A)A=n(A,b),A=o(A,b);else if("[object Array]"!==Object.prototype.toString.apply(A)||G.returnObjectTrees||b.returnObjectTrees){if(null===A&&G.fallbackOnNull===!0)A=void 0;else if(null!==A)if(G.returnObjectTrees||b.returnObjectTrees){if("number"!=typeof A){var D={};K.each(A,function(c){D[c]=v(h+G.nsseparator+a+G.keyseparator+c,b)}),A=D}}else A="key '"+h+":"+a+" ("+y+")' "+"returned a object instead of string.",K.log(A)}else A=A.join("\n"),A=n(A,b),A=o(A,b);m=A}}if(void 0===m&&!b.isFallbackLookup&&(G.fallbackToDefaultNS===!0||G.fallbackNS&&G.fallbackNS.length>0))if(b.isFallbackLookup=!0,G.fallbackNS.length){for(var F=0,H=G.fallbackNS.length;H>F;F++)if(m=w(G.fallbackNS[F]+G.nsseparator+a,b)){var I=m.indexOf(G.nsseparator)>-1?m.split(G.nsseparator)[1]:m,J=e.indexOf(G.nsseparator)>-1?e.split(G.nsseparator)[1]:e;if(I!==J)break}}else m=w(a,b);return m}function x(){var a,b=[];if("undefined"!=typeof window&&(!function(){for(var a=window.location.search.substring(1),c=a.split("&"),d=0;d0){var f=c[d].substring(0,e),g=c[d].substring(e+1);b[f]=g}}}(),b[G.detectLngQS]&&(a=b[G.detectLngQS])),!a&&"undefined"!=typeof document&&G.useCookie){var c=K.cookie.read(G.cookieName);c&&(a=c)}return a||"undefined"==typeof navigator||(a=navigator.language?navigator.language:navigator.userLanguage),a}Array.prototype.indexOf||(Array.prototype.indexOf=function(a){"use strict";if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>0&&(d=Number(arguments[1]),d!=d?d=0:0!=d&&1/0!=d&&d!=-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1}),Array.prototype.lastIndexOf||(Array.prototype.lastIndexOf=function(a){"use strict";if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=c;arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!=d&&d!=1/0&&d!=-(1/0)&&(d=(d>0||-1)*Math.floor(Math.abs(d))));for(var e=d>=0?Math.min(d,c-1):c-Math.abs(d);e>=0;e--)if(e in b&&b[e]===a)return e;return-1});var y,z=this,A=z.jQuery||z.Zepto,B={},C={},D=0,E=[],F=!1;"undefined"!=typeof module&&module.exports?module.exports=B:(A&&(A.i18n=A.i18n||B),z.i18n=z.i18n||B);var G={lng:void 0,load:"all",preload:[],lowerCaseLng:!1,returnObjectTrees:!1,fallbackLng:"dev",fallbackNS:[],detectLngQS:"setLng",ns:"translation",fallbackOnNull:!0,fallbackToDefaultNS:!1,nsseparator:":",keyseparator:".",selectorAttr:"data-i18n",debug:!1,resGetPath:"locales/__lng__/__ns__.json",resPostPath:"locales/add/__lng__/__ns__",getAsync:!0,postAsync:!0,resStore:void 0,useLocalStorage:!1,localStorageExpirationTime:6048e5,dynamicLoad:!1,sendMissing:!1,sendMissingTo:"fallback",sendType:"POST",interpolationPrefix:"__",interpolationSuffix:"__",reusePrefix:"$t(",reuseSuffix:")",pluralSuffix:"_plural",pluralNotFound:["plural_not_found",Math.random()].join(""),contextNotFound:["context_not_found",Math.random()].join(""),escapeInterpolation:!1,setJqueryExt:!0,defaultValueFromContent:!0,useDataAttrOptions:!1,cookieExpirationTime:void 0,useCookie:!0,cookieName:"i18next",cookieDomain:void 0,postProcess:void 0,parseMissingKey:void 0,shortcutFunction:"sprintf"},H={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},I={create:function(a,b,c,d){var e;if(c){var f=new Date;f.setTime(f.getTime()+1e3*60*c),e="; expires="+f.toGMTString()}else e="";d=d?"domain="+d+";":"",document.cookie=a+"="+b+e+";"+d+"path=/"},read:function(a){for(var b=a+"=",c=document.cookie.split(";"),d=0;d-1){var c=a.split("-");a=G.lowerCaseLng?c[0].toLowerCase()+"-"+c[1].toLowerCase():c[0].toLowerCase()+"-"+c[1].toUpperCase(),"unspecific"!==G.load&&b.push(a),"current"!==G.load&&b.push(c[0])}else b.push(a);return-1===b.indexOf(G.fallbackLng)&&G.fallbackLng&&b.push(G.fallbackLng),b},regexEscape:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}};K.applyReplacement=n;var L={load:function(a,b,c){b.useLocalStorage?L._loadLocal(a,b,function(d,e){for(var f=[],g=0,h=a.length;h>g;g++)e[a[g]]||f.push(a[g]);f.length>0?L._fetch(f,b,function(a,b){K.extend(e,b),L._storeLocal(b),c(null,e)}):c(null,e)}):L._fetch(a,b,function(a,b){c(null,b)})},_loadLocal:function(a,b,c){var d={},e=(new Date).getTime();if(window.localStorage){var f=a.length;K.each(a,function(a,g){var h=window.localStorage.getItem("res_"+g);h&&(h=JSON.parse(h),h.i18nStamp&&h.i18nStamp+b.localStorageExpirationTime>e&&(d[g]=h)),f--,0===f&&c(null,d)})}},_storeLocal:function(a){if(window.localStorage)for(var b in a)a[b].i18nStamp=(new Date).getTime(),window.localStorage.setItem("res_"+b,JSON.stringify(a[b]))},_fetch:function(a,b,c){var d=b.ns,e={};if(b.dynamicLoad){var f=function(a,b){c(null,b)};if("function"==typeof b.customLoad)b.customLoad(a,d.namespaces,b,f);else{var g=n(b.resGetPath,{lng:a.join("+"),ns:d.namespaces.join("+")});K.ajax({url:g,success:function(a){K.log("loaded: "+g),f(null,a)},error:function(a,b,c){K.log("failed loading: "+g),f("failed loading resource.json error: "+c)},dataType:"json",async:b.getAsync})}}else{var h,i=d.namespaces.length*a.length;K.each(d.namespaces,function(d,f){K.each(a,function(a,d){var g=function(a,b){a&&(h=h||[],h.push(a)),e[d]=e[d]||{},e[d][f]=b,i--,0===i&&c(h,e)};"function"==typeof b.customLoad?b.customLoad(d,f,b,g):L._fetchOne(d,f,b,g)})})}},_fetchOne:function(a,b,c,d){var e=n(c.resGetPath,{lng:a,ns:b});K.ajax({url:e,success:function(a){K.log("loaded: "+e),d(null,a)},error:function(a,b,c){K.log("failed loading: "+e),d(c,{})},dataType:"json",async:c.getAsync})},postMissing:function(a,b,c,d,e){var f={};f[c]=d;var g=[];if("fallback"===G.sendMissingTo&&G.fallbackLng!==!1)g.push({lng:G.fallbackLng,url:n(G.resPostPath,{lng:G.fallbackLng,ns:b})});else if("current"===G.sendMissingTo||"fallback"===G.sendMissingTo&&G.fallbackLng===!1)g.push({lng:a,url:n(G.resPostPath,{lng:a,ns:b})});else if("all"===G.sendMissingTo)for(var h=0,i=e.length;i>h;h++)g.push({lng:e[h],url:n(G.resPostPath,{lng:e[h],ns:b})});for(var j=0,k=g.length;k>j;j++){var l=g[j];K.ajax({url:l.url,type:G.sendType,data:f,success:function(){K.log("posted missing key '"+c+"' to: "+l.url);for(var a=c.split("."),e=0,f=C[l.lng][b];a[e];)f=f[a[e]]=e===a.length-1?d:f[a[e]]||{},e++},error:function(){K.log("failed posting missing key '"+c+"' to: "+l.url)},dataType:"json",async:G.postAsync})}}},M={rules:{ach:{name:"Acholi",numbers:[1,2],plurals:function(a){return Number(a>1)}},af:{name:"Afrikaans",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ak:{name:"Akan",numbers:[1,2],plurals:function(a){return Number(a>1)}},am:{name:"Amharic",numbers:[1,2],plurals:function(a){return Number(a>1)}},an:{name:"Aragonese",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ar:{name:"Arabic",numbers:[0,1,2,3,11,100],plurals:function(a){return Number(0===a?0:1==a?1:2==a?2:a%100>=3&&10>=a%100?3:a%100>=11?4:5)}},arn:{name:"Mapudungun",numbers:[1,2],plurals:function(a){return Number(a>1)}},ast:{name:"Asturian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ay:{name:"Aymará",numbers:[1],plurals:function(){return 0}},az:{name:"Azerbaijani",numbers:[1,2],plurals:function(a){return Number(1!=a)}},be:{name:"Belarusian",numbers:[1,2,5],plurals:function(a){return Number(1==a%10&&11!=a%100?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)}},bg:{name:"Bulgarian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},bn:{name:"Bengali",numbers:[1,2],plurals:function(a){return Number(1!=a)}},bo:{name:"Tibetan",numbers:[1],plurals:function(){return 0}},br:{name:"Breton",numbers:[1,2],plurals:function(a){return Number(a>1)}},bs:{name:"Bosnian",numbers:[1,2,5],plurals:function(a){return Number(1==a%10&&11!=a%100?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)}},ca:{name:"Catalan",numbers:[1,2],plurals:function(a){return Number(1!=a)}},cgg:{name:"Chiga",numbers:[1],plurals:function(){return 0}},cs:{name:"Czech",numbers:[1,2,5],plurals:function(a){return Number(1==a?0:a>=2&&4>=a?1:2)}},csb:{name:"Kashubian",numbers:[1,2,5],plurals:function(a){return Number(1==a?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)}},cy:{name:"Welsh",numbers:[1,2,3,8],plurals:function(a){return Number(1==a?0:2==a?1:8!=a&&11!=a?2:3)}},da:{name:"Danish",numbers:[1,2],plurals:function(a){return Number(1!=a)}},de:{name:"German",numbers:[1,2],plurals:function(a){return Number(1!=a)}},dz:{name:"Dzongkha",numbers:[1],plurals:function(){return 0}},el:{name:"Greek",numbers:[1,2],plurals:function(a){return Number(1!=a)}},en:{name:"English",numbers:[1,2],plurals:function(a){return Number(1!=a)}},eo:{name:"Esperanto",numbers:[1,2],plurals:function(a){return Number(1!=a)}},es:{name:"Spanish",numbers:[1,2],plurals:function(a){return Number(1!=a)}},es_ar:{name:"Argentinean Spanish",numbers:[1,2],plurals:function(a){return Number(1!=a)}},et:{name:"Estonian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},eu:{name:"Basque",numbers:[1,2],plurals:function(a){return Number(1!=a)}},fa:{name:"Persian",numbers:[1],plurals:function(){return 0}},fi:{name:"Finnish",numbers:[1,2],plurals:function(a){return Number(1!=a)}},fil:{name:"Filipino",numbers:[1,2],plurals:function(a){return Number(a>1)}},fo:{name:"Faroese",numbers:[1,2],plurals:function(a){return Number(1!=a)}},fr:{name:"French",numbers:[1,2],plurals:function(a){return Number(a>1)}},fur:{name:"Friulian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},fy:{name:"Frisian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ga:{name:"Irish",numbers:[1,2,3,7,11],plurals:function(a){return Number(1==a?0:2==a?1:7>a?2:11>a?3:4)}},gd:{name:"Scottish Gaelic",numbers:[1,2,3,20],plurals:function(a){return Number(1==a||11==a?0:2==a||12==a?1:a>2&&20>a?2:3)}},gl:{name:"Galician",numbers:[1,2],plurals:function(a){return Number(1!=a)}},gu:{name:"Gujarati",numbers:[1,2],plurals:function(a){return Number(1!=a)}},gun:{name:"Gun",numbers:[1,2],plurals:function(a){return Number(a>1)}},ha:{name:"Hausa",numbers:[1,2],plurals:function(a){return Number(1!=a)}},he:{name:"Hebrew",numbers:[1,2],plurals:function(a){return Number(1!=a)}},hi:{name:"Hindi",numbers:[1,2],plurals:function(a){return Number(1!=a)}},hr:{name:"Croatian",numbers:[1,2,5],plurals:function(a){return Number(1==a%10&&11!=a%100?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)}},hu:{name:"Hungarian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},hy:{name:"Armenian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ia:{name:"Interlingua",numbers:[1,2],plurals:function(a){return Number(1!=a)}},id:{name:"Indonesian",numbers:[1],plurals:function(){return 0}},is:{name:"Icelandic",numbers:[1,2],plurals:function(a){return Number(1!=a%10||11==a%100)}},it:{name:"Italian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ja:{name:"Japanese",numbers:[1],plurals:function(){return 0}},jbo:{name:"Lojban",numbers:[1],plurals:function(){return 0}},jv:{name:"Javanese",numbers:[0,1],plurals:function(a){return Number(0!==a)}},ka:{name:"Georgian",numbers:[1],plurals:function(){return 0}},kk:{name:"Kazakh",numbers:[1],plurals:function(){return 0}},km:{name:"Khmer",numbers:[1],plurals:function(){return 0}},kn:{name:"Kannada",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ko:{name:"Korean",numbers:[1],plurals:function(){return 0}},ku:{name:"Kurdish",numbers:[1,2],plurals:function(a){return Number(1!=a)}},kw:{name:"Cornish",numbers:[1,2,3,4],plurals:function(a){return Number(1==a?0:2==a?1:3==a?2:3)}},ky:{name:"Kyrgyz",numbers:[1],plurals:function(){return 0}},lb:{name:"Letzeburgesch",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ln:{name:"Lingala",numbers:[1,2],plurals:function(a){return Number(a>1)}},lo:{name:"Lao",numbers:[1],plurals:function(){return 0}},lt:{name:"Lithuanian",numbers:[1,2,10],plurals:function(a){return Number(1==a%10&&11!=a%100?0:a%10>=2&&(10>a%100||a%100>=20)?1:2)}},lv:{name:"Latvian",numbers:[0,1,2],plurals:function(a){return Number(1==a%10&&11!=a%100?0:0!==a?1:2)}},mai:{name:"Maithili",numbers:[1,2],plurals:function(a){return Number(1!=a)}},mfe:{name:"Mauritian Creole",numbers:[1,2],plurals:function(a){return Number(a>1)}},mg:{name:"Malagasy",numbers:[1,2],plurals:function(a){return Number(a>1)}},mi:{name:"Maori",numbers:[1,2],plurals:function(a){return Number(a>1)}},mk:{name:"Macedonian",numbers:[1,2],plurals:function(a){return Number(1==a||1==a%10?0:1)}},ml:{name:"Malayalam",numbers:[1,2],plurals:function(a){return Number(1!=a)}},mn:{name:"Mongolian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},mnk:{name:"Mandinka",numbers:[0,1,2],plurals:function(a){return Number(1==a?1:2)}},mr:{name:"Marathi",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ms:{name:"Malay",numbers:[1],plurals:function(){return 0}},mt:{name:"Maltese",numbers:[1,2,11,20],plurals:function(a){return Number(1==a?0:0===a||a%100>1&&11>a%100?1:a%100>10&&20>a%100?2:3)}},nah:{name:"Nahuatl",numbers:[1,2],plurals:function(a){return Number(1!=a)}},nap:{name:"Neapolitan",numbers:[1,2],plurals:function(a){return Number(1!=a)}},nb:{name:"Norwegian Bokmal",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ne:{name:"Nepali",numbers:[1,2],plurals:function(a){return Number(1!=a)}},nl:{name:"Dutch",numbers:[1,2],plurals:function(a){return Number(1!=a)}},nn:{name:"Norwegian Nynorsk",numbers:[1,2],plurals:function(a){return Number(1!=a)}},no:{name:"Norwegian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},nso:{name:"Northern Sotho",numbers:[1,2],plurals:function(a){return Number(1!=a)}},oc:{name:"Occitan",numbers:[1,2],plurals:function(a){return Number(a>1)}},or:{name:"Oriya",numbers:[2,1],plurals:function(a){return Number(1!=a)}},pa:{name:"Punjabi",numbers:[1,2],plurals:function(a){return Number(1!=a)}},pap:{name:"Papiamento",numbers:[1,2],plurals:function(a){return Number(1!=a)}},pl:{name:"Polish",numbers:[1,2,5],plurals:function(a){return Number(1==a?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)}},pms:{name:"Piemontese",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ps:{name:"Pashto",numbers:[1,2],plurals:function(a){return Number(1!=a)}},pt:{name:"Portuguese",numbers:[1,2],plurals:function(a){return Number(1!=a)}},pt_br:{name:"Brazilian Portuguese",numbers:[1,2],plurals:function(a){return Number(1!=a)}},rm:{name:"Romansh",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ro:{name:"Romanian",numbers:[1,2,20],plurals:function(a){return Number(1==a?0:0===a||a%100>0&&20>a%100?1:2)}},ru:{name:"Russian",numbers:[1,2,5],plurals:function(a){return Number(1==a%10&&11!=a%100?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)}},sah:{name:"Yakut",numbers:[1],plurals:function(){return 0}},sco:{name:"Scots",numbers:[1,2],plurals:function(a){return Number(1!=a)}},se:{name:"Northern Sami",numbers:[1,2],plurals:function(a){return Number(1!=a)}},si:{name:"Sinhala",numbers:[1,2],plurals:function(a){return Number(1!=a)}},sk:{name:"Slovak",numbers:[1,2,5],plurals:function(a){return Number(1==a?0:a>=2&&4>=a?1:2)}},sl:{name:"Slovenian",numbers:[5,1,2,3],plurals:function(a){return Number(1==a%100?1:2==a%100?2:3==a%100||4==a%100?3:0)}},so:{name:"Somali",numbers:[1,2],plurals:function(a){return Number(1!=a)}},son:{name:"Songhay",numbers:[1,2],plurals:function(a){return Number(1!=a)}},sq:{name:"Albanian",numbers:[1,2],plurals:function(a){return Number(1!=a)}},sr:{name:"Serbian",numbers:[1,2,5],plurals:function(a){return Number(1==a%10&&11!=a%100?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)}},su:{name:"Sundanese",numbers:[1],plurals:function(){return 0}},sv:{name:"Swedish",numbers:[1,2],plurals:function(a){return Number(1!=a)}},sw:{name:"Swahili",numbers:[1,2],plurals:function(a){return Number(1!=a)}},ta:{name:"Tamil",numbers:[1,2],plurals:function(a){return Number(1!=a)}},te:{name:"Telugu",numbers:[1,2],plurals:function(a){return Number(1!=a)}},tg:{name:"Tajik",numbers:[1,2],plurals:function(a){return Number(a>1)}},th:{name:"Thai",numbers:[1],plurals:function(){return 0}},ti:{name:"Tigrinya",numbers:[1,2],plurals:function(a){return Number(a>1)}},tk:{name:"Turkmen",numbers:[1,2],plurals:function(a){return Number(1!=a)}},tr:{name:"Turkish",numbers:[1,2],plurals:function(a){return Number(a>1)}},tt:{name:"Tatar",numbers:[1],plurals:function(){return 0}},ug:{name:"Uyghur",numbers:[1],plurals:function(){return 0}},uk:{name:"Ukrainian",numbers:[1,2,5],plurals:function(a){return Number(1==a%10&&11!=a%100?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)}},ur:{name:"Urdu",numbers:[1,2],plurals:function(a){return Number(1!=a)}},uz:{name:"Uzbek",numbers:[1,2],plurals:function(a){return Number(a>1)}},vi:{name:"Vietnamese",numbers:[1],plurals:function(){return 0}},wa:{name:"Walloon",numbers:[1,2],plurals:function(a){return Number(a>1)}},wo:{name:"Wolof",numbers:[1],plurals:function(){return 0}},yo:{name:"Yoruba",numbers:[1,2],plurals:function(a){return Number(1!=a)}},zh:{name:"Chinese",numbers:[1],plurals:function(){return 0}}},addRule:function(a,b){M.rules[a]=b},setCurrentLng:function(a){if(!M.currentRule||M.currentRule.lng!==a){var b=a.split("-");M.currentRule={lng:a,rule:M.rules[b[0]]}}},get:function(a,b){function c(b,c){var d;if(d=M.currentRule&&M.currentRule.lng===a?M.currentRule.rule:M.rules[b]){var e=d.plurals(c),f=d.numbers[e];return 2===d.numbers.length&&1===d.numbers[0]&&(2===f?f=-1:1===f&&(f=1)),f}return 1===c?"1":"-1"}var d=a.split("-");return c(d[0],b)}},N={},O=function(a,b){N[a]=b},P=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}function b(a,b){for(var c=[];b>0;c[--b]=a);return c.join("")}var c=function(){return c.cache.hasOwnProperty(arguments[0])||(c.cache[arguments[0]]=c.parse(arguments[0])),c.format.call(null,c.cache[arguments[0]],arguments)};return c.format=function(c,d){var e,f,g,h,i,j,k,l=1,m=c.length,n="",o=[];for(f=0;m>f;f++)if(n=a(c[f]),"string"===n)o.push(c[f]);else if("array"===n){if(h=c[f],h[2])for(e=d[l],g=0;g=0?"+"+e:e,j=h[4]?"0"==h[4]?"0":h[4].charAt(1):" ",k=h[6]-String(e).length,i=h[6]?b(j,k):"",o.push(h[5]?e+i:i+e)}return o.join("")},c.cache={},c.parse=function(a){for(var b=a,c=[],d=[],e=0;b;){if(null!==(c=/^[^\x25]+/.exec(b)))d.push(c[0]);else if(null!==(c=/^\x25{2}/.exec(b)))d.push("%");else{if(null===(c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b)))throw"[sprintf] huh?";if(c[2]){e|=1;var f=[],g=c[2],h=[];if(null===(h=/^([a-z_][a-z_\d]*)/i.exec(g)))throw"[sprintf] huh?";for(f.push(h[1]);""!==(g=g.substring(h[0].length));)if(null!==(h=/^\.([a-z_][a-z_\d]*)/i.exec(g)))f.push(h[1]);else{if(null===(h=/^\[(\d+)\]/.exec(g)))throw"[sprintf] huh?";f.push(h[1])}c[2]=f}else e|=2;if(3===e)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";d.push(c)}b=b.substring(c[0].length)}return d},c}(),Q=function(a,b){return b.unshift(a),P.apply(null,b)};O("sprintf",function(a,b,c){return c.sprintf?"[object Array]"===Object.prototype.toString.apply(c.sprintf)?Q(a,c.sprintf):"object"==typeof c.sprintf?P(a,c.sprintf):a:a}),B.init=e,B.setLng=k,B.preload=f,B.addResourceBundle=g,B.loadNamespace=i,B.loadNamespaces=j,B.setDefaultNamespace=h,B.t=s,B.translate=s,B.exists=r,B.detectLanguage=K.detectLanguage,B.pluralExtensions=M,B.sync=L,B.functions=K,B.lng=l,B.addPostProcessor=O,B.options=G}(); \ No newline at end of file diff --git a/Vocaluxe/Website/js/jquery-1.9.1.min.js b/Vocaluxe/Website/js/jquery-1.9.1.min.js deleted file mode 100644 index 006e9531..00000000 --- a/Vocaluxe/Website/js/jquery-1.9.1.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license -//@ sourceMappingURL=jquery.min.map -*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
            a",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="
            t
            ",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
            ",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj; -return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="
            ",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
            ","
            "],area:[1,"",""],param:[1,"",""],thead:[1,"","
            "],tr:[2,"","
            "],col:[2,"","
            "],td:[3,"","
            "],_default:b.support.htmlSerialize?[0,"",""]:[1,"X
            ","
            "]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l) -}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("