From 4729528e8c8ece9cf59d279e13e7a640c9f7a259 Mon Sep 17 00:00:00 2001 From: Paul Flowers Date: Thu, 22 Feb 2018 11:27:02 +0000 Subject: [PATCH] initial commit --- .appveyor.yml | 18 + .deployment | 2 + CONTRIBUTING.md | 4 + Directory.Build.props | 12 + Directory.Build.targets | 6 + LICENSE.txt | 14 + MusicStore.sln | 64 + MusicStore.sln.DotSettings | 108 + NuGet.config | 7 + README.md | 20 + build.cmd | 2 + build.sh | 8 + build/dependencies.props | 45 + build/repo.props | 14 + build/repo.targets | 39 + build/sources.props | 16 + korebuild-lock.txt | 2 + korebuild.json | 4 + run.cmd | 2 + run.ps1 | 196 + run.sh | 231 + .../Controllers/StoreManagerController.cs | 219 + .../Admin/Views/StoreManager/Create.cshtml | 75 + .../Admin/Views/StoreManager/Details.cshtml | 58 + .../Admin/Views/StoreManager/Edit.cshtml | 76 + .../Admin/Views/StoreManager/Index.cshtml | 66 + .../Views/StoreManager/RemoveAlbum.cshtml | 29 + .../Areas/Admin/Views/_ViewStart.cshtml | 3 + .../Components/CartSummaryComponent.cs | 31 + .../Components/GenreMenuComponent.cs | 31 + samples/MusicStore/Components/ISystemClock.cs | 16 + samples/MusicStore/Components/SystemClock.cs | 22 + .../Controllers/AccountController.cs | 512 + .../Controllers/CheckoutController.cs | 113 + .../MusicStore/Controllers/HomeController.cs | 79 + .../Controllers/ManageController.cs | 365 + .../Controllers/ShoppingCartController.cs | 113 + .../MusicStore/Controllers/StoreController.cs | 86 + .../Mocks/Common/CustomStateDataFormat.cs | 41 + .../ForTesting/Mocks/Common/Helpers.cs | 15 + .../FacebookMockBackChannelHttpHandler.cs | 57 + .../Mocks/Facebook/TestFacebookEvents.cs | 56 + .../GoogleMockBackChannelHttpHandler.cs | 55 + .../Mocks/Google/TestGoogleEvents.cs | 56 + .../MicrosoftAccountMockBackChannelHandler.cs | 56 + .../TestMicrosoftAccountEvents.cs | 57 + .../OpenIdConnect/CustomStringDataFormat.cs | 29 + .../OpenIdConnectBackChannelHttpHandler.cs | 33 + .../OpenIdConnect/TestOpenIdConnectEvents.cs | 62 + .../ForTesting/Mocks/OpenIdConnect/keys.json | 26 + .../OpenIdConnect/openid-configuration.json | 34 + .../Mocks/StartupOpenIdConnectTesting.cs | 167 + .../ForTesting/Mocks/StartupSocialTesting.cs | 209 + .../Twitter/CustomTwitterStateDataFormat.cs | 46 + .../Mocks/Twitter/TestTwitterEvents.cs | 50 + .../TwitterMockBackChannelHttpHandler.cs | 67 + .../MusicStore/ForTesting/MusicStoreConfig.cs | 7 + samples/MusicStore/ForTesting/Readme.md | 1 + samples/MusicStore/MessageServices.cs | 19 + .../MusicStore/Models/AccountViewModels.cs | 113 + samples/MusicStore/Models/Album.cs | 51 + samples/MusicStore/Models/Artist.cs | 12 + samples/MusicStore/Models/CartItem.cs | 21 + samples/MusicStore/Models/Genre.cs | 17 + samples/MusicStore/Models/ManageViewModels.cs | 87 + .../MusicStore/Models/MusicStoreContext.cs | 25 + samples/MusicStore/Models/Order.cs | 74 + samples/MusicStore/Models/OrderDetail.cs | 22 + samples/MusicStore/Models/SampleData.cs | 965 ++ samples/MusicStore/Models/ShoppingCart.cs | 184 + samples/MusicStore/MusicStore.csproj | 55 + .../MusicStore/Pages/PageThatThrows.cshtml | 2 + samples/MusicStore/Platform.cs | 110 + samples/MusicStore/Program.cs | 67 + samples/MusicStore/Properties/AppSettings.cs | 9 + .../MusicStore/Properties/launchSettings.json | 27 + samples/MusicStore/Scripts/_references.js | 8 + samples/MusicStore/Startup.cs | 216 + .../MusicStore/StartupNtlmAuthentication.cs | 160 + samples/MusicStore/StartupOpenIdConnect.cs | 165 + samples/MusicStore/ViewModels/AlbumData.cs | 9 + .../ViewModels/ShoppingCartRemoveViewModel.cs | 11 + .../ViewModels/ShoppingCartViewModel.cs | 11 + .../Views/Account/ConfirmEmail.cshtml | 10 + .../Account/ExternalLoginConfirmation.cshtml | 34 + .../Views/Account/ExternalLoginFailure.cshtml | 8 + .../Views/Account/ForgotPassword.cshtml | 28 + .../Account/ForgotPasswordConfirmation.cshtml | 15 + samples/MusicStore/Views/Account/Login.cshtml | 60 + .../MusicStore/Views/Account/Register.cshtml | 42 + .../Views/Account/RegisterConfirmation.cshtml | 15 + .../Views/Account/ResetPassword.cshtml | 43 + .../Account/ResetPasswordConfirmation.cshtml | 12 + .../MusicStore/Views/Account/SendCode.cshtml | 21 + .../Views/Account/VerifyCode.cshtml | 43 + .../Account/_ExternalLoginsListPartial.cshtml | 31 + .../Views/Checkout/AddressAndPayment.cshtml | 33 + .../MusicStore/Views/Checkout/Complete.cshtml | 14 + samples/MusicStore/Views/Home/Index.cshtml | 21 + .../Views/Manage/AddPhoneNumber.cshtml | 27 + .../Views/Manage/ChangePassword.cshtml | 42 + samples/MusicStore/Views/Manage/Index.cshtml | 70 + .../Views/Manage/ManageLogins.cshtml | 53 + .../Views/Manage/SetPassword.cshtml | 38 + .../Views/Manage/VerifyPhoneNumber.cshtml | 34 + .../Views/Shared/AccessDenied.cshtml | 5 + .../Components/Announcement/Default.cshtml | 10 + .../Components/CartSummary/Default.cshtml | 11 + .../Components/GenreMenu/Default.cshtml | 17 + .../Views/Shared/DemoLinkDisplay.cshtml | 21 + samples/MusicStore/Views/Shared/Error.cshtml | 6 + .../MusicStore/Views/Shared/Lockout.cshtml | 8 + .../Views/Shared/StatusCodePage.cshtml | 6 + .../MusicStore/Views/Shared/_Layout.cshtml | 74 + .../Views/Shared/_LoginPartial.cshtml | 33 + .../Shared/_ValidationScriptsPartial.cshtml | 14 + .../Views/ShoppingCart/Index.cshtml | 106 + samples/MusicStore/Views/Store/Browse.cshtml | 24 + samples/MusicStore/Views/Store/Details.cshtml | 29 + samples/MusicStore/Views/Store/Index.cshtml | 15 + samples/MusicStore/Views/_ViewImports.cshtml | 5 + samples/MusicStore/Views/_ViewStart.cshtml | 3 + samples/MusicStore/config.json | 15 + samples/MusicStore/wwwroot/Content/Site.css | 70 + .../MusicStore/wwwroot/Content/bootstrap.css | 6816 +++++++++++++ .../wwwroot/Content/bootstrap.min.css | 20 + .../wwwroot/Images/home-showcase.png | Bin 0 -> 254130 bytes samples/MusicStore/wwwroot/Images/logo.png | Bin 0 -> 2963 bytes samples/MusicStore/wwwroot/Images/logo.svg | 303 + .../MusicStore/wwwroot/Images/placeholder.png | Bin 0 -> 1221 bytes .../MusicStore/wwwroot/Images/placeholder.svg | 112 + .../MusicStore/wwwroot/Scripts/bootstrap.js | 2014 ++++ .../wwwroot/Scripts/bootstrap.min.js | 21 + .../Scripts/jquery-2.0.3.intellisense.js | 2670 +++++ .../wwwroot/Scripts/jquery-2.0.3.js | 8829 +++++++++++++++++ .../wwwroot/Scripts/jquery-2.0.3.min.js | 6 + .../wwwroot/Scripts/jquery-2.0.3.min.map | 1 + .../wwwroot/Scripts/jquery.signalR-2.0.1.js | 2602 +++++ .../Scripts/jquery.signalR-2.0.1.min.js | 8 + .../wwwroot/Scripts/jquery.validate-vsdoc.js | 1302 +++ .../wwwroot/Scripts/jquery.validate.js | 1245 +++ .../wwwroot/Scripts/jquery.validate.min.js | 16 + .../Scripts/jquery.validate.unobtrusive.js | 344 + .../jquery.validate.unobtrusive.min.js | 19 + .../wwwroot/Scripts/modernizr-2.6.2.js | 1416 +++ samples/MusicStore/wwwroot/Scripts/respond.js | 340 + .../MusicStore/wwwroot/Scripts/respond.min.js | 20 + samples/MusicStore/wwwroot/favicon.ico | Bin 0 -> 32038 bytes .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 14079 bytes .../fonts/glyphicons-halflings-regular.svg | 228 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 29512 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 16448 bytes test/Directory.Build.props | 16 + test/MusicStore.E2ETests/Common/DbUtils.cs | 55 + test/MusicStore.E2ETests/Common/Helpers.cs | 63 + .../Common/HtmlDOMHelper.cs | 60 + .../MusicStore.E2ETests/Common/XunitLogger.cs | 59 + test/MusicStore.E2ETests/Http.config | 1029 ++ .../Implementation/FacebookLoginScenarios.cs | 98 + .../Implementation/GoogleLoginScenarios.cs | 102 + ...MicrosoftAccountAuthenticationScenarios.cs | 98 + .../OpenIdConnectLoginScenarios.cs | 140 + .../Implementation/TwitterLoginScenarios.cs | 95 + .../Implementation/Validator.cs | 549 + .../MusicStore.E2ETests.csproj | 33 + test/MusicStore.E2ETests/MusicStoreConfig.cs | 7 + .../NtlmAuthentation.config | 1041 ++ .../NtlmAuthentationTest.cs | 121 + .../MusicStore.E2ETests/OpenIdConnectTests.cs | 98 + .../Properties/AssemblyInfo.cs | 3 + .../PublishAndRunTestRunner.cs | 142 + .../PublishAndRunTests_X64.cs | 77 + .../PublishAndRunTests_X86.cs | 42 + .../RemoteDeploymentConfig.cs | 43 + test/MusicStore.E2ETests/SmokeTestRunner.cs | 154 + .../SmokeTestsOnNanoServer.cs | 289 + .../SmokeTestsUsingStore/TestHelper.cs | 99 + .../SmokeTestsUsingStore/Tests.cs | 31 + test/MusicStore.E2ETests/SmokeTests_X64.cs | 87 + .../remoteDeploymentConfig.json | 10 + .../CartSummaryComponentTest.cs | 87 + .../MusicStore.Test/CheckoutControllerTest.cs | 251 + .../MusicStore.Test/GenreMenuComponentTest.cs | 56 + test/MusicStore.Test/HomeControllerTest.cs | 128 + test/MusicStore.Test/ManageControllerTest.cs | 120 + .../Models/ShoppingCartTest.cs | 60 + test/MusicStore.Test/MusicStore.Test.csproj | 16 + .../ShoppingCartControllerTest.cs | 241 + test/MusicStore.Test/StoreControllerTest.cs | 179 + test/MusicStore.Test/TestAppSettings.cs | 26 + test/MusicStore.Test/TestSession.cs | 50 + test/RemoteTest.cmd | 3 + test/RemoteTest.ps1 | 47 + tools/BundleAndDeploy.cmd | 3 + tools/BundleAndDeploy.ps1 | 89 + 195 files changed, 41767 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .deployment create mode 100644 CONTRIBUTING.md create mode 100644 Directory.Build.props create mode 100644 Directory.Build.targets create mode 100644 LICENSE.txt create mode 100644 MusicStore.sln create mode 100644 MusicStore.sln.DotSettings create mode 100644 NuGet.config create mode 100644 README.md create mode 100644 build.cmd create mode 100755 build.sh create mode 100644 build/dependencies.props create mode 100644 build/repo.props create mode 100644 build/repo.targets create mode 100644 build/sources.props create mode 100644 korebuild-lock.txt create mode 100644 korebuild.json create mode 100644 run.cmd create mode 100644 run.ps1 create mode 100755 run.sh create mode 100644 samples/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs create mode 100644 samples/MusicStore/Areas/Admin/Views/StoreManager/Create.cshtml create mode 100644 samples/MusicStore/Areas/Admin/Views/StoreManager/Details.cshtml create mode 100644 samples/MusicStore/Areas/Admin/Views/StoreManager/Edit.cshtml create mode 100644 samples/MusicStore/Areas/Admin/Views/StoreManager/Index.cshtml create mode 100644 samples/MusicStore/Areas/Admin/Views/StoreManager/RemoveAlbum.cshtml create mode 100644 samples/MusicStore/Areas/Admin/Views/_ViewStart.cshtml create mode 100644 samples/MusicStore/Components/CartSummaryComponent.cs create mode 100644 samples/MusicStore/Components/GenreMenuComponent.cs create mode 100644 samples/MusicStore/Components/ISystemClock.cs create mode 100644 samples/MusicStore/Components/SystemClock.cs create mode 100644 samples/MusicStore/Controllers/AccountController.cs create mode 100644 samples/MusicStore/Controllers/CheckoutController.cs create mode 100644 samples/MusicStore/Controllers/HomeController.cs create mode 100644 samples/MusicStore/Controllers/ManageController.cs create mode 100644 samples/MusicStore/Controllers/ShoppingCartController.cs create mode 100644 samples/MusicStore/Controllers/StoreController.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Common/CustomStateDataFormat.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Common/Helpers.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Facebook/FacebookMockBackChannelHttpHandler.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Facebook/TestFacebookEvents.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Google/GoogleMockBackChannelHttpHandler.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Google/TestGoogleEvents.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/MicrosoftAccount/MicrosoftAccountMockBackChannelHandler.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/MicrosoftAccount/TestMicrosoftAccountEvents.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/OpenIdConnect/CustomStringDataFormat.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/OpenIdConnect/OpenIdConnectBackChannelHttpHandler.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/OpenIdConnect/TestOpenIdConnectEvents.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/OpenIdConnect/keys.json create mode 100644 samples/MusicStore/ForTesting/Mocks/OpenIdConnect/openid-configuration.json create mode 100644 samples/MusicStore/ForTesting/Mocks/StartupOpenIdConnectTesting.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/StartupSocialTesting.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Twitter/CustomTwitterStateDataFormat.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Twitter/TestTwitterEvents.cs create mode 100644 samples/MusicStore/ForTesting/Mocks/Twitter/TwitterMockBackChannelHttpHandler.cs create mode 100644 samples/MusicStore/ForTesting/MusicStoreConfig.cs create mode 100644 samples/MusicStore/ForTesting/Readme.md create mode 100644 samples/MusicStore/MessageServices.cs create mode 100644 samples/MusicStore/Models/AccountViewModels.cs create mode 100644 samples/MusicStore/Models/Album.cs create mode 100644 samples/MusicStore/Models/Artist.cs create mode 100644 samples/MusicStore/Models/CartItem.cs create mode 100644 samples/MusicStore/Models/Genre.cs create mode 100644 samples/MusicStore/Models/ManageViewModels.cs create mode 100644 samples/MusicStore/Models/MusicStoreContext.cs create mode 100644 samples/MusicStore/Models/Order.cs create mode 100644 samples/MusicStore/Models/OrderDetail.cs create mode 100644 samples/MusicStore/Models/SampleData.cs create mode 100644 samples/MusicStore/Models/ShoppingCart.cs create mode 100644 samples/MusicStore/MusicStore.csproj create mode 100644 samples/MusicStore/Pages/PageThatThrows.cshtml create mode 100644 samples/MusicStore/Platform.cs create mode 100644 samples/MusicStore/Program.cs create mode 100644 samples/MusicStore/Properties/AppSettings.cs create mode 100644 samples/MusicStore/Properties/launchSettings.json create mode 100644 samples/MusicStore/Scripts/_references.js create mode 100644 samples/MusicStore/Startup.cs create mode 100644 samples/MusicStore/StartupNtlmAuthentication.cs create mode 100644 samples/MusicStore/StartupOpenIdConnect.cs create mode 100644 samples/MusicStore/ViewModels/AlbumData.cs create mode 100644 samples/MusicStore/ViewModels/ShoppingCartRemoveViewModel.cs create mode 100644 samples/MusicStore/ViewModels/ShoppingCartViewModel.cs create mode 100644 samples/MusicStore/Views/Account/ConfirmEmail.cshtml create mode 100644 samples/MusicStore/Views/Account/ExternalLoginConfirmation.cshtml create mode 100644 samples/MusicStore/Views/Account/ExternalLoginFailure.cshtml create mode 100644 samples/MusicStore/Views/Account/ForgotPassword.cshtml create mode 100644 samples/MusicStore/Views/Account/ForgotPasswordConfirmation.cshtml create mode 100644 samples/MusicStore/Views/Account/Login.cshtml create mode 100644 samples/MusicStore/Views/Account/Register.cshtml create mode 100644 samples/MusicStore/Views/Account/RegisterConfirmation.cshtml create mode 100644 samples/MusicStore/Views/Account/ResetPassword.cshtml create mode 100644 samples/MusicStore/Views/Account/ResetPasswordConfirmation.cshtml create mode 100644 samples/MusicStore/Views/Account/SendCode.cshtml create mode 100644 samples/MusicStore/Views/Account/VerifyCode.cshtml create mode 100644 samples/MusicStore/Views/Account/_ExternalLoginsListPartial.cshtml create mode 100644 samples/MusicStore/Views/Checkout/AddressAndPayment.cshtml create mode 100644 samples/MusicStore/Views/Checkout/Complete.cshtml create mode 100644 samples/MusicStore/Views/Home/Index.cshtml create mode 100644 samples/MusicStore/Views/Manage/AddPhoneNumber.cshtml create mode 100644 samples/MusicStore/Views/Manage/ChangePassword.cshtml create mode 100644 samples/MusicStore/Views/Manage/Index.cshtml create mode 100644 samples/MusicStore/Views/Manage/ManageLogins.cshtml create mode 100644 samples/MusicStore/Views/Manage/SetPassword.cshtml create mode 100644 samples/MusicStore/Views/Manage/VerifyPhoneNumber.cshtml create mode 100644 samples/MusicStore/Views/Shared/AccessDenied.cshtml create mode 100644 samples/MusicStore/Views/Shared/Components/Announcement/Default.cshtml create mode 100644 samples/MusicStore/Views/Shared/Components/CartSummary/Default.cshtml create mode 100644 samples/MusicStore/Views/Shared/Components/GenreMenu/Default.cshtml create mode 100644 samples/MusicStore/Views/Shared/DemoLinkDisplay.cshtml create mode 100644 samples/MusicStore/Views/Shared/Error.cshtml create mode 100644 samples/MusicStore/Views/Shared/Lockout.cshtml create mode 100644 samples/MusicStore/Views/Shared/StatusCodePage.cshtml create mode 100644 samples/MusicStore/Views/Shared/_Layout.cshtml create mode 100644 samples/MusicStore/Views/Shared/_LoginPartial.cshtml create mode 100644 samples/MusicStore/Views/Shared/_ValidationScriptsPartial.cshtml create mode 100644 samples/MusicStore/Views/ShoppingCart/Index.cshtml create mode 100644 samples/MusicStore/Views/Store/Browse.cshtml create mode 100644 samples/MusicStore/Views/Store/Details.cshtml create mode 100644 samples/MusicStore/Views/Store/Index.cshtml create mode 100644 samples/MusicStore/Views/_ViewImports.cshtml create mode 100644 samples/MusicStore/Views/_ViewStart.cshtml create mode 100644 samples/MusicStore/config.json create mode 100644 samples/MusicStore/wwwroot/Content/Site.css create mode 100644 samples/MusicStore/wwwroot/Content/bootstrap.css create mode 100644 samples/MusicStore/wwwroot/Content/bootstrap.min.css create mode 100644 samples/MusicStore/wwwroot/Images/home-showcase.png create mode 100644 samples/MusicStore/wwwroot/Images/logo.png create mode 100644 samples/MusicStore/wwwroot/Images/logo.svg create mode 100644 samples/MusicStore/wwwroot/Images/placeholder.png create mode 100644 samples/MusicStore/wwwroot/Images/placeholder.svg create mode 100644 samples/MusicStore/wwwroot/Scripts/bootstrap.js create mode 100644 samples/MusicStore/wwwroot/Scripts/bootstrap.min.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery-2.0.3.intellisense.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery-2.0.3.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery-2.0.3.min.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery-2.0.3.min.map create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery.signalR-2.0.1.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery.signalR-2.0.1.min.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery.validate-vsdoc.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery.validate.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery.validate.min.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery.validate.unobtrusive.js create mode 100644 samples/MusicStore/wwwroot/Scripts/jquery.validate.unobtrusive.min.js create mode 100644 samples/MusicStore/wwwroot/Scripts/modernizr-2.6.2.js create mode 100644 samples/MusicStore/wwwroot/Scripts/respond.js create mode 100644 samples/MusicStore/wwwroot/Scripts/respond.min.js create mode 100644 samples/MusicStore/wwwroot/favicon.ico create mode 100644 samples/MusicStore/wwwroot/fonts/glyphicons-halflings-regular.eot create mode 100644 samples/MusicStore/wwwroot/fonts/glyphicons-halflings-regular.svg create mode 100644 samples/MusicStore/wwwroot/fonts/glyphicons-halflings-regular.ttf create mode 100644 samples/MusicStore/wwwroot/fonts/glyphicons-halflings-regular.woff create mode 100644 test/Directory.Build.props create mode 100644 test/MusicStore.E2ETests/Common/DbUtils.cs create mode 100644 test/MusicStore.E2ETests/Common/Helpers.cs create mode 100644 test/MusicStore.E2ETests/Common/HtmlDOMHelper.cs create mode 100644 test/MusicStore.E2ETests/Common/XunitLogger.cs create mode 100644 test/MusicStore.E2ETests/Http.config create mode 100644 test/MusicStore.E2ETests/Implementation/FacebookLoginScenarios.cs create mode 100644 test/MusicStore.E2ETests/Implementation/GoogleLoginScenarios.cs create mode 100644 test/MusicStore.E2ETests/Implementation/MicrosoftAccountAuthenticationScenarios.cs create mode 100644 test/MusicStore.E2ETests/Implementation/OpenIdConnectLoginScenarios.cs create mode 100644 test/MusicStore.E2ETests/Implementation/TwitterLoginScenarios.cs create mode 100644 test/MusicStore.E2ETests/Implementation/Validator.cs create mode 100644 test/MusicStore.E2ETests/MusicStore.E2ETests.csproj create mode 100644 test/MusicStore.E2ETests/MusicStoreConfig.cs create mode 100644 test/MusicStore.E2ETests/NtlmAuthentation.config create mode 100644 test/MusicStore.E2ETests/NtlmAuthentationTest.cs create mode 100644 test/MusicStore.E2ETests/OpenIdConnectTests.cs create mode 100644 test/MusicStore.E2ETests/Properties/AssemblyInfo.cs create mode 100644 test/MusicStore.E2ETests/PublishAndRunTestRunner.cs create mode 100644 test/MusicStore.E2ETests/PublishAndRunTests_X64.cs create mode 100644 test/MusicStore.E2ETests/PublishAndRunTests_X86.cs create mode 100644 test/MusicStore.E2ETests/RemoteDeploymentConfig.cs create mode 100644 test/MusicStore.E2ETests/SmokeTestRunner.cs create mode 100644 test/MusicStore.E2ETests/SmokeTestsOnNanoServer.cs create mode 100644 test/MusicStore.E2ETests/SmokeTestsUsingStore/TestHelper.cs create mode 100644 test/MusicStore.E2ETests/SmokeTestsUsingStore/Tests.cs create mode 100644 test/MusicStore.E2ETests/SmokeTests_X64.cs create mode 100644 test/MusicStore.E2ETests/remoteDeploymentConfig.json create mode 100644 test/MusicStore.Test/CartSummaryComponentTest.cs create mode 100644 test/MusicStore.Test/CheckoutControllerTest.cs create mode 100644 test/MusicStore.Test/GenreMenuComponentTest.cs create mode 100644 test/MusicStore.Test/HomeControllerTest.cs create mode 100644 test/MusicStore.Test/ManageControllerTest.cs create mode 100644 test/MusicStore.Test/Models/ShoppingCartTest.cs create mode 100644 test/MusicStore.Test/MusicStore.Test.csproj create mode 100644 test/MusicStore.Test/ShoppingCartControllerTest.cs create mode 100644 test/MusicStore.Test/StoreControllerTest.cs create mode 100644 test/MusicStore.Test/TestAppSettings.cs create mode 100644 test/MusicStore.Test/TestSession.cs create mode 100644 test/RemoteTest.cmd create mode 100644 test/RemoteTest.ps1 create mode 100644 tools/BundleAndDeploy.cmd create mode 100644 tools/BundleAndDeploy.ps1 diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..4603878 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,18 @@ +init: + - git config --global core.autocrlf true +branches: + only: + - master + - release + - dev + - /^(.*\/)?ci-.*$/ +build_script: + - ps: .\run.ps1 default-build +clone_depth: 1 +environment: + global: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: 1 +test: off +deploy: off +os: Visual Studio 2017 diff --git a/.deployment b/.deployment new file mode 100644 index 0000000..38d6c46 --- /dev/null +++ b/.deployment @@ -0,0 +1,2 @@ ++[config] ++project = src/MusicStore/MusicStore.csproj diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..64ff041 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,4 @@ +Contributing +====== + +Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo. diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..0a0ea64 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,12 @@ + + + + + + + + true + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000..894b1d0 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,6 @@ + + + $(MicrosoftNETCoreApp20PackageVersion) + $(MicrosoftNETCoreApp21PackageVersion) + + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..7b2956e --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,14 @@ +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/MusicStore.sln b/MusicStore.sln new file mode 100644 index 0000000..caee14a --- /dev/null +++ b/MusicStore.sln @@ -0,0 +1,64 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.12 +MinimumVisualStudioVersion = 15.0.26730.03 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7D749BDA-4638-4517-B66A-D40DEDEEB141}" + ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + NuGet.config = NuGet.config + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B7B176B6-8D4D-4EF1-BBD2-DDA650C78FFF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{363D2681-31A6-48C9-90BB-9ACFF4A41F06}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicStore", "samples\MusicStore\MusicStore.csproj", "{3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicStore.Test", "test\MusicStore.Test\MusicStore.Test.csproj", "{CA663205-77DE-4E55-B300-85594181B5A9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicStore.E2ETests", "test\MusicStore.E2ETests\MusicStore.E2ETests.csproj", "{72A5F455-121F-4954-BF28-D712C6BE88EA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{88A30728-49E5-46C5-9CEC-9D8FD346A043}" + ProjectSection(SolutionItems) = preProject + build\repo.targets = build\repo.targets + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + RuntimeStore|Any CPU = RuntimeStore|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.Release|Any CPU.Build.0 = Release|Any CPU + {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.RuntimeStore|Any CPU.ActiveCfg = RuntimeStore|Any CPU + {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0}.RuntimeStore|Any CPU.Build.0 = RuntimeStore|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.Release|Any CPU.Build.0 = Release|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.RuntimeStore|Any CPU.ActiveCfg = Release|Any CPU + {CA663205-77DE-4E55-B300-85594181B5A9}.RuntimeStore|Any CPU.Build.0 = Release|Any CPU + {72A5F455-121F-4954-BF28-D712C6BE88EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72A5F455-121F-4954-BF28-D712C6BE88EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72A5F455-121F-4954-BF28-D712C6BE88EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72A5F455-121F-4954-BF28-D712C6BE88EA}.Release|Any CPU.Build.0 = Release|Any CPU + {72A5F455-121F-4954-BF28-D712C6BE88EA}.RuntimeStore|Any CPU.ActiveCfg = Release|Any CPU + {72A5F455-121F-4954-BF28-D712C6BE88EA}.RuntimeStore|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {3CFBED5D-2ED8-49DB-96FB-BDAA748DC5A0} = {B7B176B6-8D4D-4EF1-BBD2-DDA650C78FFF} + {CA663205-77DE-4E55-B300-85594181B5A9} = {363D2681-31A6-48C9-90BB-9ACFF4A41F06} + {72A5F455-121F-4954-BF28-D712C6BE88EA} = {363D2681-31A6-48C9-90BB-9ACFF4A41F06} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4AC7A44E-260A-4E70-88A7-77A0027E12A5} + EndGlobalSection +EndGlobal diff --git a/MusicStore.sln.DotSettings b/MusicStore.sln.DotSettings new file mode 100644 index 0000000..4f3db97 --- /dev/null +++ b/MusicStore.sln.DotSettings @@ -0,0 +1,108 @@ + + + <?xml version="1.0" encoding="utf-16"?><Profile name="MusicStore"><HtmlReformatCode>True</HtmlReformatCode><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_IMPLICIT</LocalVariableStyle><ForeachVariableStyle>ALWAYS_IMPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><XMLReformatCode>True</XMLReformatCode><CSUpdateFileHeader>True</CSUpdateFileHeader><CSharpFormatDocComments>True</CSharpFormatDocComments></Profile> + + MusicStore + MusicStore + False + False + False + SEPARATE + True + True + True + ALWAYS_ADD + ALWAYS_ADD + ALWAYS_ADD + ALWAYS_ADD + ALWAYS_ADD + ALWAYS_ADD + True + 1 + 1 + True + False + False + False + True + LINE_BREAK + False + True + False + True + True + True + True + True + 140 + CHOP_ALWAYS + True + + True + False + True + + True + + + Copyright (c) .NET Foundation. All rights reserved. +See License.txt in the project root for license information + True + True + True + Side by side + Side by side + False + False + False + True + False + False + True + False + False + True + $object$_On$event$ + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> + $object$_On$event$ + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True + True + True + True \ No newline at end of file diff --git a/NuGet.config b/NuGet.config new file mode 100644 index 0000000..e32bddf --- /dev/null +++ b/NuGet.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..7574a9b --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +MusicStore (test application) +============================= + +AppVeyor: [![AppVeyor][appveyor-badge]][appveyor-build] + +Travis: [![Travis][travis-badge]][travis-build] + +[appveyor-badge]: https://ci.appveyor.com/api/projects/status/ja8a7j6jscj7k3xa/branch/dev?svg=true +[appveyor-build]: https://ci.appveyor.com/project/aspnetci/MusicStore/branch/dev +[travis-badge]: https://travis-ci.org/aspnet/MusicStore.svg?branch=dev +[travis-build]: https://travis-ci.org/aspnet/MusicStore + +This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo. + +## About this repo + +This repository is a test application used for ASP.NET Core internal test processes. +It is not intended to be a representative sample of how to use ASP.NET Core. + +Samples and docs for ASP.NET Core can be found here: . diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..c0050bd --- /dev/null +++ b/build.cmd @@ -0,0 +1,2 @@ +@ECHO OFF +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE" diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..98a4b22 --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -euo pipefail +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs) +chmod +x "$DIR/run.sh"; sync +"$DIR/run.sh" default-build "$@" diff --git a/build/dependencies.props b/build/dependencies.props new file mode 100644 index 0000000..37a350b --- /dev/null +++ b/build/dependencies.props @@ -0,0 +1,45 @@ + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 0.5.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.1.0-preview2-30131 + 2.0.0 + 2.1.0-preview2-26130-04 + 15.3.0 + 4.5.0-preview2-26130-01 + 2.3.1 + 2.4.0-beta.1.build3945 + + + diff --git a/build/repo.props b/build/repo.props new file mode 100644 index 0000000..78b0ce5 --- /dev/null +++ b/build/repo.props @@ -0,0 +1,14 @@ + + + + + + Internal.AspNetCore.Universe.Lineup + https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json + + + + + + + diff --git a/build/repo.targets b/build/repo.targets new file mode 100644 index 0000000..9d4c8a8 --- /dev/null +++ b/build/repo.targets @@ -0,0 +1,39 @@ + + + + + Configuration=RuntimeStore + + + + + $(RepositoryRoot)test\MusicStore.E2ETests\MusicStore.E2ETests.csproj + + + + + + + + + + + + + + + + + + VSTestTestCaseFilter=E2ETests=NanoServer + + + + + + VSTestTestCaseFilter=smoketests=usestore + + + + diff --git a/build/sources.props b/build/sources.props new file mode 100644 index 0000000..9feff29 --- /dev/null +++ b/build/sources.props @@ -0,0 +1,16 @@ + + + + + $(DotNetRestoreSources) + + $(RestoreSources); + https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; + https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; + + + $(RestoreSources); + https://api.nuget.org/v3/index.json; + + + diff --git a/korebuild-lock.txt b/korebuild-lock.txt new file mode 100644 index 0000000..89d0ad3 --- /dev/null +++ b/korebuild-lock.txt @@ -0,0 +1,2 @@ +version:2.1.0-preview2-15707 +commithash:e74e53f129ab34332947fea7ac7b7591b027cb22 diff --git a/korebuild.json b/korebuild.json new file mode 100644 index 0000000..bd5d51a --- /dev/null +++ b/korebuild.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", + "channel": "dev" +} diff --git a/run.cmd b/run.cmd new file mode 100644 index 0000000..d52d5c7 --- /dev/null +++ b/run.cmd @@ -0,0 +1,2 @@ +@ECHO OFF +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" diff --git a/run.ps1 b/run.ps1 new file mode 100644 index 0000000..27dcf84 --- /dev/null +++ b/run.ps1 @@ -0,0 +1,196 @@ +#!/usr/bin/env powershell +#requires -version 4 + +<# +.SYNOPSIS +Executes KoreBuild commands. + +.DESCRIPTION +Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`. + +.PARAMETER Command +The KoreBuild command to run. + +.PARAMETER Path +The folder to build. Defaults to the folder containing this script. + +.PARAMETER Channel +The channel of KoreBuild to download. Overrides the value from the config file. + +.PARAMETER DotNetHome +The directory where .NET Core tools will be stored. + +.PARAMETER ToolsSource +The base url where build tools can be downloaded. Overrides the value from the config file. + +.PARAMETER Update +Updates KoreBuild to the latest version even if a lock file is present. + +.PARAMETER ConfigFile +The path to the configuration file that stores values. Defaults to korebuild.json. + +.PARAMETER ToolsSourceSuffix +The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores. + +.PARAMETER Arguments +Arguments to be passed to the command + +.NOTES +This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be. +When the lockfile is not present, KoreBuild will create one using latest available version from $Channel. + +The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set +in the file are overridden by command line parameters. + +.EXAMPLE +Example config file: +```json +{ + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", + "channel": "dev", + "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" +} +``` +#> +[CmdletBinding(PositionalBinding = $false)] +param( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Command, + [string]$Path = $PSScriptRoot, + [Alias('c')] + [string]$Channel, + [Alias('d')] + [string]$DotNetHome, + [Alias('s')] + [string]$ToolsSource, + [Alias('u')] + [switch]$Update, + [string]$ConfigFile, + [string]$ToolsSourceSuffix, + [Parameter(ValueFromRemainingArguments = $true)] + [string[]]$Arguments +) + +Set-StrictMode -Version 2 +$ErrorActionPreference = 'Stop' + +# +# Functions +# + +function Get-KoreBuild { + + $lockFile = Join-Path $Path 'korebuild-lock.txt' + + if (!(Test-Path $lockFile) -or $Update) { + Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix + } + + $version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1 + if (!$version) { + Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'" + } + $version = $version.TrimStart('version:').Trim() + $korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version) + + if (!(Test-Path $korebuildPath)) { + Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version" + New-Item -ItemType Directory -Path $korebuildPath | Out-Null + $remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip" + + try { + $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip" + Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix + if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) { + # Use built-in commands where possible as they are cross-plat compatible + Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath + } + else { + # Fallback to old approach for old installations of PowerShell + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath) + } + } + catch { + Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore + throw + } + finally { + Remove-Item $tmpfile -ErrorAction Ignore + } + } + + return $korebuildPath +} + +function Join-Paths([string]$path, [string[]]$childPaths) { + $childPaths | ForEach-Object { $path = Join-Path $path $_ } + return $path +} + +function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) { + if ($RemotePath -notlike 'http*') { + Copy-Item $RemotePath $LocalPath + return + } + + $retries = 10 + while ($retries -gt 0) { + $retries -= 1 + try { + Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath + return + } + catch { + Write-Verbose "Request failed. $retries retries remaining" + } + } + + Write-Error "Download failed: '$RemotePath'." +} + +# +# Main +# + +# Load configuration or set defaults + +$Path = Resolve-Path $Path +if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' } + +if (Test-Path $ConfigFile) { + try { + $config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json + if ($config) { + if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel } + if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource} + } + } + catch { + Write-Warning "$ConfigFile could not be read. Its settings will be ignored." + Write-Warning $Error[0] + } +} + +if (!$DotNetHome) { + $DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } ` + elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} ` + elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}` + else { Join-Path $PSScriptRoot '.dotnet'} +} + +if (!$Channel) { $Channel = 'dev' } +if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } + +# Execute + +$korebuildPath = Get-KoreBuild +Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1') + +try { + Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile + Invoke-KoreBuildCommand $Command @Arguments +} +finally { + Remove-Module 'KoreBuild' -ErrorAction Ignore +} diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..834961f --- /dev/null +++ b/run.sh @@ -0,0 +1,231 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# +# variables +# + +RESET="\033[0m" +RED="\033[0;31m" +YELLOW="\033[0;33m" +MAGENTA="\033[0;95m" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" +verbose=false +update=false +repo_path="$DIR" +channel='' +tools_source='' +tools_source_suffix='' + +# +# Functions +# +__usage() { + echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] ...]" + echo "" + echo "Arguments:" + echo " command The command to be run." + echo " ... Arguments passed to the command. Variable number of arguments allowed." + echo "" + echo "Options:" + echo " --verbose Show verbose output." + echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." + echo " --config-file The path to the configuration file that stores values. Defaults to korebuild.json." + echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." + echo " --path The directory to build. Defaults to the directory containing the script." + echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file." + echo " --tools-source-suffix|-ToolsSourceSuffix The suffix to append to tools-source. Useful for query strings." + echo " -u|--update Update to the latest KoreBuild even if the lock file is present." + echo "" + echo "Description:" + echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." + echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel." + + if [[ "${1:-}" != '--no-exit' ]]; then + exit 2 + fi +} + +get_korebuild() { + local version + local lock_file="$repo_path/korebuild-lock.txt" + if [ ! -f "$lock_file" ] || [ "$update" = true ]; then + __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix" + fi + version="$(grep 'version:*' -m 1 "$lock_file")" + if [[ "$version" == '' ]]; then + __error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'" + return 1 + fi + version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" + + { + if [ ! -d "$korebuild_path" ]; then + mkdir -p "$korebuild_path" + local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" + tmpfile="$(mktemp)" + echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" + if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then + unzip -q -d "$korebuild_path" "$tmpfile" + fi + rm "$tmpfile" || true + fi + + source "$korebuild_path/KoreBuild.sh" + } || { + if [ -d "$korebuild_path" ]; then + echo "Cleaning up after failed installation" + rm -rf "$korebuild_path" || true + fi + return 1 + } +} + +__error() { + echo -e "${RED}error: $*${RESET}" 1>&2 +} + +__warn() { + echo -e "${YELLOW}warning: $*${RESET}" +} + +__machine_has() { + hash "$1" > /dev/null 2>&1 + return $? +} + +__get_remote_file() { + local remote_path=$1 + local local_path=$2 + local remote_path_suffix=$3 + + if [[ "$remote_path" != 'http'* ]]; then + cp "$remote_path" "$local_path" + return 0 + fi + + local failed=false + if __machine_has wget; then + wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true + else + failed=true + fi + + if [ "$failed" = true ] && __machine_has curl; then + failed=false + curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true + fi + + if [ "$failed" = true ]; then + __error "Download failed: $remote_path" 1>&2 + return 1 + fi +} + +# +# main +# + +command="${1:-}" +shift + +while [[ $# -gt 0 ]]; do + case $1 in + -\?|-h|--help) + __usage --no-exit + exit 0 + ;; + -c|--channel|-Channel) + shift + channel="${1:-}" + [ -z "$channel" ] && __usage + ;; + --config-file|-ConfigFile) + shift + config_file="${1:-}" + [ -z "$config_file" ] && __usage + if [ ! -f "$config_file" ]; then + __error "Invalid value for --config-file. $config_file does not exist." + exit 1 + fi + ;; + -d|--dotnet-home|-DotNetHome) + shift + DOTNET_HOME="${1:-}" + [ -z "$DOTNET_HOME" ] && __usage + ;; + --path|-Path) + shift + repo_path="${1:-}" + [ -z "$repo_path" ] && __usage + ;; + -s|--tools-source|-ToolsSource) + shift + tools_source="${1:-}" + [ -z "$tools_source" ] && __usage + ;; + --tools-source-suffix|-ToolsSourceSuffix) + shift + tools_source_suffix="${1:-}" + [ -z "$tools_source_suffix" ] && __usage + ;; + -u|--update|-Update) + update=true + ;; + --verbose|-Verbose) + verbose=true + ;; + --) + shift + break + ;; + *) + break + ;; + esac + shift +done + +if ! __machine_has unzip; then + __error 'Missing required command: unzip' + exit 1 +fi + +if ! __machine_has curl && ! __machine_has wget; then + __error 'Missing required command. Either wget or curl is required.' + exit 1 +fi + +[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json" +if [ -f "$config_file" ]; then + if __machine_has jq ; then + if jq '.' "$config_file" >/dev/null ; then + config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")" + config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")" + else + __warn "$config_file is invalid JSON. Its settings will be ignored." + fi + elif __machine_has python ; then + if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then + config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" + config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" + else + __warn "$config_file is invalid JSON. Its settings will be ignored." + fi + else + __warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.' + fi + + [ ! -z "${config_channel:-}" ] && channel="$config_channel" + [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" +fi + +[ -z "$channel" ] && channel='dev' +[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' + +get_korebuild +set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" +invoke_korebuild_command "$command" "$@" diff --git a/samples/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs b/samples/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs new file mode 100644 index 0000000..9a75e4a --- /dev/null +++ b/samples/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs @@ -0,0 +1,219 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Options; +using MusicStore.Models; +using MusicStore.ViewModels; + +namespace MusicStore.Areas.Admin.Controllers +{ + [Area("Admin")] + [Authorize("ManageStore")] + public class StoreManagerController : Controller + { + private readonly AppSettings _appSettings; + + public StoreManagerController(MusicStoreContext dbContext, IOptions options) + { + DbContext = dbContext; + _appSettings = options.Value; + } + + public MusicStoreContext DbContext { get; } + + // + // GET: /StoreManager/ + public async Task Index() + { + var albums = await DbContext.Albums + .Include(a => a.Genre) + .Include(a => a.Artist) + .ToListAsync(); + + return View(albums); + } + + // + // GET: /StoreManager/Details/5 + public async Task Details( + [FromServices] IMemoryCache cache, + int id) + { + var cacheKey = GetCacheKey(id); + + Album album; + if (!cache.TryGetValue(cacheKey, out album)) + { + album = await DbContext.Albums + .Where(a => a.AlbumId == id) + .Include(a => a.Artist) + .Include(a => a.Genre) + .FirstOrDefaultAsync(); + + if (album != null) + { + if (_appSettings.CacheDbResults) + { + //Remove it from cache if not retrieved in last 10 minutes. + cache.Set( + cacheKey, + album, + new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(10))); + } + } + } + + if (album == null) + { + cache.Remove(cacheKey); + return NotFound(); + } + + return View(album); + } + + // + // GET: /StoreManager/Create + public IActionResult Create() + { + ViewBag.GenreId = new SelectList(DbContext.Genres, "GenreId", "Name"); + ViewBag.ArtistId = new SelectList(DbContext.Artists, "ArtistId", "Name"); + return View(); + } + + // POST: /StoreManager/Create + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create( + Album album, + [FromServices] IMemoryCache cache, + CancellationToken requestAborted) + { + if (ModelState.IsValid) + { + DbContext.Albums.Add(album); + await DbContext.SaveChangesAsync(requestAborted); + + var albumData = new AlbumData + { + Title = album.Title, + Url = Url.Action("Details", "Store", new { id = album.AlbumId }) + }; + + cache.Remove("latestAlbum"); + return RedirectToAction("Index"); + } + + ViewBag.GenreId = new SelectList(DbContext.Genres, "GenreId", "Name", album.GenreId); + ViewBag.ArtistId = new SelectList(DbContext.Artists, "ArtistId", "Name", album.ArtistId); + return View(album); + } + + // + // GET: /StoreManager/Edit/5 + public async Task Edit(int id) + { + var album = await DbContext.Albums. + Where(a => a.AlbumId == id). + FirstOrDefaultAsync(); + + if (album == null) + { + return NotFound(); + } + + ViewBag.GenreId = new SelectList(DbContext.Genres, "GenreId", "Name", album.GenreId); + ViewBag.ArtistId = new SelectList(DbContext.Artists, "ArtistId", "Name", album.ArtistId); + return View(album); + } + + // + // POST: /StoreManager/Edit/5 + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit( + [FromServices] IMemoryCache cache, + Album album, + CancellationToken requestAborted) + { + if (ModelState.IsValid) + { + DbContext.Update(album); + await DbContext.SaveChangesAsync(requestAborted); + //Invalidate the cache entry as it is modified + cache.Remove(GetCacheKey(album.AlbumId)); + return RedirectToAction("Index"); + } + + ViewBag.GenreId = new SelectList(DbContext.Genres, "GenreId", "Name", album.GenreId); + ViewBag.ArtistId = new SelectList(DbContext.Artists, "ArtistId", "Name", album.ArtistId); + return View(album); + } + + // + // GET: /StoreManager/RemoveAlbum/5 + public async Task RemoveAlbum(int id) + { + var album = await DbContext.Albums.Where(a => a.AlbumId == id).FirstOrDefaultAsync(); + if (album == null) + { + return NotFound(); + } + + return View(album); + } + + // + // POST: /StoreManager/RemoveAlbum/5 + [HttpPost, ActionName("RemoveAlbum")] + public async Task RemoveAlbumConfirmed( + [FromServices] IMemoryCache cache, + int id, + CancellationToken requestAborted) + { + var album = await DbContext.Albums.Where(a => a.AlbumId == id).FirstOrDefaultAsync(); + if (album == null) + { + return NotFound(); + } + + DbContext.Albums.Remove(album); + await DbContext.SaveChangesAsync(requestAborted); + //Remove the cache entry as it is removed + cache.Remove(GetCacheKey(id)); + + return RedirectToAction("Index"); + } + + private static string GetCacheKey(int id) + { + return string.Format("album_{0}", id); + } + + // NOTE: this is used for end to end testing only + // + // GET: /StoreManager/GetAlbumIdFromName + // Note: Added for automated testing purpose. Application does not use this. + [HttpGet] + [SkipStatusCodePages] + [EnableCors("CorsPolicy")] + public async Task GetAlbumIdFromName(string albumName) + { + var album = await DbContext.Albums.Where(a => a.Title == albumName).FirstOrDefaultAsync(); + + if (album == null) + { + return NotFound(); + } + + return Content(album.AlbumId.ToString()); + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Areas/Admin/Views/StoreManager/Create.cshtml b/samples/MusicStore/Areas/Admin/Views/StoreManager/Create.cshtml new file mode 100644 index 0000000..3a15331 --- /dev/null +++ b/samples/MusicStore/Areas/Admin/Views/StoreManager/Create.cshtml @@ -0,0 +1,75 @@ +@model MusicStore.Models.Album + +@{ + ViewBag.Title = "Create"; +} + +

Create

+ +@using (Html.BeginForm()) +{ + @Html.AntiForgeryToken() + +
+

Album

+
+ @Html.ValidationSummary(true) + +
+ @Html.LabelFor(model => model.GenreId, "GenreId", new { @class = "control-label col-md-2" }) +
+ @Html.DropDownList("GenreId", String.Empty) + @Html.ValidationMessageFor(model => model.GenreId) +
+
+ +
+ @Html.LabelFor(model => model.ArtistId, "ArtistId", new { @class = "control-label col-md-2" }) +
+ @Html.DropDownList("ArtistId", String.Empty) + @Html.ValidationMessageFor(model => model.ArtistId) +
+
+ +
+ @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Title) + @Html.ValidationMessageFor(model => model.Title) +
+
+ +
+ @Html.LabelFor(model => model.Price, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Price) + @Html.ValidationMessageFor(model => model.Price) +
+
+ +
+ @Html.LabelFor(model => model.AlbumArtUrl, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.AlbumArtUrl) + @Html.ValidationMessageFor(model => model.AlbumArtUrl) +
+
+ +
+
+ +
+
+
+} + +
+ @Html.ActionLink("Back to List", "Index") +
+ +@section Scripts { + @*TODO : Until script helpers are available, adding script references manually*@ + @*@Scripts.Render("~/bundles/jqueryval")*@ + + +} \ No newline at end of file diff --git a/samples/MusicStore/Areas/Admin/Views/StoreManager/Details.cshtml b/samples/MusicStore/Areas/Admin/Views/StoreManager/Details.cshtml new file mode 100644 index 0000000..3e65c71 --- /dev/null +++ b/samples/MusicStore/Areas/Admin/Views/StoreManager/Details.cshtml @@ -0,0 +1,58 @@ +@model MusicStore.Models.Album + +@{ + ViewBag.Title = "Details"; +} + +

Details

+ +
+

Album

+
+
+
+ @Html.DisplayNameFor(model => model.Artist.Name) +
+ +
+ @Html.DisplayFor(model => model.Artist.Name) +
+ +
+ @Html.DisplayNameFor(model => model.Genre.Name) +
+ +
+ @Html.DisplayFor(model => model.Genre.Name) +
+ +
+ @Html.DisplayNameFor(model => model.Title) +
+ +
+ @Html.DisplayFor(model => model.Title) +
+ +
+ @Html.DisplayNameFor(model => model.Price) +
+ +
+ @Html.DisplayFor(model => model.Price) +
+ +
+ @Html.DisplayNameFor(model => model.AlbumArtUrl) +
+ +
+ @Html.DisplayFor(model => model.AlbumArtUrl) +
+ +
+
+

+ @Html.ActionLink("Edit", "Edit", new { id = Model.AlbumId }) | + @Html.ActionLink("Back to List", "Index") +

\ No newline at end of file diff --git a/samples/MusicStore/Areas/Admin/Views/StoreManager/Edit.cshtml b/samples/MusicStore/Areas/Admin/Views/StoreManager/Edit.cshtml new file mode 100644 index 0000000..3e9def0 --- /dev/null +++ b/samples/MusicStore/Areas/Admin/Views/StoreManager/Edit.cshtml @@ -0,0 +1,76 @@ +@model MusicStore.Models.Album + +@{ + ViewBag.Title = "Edit"; +} + +

Edit

+ +@using (Html.BeginForm()) +{ + @Html.AntiForgeryToken() + +
+

Album

+
+ @Html.ValidationSummary(true) + @Html.HiddenFor(model => model.AlbumId) + +
+ @Html.LabelFor(model => model.GenreId, "GenreId", new { @class = "control-label col-md-2" }) +
+ @Html.DropDownList("GenreId", String.Empty) + @Html.ValidationMessageFor(model => model.GenreId) +
+
+ +
+ @Html.LabelFor(model => model.ArtistId, "ArtistId", new { @class = "control-label col-md-2" }) +
+ @Html.DropDownList("ArtistId", String.Empty) + @Html.ValidationMessageFor(model => model.ArtistId) +
+
+ +
+ @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Title) + @Html.ValidationMessageFor(model => model.Title) +
+
+ +
+ @Html.LabelFor(model => model.Price, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Price) + @Html.ValidationMessageFor(model => model.Price) +
+
+ +
+ @Html.LabelFor(model => model.AlbumArtUrl, new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.AlbumArtUrl) + @Html.ValidationMessageFor(model => model.AlbumArtUrl) +
+
+ +
+
+ +
+
+
+} + +
+ @Html.ActionLink("Back to List", "Index") +
+ +@section Scripts { + @*TODO : Until script helpers are available, adding script references manually*@ + @*@Scripts.Render("~/bundles/jqueryval")*@ + + +} \ No newline at end of file diff --git a/samples/MusicStore/Areas/Admin/Views/StoreManager/Index.cshtml b/samples/MusicStore/Areas/Admin/Views/StoreManager/Index.cshtml new file mode 100644 index 0000000..bc30dd2 --- /dev/null +++ b/samples/MusicStore/Areas/Admin/Views/StoreManager/Index.cshtml @@ -0,0 +1,66 @@ +@model IEnumerable + +@{ + ViewBag.Title = "Index"; +} + +

Index

+ +

+ @Html.ActionLink("Create New", "Create") +

+ + + + + + + + + + @foreach (var item in Model) + { + + + + + + + + } + +
+ @Html.DisplayNameFor(model => model.Genre.Name) + + @Html.DisplayNameFor(model => model.FirstOrDefault().Artist.Name) + + @Html.DisplayNameFor(model => model.FirstOrDefault().Title) + + @Html.DisplayNameFor(model => model.FirstOrDefault().Price) +
+ @Html.DisplayFor(modelItem => item.Genre.Name) + + @if (item.Artist.Name.Length <= 25) + { + @item.Artist.Name + } + else + { + @item.Artist.Name.Substring(0, 25)... + } + + @if (item.Title.Length <= 25) + { + @item.Title + } + else + { + @item.Title.Substring(0, 25)... + } + + @Html.DisplayFor(modelItem => item.Price) + + @Html.ActionLink("Edit", "Edit", new { id = item.AlbumId }) | + @Html.ActionLink("Details", "Details", new { id = item.AlbumId }) | + @Html.ActionLink("Delete", "RemoveAlbum", new { id = item.AlbumId }) +
\ No newline at end of file diff --git a/samples/MusicStore/Areas/Admin/Views/StoreManager/RemoveAlbum.cshtml b/samples/MusicStore/Areas/Admin/Views/StoreManager/RemoveAlbum.cshtml new file mode 100644 index 0000000..49cdeaa --- /dev/null +++ b/samples/MusicStore/Areas/Admin/Views/StoreManager/RemoveAlbum.cshtml @@ -0,0 +1,29 @@ +@model MusicStore.Models.Album + +@{ + ViewBag.Title = "Delete"; +} + +@if (Model != null) +{ +

Delete Confirmation

+ +

+ Are you sure you want to delete the album titled + @Model.Title? +

+ + @using (Html.BeginForm()) + { +

+ +

+

+ @Html.ActionLink("Back to List", "Index") +

+ } +} +else +{ + @Html.Label(null, "Unable to locate the album") +} \ No newline at end of file diff --git a/samples/MusicStore/Areas/Admin/Views/_ViewStart.cshtml b/samples/MusicStore/Areas/Admin/Views/_ViewStart.cshtml new file mode 100644 index 0000000..ab23e9a --- /dev/null +++ b/samples/MusicStore/Areas/Admin/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "/Views/Shared/_Layout.cshtml"; +} \ No newline at end of file diff --git a/samples/MusicStore/Components/CartSummaryComponent.cs b/samples/MusicStore/Components/CartSummaryComponent.cs new file mode 100644 index 0000000..f2917af --- /dev/null +++ b/samples/MusicStore/Components/CartSummaryComponent.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using MusicStore.Models; + +namespace MusicStore.Components +{ + [ViewComponent(Name = "CartSummary")] + public class CartSummaryComponent : ViewComponent + { + public CartSummaryComponent(MusicStoreContext dbContext) + { + DbContext = dbContext; + } + + private MusicStoreContext DbContext { get; } + + public async Task InvokeAsync() + { + var cart = ShoppingCart.GetCart(DbContext, HttpContext); + + var cartItems = await cart.GetCartItems(); + + ViewBag.CartCount = cartItems.Sum(c => c.Count); + ViewBag.CartSummary = string.Join("\n", cartItems.Select(c => c.Album.Title).Distinct()); + + return View(); + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Components/GenreMenuComponent.cs b/samples/MusicStore/Components/GenreMenuComponent.cs new file mode 100644 index 0000000..94f4d18 --- /dev/null +++ b/samples/MusicStore/Components/GenreMenuComponent.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using MusicStore.Models; + +namespace MusicStore.Components +{ + [ViewComponent(Name = "GenreMenu")] + public class GenreMenuComponent : ViewComponent + { + public GenreMenuComponent(MusicStoreContext dbContext) + { + DbContext = dbContext; + } + + private MusicStoreContext DbContext { get; } + + public async Task InvokeAsync() + { + // TODO use nested sum https://github.com/aspnet/EntityFramework/issues/3792 + //.OrderByDescending( + // g => g.Albums.Sum(a => a.OrderDetails.Sum(od => od.Quantity))) + + var genres = await DbContext.Genres.Select(g => g.Name).Take(9).ToListAsync(); + + return View(genres); + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Components/ISystemClock.cs b/samples/MusicStore/Components/ISystemClock.cs new file mode 100644 index 0000000..9673d00 --- /dev/null +++ b/samples/MusicStore/Components/ISystemClock.cs @@ -0,0 +1,16 @@ +using System; + +namespace MusicStore.Components +{ + /// + /// Abstracts the system clock to facilitate testing. + /// + public interface ISystemClock + { + /// + /// Gets a DateTime object that is set to the current date and time on this computer, + /// expressed as the Coordinated Universal Time(UTC) + /// + DateTime UtcNow { get; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Components/SystemClock.cs b/samples/MusicStore/Components/SystemClock.cs new file mode 100644 index 0000000..68fa7b7 --- /dev/null +++ b/samples/MusicStore/Components/SystemClock.cs @@ -0,0 +1,22 @@ +using System; + +namespace MusicStore.Components +{ + /// + /// Provides access to the normal system clock. + /// + public class SystemClock : ISystemClock + { + /// + public DateTime UtcNow + { + get + { + // The clock measures whole seconds only, and truncates the milliseconds, + // because millisecond resolution is inconsistent among various underlying systems. + DateTime utcNow = DateTime.UtcNow; + return utcNow.AddMilliseconds(-utcNow.Millisecond); + } + } + } +} diff --git a/samples/MusicStore/Controllers/AccountController.cs b/samples/MusicStore/Controllers/AccountController.cs new file mode 100644 index 0000000..25e5e43 --- /dev/null +++ b/samples/MusicStore/Controllers/AccountController.cs @@ -0,0 +1,512 @@ +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using MusicStore.Models; + +namespace MusicStore.Controllers +{ + [Authorize] + public class AccountController : Controller + { + private readonly ILogger _logger; + + public AccountController( + UserManager userManager, + SignInManager signInManager, + ILogger logger) + { + UserManager = userManager; + SignInManager = signInManager; + _logger = logger; + } + + public UserManager UserManager { get; } + + public SignInManager SignInManager { get; } + + // + // GET: /Account/Login + [AllowAnonymous] + public IActionResult Login(string returnUrl = null) + { + ViewBag.ReturnUrl = returnUrl; + return View(); + } + + // + // POST: /Account/Login + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Login(LoginViewModel model, string returnUrl = null) + { + if (!ModelState.IsValid) + { + return View(model); + } + + // This doesn't count login failures towards account lockout + // To enable password failures to trigger account lockout, change to lockoutOnFailure: true + var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); + if (result.Succeeded) + { + _logger.LogInformation("Logged in {userName}.", model.Email); + return RedirectToLocal(returnUrl); + } + if (result.RequiresTwoFactor) + { + return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); + } + if (result.IsLockedOut) + { + return View("Lockout"); + } + else + { + _logger.LogWarning("Failed to log in {userName}.", model.Email); + ModelState.AddModelError("", "Invalid login attempt."); + return View(model); + } + } + + // + // GET: /Account/VerifyCode + [AllowAnonymous] + public async Task VerifyCode(string provider, bool rememberMe, string returnUrl = null) + { + var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + return View("Error"); + } + + // Remove before production +#if DEMO + if (user != null) + { + ViewBag.Code = await UserManager.GenerateTwoFactorTokenAsync(user, provider); + } +#endif + return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe }); + } + + // + // POST: /Account/VerifyCode + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task VerifyCode(VerifyCodeViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + // The following code protects for brute force attacks against the two factor codes. + // If a user enters incorrect codes for a specified amount of time then the user account + // will be locked out for a specified amount of time. + // You can configure the account lockout settings in IdentityConfig + var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser); + if (result.Succeeded) + { + return RedirectToLocal(model.ReturnUrl); + } + if (result.IsLockedOut) + { + return View("Lockout"); + } + else + { + ModelState.AddModelError("", "Invalid code."); + return View(model); + } + + } + + // + // GET: /Account/Register + [AllowAnonymous] + public IActionResult Register() + { + return View(); + } + + // + // POST: /Account/Register + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Register(RegisterViewModel model) + { + if (ModelState.IsValid) + { + var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; + var result = await UserManager.CreateAsync(user, model.Password); + if (result.Succeeded) + { + _logger.LogInformation("User {userName} was created.", model.Email); + //Bug: Remember browser option missing? + //Uncomment this and comment the later part if account verification is not needed. + //await SignInManager.SignInAsync(user, isPersistent: false); + + // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 + // Send an email with this link + string code = await UserManager.GenerateEmailConfirmationTokenAsync(user); + var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); + await MessageServices.SendEmailAsync(model.Email, "Confirm your account", + "Please confirm your account by clicking this link: link"); +#if !DEMO + return RedirectToAction("Index", "Home"); +#else + //To display the email link in a friendly page instead of sending email + ViewBag.Link = callbackUrl; + return View("DemoLinkDisplay"); +#endif + + } + AddErrors(result); + } + // If we got this far, something failed, redisplay form + return View(model); + } + + // + // GET: /Account/ConfirmEmail + [AllowAnonymous] + public async Task ConfirmEmail(string userId, string code) + { + if (userId == null || code == null) + { + return View("Error"); + } + + var user = await UserManager.FindByIdAsync(userId); + if (user == null) + { + return View("Error"); + } + var result = await UserManager.ConfirmEmailAsync(user, code); + return View(result.Succeeded ? "ConfirmEmail" : "Error"); + } + + // + // GET: /Account/ForgotPassword + [AllowAnonymous] + public ActionResult ForgotPassword() + { + return View(); + } + + // + // POST: /Account/ForgotPassword + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ForgotPassword(ForgotPasswordViewModel model) + { + if (ModelState.IsValid) + { + var user = await UserManager.FindByNameAsync(model.Email); + if (user == null || !(await UserManager.IsEmailConfirmedAsync(user))) + { + // Don't reveal that the user does not exist or is not confirmed + return View("ForgotPasswordConfirmation"); + } + + // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 + // Send an email with this link + string code = await UserManager.GeneratePasswordResetTokenAsync(user); + var callbackUrl = Url.Action("ResetPassword", "Account", new { code = code }, protocol: HttpContext.Request.Scheme); + await MessageServices.SendEmailAsync(model.Email, "Reset Password", + "Please reset your password by clicking here: link"); +#if !DEMO + return RedirectToAction("ForgotPasswordConfirmation"); +#else + //To display the email link in a friendly page instead of sending email + ViewBag.Link = callbackUrl; + return View("DemoLinkDisplay"); +#endif + } + + ModelState.AddModelError("", string.Format("We could not locate an account with email : {0}", model.Email)); + + // If we got this far, something failed, redisplay form + return View(model); + } + + // + // GET: /Account/ForgotPasswordConfirmation + [AllowAnonymous] + public ActionResult ForgotPasswordConfirmation() + { + return View(); + } + + // + // GET: /Account/ResetPassword + [AllowAnonymous] + public ActionResult ResetPassword(string code) + { + //TODO: Fix this? + var resetPasswordViewModel = new ResetPasswordViewModel() { Code = code }; + return code == null ? View("Error") : View(resetPasswordViewModel); + } + + // + // POST: /Account/ResetPassword + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ResetPassword(ResetPasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + var user = await UserManager.FindByNameAsync(model.Email); + if (user == null) + { + // Don't reveal that the user does not exist + return RedirectToAction("ResetPasswordConfirmation", "Account"); + } + var result = await UserManager.ResetPasswordAsync(user, model.Code, model.Password); + if (result.Succeeded) + { + return RedirectToAction("ResetPasswordConfirmation", "Account"); + } + AddErrors(result); + return View(); + } + + // + // GET: /Account/ResetPasswordConfirmation + [AllowAnonymous] + public ActionResult ResetPasswordConfirmation() + { + return View(); + } + + // + // POST: /Account/ExternalLogin + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public ActionResult ExternalLogin(string provider, string returnUrl = null) + { + // Request a redirect to the external login provider + var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }); + var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); + return new ChallengeResult(provider, properties); + } + + // + // GET: /Account/SendCode + [AllowAnonymous] + public async Task SendCode(bool rememberMe, string returnUrl = null) + { + //TODO : Default rememberMe as well? + var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + return View("Error"); + } + var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(user); + var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList(); + return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe }); + } + + // + // POST: /Account/SendCode + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task SendCode(SendCodeViewModel model) + { + if (!ModelState.IsValid) + { + return View(); + } + + var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + return View("Error"); + } + + // Generate the token and send it + var code = await UserManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider); + if (string.IsNullOrWhiteSpace(code)) + { + return View("Error"); + } + + var message = "Your security code is: " + code; + if (model.SelectedProvider == "Email") + { + await MessageServices.SendEmailAsync(await UserManager.GetEmailAsync(user), "Security Code", message); + } + else if (model.SelectedProvider == "Phone") + { + await MessageServices.SendSmsAsync(await UserManager.GetPhoneNumberAsync(user), message); + } + + return RedirectToAction("VerifyCode", new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe }); + } + + // + // GET: /Account/ExternalLoginCallback + [AllowAnonymous] + public async Task ExternalLoginCallback(string returnUrl = null) + { + var loginInfo = await SignInManager.GetExternalLoginInfoAsync(); + if (loginInfo == null) + { + return RedirectToAction("Login"); + } + + // Sign in the user with this external login provider if the user already has a login + var result = await SignInManager.ExternalLoginSignInAsync(loginInfo.LoginProvider, loginInfo.ProviderKey, isPersistent: false); + if (result.Succeeded) + { + return RedirectToLocal(returnUrl); + } + if (result.RequiresTwoFactor) + { + return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false }); + } + if (result.IsLockedOut) + { + return View("Lockout"); + } + else + { + // If the user does not have an account, then prompt the user to create an account + ViewBag.ReturnUrl = returnUrl; + ViewBag.LoginProvider = loginInfo.LoginProvider; + // REVIEW: handle case where email not in claims? + var email = loginInfo.Principal.FindFirstValue(ClaimTypes.Email); + return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email }); + } + } + + // + // POST: /Account/ExternalLoginConfirmation + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl = null) + { + if (SignInManager.IsSignedIn(User)) + { + return RedirectToAction("Index", "Manage"); + } + + if (ModelState.IsValid) + { + // Get the information about the user from the external login provider + var info = await SignInManager.GetExternalLoginInfoAsync(); + if (info == null) + { + return View("ExternalLoginFailure"); + } + var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; + var result = await UserManager.CreateAsync(user); + + // NOTE: Used for end to end testing only + //Just for automated testing adding a claim named 'ManageStore' - Not required for production + var manageClaim = info.Principal.Claims.Where(c => c.Type == "ManageStore").FirstOrDefault(); + if (manageClaim != null) + { + await UserManager.AddClaimAsync(user, manageClaim); + } + + if (result.Succeeded) + { + result = await UserManager.AddLoginAsync(user, info); + if (result.Succeeded) + { + await SignInManager.SignInAsync(user, isPersistent: false); + return RedirectToLocal(returnUrl); + } + } + AddErrors(result); + } + + ViewBag.ReturnUrl = returnUrl; + return View(model); + } + + // + // POST: /Account/LogOff + [HttpPost] + [ValidateAntiForgeryToken] + public async Task LogOff() + { + var userName = HttpContext.User.Identity.Name; + // clear all items from the cart + HttpContext.Session.Clear(); + + await SignInManager.SignOutAsync(); + + // TODO: Currently SignInManager.SignOut does not sign out OpenIdc and does not have a way to pass in a specific + // AuthType to sign out. + var appEnv = HttpContext.RequestServices.GetService(); + if (appEnv.EnvironmentName.StartsWith("OpenIdConnect")) + { + return new SignOutResult("OpenIdConnect", new AuthenticationProperties + { + RedirectUri = Url.Action("Index", "Home") + }); + } + + _logger.LogInformation("{userName} logged out.", userName); + return RedirectToAction("Index", "Home"); + } + + // + // GET: /Account/ExternalLoginFailure + [AllowAnonymous] + public ActionResult ExternalLoginFailure() + { + return View(); + } + + #region Helpers + + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { + ModelState.AddModelError("", error.Description); + _logger.LogWarning("Error in creating user: {error}", error.Description); + } + } + + private Task GetCurrentUserAsync() + { + return UserManager.GetUserAsync(HttpContext.User); + } + + private ActionResult RedirectToLocal(string returnUrl) + { + if (Url.IsLocalUrl(returnUrl)) + { + return Redirect(returnUrl); + } + else + { + return RedirectToAction("Index", "Home"); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/samples/MusicStore/Controllers/CheckoutController.cs b/samples/MusicStore/Controllers/CheckoutController.cs new file mode 100644 index 0000000..5f7a5e2 --- /dev/null +++ b/samples/MusicStore/Controllers/CheckoutController.cs @@ -0,0 +1,113 @@ +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using MusicStore.Models; + +namespace MusicStore.Controllers +{ + [Authorize] + public class CheckoutController : Controller + { + private const string PromoCode = "FREE"; + + private readonly ILogger _logger; + + public CheckoutController(ILogger logger) + { + _logger = logger; + } + + // + // GET: /Checkout/ + public IActionResult AddressAndPayment() + { + return View(); + } + + // + // POST: /Checkout/AddressAndPayment + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task AddressAndPayment( + [FromServices] MusicStoreContext dbContext, + [FromForm] Order order, + CancellationToken requestAborted) + { + if (!ModelState.IsValid) + { + return View(order); + } + + var formCollection = await HttpContext.Request.ReadFormAsync(); + + try + { + if (string.Equals(formCollection["PromoCode"].FirstOrDefault(), PromoCode, + StringComparison.OrdinalIgnoreCase) == false) + { + return View(order); + } + else + { + order.Username = HttpContext.User.Identity.Name; + order.OrderDate = DateTime.Now; + + //Add the Order + dbContext.Orders.Add(order); + + //Process the order + var cart = ShoppingCart.GetCart(dbContext, HttpContext); + await cart.CreateOrder(order); + + _logger.LogInformation("User {userName} started checkout of {orderId}.", order.Username, order.OrderId); + + // Save all changes + await dbContext.SaveChangesAsync(requestAborted); + + return RedirectToAction("Complete", new { id = order.OrderId }); + } + } + catch + { + //Invalid - redisplay with errors + return View(order); + } + } + + // + // GET: /Checkout/Complete + + public async Task Complete( + [FromServices] MusicStoreContext dbContext, + int id) + { + var userName = HttpContext.User.Identity.Name; + + // Validate customer owns this order + bool isValid = await dbContext.Orders.AnyAsync( + o => o.OrderId == id && + o.Username == userName); + + if (isValid) + { + _logger.LogInformation("User {userName} completed checkout on order {orderId}.", userName, id); + return View(id); + } + else + { + _logger.LogError( + "User {userName} tried to checkout with an order ({orderId}) that doesn't belong to them.", + userName, + id); + return View("Error"); + } + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Controllers/HomeController.cs b/samples/MusicStore/Controllers/HomeController.cs new file mode 100644 index 0000000..992a4f2 --- /dev/null +++ b/samples/MusicStore/Controllers/HomeController.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Options; +using MusicStore.Models; + +namespace MusicStore.Controllers +{ + public class HomeController : Controller + { + private readonly AppSettings _appSettings; + + public HomeController(IOptions options) + { + _appSettings = options.Value; + } + // + // GET: /Home/ + public async Task Index( + [FromServices] MusicStoreContext dbContext, + [FromServices] IMemoryCache cache) + { + // Get most popular albums + var cacheKey = "topselling"; + List albums; + if (!cache.TryGetValue(cacheKey, out albums)) + { + albums = await GetTopSellingAlbumsAsync(dbContext, 6); + + if (albums != null && albums.Count > 0) + { + if (_appSettings.CacheDbResults) + { + // Refresh it every 10 minutes. + // Let this be the last item to be removed by cache if cache GC kicks in. + cache.Set( + cacheKey, + albums, + new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(TimeSpan.FromMinutes(10)) + .SetPriority(CacheItemPriority.High)); + } + } + } + + return View(albums); + } + + public IActionResult Error() + { + return View("~/Views/Shared/Error.cshtml"); + } + + public IActionResult StatusCodePage() + { + return View("~/Views/Shared/StatusCodePage.cshtml"); + } + + public IActionResult AccessDenied() + { + return View("~/Views/Shared/AccessDenied.cshtml"); + } + + private Task> GetTopSellingAlbumsAsync(MusicStoreContext dbContext, int count) + { + // Group the order details by album and return + // the albums with the highest count + + return dbContext.Albums + .OrderByDescending(a => a.OrderDetails.Count) + .Take(count) + .ToListAsync(); + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Controllers/ManageController.cs b/samples/MusicStore/Controllers/ManageController.cs new file mode 100644 index 0000000..5e1ed74 --- /dev/null +++ b/samples/MusicStore/Controllers/ManageController.cs @@ -0,0 +1,365 @@ +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using MusicStore.Models; + +namespace MusicStore.Controllers +{ + [Authorize] + public class ManageController : Controller + { + public ManageController( + UserManager userManager, + SignInManager signInManager, + IAuthenticationSchemeProvider schemes) + { + UserManager = userManager; + SignInManager = signInManager; + SchemeProvider = schemes; + } + + public UserManager UserManager { get; } + + public SignInManager SignInManager { get; } + + public IAuthenticationSchemeProvider SchemeProvider { get; } + + // + // GET: /Manage/Index + public async Task Index(ManageMessageId? message = null) + { + ViewBag.StatusMessage = + message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." + : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set." + : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set." + : message == ManageMessageId.Error ? "An error has occurred." + : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added." + : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed." + : ""; + + var user = await GetCurrentUserAsync(); + var model = new IndexViewModel + { + HasPassword = await UserManager.HasPasswordAsync(user), + PhoneNumber = await UserManager.GetPhoneNumberAsync(user), + TwoFactor = await UserManager.GetTwoFactorEnabledAsync(user), + Logins = await UserManager.GetLoginsAsync(user), + BrowserRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(user) + }; + + return View(model); + } + + // + // POST: /Manage/RemoveLogin + [HttpPost] + [ValidateAntiForgeryToken] + public async Task RemoveLogin(string loginProvider, string providerKey) + { + ManageMessageId? message = ManageMessageId.Error; + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await UserManager.RemoveLoginAsync(user, loginProvider, providerKey); + if (result.Succeeded) + { + await SignInManager.SignInAsync(user, isPersistent: false); + message = ManageMessageId.RemoveLoginSuccess; + } + } + return RedirectToAction("ManageLogins", new { Message = message }); + } + + // + // GET: /Account/AddPhoneNumber + public IActionResult AddPhoneNumber() + { + return View(); + } + + // + // POST: /Account/AddPhoneNumber + [HttpPost] + [ValidateAntiForgeryToken] + public async Task AddPhoneNumber(AddPhoneNumberViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + var user = await GetCurrentUserAsync(); + // Generate the token and send it + var code = await UserManager.GenerateChangePhoneNumberTokenAsync(user, model.Number); + await MessageServices.SendSmsAsync(model.Number, "Your security code is: " + code); + return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number }); + } + + // + // POST: /Manage/EnableTwoFactorAuthentication + [HttpPost] + [ValidateAntiForgeryToken] + public async Task EnableTwoFactorAuthentication() + { + var user = await GetCurrentUserAsync(); + if (user != null) + { + await UserManager.SetTwoFactorEnabledAsync(user, true); + // TODO: flow remember me somehow? + await SignInManager.SignInAsync(user, isPersistent: false); + } + return RedirectToAction("Index", "Manage"); + } + + // + // POST: /Manage/DisableTwoFactorAuthentication + [HttpPost] + [ValidateAntiForgeryToken] + public async Task DisableTwoFactorAuthentication() + { + var user = await GetCurrentUserAsync(); + if (user != null) + { + await UserManager.SetTwoFactorEnabledAsync(user, false); + await SignInManager.SignInAsync(user, isPersistent: false); + } + return RedirectToAction("Index", "Manage"); + } + + // + // GET: /Account/VerifyPhoneNumber + public async Task VerifyPhoneNumber(string phoneNumber) + { + // This code allows you exercise the flow without actually sending codes + // For production use please register a SMS provider in IdentityConfig and generate a code here. +#if DEMO + ViewBag.Code = await UserManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber); +#endif + return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber }); + } + + // + // POST: /Account/VerifyPhoneNumber + [HttpPost] + [ValidateAntiForgeryToken] + public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await UserManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code); + if (result.Succeeded) + { + await SignInManager.SignInAsync(user, isPersistent: false); + return RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess }); + } + } + // If we got this far, something failed, redisplay form + ModelState.AddModelError("", "Failed to verify phone"); + return View(model); + } + + // + // GET: /Account/RemovePhoneNumber + [HttpPost] + [ValidateAntiForgeryToken] + public async Task RemovePhoneNumber() + { + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await UserManager.SetPhoneNumberAsync(user, null); + if (result.Succeeded) + { + await SignInManager.SignInAsync(user, isPersistent: false); + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess }); + } + } + return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); + } + + // + // GET: /Manage/ChangePassword + public IActionResult ChangePassword() + { + return View(); + } + + // + // POST: /Account/Manage + [HttpPost] + [ValidateAntiForgeryToken] + public async Task ChangePassword(ChangePasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await UserManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); + if (result.Succeeded) + { + await SignInManager.SignInAsync(user, isPersistent: false); + return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess }); + } + AddErrors(result); + return View(model); + } + return RedirectToAction("Index", new { Message = ManageMessageId.Error }); + } + + // + // GET: /Manage/SetPassword + public IActionResult SetPassword() + { + return View(); + } + + // + // POST: /Manage/SetPassword + [HttpPost] + [ValidateAntiForgeryToken] + public async Task SetPassword(SetPasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + var user = await GetCurrentUserAsync(); + if (user != null) + { + var result = await UserManager.AddPasswordAsync(user, model.NewPassword); + if (result.Succeeded) + { + await SignInManager.SignInAsync(user, isPersistent: false); + return RedirectToAction("Index", new { Message = ManageMessageId.SetPasswordSuccess }); + } + AddErrors(result); + return View(model); + } + return RedirectToAction("Index", new { Message = ManageMessageId.Error }); + } + + // + // POST: /Manage/RememberBrowser + [HttpPost] + [ValidateAntiForgeryToken] + public async Task RememberBrowser() + { + var user = await GetCurrentUserAsync(); + if (user != null) + { + await SignInManager.RememberTwoFactorClientAsync(user); + await SignInManager.SignInAsync(user, isPersistent: false); + } + return RedirectToAction("Index", "Manage"); + } + + // + // POST: /Manage/ForgetBrowser + [HttpPost] + [ValidateAntiForgeryToken] + public async Task ForgetBrowser() + { + await SignInManager.ForgetTwoFactorClientAsync(); + return RedirectToAction("Index", "Manage"); + } + + // + // GET: /Account/Manage + public async Task ManageLogins(ManageMessageId? message = null) + { + ViewBag.StatusMessage = + message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed." + : message == ManageMessageId.AddLoginSuccess ? "The external login was added." + : message == ManageMessageId.Error ? "An error has occurred." + : ""; + var user = await GetCurrentUserAsync(); + if (user == null) + { + return View("Error"); + } + var userLogins = await UserManager.GetLoginsAsync(user); + var schemes = await SchemeProvider.GetAllSchemesAsync(); + var otherLogins = schemes.Where(auth => userLogins.All(ul => auth.Name != ul.LoginProvider)).ToList(); + ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1; + return View(new ManageLoginsViewModel + { + CurrentLogins = userLogins, + OtherLogins = otherLogins + }); + } + + // + // POST: /Manage/LinkLogin + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult LinkLogin(string provider) + { + // Request a redirect to the external login provider to link a login for the current user + var redirectUrl = Url.Action("LinkLoginCallback", "Manage"); + var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, UserManager.GetUserId(User)); + return new ChallengeResult(provider, properties); + } + + // + // GET: /Manage/LinkLoginCallback + public async Task LinkLoginCallback() + { + var user = await GetCurrentUserAsync(); + if (user == null) + { + return View("Error"); + } + + var loginInfo = await SignInManager.GetExternalLoginInfoAsync(await UserManager.GetUserIdAsync(user)); + if (loginInfo == null) + { + return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error }); + } + + var result = await UserManager.AddLoginAsync(user, loginInfo); + var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error; + return RedirectToAction("ManageLogins", new { Message = message }); + } + + #region Helpers + + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { + ModelState.AddModelError("", error.Description); + } + } + + public enum ManageMessageId + { + AddPhoneSuccess, + AddLoginSuccess, + ChangePasswordSuccess, + SetTwoFactorSuccess, + SetPasswordSuccess, + RemoveLoginSuccess, + RemovePhoneSuccess, + Error + } + + private Task GetCurrentUserAsync() + { + return UserManager.GetUserAsync(HttpContext.User); + } + + #endregion + } +} \ No newline at end of file diff --git a/samples/MusicStore/Controllers/ShoppingCartController.cs b/samples/MusicStore/Controllers/ShoppingCartController.cs new file mode 100644 index 0000000..f99d999 --- /dev/null +++ b/samples/MusicStore/Controllers/ShoppingCartController.cs @@ -0,0 +1,113 @@ +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using MusicStore.Models; +using MusicStore.ViewModels; + +namespace MusicStore.Controllers +{ + public class ShoppingCartController : Controller + { + private readonly ILogger _logger; + + public ShoppingCartController(MusicStoreContext dbContext, ILogger logger) + { + DbContext = dbContext; + _logger = logger; + } + + public MusicStoreContext DbContext { get; } + + // + // GET: /ShoppingCart/ + public async Task Index() + { + var cart = ShoppingCart.GetCart(DbContext, HttpContext); + + // Set up our ViewModel + var viewModel = new ShoppingCartViewModel + { + CartItems = await cart.GetCartItems(), + CartTotal = await cart.GetTotal() + }; + + // Return the view + return View(viewModel); + } + + // + // GET: /ShoppingCart/AddToCart/5 + + public async Task AddToCart(int id, CancellationToken requestAborted) + { + // Retrieve the album from the database + var addedAlbum = await DbContext.Albums + .SingleAsync(album => album.AlbumId == id); + + // Add it to the shopping cart + var cart = ShoppingCart.GetCart(DbContext, HttpContext); + + await cart.AddToCart(addedAlbum); + + await DbContext.SaveChangesAsync(requestAborted); + _logger.LogInformation("Album {albumId} was added to the cart.", addedAlbum.AlbumId); + + // Go back to the main store page for more shopping + return RedirectToAction("Index"); + } + + // + // AJAX: /ShoppingCart/RemoveFromCart/5 + [HttpPost] + [ValidateAntiForgeryToken] + public async Task RemoveFromCart( + int id, + CancellationToken requestAborted) + { + // Retrieve the current user's shopping cart + var cart = ShoppingCart.GetCart(DbContext, HttpContext); + + // Get the name of the album to display confirmation + var cartItem = await DbContext.CartItems + .Where(item => item.CartItemId == id) + .Include(c => c.Album) + .SingleOrDefaultAsync(); + + string message; + int itemCount; + if (cartItem != null) + { + // Remove from cart + itemCount = cart.RemoveFromCart(id); + + await DbContext.SaveChangesAsync(requestAborted); + + string removed = (itemCount > 0) ? " 1 copy of " : string.Empty; + message = removed + cartItem.Album.Title + " has been removed from your shopping cart."; + } + else + { + itemCount = 0; + message = "Could not find this item, nothing has been removed from your shopping cart."; + } + + // Display the confirmation message + + var results = new ShoppingCartRemoveViewModel + { + Message = message, + CartTotal = await cart.GetTotal(), + CartCount = await cart.GetCount(), + ItemCount = itemCount, + DeleteId = id + }; + + _logger.LogInformation("Album {id} was removed from a cart.", id); + + return Json(results); + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Controllers/StoreController.cs b/samples/MusicStore/Controllers/StoreController.cs new file mode 100644 index 0000000..dfa2336 --- /dev/null +++ b/samples/MusicStore/Controllers/StoreController.cs @@ -0,0 +1,86 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Options; +using MusicStore.Models; + +namespace MusicStore.Controllers +{ + public class StoreController : Controller + { + private readonly AppSettings _appSettings; + + public StoreController(MusicStoreContext dbContext, IOptions options) + { + DbContext = dbContext; + _appSettings = options.Value; + } + + public MusicStoreContext DbContext { get; } + + // + // GET: /Store/ + public async Task Index() + { + var genres = await DbContext.Genres.ToListAsync(); + + return View(genres); + } + + // + // GET: /Store/Browse?genre=Disco + public async Task Browse(string genre) + { + // Retrieve Genre genre and its Associated associated Albums albums from database + var genreModel = await DbContext.Genres + .Include(g => g.Albums) + .Where(g => g.Name == genre) + .FirstOrDefaultAsync(); + + if (genreModel == null) + { + return NotFound(); + } + + return View(genreModel); + } + + public async Task Details( + [FromServices] IMemoryCache cache, + int id) + { + var cacheKey = string.Format("album_{0}", id); + Album album; + if (!cache.TryGetValue(cacheKey, out album)) + { + album = await DbContext.Albums + .Where(a => a.AlbumId == id) + .Include(a => a.Artist) + .Include(a => a.Genre) + .FirstOrDefaultAsync(); + + if (album != null) + { + if (_appSettings.CacheDbResults) + { + //Remove it from cache if not retrieved in last 10 minutes + cache.Set( + cacheKey, + album, + new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(10))); + } + } + } + + if (album == null) + { + return NotFound(); + } + + return View(album); + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/ForTesting/Mocks/Common/CustomStateDataFormat.cs b/samples/MusicStore/ForTesting/Mocks/Common/CustomStateDataFormat.cs new file mode 100644 index 0000000..22ab649 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Common/CustomStateDataFormat.cs @@ -0,0 +1,41 @@ +using Microsoft.AspNetCore.Authentication; +using Newtonsoft.Json; + +namespace MusicStore.Mocks.Common +{ + public class CustomStateDataFormat : ISecureDataFormat + { + private static string _lastSavedAuthenticationProperties; + + public string Protect(AuthenticationProperties data, string purose) + { + return Protect(data); + } + + public string Protect(AuthenticationProperties data) + { + _lastSavedAuthenticationProperties = Serialize(data); + return "ValidStateData"; + } + + public AuthenticationProperties Unprotect(string state, string purpose) + { + return Unprotect(state); + } + + public AuthenticationProperties Unprotect(string state) + { + return state == "ValidStateData" ? DeSerialize(_lastSavedAuthenticationProperties) : null; + } + + private string Serialize(AuthenticationProperties data) + { + return JsonConvert.SerializeObject(data, Formatting.Indented); + } + + private AuthenticationProperties DeSerialize(string state) + { + return JsonConvert.DeserializeObject(state); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/Common/Helpers.cs b/samples/MusicStore/ForTesting/Mocks/Common/Helpers.cs new file mode 100644 index 0000000..2dfe3ad --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Common/Helpers.cs @@ -0,0 +1,15 @@ +using System; + +namespace MusicStore.Mocks.Common +{ + internal class Helpers + { + internal static void ThrowIfConditionFailed(Func condition, string errorMessage) + { + if (!condition()) + { + throw new Exception(errorMessage); + } + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/Facebook/FacebookMockBackChannelHttpHandler.cs b/samples/MusicStore/ForTesting/Mocks/Facebook/FacebookMockBackChannelHttpHandler.cs new file mode 100644 index 0000000..3982964 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Facebook/FacebookMockBackChannelHttpHandler.cs @@ -0,0 +1,57 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Internal; +using Microsoft.AspNetCore.WebUtilities; +using MusicStore.Mocks.Common; + +namespace MusicStore.Mocks.Facebook +{ + /// + /// Summary description for FacebookMockBackChannelHttpHandler + /// + public class FacebookMockBackChannelHttpHandler : HttpMessageHandler + { + protected async override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var response = new HttpResponseMessage(); + + if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.facebook.com/v2.6/oauth/access_token")) + { + var formData = new FormCollection(await new FormReader(await request.Content.ReadAsStreamAsync()).ReadFormAsync()); + if (formData["grant_type"] == "authorization_code") + { + if (formData["code"] == "ValidCode") + { + Helpers.ThrowIfConditionFailed(() => ((string)formData["redirect_uri"]).EndsWith("signin-facebook"), "Redirect URI is not ending with /signin-facebook"); + Helpers.ThrowIfConditionFailed(() => formData["client_id"] == "[AppId]", "Invalid client Id received"); + Helpers.ThrowIfConditionFailed(() => formData["client_secret"] == "[AppSecret]", "Invalid client secret received"); + response.Content = new StringContent("{ \"access_token\": \"ValidAccessToken\", \"expires_in\": \"100\" }"); + return response; + } + response.StatusCode = (HttpStatusCode)400; + return response; + } + } + else if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.facebook.com/v2.6/me")) + { + var queryParameters = new QueryCollection(QueryHelpers.ParseQuery(request.RequestUri.Query)); + Helpers.ThrowIfConditionFailed(() => queryParameters["appsecret_proof"].Count > 0, "appsecret_proof is empty"); + if (queryParameters["access_token"] == "ValidAccessToken") + { + response.Content = new StringContent("{\"id\":\"Id\",\"name\":\"AspnetvnextTest AspnetvnextTest\",\"first_name\":\"AspnetvnextTest\",\"last_name\":\"AspnetvnextTest\",\"link\":\"https:\\/\\/www.facebook.com\\/myLink\",\"username\":\"AspnetvnextTest.AspnetvnextTest.7\",\"gender\":\"male\",\"email\":\"AspnetvnextTest\\u0040test.com\",\"timezone\":-7,\"locale\":\"en_US\",\"verified\":true,\"updated_time\":\"2013-08-06T20:38:48+0000\",\"CertValidatorInvoked\":\"ValidAccessToken\"}"); + } + else + { + response.Content = new StringContent("{\"error\":{\"message\":\"Invalid OAuth access token.\",\"type\":\"OAuthException\",\"code\":190}}"); + } + return response; + } + + throw new NotImplementedException(request.RequestUri.AbsoluteUri); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/Facebook/TestFacebookEvents.cs b/samples/MusicStore/ForTesting/Mocks/Facebook/TestFacebookEvents.cs new file mode 100644 index 0000000..cf8bb10 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Facebook/TestFacebookEvents.cs @@ -0,0 +1,56 @@ +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Facebook; +using Microsoft.AspNetCore.Authentication.OAuth; +using Microsoft.AspNetCore.Identity; +using MusicStore.Mocks.Common; + +namespace MusicStore.Mocks.Facebook +{ + internal class TestFacebookEvents + { + internal static Task OnCreatingTicket(OAuthCreatingTicketContext context) + { + if (context.Principal != null) + { + Helpers.ThrowIfConditionFailed(() => context.AccessToken == "ValidAccessToken", ""); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.Email)?.Value == "AspnetvnextTest@test.com", ""); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.NameIdentifier)?.Value == "Id", ""); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst("urn:facebook:link")?.Value == "https://www.facebook.com/myLink", ""); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.Name)?.Value == "AspnetvnextTest AspnetvnextTest", ""); + Helpers.ThrowIfConditionFailed(() => context.User.SelectToken("id").ToString() == context.Identity.FindFirst(ClaimTypes.NameIdentifier)?.Value, ""); + Helpers.ThrowIfConditionFailed(() => context.ExpiresIn.Value == TimeSpan.FromSeconds(100), ""); + Helpers.ThrowIfConditionFailed(() => context.AccessToken == "ValidAccessToken", ""); + context.Principal.Identities.First().AddClaim(new Claim("ManageStore", "false")); + } + + return Task.FromResult(0); + } + + internal static Task OnTicketReceived(TicketReceivedContext context) + { + if (context.Principal != null && context.Options.SignInScheme == IdentityConstants.ExternalScheme) + { + //This way we will know all events were fired. + var identity = context.Principal.Identities.First(); + var manageStoreClaim = identity?.Claims.Where(c => c.Type == "ManageStore" && c.Value == "false").FirstOrDefault(); + if (manageStoreClaim != null) + { + identity.RemoveClaim(manageStoreClaim); + identity.AddClaim(new Claim("ManageStore", "Allowed")); + } + } + + return Task.FromResult(0); + } + + internal static Task RedirectToAuthorizationEndpoint(RedirectContext context) + { + context.Response.Redirect(context.RedirectUri + "&custom_redirect_uri=custom"); + return Task.FromResult(0); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/Google/GoogleMockBackChannelHttpHandler.cs b/samples/MusicStore/ForTesting/Mocks/Google/GoogleMockBackChannelHttpHandler.cs new file mode 100644 index 0000000..f5eb4a9 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Google/GoogleMockBackChannelHttpHandler.cs @@ -0,0 +1,55 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.WebUtilities; + +namespace MusicStore.Mocks.Google +{ + /// + /// Summary description for GoogleMockBackChannelHttpHandler + /// + public class GoogleMockBackChannelHttpHandler : HttpMessageHandler + { + protected async override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var response = new HttpResponseMessage(); + + if (request.RequestUri.AbsoluteUri.StartsWith("https://www.googleapis.com/oauth2/v4/token")) + { + var formData = new FormCollection(await new FormReader(await request.Content.ReadAsStreamAsync()).ReadFormAsync()); + if (formData["grant_type"] == "authorization_code") + { + if (formData["code"] == "ValidCode") + { + if (formData["redirect_uri"].Count > 0 && ((string)formData["redirect_uri"]).EndsWith("signin-google") && + formData["client_id"] == "[ClientId]" && formData["client_secret"] == "[ClientSecret]") + { + response.Content = new StringContent("{\"access_token\":\"ValidAccessToken\",\"refresh_token\":\"ValidRefreshToken\",\"token_type\":\"Bearer\",\"expires_in\":\"1200\",\"id_token\":\"Token\"}", Encoding.UTF8, "application/json"); + return response; + } + } + } + response.StatusCode = (HttpStatusCode)400; + return response; + } + else if (request.RequestUri.AbsoluteUri.StartsWith("https://www.googleapis.com/plus/v1/people/me")) + { + if (request.Headers.Authorization.Parameter == "ValidAccessToken") + { + response.Content = new StringContent("{ \"kind\": \"plus#person\",\n \"etag\": \"\\\"YFr-hUROXQN7IOa3dUHg9dQ8eq0/2hY18HdHEP8NLykSTVEiAhkKsBE\\\"\",\n \"gender\": \"male\",\n \"emails\": [\n {\n \"value\": \"AspnetvnextTest@gmail.com\",\n \"type\": \"account\"\n }\n ],\n \"objectType\": \"person\",\n \"id\": \"106790274378320830963\",\n \"displayName\": \"AspnetvnextTest AspnetvnextTest\",\n \"name\": {\n \"familyName\": \"AspnetvnextTest\",\n \"givenName\": \"FirstName\"\n },\n \"url\": \"https://plus.google.com/106790274378320830963\",\n \"image\": {\n \"url\": \"https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg?sz=50\"\n },\n \"isPlusUser\": true,\n \"language\": \"en\",\n \"circledByCount\": 0,\n \"verified\": false\n}\n", Encoding.UTF8, "application/json"); + } + else + { + response.Content = new StringContent("{\"error\":{\"message\":\"Invalid OAuth access token.\",\"type\":\"OAuthException\",\"code\":190}}"); + } + return response; + } + + throw new NotImplementedException(request.RequestUri.AbsoluteUri); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/Google/TestGoogleEvents.cs b/samples/MusicStore/ForTesting/Mocks/Google/TestGoogleEvents.cs new file mode 100644 index 0000000..4dec753 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Google/TestGoogleEvents.cs @@ -0,0 +1,56 @@ +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Google; +using Microsoft.AspNetCore.Authentication.OAuth; +using Microsoft.AspNetCore.Identity; +using MusicStore.Mocks.Common; + +namespace MusicStore.Mocks.Google +{ + internal class TestGoogleEvents + { + internal static Task OnCreatingTicket(OAuthCreatingTicketContext context) + { + if (context.Principal != null) + { + Helpers.ThrowIfConditionFailed(() => context.AccessToken == "ValidAccessToken", "Access token is not valid"); + Helpers.ThrowIfConditionFailed(() => context.RefreshToken == "ValidRefreshToken", "Refresh token is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.Email)?.Value == "AspnetvnextTest@gmail.com", "Email is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.NameIdentifier)?.Value == "106790274378320830963", "Id is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.Surname)?.Value == "AspnetvnextTest", "FamilyName is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.Name)?.Value == "AspnetvnextTest AspnetvnextTest", "Name is not valid"); + Helpers.ThrowIfConditionFailed(() => context.ExpiresIn.Value == TimeSpan.FromSeconds(1200), "ExpiresIn is not valid"); + Helpers.ThrowIfConditionFailed(() => context.User != null, "User object is not valid"); + context.Principal.Identities.First().AddClaim(new Claim("ManageStore", "false")); + } + + return Task.FromResult(0); + } + + internal static Task OnTicketReceived(TicketReceivedContext context) + { + if (context.Principal != null && context.Options.SignInScheme == IdentityConstants.ExternalScheme) + { + //This way we will know all events were fired. + var identity = context.Principal.Identities.First(); + var manageStoreClaim = identity?.Claims.Where(c => c.Type == "ManageStore" && c.Value == "false").FirstOrDefault(); + if (manageStoreClaim != null) + { + identity.RemoveClaim(manageStoreClaim); + identity.AddClaim(new Claim("ManageStore", "Allowed")); + } + } + + return Task.FromResult(0); + } + + internal static Task RedirectToAuthorizationEndpoint(RedirectContext context) + { + context.Response.Redirect(context.RedirectUri + "&custom_redirect_uri=custom"); + return Task.FromResult(0); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/MicrosoftAccount/MicrosoftAccountMockBackChannelHandler.cs b/samples/MusicStore/ForTesting/Mocks/MicrosoftAccount/MicrosoftAccountMockBackChannelHandler.cs new file mode 100644 index 0000000..3ebf70a --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/MicrosoftAccount/MicrosoftAccountMockBackChannelHandler.cs @@ -0,0 +1,56 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.WebUtilities; + +namespace MusicStore.Mocks.MicrosoftAccount +{ + /// + /// Summary description for MicrosoftAccountMockBackChannelHandler + /// + public class MicrosoftAccountMockBackChannelHandler : HttpMessageHandler + { + protected async override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var response = new HttpResponseMessage(); + + if (request.RequestUri.AbsoluteUri.StartsWith("https://login.microsoftonline.com/common/oauth2/v2.0/token")) + { + var formData = new FormCollection(await new FormReader(await request.Content.ReadAsStreamAsync()).ReadFormAsync()); + if (formData["grant_type"] == "authorization_code") + { + if (formData["code"] == "ValidCode") + { + if (formData["redirect_uri"].Count > 0 && ((string)formData["redirect_uri"]).EndsWith("signin-microsoft") && + formData["client_id"] == "[ClientId]" && formData["client_secret"] == "[ClientSecret]") + { + response.Content = new StringContent("{\"token_type\":\"bearer\",\"expires_in\":3600,\"scope\":\"https://graph.microsoft.com/user.read\",\"access_token\":\"ValidAccessToken\",\"refresh_token\":\"ValidRefreshToken\",\"authentication_token\":\"ValidAuthenticationToken\"}"); + return response; + } + } + } + + response.StatusCode = (HttpStatusCode)400; + return response; + } + else if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.microsoft.com/v1.0/me")) + { + if (request.Headers.Authorization.Parameter == "ValidAccessToken") + { + response.Content = new StringContent("{\r \"id\": \"fccf9a24999f4f4f\", \r \"displayName\": \"AspnetvnextTest AspnetvnextTest\", \r \"givenName\": \"AspnetvnextTest\", \r \"surname\": \"AspnetvnextTest\", \r \"link\": \"https://profile.live.com/\", \r \"gender\": null, \r \"locale\": \"en_US\", \r \"updated_time\": \"2013-08-27T22:18:14+0000\"\r}"); + } + else + { + response.Content = new StringContent("{\r \"error\": {\r \"code\": \"request_token_invalid\", \r \"message\": \"The access token isn't valid.\"\r }\r}", Encoding.UTF8, "text/javascript"); + } + return response; + } + + throw new NotImplementedException(request.RequestUri.AbsoluteUri); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/MicrosoftAccount/TestMicrosoftAccountEvents.cs b/samples/MusicStore/ForTesting/Mocks/MicrosoftAccount/TestMicrosoftAccountEvents.cs new file mode 100644 index 0000000..3639a7b --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/MicrosoftAccount/TestMicrosoftAccountEvents.cs @@ -0,0 +1,57 @@ +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.MicrosoftAccount; +using Microsoft.AspNetCore.Authentication.OAuth; +using Microsoft.AspNetCore.Identity; +using MusicStore.Mocks.Common; + +namespace MusicStore.Mocks.MicrosoftAccount +{ + internal class TestMicrosoftAccountEvents + { + internal static Task OnCreatingTicket(OAuthCreatingTicketContext context) + { + if (context.Principal != null) + { + Helpers.ThrowIfConditionFailed(() => context.AccessToken == "ValidAccessToken", "Access token is not valid"); + Helpers.ThrowIfConditionFailed(() => context.RefreshToken == "ValidRefreshToken", "Refresh token is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.GivenName)?.Value == "AspnetvnextTest", "Given name is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.Surname)?.Value == "AspnetvnextTest", "Surname is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.NameIdentifier)?.Value == "fccf9a24999f4f4f", "Id is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.Name)?.Value == "AspnetvnextTest AspnetvnextTest", "Name is not valid"); + Helpers.ThrowIfConditionFailed(() => context.ExpiresIn.Value == TimeSpan.FromSeconds(3600), "ExpiresIn is not valid"); + Helpers.ThrowIfConditionFailed(() => context.User != null, "User object is not valid"); + Helpers.ThrowIfConditionFailed(() => context.Identity.FindFirst(ClaimTypes.NameIdentifier)?.Value == context.User.SelectToken("id").ToString(), "User id is not valid"); + context.Principal.Identities.First().AddClaim(new Claim("ManageStore", "false")); + } + + return Task.FromResult(0); + } + + internal static Task OnTicketReceived(TicketReceivedContext context) + { + if (context.Principal != null && context.Options.SignInScheme == IdentityConstants.ExternalScheme) + { + //This way we will know all events were fired. + var identity = context.Principal.Identities.First(); + var manageStoreClaim = identity?.Claims.Where(c => c.Type == "ManageStore" && c.Value == "false").FirstOrDefault(); + if (manageStoreClaim != null) + { + identity.RemoveClaim(manageStoreClaim); + identity.AddClaim(new Claim("ManageStore", "Allowed")); + } + } + + return Task.FromResult(0); + } + + internal static Task RedirectToAuthorizationEndpoint(RedirectContext context) + { + context.Response.Redirect(context.RedirectUri + "&custom_redirect_uri=custom"); + return Task.FromResult(0); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/CustomStringDataFormat.cs b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/CustomStringDataFormat.cs new file mode 100644 index 0000000..dc433f9 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/CustomStringDataFormat.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Authentication; + +namespace MusicStore.Mocks.OpenIdConnect +{ + internal class CustomStringDataFormat : ISecureDataFormat + { + private const string _capturedNonce = "635579928639517715.OTRjOTVkM2EtMDRmYS00ZDE3LThhZGUtZWZmZGM4ODkzZGZkMDRlNDhkN2MtOWIwMC00ZmVkLWI5MTItMTUwYmQ4MzdmOWI0"; + + public string Protect(string data) + { + return "protectedString"; + } + + public string Protect(string data, string purpose) + { + return purpose + "protectedString"; + } + + public string Unprotect(string protectedText) + { + return protectedText == "protectedString" ? _capturedNonce : null; + } + + public string Unprotect(string protectedText, string purpose) + { + return protectedText == (purpose + "protectedString") ? _capturedNonce : null; + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/OpenIdConnectBackChannelHttpHandler.cs b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/OpenIdConnectBackChannelHttpHandler.cs new file mode 100644 index 0000000..cc84ec5 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/OpenIdConnectBackChannelHttpHandler.cs @@ -0,0 +1,33 @@ +using System; +using System.IO; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace MusicStore.Mocks.OpenIdConnect +{ + internal class OpenIdConnectBackChannelHttpHandler : HttpMessageHandler + { + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var response = new HttpResponseMessage(); + + var basePath = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "ForTesting", "Mocks", "OpenIdConnect")); + + if (request.RequestUri.AbsoluteUri == "https://login.windows.net/[tenantName].onmicrosoft.com/.well-known/openid-configuration") + { + response.Content = new StringContent(File.ReadAllText(Path.Combine(basePath, "openid-configuration.json"))); + } + else if (request.RequestUri.AbsoluteUri == "https://login.windows.net/common/discovery/keys") + { + response.Content = new StringContent(File.ReadAllText(Path.Combine(basePath, "keys.json"))); + } + else if (request.RequestUri.AbsoluteUri == "https://login.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/oauth2/token") + { + response.Content = new StringContent("{\"id_token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtyaU1QZG1Cdng2OHNrVDgtbVBBQjNCc2VlQSJ9.eyJhdWQiOiJjOTk0OTdhYS0zZWUyLTQ3MDctYjhhOC1jMzNmNTEzMjNmZWYiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC80YWZiYzY4OS04MDViLTQ4Y2YtYTI0Yy1kNGFhMzI0OGEyNDgvIiwiaWF0IjoxNDIyMzk1NzYzLCJuYmYiOjE0MjIzOTU3NjMsImV4cCI6MTQyMjM5OTY2MywidmVyIjoiMS4wIiwidGlkIjoiNGFmYmM2ODktODA1Yi00OGNmLWEyNGMtZDRhYTMyNDhhMjQ4IiwiYW1yIjpbInB3ZCJdLCJvaWQiOiJmODc2YWJlYi1kNmI1LTQ0ZTQtOTcxNi02MjY2YWMwMTgxYTgiLCJ1cG4iOiJ1c2VyM0BwcmFidXJhamdtYWlsLm9ubWljcm9zb2Z0LmNvbSIsInN1YiI6IlBVZGhjbFA1UGdJalNVOVAxUy1IZWxEYVNGU2YtbVhWMVk2MC1LMnZXcXciLCJnaXZlbl9uYW1lIjoiVXNlcjMiLCJmYW1pbHlfbmFtZSI6IlVzZXIzIiwibmFtZSI6IlVzZXIzIiwidW5pcXVlX25hbWUiOiJ1c2VyM0BwcmFidXJhamdtYWlsLm9ubWljcm9zb2Z0LmNvbSIsIm5vbmNlIjoiNjM1NTc5OTI4NjM5NTE3NzE1Lk9UUmpPVFZrTTJFdE1EUm1ZUzAwWkRFM0xUaGhaR1V0WldabVpHTTRPRGt6Wkdaa01EUmxORGhrTjJNdE9XSXdNQzAwWm1Wa0xXSTVNVEl0TVRVd1ltUTRNemRtT1dJMCIsImNfaGFzaCI6IkZHdDN3Y1FBRGUwUFkxUXg3TzFyNmciLCJwd2RfZXhwIjoiNjY5MzI4MCIsInB3ZF91cmwiOiJodHRwczovL3BvcnRhbC5taWNyb3NvZnRvbmxpbmUuY29tL0NoYW5nZVBhc3N3b3JkLmFzcHgifQ.coAdCkdMgnslMHagdU8IBgH7Z0dilRdMfKytyqPJuTr6sbmbhrAoAj-KeGwbKgzrd-BeDk_rW47dntWuuAqGrAOGzxXvS2dcSWgoEKoXuDccIL5b4rIomRpfJpaeE-YwiU3usyRvoQCpHmtOa0g7xVilIj3_1-9ylMgRDY5qcrtQ_hEZlGuYyiCPR0dw8WmNU7r6PKObG-o3Yk_RbEBHjnaWxKoJwrVUEZUQOJDAvlr6ZYEmGTlD_BM0Rc_0fJZPU7A3uN9PHLw1atm-chN06IDXf23R33JI_xFuEZnj9HZQ_eIzNCl7GFmUryK3FFgYJpIbsI0BIFuksSikXz33IA\", \"access_token\": \"access\"}"); + } + + return Task.FromResult(response); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/TestOpenIdConnectEvents.cs b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/TestOpenIdConnectEvents.cs new file mode 100644 index 0000000..781aa24 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/TestOpenIdConnectEvents.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.AspNetCore.Http; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using MusicStore.Mocks.Common; + +namespace MusicStore.Mocks.OpenIdConnect +{ + internal class TestOpenIdConnectEvents + { + private static List eventsFired = new List(); + + internal static Task MessageReceived(MessageReceivedContext context) + { + Helpers.ThrowIfConditionFailed(() => context.ProtocolMessage != null, "ProtocolMessage is null."); + eventsFired.Add(nameof(MessageReceived)); + return Task.FromResult(0); + } + + internal static Task TokenValidated(TokenValidatedContext context) + { + Helpers.ThrowIfConditionFailed(() => context.Principal != null, "context.Principal is null."); + Helpers.ThrowIfConditionFailed(() => context.Principal.Identity != null, "context.Principal.Identity is null."); + Helpers.ThrowIfConditionFailed(() => !string.IsNullOrWhiteSpace(context.Principal.Identity.Name), "context.Principal.Identity.Name is null."); + eventsFired.Add(nameof(TokenValidated)); + return Task.FromResult(0); + } + + internal static Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context) + { + Helpers.ThrowIfConditionFailed(() => context.TokenEndpointRequest.Code == "AAABAAAAvPM1KaPlrEqdFSBzjqfTGGBtrTYVn589oKw4lLgJ6Svz0AhPVOJr0J2-Uu_KffGlqIbYlRAyxmt-vZ7VlSVdrWvOkNhK9OaAMaSD7LDoPbBTVMEkB0MdAgBTV34l2el-s8ZI02_9PvgQaORZs7n8eGaGbcoKAoxiDn2OcKuJVplXYgrGUwU4VpRaqe6RaNzuseM7qBFbLIv4Wps8CndE6W8ccmuu6EvGC6-H4uF9EZL7gU4nEcTcvkE4Qyt8do6VhTVfM1ygRNQgmV1BCig5t_5xfhL6-xWQdy15Uzn_Df8VSsyDXe8s9cxyKlqc_AIyLFy_NEiMQFUqjZWKd_rR3A8ugug15SEEGuo1kF3jMc7dVMdE6OF9UBd-Ax5ILWT7V4clnRQb6-CXB538DlolREfE-PowXYruFBA-ARD6rwAVtuVfCSbS0Zr4ZqfNjt6x8yQdK-OkdQRZ1thiZcZlm1lyb2EquGZ8Deh2iWBoY1uNcyjzhG-L43EivxtHAp6Y8cErhbo41iacgqOycgyJWxiB5J0HHkxD0nQ2RVVuY8Ybc9sdgyfKkkK2wZ3idGaRCdZN8Q9VBhWRXPDMqHWG8t3aZRtvJ_Xd3WhjNPJC0GpepUGNNQtXiEoIECC363o1z6PZC5-E7U3l9xK06BZkcfTOnggUiSWNCrxUKS44dNqaozdYlO5E028UgAEhJ4eDtcP3PZty-0j4j5Mw0F2FmyAA", + "context.TokenEndpointRequest.Code is invalid."); + eventsFired.Add(nameof(AuthorizationCodeReceived)); + + // Verify all events are fired. + if (eventsFired.Contains(nameof(RedirectToIdentityProvider)) && + eventsFired.Contains(nameof(MessageReceived)) && + eventsFired.Contains(nameof(TokenValidated)) && + eventsFired.Contains(nameof(AuthorizationCodeReceived))) + { + ((ClaimsIdentity)context.Principal.Identity).AddClaim(new Claim("ManageStore", "Allowed")); + } + + return Task.FromResult(0); + } + + internal static Task RedirectToIdentityProvider(RedirectContext context) + { + eventsFired.Add(nameof(RedirectToIdentityProvider)); + + if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout) + { + context.ProtocolMessage.PostLogoutRedirectUri = + context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + new PathString("/Account/Login"); + } + + return Task.FromResult(0); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/keys.json b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/keys.json new file mode 100644 index 0000000..5910c9b --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/keys.json @@ -0,0 +1,26 @@ +{ + "keys": [ + { + "kty": "RSA", + "use": "sig", + "kid": "kriMPdmBvx68skT8-mPAB3BseeA", + "x5t": "kriMPdmBvx68skT8-mPAB3BseeA", + "n": "kSCWg6q9iYxvJE2NIhSyOiKvqoWCO2GFipgH0sTSAs5FalHQosk9ZNTztX0ywS/AHsBeQPqYygfYVJL6/EgzVuwRk5txr9e3n1uml94fLyq/AXbwo9yAduf4dCHTP8CWR1dnDR+Qnz/4PYlWVEuuHHONOw/blbfdMjhY+C/BYM2E3pRxbohBb3x//CfueV7ddz2LYiH3wjz0QS/7kjPiNCsXcNyKQEOTkbHFi3mu0u13SQwNddhcynd/GTgWN8A+6SN1r4hzpjFKFLbZnBt77ACSiYx+IHK4Mp+NaVEi5wQtSsjQtI++XsokxRDqYLwus1I1SihgbV/STTg5enufuw==", + "e": "AQAB", + "x5c": [ + "MIIDPjCCAiqgAwIBAgIQsRiM0jheFZhKk49YD0SK1TAJBgUrDgMCHQUAMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwHhcNMTQwMTAxMDcwMDAwWhcNMTYwMTAxMDcwMDAwWjAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkSCWg6q9iYxvJE2NIhSyOiKvqoWCO2GFipgH0sTSAs5FalHQosk9ZNTztX0ywS/AHsBeQPqYygfYVJL6/EgzVuwRk5txr9e3n1uml94fLyq/AXbwo9yAduf4dCHTP8CWR1dnDR+Qnz/4PYlWVEuuHHONOw/blbfdMjhY+C/BYM2E3pRxbohBb3x//CfueV7ddz2LYiH3wjz0QS/7kjPiNCsXcNyKQEOTkbHFi3mu0u13SQwNddhcynd/GTgWN8A+6SN1r4hzpjFKFLbZnBt77ACSiYx+IHK4Mp+NaVEi5wQtSsjQtI++XsokxRDqYLwus1I1SihgbV/STTg5enufuwIDAQABo2IwYDBeBgNVHQEEVzBVgBDLebM6bK3BjWGqIBrBNFeNoS8wLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldIIQsRiM0jheFZhKk49YD0SK1TAJBgUrDgMCHQUAA4IBAQCJ4JApryF77EKC4zF5bUaBLQHQ1PNtA1uMDbdNVGKCmSf8M65b8h0NwlIjGGGy/unK8P6jWFdm5IlZ0YPTOgzcRZguXDPj7ajyvlVEQ2K2ICvTYiRQqrOhEhZMSSZsTKXFVwNfW6ADDkN3bvVOVbtpty+nBY5UqnI7xbcoHLZ4wYD251uj5+lo13YLnsVrmQ16NCBYq2nQFNPuNJw6t3XUbwBHXpF46aLT1/eGf/7Xx6iy8yPJX4DyrpFTutDz882RWofGEO5t4Cw+zZg70dJ/hH/ODYRMorfXEW+8uKmXMKmX2wyxMKvfiPbTy5LmAU8Jvjs2tLg4rOBcXWLAIarZ" + ] + }, + { + "kty": "RSA", + "use": "sig", + "kid": "MnC_VZcATfM5pOYiJHMba9goEKY", + "x5t": "MnC_VZcATfM5pOYiJHMba9goEKY", + "n": "vIqz+4+ER/vNWLON9yv8hIYV737JQ6rCl6XfzOC628seYUPf0TaGk91CFxefhzh23V9Tkq+RtwN1Vs/z57hO82kkzL+cQHZX3bMJD+GEGOKXCEXURN7VMyZWMAuzQoW9vFb1k3cR1RW/EW/P+C8bb2dCGXhBYqPfHyimvz2WarXhntPSbM5XyS5v5yCw5T/Vuwqqsio3V8wooWGMpp61y12NhN8bNVDQAkDPNu2DT9DXB1g0CeFINp/KAS/qQ2Kq6TSvRHJqxRR68RezYtje9KAqwqx4jxlmVAQy0T3+T+IAbsk1wRtWDndhO6s1Os+dck5TzyZ/dNOhfXgelixLUQ==", + "e": "AQAB", + "x5c": [ + "MIIC4jCCAcqgAwIBAgIQQNXrmzhLN4VGlUXDYCRT3zANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE0MTAyODAwMDAwMFoXDTE2MTAyNzAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALyKs/uPhEf7zVizjfcr/ISGFe9+yUOqwpel38zgutvLHmFD39E2hpPdQhcXn4c4dt1fU5KvkbcDdVbP8+e4TvNpJMy/nEB2V92zCQ/hhBjilwhF1ETe1TMmVjALs0KFvbxW9ZN3EdUVvxFvz/gvG29nQhl4QWKj3x8opr89lmq14Z7T0mzOV8kub+cgsOU/1bsKqrIqN1fMKKFhjKaetctdjYTfGzVQ0AJAzzbtg0/Q1wdYNAnhSDafygEv6kNiquk0r0RyasUUevEXs2LY3vSgKsKseI8ZZlQEMtE9/k/iAG7JNcEbVg53YTurNTrPnXJOU88mf3TToX14HpYsS1ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAfolx45w0i8CdAUjjeAaYdhG9+NDHxop0UvNOqlGqYJexqPLuvX8iyUaYxNGzZxFgGI3GpKfmQP2JQWQ1E5JtY/n8iNLOKRMwqkuxSCKJxZJq4Sl/m/Yv7TS1P5LNgAj8QLCypxsWrTAmq2HSpkeSk4JBtsYxX6uhbGM/K1sEktKybVTHu22/7TmRqWTmOUy9wQvMjJb2IXdMGLG3hVntN/WWcs5w8vbt1i8Kk6o19W2MjZ95JaECKjBDYRlhG1KmSBtrsKsCBQoBzwH/rXfksTO9JoUYLXiW0IppB7DhNH4PJ5hZI91R8rR0H3/bKkLSuDaKLWSqMhozdhXsIIKvJQ==" + ] + } + ] +} \ No newline at end of file diff --git a/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/openid-configuration.json b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/openid-configuration.json new file mode 100644 index 0000000..802aeed --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/OpenIdConnect/openid-configuration.json @@ -0,0 +1,34 @@ +{ + "issuer": "https://sts.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/", + "authorization_endpoint": "https://login.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/oauth2/authorize", + "token_endpoint": "https://login.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_post", + "private_key_jwt" + ], + "jwks_uri": "https://login.windows.net/common/discovery/keys", + "response_types_supported": [ + "code", + "id_token", + "code id_token", + "token" + ], + "response_modes_supported": [ + "query", + "fragment", + "form_post" + ], + "subject_types_supported": [ + "pairwise" + ], + "scopes_supported": [ + "openid" + ], + "id_token_signing_alg_values_supported": [ + "RS256" + ], + "microsoft_multi_refresh_token": true, + "check_session_iframe": "https://login.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/oauth2/checksession", + "end_session_endpoint": "https://login.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/oauth2/logout", + "userinfo_endpoint": "https://login.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/openid/userinfo" +} \ No newline at end of file diff --git a/samples/MusicStore/ForTesting/Mocks/StartupOpenIdConnectTesting.cs b/samples/MusicStore/ForTesting/Mocks/StartupOpenIdConnectTesting.cs new file mode 100644 index 0000000..9f83bdd --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/StartupOpenIdConnectTesting.cs @@ -0,0 +1,167 @@ +using System; +using System.Globalization; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Localization; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using MusicStore.Components; +using MusicStore.Mocks.Common; +using MusicStore.Mocks.OpenIdConnect; +using MusicStore.Models; + +namespace MusicStore +{ + public class StartupOpenIdConnectTesting + { + private readonly Platform _platform; + + public StartupOpenIdConnectTesting(IHostingEnvironment env) + { + //Below code demonstrates usage of multiple configuration sources. For instance a setting say 'setting1' is found in both the registered sources, + //then the later source will win. By this way a Local config can be overridden by a different setting while deployed remotely. + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("config.json") + .AddEnvironmentVariables(); //All environment variables in the process's context flow in as configuration values. + + Configuration = builder.Build(); + _platform = new Platform(); + } + + public IConfiguration Configuration { get; private set; } + + public void ConfigureServices(IServiceCollection services) + { + services.Configure(Configuration.GetSection("AppSettings")); + + // Add EF services to the services container + if (_platform.UseInMemoryStore) + { + services.AddDbContext(options => + options.UseInMemoryDatabase("Scratch")); + } + else + { + services.AddDbContext(options => + options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); + } + + // Add Identity services to the services container + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + // Create an Azure Active directory application and copy paste the following + services.AddAuthentication().AddOpenIdConnect(options => + { + options.Authority = "https://login.windows.net/[tenantName].onmicrosoft.com"; + options.ClientId = "c99497aa-3ee2-4707-b8a8-c33f51323fef"; + options.BackchannelHttpHandler = new OpenIdConnectBackChannelHttpHandler(); + options.StringDataFormat = new CustomStringDataFormat(); + options.StateDataFormat = new CustomStateDataFormat(); + options.ResponseType = OpenIdConnectResponseType.CodeIdToken; + options.UseTokenLifetime = false; + options.TokenValidationParameters.ValidateLifetime = false; + options.ProtocolValidator.RequireNonce = true; + options.ProtocolValidator.NonceLifetime = TimeSpan.FromDays(36500); + + options.Events = new OpenIdConnectEvents + { + OnMessageReceived = TestOpenIdConnectEvents.MessageReceived, + OnAuthorizationCodeReceived = TestOpenIdConnectEvents.AuthorizationCodeReceived, + OnRedirectToIdentityProvider = TestOpenIdConnectEvents.RedirectToIdentityProvider, + OnTokenValidated = TestOpenIdConnectEvents.TokenValidated, + }; + }); + + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", builder => + { + builder.WithOrigins("http://example.com"); + }); + }); + + // Add MVC services to the services container + services.AddMvc(); + + //Add InMemoryCache + services.AddSingleton(); + + // Add session related services. + services.AddMemoryCache(); + services.AddDistributedMemoryCache(); + services.AddSession(); + + // Add the system clock service + services.AddSingleton(); + + // Configure Auth + services.Configure(options => + { + options.AddPolicy("ManageStore", new AuthorizationPolicyBuilder().RequireClaim("ManageStore", "Allowed").Build()); + }); + } + + public void Configure(IApplicationBuilder app) + { + // force the en-US culture, so that the app behaves the same even on machines with different default culture + var supportedCultures = new[] { new CultureInfo("en-US") }; + + app.UseRequestLocalization(new RequestLocalizationOptions + { + DefaultRequestCulture = new RequestCulture("en-US"), + SupportedCultures = supportedCultures, + SupportedUICultures = supportedCultures + }); + + app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage"); + + // Display custom error page in production when error occurs + // During development use the ErrorPage middleware to display error information in the browser + app.UseDeveloperExceptionPage(); + + app.UseDatabaseErrorPage(); + + // Configure Session. + app.UseSession(); + + // Add static files to the request pipeline + app.UseStaticFiles(); + + // Add authentication to the request pipeline + app.UseAuthentication(); + + // Add MVC to the request pipeline + app.UseMvc(routes => + { + routes.MapRoute( + name: "areaRoute", + template: "{area:exists}/{controller}/{action}", + defaults: new { action = "Index" }); + + routes.MapRoute( + name: "default", + template: "{controller}/{action}/{id?}", + defaults: new { controller = "Home", action = "Index" }); + + routes.MapRoute( + name: "api", + template: "{controller}/{id?}"); + }); + + //Populates the MusicStore sample data + SampleData.InitializeMusicStoreDatabaseAsync(app.ApplicationServices).Wait(); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/StartupSocialTesting.cs b/samples/MusicStore/ForTesting/Mocks/StartupSocialTesting.cs new file mode 100644 index 0000000..ffe81ad --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/StartupSocialTesting.cs @@ -0,0 +1,209 @@ +using System; +using System.Globalization; +using Microsoft.AspNetCore.Authentication.OAuth; +using Microsoft.AspNetCore.Authentication.Twitter; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Localization; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using MusicStore.Components; +using MusicStore.Mocks.Common; +using MusicStore.Mocks.Facebook; +using MusicStore.Mocks.Google; +using MusicStore.Mocks.MicrosoftAccount; +using MusicStore.Mocks.Twitter; +using MusicStore.Models; + +namespace MusicStore +{ + public class StartupSocialTesting + { + private readonly Platform _platform; + + public StartupSocialTesting(IHostingEnvironment hostingEnvironment) + { + //Below code demonstrates usage of multiple configuration sources. For instance a setting say 'setting1' is found in both the registered sources, + //then the later source will win. By this way a Local config can be overridden by a different setting while deployed remotely. + var builder = new ConfigurationBuilder() + .SetBasePath(hostingEnvironment.ContentRootPath) + .AddJsonFile("config.json") + .AddEnvironmentVariables() //All environment variables in the process's context flow in as configuration values. + .AddJsonFile("configoverride.json", optional: true); // Used to override some configuration parameters that cannot be overridden by environment. + + Configuration = builder.Build(); + _platform = new Platform(); + } + + public IConfiguration Configuration { get; private set; } + + public void ConfigureServices(IServiceCollection services) + { + services.Configure(Configuration.GetSection("AppSettings")); + + // Add EF services to the services container + if (_platform.UseInMemoryStore) + { + services.AddDbContext(options => + options.UseInMemoryDatabase("Scratch")); + } + else + { + services.AddDbContext(options => + options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); + } + + // Add Identity services to the services container + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.ConfigureApplicationCookie(options => options.AccessDeniedPath = "/Home/AccessDenied"); + + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", builder => + { + builder.WithOrigins("http://example.com"); + }); + }); + + // Add MVC services to the services container + services.AddMvc(); + + //Add InMemoryCache + services.AddSingleton(); + + // Add session related services. + services.AddMemoryCache(); + services.AddDistributedMemoryCache(); + services.AddSession(); + + // Add the system clock service + services.AddSingleton(); + + // Configure Auth + services.AddAuthorization(options => + { + options.AddPolicy("ManageStore", new AuthorizationPolicyBuilder().RequireClaim("ManageStore", "Allowed").Build()); + }); + + services.AddAuthentication() + .AddFacebook(options => + { + options.AppId = "[AppId]"; + options.AppSecret = "[AppSecret]"; + options.Events = new OAuthEvents() + { + OnCreatingTicket = TestFacebookEvents.OnCreatingTicket, + OnTicketReceived = TestFacebookEvents.OnTicketReceived, + OnRedirectToAuthorizationEndpoint = TestFacebookEvents.RedirectToAuthorizationEndpoint + }; + options.BackchannelHttpHandler = new FacebookMockBackChannelHttpHandler(); + options.StateDataFormat = new CustomStateDataFormat(); + options.Scope.Add("email"); + options.Scope.Add("read_friendlists"); + options.Scope.Add("user_checkins"); + }).AddGoogle(options => + { + options.ClientId = "[ClientId]"; + options.ClientSecret = "[ClientSecret]"; + options.AccessType = "offline"; + options.Events = new OAuthEvents() + { + OnCreatingTicket = TestGoogleEvents.OnCreatingTicket, + OnTicketReceived = TestGoogleEvents.OnTicketReceived, + OnRedirectToAuthorizationEndpoint = TestGoogleEvents.RedirectToAuthorizationEndpoint + }; + options.StateDataFormat = new CustomStateDataFormat(); + options.BackchannelHttpHandler = new GoogleMockBackChannelHttpHandler(); + }).AddTwitter(options => + { + options.ConsumerKey = "[ConsumerKey]"; + options.ConsumerSecret = "[ConsumerSecret]"; + options.Events = new TwitterEvents() + { + OnCreatingTicket = TestTwitterEvents.OnCreatingTicket, + OnTicketReceived = TestTwitterEvents.OnTicketReceived, + OnRedirectToAuthorizationEndpoint = TestTwitterEvents.RedirectToAuthorizationEndpoint + }; + options.StateDataFormat = new CustomTwitterStateDataFormat(); + options.BackchannelHttpHandler = new TwitterMockBackChannelHttpHandler(); + }).AddMicrosoftAccount(options => + { + options.ClientId = "[ClientId]"; + options.ClientSecret = "[ClientSecret]"; + options.Events = new OAuthEvents() + { + OnCreatingTicket = TestMicrosoftAccountEvents.OnCreatingTicket, + OnTicketReceived = TestMicrosoftAccountEvents.OnTicketReceived, + OnRedirectToAuthorizationEndpoint = TestMicrosoftAccountEvents.RedirectToAuthorizationEndpoint + }; + options.BackchannelHttpHandler = new MicrosoftAccountMockBackChannelHandler(); + options.StateDataFormat = new CustomStateDataFormat(); + options.Scope.Add("wl.basic"); + options.Scope.Add("wl.signin"); + }); + + } + + public void Configure(IApplicationBuilder app) + { + // force the en-US culture, so that the app behaves the same even on machines with different default culture + var supportedCultures = new[] { new CultureInfo("en-US") }; + + app.UseRequestLocalization(new RequestLocalizationOptions + { + DefaultRequestCulture = new RequestCulture("en-US"), + SupportedCultures = supportedCultures, + SupportedUICultures = supportedCultures + }); + + app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage"); + + // Error page middleware displays a nice formatted HTML page for any unhandled exceptions in the request pipeline. + // Note: Not recommended for production. + app.UseDeveloperExceptionPage(); + + app.UseDatabaseErrorPage(); + + // Configure Session. + app.UseSession(); + + // Add static files to the request pipeline + app.UseStaticFiles(); + + // Add cookie-based authentication to the request pipeline + app.UseAuthentication(); + + // Add MVC to the request pipeline + app.UseMvc(routes => + { + routes.MapRoute( + name: "areaRoute", + template: "{area:exists}/{controller}/{action}", + defaults: new { action = "Index" }); + + routes.MapRoute( + name: "default", + template: "{controller}/{action}/{id?}", + defaults: new { controller = "Home", action = "Index" }); + + routes.MapRoute( + name: "api", + template: "{controller}/{id?}"); + }); + + //Populates the MusicStore sample data + SampleData.InitializeMusicStoreDatabaseAsync(app.ApplicationServices).Wait(); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/Twitter/CustomTwitterStateDataFormat.cs b/samples/MusicStore/ForTesting/Mocks/Twitter/CustomTwitterStateDataFormat.cs new file mode 100644 index 0000000..422ae29 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Twitter/CustomTwitterStateDataFormat.cs @@ -0,0 +1,46 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Twitter; +using Newtonsoft.Json; + +namespace MusicStore.Mocks.Twitter +{ + /// + /// Summary description for CustomTwitterStateDataFormat + /// + public class CustomTwitterStateDataFormat : ISecureDataFormat + { + private static string _lastSavedRequestToken; + + public string Protect(RequestToken data) + { + data.Token = "valid_oauth_token"; + _lastSavedRequestToken = Serialize(data); + return "valid_oauth_token"; + } + + public string Protect(RequestToken data, string purpose) + { + return Protect(data); + } + + public RequestToken Unprotect(string state) + { + return state == "valid_oauth_token" ? DeSerialize(_lastSavedRequestToken) : null; + } + + public RequestToken Unprotect(string state, string purpose) + { + return Unprotect(state); + } + + private string Serialize(RequestToken data) + { + return JsonConvert.SerializeObject(data, Formatting.Indented); + } + + private RequestToken DeSerialize(string state) + { + return JsonConvert.DeserializeObject(state); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/Twitter/TestTwitterEvents.cs b/samples/MusicStore/ForTesting/Mocks/Twitter/TestTwitterEvents.cs new file mode 100644 index 0000000..fee4bc7 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Twitter/TestTwitterEvents.cs @@ -0,0 +1,50 @@ +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Twitter; +using Microsoft.AspNetCore.Identity; +using MusicStore.Mocks.Common; + +namespace MusicStore.Mocks.Twitter +{ + internal class TestTwitterEvents + { + internal static Task OnCreatingTicket(TwitterCreatingTicketContext context) + { + if (context.Principal != null) + { + Helpers.ThrowIfConditionFailed(() => context.UserId == "valid_user_id", "UserId is not valid"); + Helpers.ThrowIfConditionFailed(() => context.ScreenName == "valid_screen_name", "ScreenName is not valid"); + Helpers.ThrowIfConditionFailed(() => context.AccessToken == "valid_oauth_token", "AccessToken is not valid"); + Helpers.ThrowIfConditionFailed(() => context.AccessTokenSecret == "valid_oauth_token_secret", "AccessTokenSecret is not valid"); + context.Principal.Identities.First().AddClaim(new Claim("ManageStore", "false")); + } + + return Task.FromResult(0); + } + + internal static Task OnTicketReceived(TicketReceivedContext context) + { + if (context.Principal != null && context.Options.SignInScheme == IdentityConstants.ExternalScheme) + { + //This way we will know all Events were fired. + var identity = context.Principal.Identities.First(); + var manageStoreClaim = identity?.Claims.Where(c => c.Type == "ManageStore" && c.Value == "false").FirstOrDefault(); + if (manageStoreClaim != null) + { + identity.RemoveClaim(manageStoreClaim); + identity.AddClaim(new Claim("ManageStore", "Allowed")); + } + } + + return Task.FromResult(0); + } + + internal static Task RedirectToAuthorizationEndpoint(RedirectContext context) + { + context.Response.Redirect(context.RedirectUri + "&custom_redirect_uri=custom"); + return Task.FromResult(0); + } + } +} diff --git a/samples/MusicStore/ForTesting/Mocks/Twitter/TwitterMockBackChannelHttpHandler.cs b/samples/MusicStore/ForTesting/Mocks/Twitter/TwitterMockBackChannelHttpHandler.cs new file mode 100644 index 0000000..2ae3194 --- /dev/null +++ b/samples/MusicStore/ForTesting/Mocks/Twitter/TwitterMockBackChannelHttpHandler.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.WebUtilities; + +namespace MusicStore.Mocks.Twitter +{ + /// + /// Summary description for TwitterMockBackChannelHttpHandler + /// + public class TwitterMockBackChannelHttpHandler : HttpMessageHandler + { + private static bool _requestTokenEndpointInvoked = false; + + protected async override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var response = new HttpResponseMessage(); + + if (request.RequestUri.AbsoluteUri.StartsWith("https://api.twitter.com/oauth/access_token")) + { + var formData = new FormCollection(await new FormReader(await request.Content.ReadAsStreamAsync()).ReadFormAsync()); + if (formData["oauth_verifier"] == "valid_oauth_verifier") + { + if (_requestTokenEndpointInvoked) + { + var response_Form_data = new List>() + { + new KeyValuePair("oauth_token", "valid_oauth_token"), + new KeyValuePair("oauth_token_secret", "valid_oauth_token_secret"), + new KeyValuePair("user_id", "valid_user_id"), + new KeyValuePair("screen_name", "valid_screen_name"), + }; + + response.Content = new FormUrlEncodedContent(response_Form_data); + } + else + { + response.StatusCode = HttpStatusCode.InternalServerError; + response.Content = new StringContent("RequestTokenEndpoint is not invoked"); + } + return response; + } + response.StatusCode = (HttpStatusCode)400; + return response; + } + else if (request.RequestUri.AbsoluteUri.StartsWith("https://api.twitter.com/oauth/request_token")) + { + var response_Form_data = new List>() + { + new KeyValuePair("oauth_callback_confirmed", "true"), + new KeyValuePair("oauth_token", "valid_oauth_token"), + new KeyValuePair("oauth_token_secret", "valid_oauth_token_secret") + }; + + _requestTokenEndpointInvoked = true; + response.Content = new FormUrlEncodedContent(response_Form_data); + return response; + } + + throw new NotImplementedException(request.RequestUri.AbsoluteUri); + } + } +} diff --git a/samples/MusicStore/ForTesting/MusicStoreConfig.cs b/samples/MusicStore/ForTesting/MusicStoreConfig.cs new file mode 100644 index 0000000..c1bcba1 --- /dev/null +++ b/samples/MusicStore/ForTesting/MusicStoreConfig.cs @@ -0,0 +1,7 @@ +namespace MusicStore +{ + public class StoreConfig + { + public const string ConnectionStringKey = "Data__DefaultConnection__ConnectionString"; + } +} \ No newline at end of file diff --git a/samples/MusicStore/ForTesting/Readme.md b/samples/MusicStore/ForTesting/Readme.md new file mode 100644 index 0000000..b8c7e75 --- /dev/null +++ b/samples/MusicStore/ForTesting/Readme.md @@ -0,0 +1 @@ +The contents of this folder are used for end to end testing. \ No newline at end of file diff --git a/samples/MusicStore/MessageServices.cs b/samples/MusicStore/MessageServices.cs new file mode 100644 index 0000000..32d4c92 --- /dev/null +++ b/samples/MusicStore/MessageServices.cs @@ -0,0 +1,19 @@ +using System.Threading.Tasks; + +namespace MusicStore +{ + public static class MessageServices + { + public static Task SendEmailAsync(string email, string subject, string message) + { + // Plug in your email service + return Task.FromResult(0); + } + + public static Task SendSmsAsync(string number, string message) + { + // Plug in your sms service + return Task.FromResult(0); + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/AccountViewModels.cs b/samples/MusicStore/Models/AccountViewModels.cs new file mode 100644 index 0000000..8b566d2 --- /dev/null +++ b/samples/MusicStore/Models/AccountViewModels.cs @@ -0,0 +1,113 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace MusicStore.Models +{ + public class ExternalLoginConfirmationViewModel + { + [Required] + [Display(Name = "Email")] + public string Email { get; set; } + } + + public class ExternalLoginListViewModel + { + public string ReturnUrl { get; set; } + } + + public class SendCodeViewModel + { + public string SelectedProvider { get; set; } + public ICollection Providers { get; set; } + public string ReturnUrl { get; set; } + public bool RememberMe { get; set; } + } + + public class VerifyCodeViewModel + { + [Required] + public string Provider { get; set; } + + [Required] + [Display(Name = "Code")] + public string Code { get; set; } + public string ReturnUrl { get; set; } + + [Display(Name = "Remember this browser?")] + public bool RememberBrowser { get; set; } + + public bool RememberMe { get; set; } + } + + public class ForgotViewModel + { + [Required] + [Display(Name = "Email")] + public string Email { get; set; } + } + + public class LoginViewModel + { + [Required] + [Display(Name = "Email")] + [EmailAddress] + public string Email { get; set; } + + [Required] + [DataType(DataType.Password)] + [Display(Name = "Password")] + public string Password { get; set; } + + [Display(Name = "Remember me?")] + public bool RememberMe { get; set; } + } + + public class RegisterViewModel + { + [Required] + [EmailAddress] + [Display(Name = "Email")] + public string Email { get; set; } + + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + [Display(Name = "Password")] + public string Password { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm password")] + [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } + } + + public class ResetPasswordViewModel + { + [Required] + [EmailAddress] + [Display(Name = "Email")] + public string Email { get; set; } + + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + [Display(Name = "Password")] + public string Password { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm password")] + [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } + + public string Code { get; set; } + } + + public class ForgotPasswordViewModel + { + [Required] + [EmailAddress] + [Display(Name = "Email")] + public string Email { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/Album.cs b/samples/MusicStore/Models/Album.cs new file mode 100644 index 0000000..7121e1d --- /dev/null +++ b/samples/MusicStore/Models/Album.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace MusicStore.Models +{ + public class Album + { + [ScaffoldColumn(false)] + public int AlbumId { get; set; } + + public int GenreId { get; set; } + + public int ArtistId { get; set; } + + [Required] + [StringLength(160, MinimumLength = 2)] + public string Title { get; set; } + + [Required] + [Range(0.01, 100.00)] + + [DataType(DataType.Currency)] + [Column(TypeName = "decimal(18,2)")] + public decimal Price { get; set; } + + [Display(Name = "Album Art URL")] + [StringLength(1024)] + public string AlbumArtUrl { get; set; } + + public virtual Genre Genre { get; set; } + public virtual Artist Artist { get; set; } + public virtual List OrderDetails { get; set; } + + [ScaffoldColumn(false)] + [BindNever] + [Required] + public DateTime Created { get; set; } + + /// + /// TODO: Temporary hack to populate the orderdetails until EF does this automatically. + /// + public Album() + { + OrderDetails = new List(); + Created = DateTime.UtcNow; + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/Artist.cs b/samples/MusicStore/Models/Artist.cs new file mode 100644 index 0000000..43d677c --- /dev/null +++ b/samples/MusicStore/Models/Artist.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace MusicStore.Models +{ + public class Artist + { + public int ArtistId { get; set; } + + [Required] + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/CartItem.cs b/samples/MusicStore/Models/CartItem.cs new file mode 100644 index 0000000..3311528 --- /dev/null +++ b/samples/MusicStore/Models/CartItem.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace MusicStore.Models +{ + public class CartItem + { + [Key] + public int CartItemId { get; set; } + + [Required] + public string CartId { get; set; } + public int AlbumId { get; set; } + public int Count { get; set; } + + [DataType(DataType.DateTime)] + public DateTime DateCreated { get; set; } + + public virtual Album Album { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/Genre.cs b/samples/MusicStore/Models/Genre.cs new file mode 100644 index 0000000..29c9107 --- /dev/null +++ b/samples/MusicStore/Models/Genre.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace MusicStore.Models +{ + public class Genre + { + public int GenreId { get; set; } + + [Required] + public string Name { get; set; } + + public string Description { get; set; } + + public List Albums { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/ManageViewModels.cs b/samples/MusicStore/Models/ManageViewModels.cs new file mode 100644 index 0000000..4204972 --- /dev/null +++ b/samples/MusicStore/Models/ManageViewModels.cs @@ -0,0 +1,87 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace MusicStore.Models +{ + public class IndexViewModel + { + public bool HasPassword { get; set; } + public IList Logins { get; set; } + public string PhoneNumber { get; set; } + public bool TwoFactor { get; set; } + public bool BrowserRemembered { get; set; } + } + + public class ManageLoginsViewModel + { + public IList CurrentLogins { get; set; } + public IList OtherLogins { get; set; } + } + + public class FactorViewModel + { + public string Purpose { get; set; } + } + + public class SetPasswordViewModel + { + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + [Display(Name = "New password")] + public string NewPassword { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm new password")] + [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } + } + + public class ChangePasswordViewModel + { + [Required] + [DataType(DataType.Password)] + [Display(Name = "Current password")] + public string OldPassword { get; set; } + + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + [Display(Name = "New password")] + public string NewPassword { get; set; } + + [DataType(DataType.Password)] + [Display(Name = "Confirm new password")] + [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] + public string ConfirmPassword { get; set; } + } + + public class AddPhoneNumberViewModel + { + [Required] + [Phone] + [Display(Name = "Phone Number")] + public string Number { get; set; } + } + + public class VerifyPhoneNumberViewModel + { + [Required] + [Display(Name = "Code")] + public string Code { get; set; } + + [Required] + [Phone] + [Display(Name = "Phone Number")] + public string PhoneNumber { get; set; } + } + + public class ConfigureTwoFactorViewModel + { + public string SelectedProvider { get; set; } + public ICollection Providers { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/MusicStoreContext.cs b/samples/MusicStore/Models/MusicStoreContext.cs new file mode 100644 index 0000000..a638016 --- /dev/null +++ b/samples/MusicStore/Models/MusicStoreContext.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; + +namespace MusicStore.Models +{ + public class ApplicationUser : IdentityUser { } + + public class MusicStoreContext : IdentityDbContext + { + public MusicStoreContext(DbContextOptions options) + : base(options) + { + // TODO: #639 + //ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + } + + public DbSet Albums { get; set; } + public DbSet Artists { get; set; } + public DbSet Orders { get; set; } + public DbSet Genres { get; set; } + public DbSet CartItems { get; set; } + public DbSet OrderDetails { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/Order.cs b/samples/MusicStore/Models/Order.cs new file mode 100644 index 0000000..3406b96 --- /dev/null +++ b/samples/MusicStore/Models/Order.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace MusicStore.Models +{ + //[Bind(Include = "FirstName,LastName,Address,City,State,PostalCode,Country,Phone,Email")] + public class Order + { + [BindNever] + [ScaffoldColumn(false)] + public int OrderId { get; set; } + + [BindNever] + [ScaffoldColumn(false)] + public System.DateTime OrderDate { get; set; } + + [BindNever] + [ScaffoldColumn(false)] + public string Username { get; set; } + + [Required] + [Display(Name = "First Name")] + [StringLength(160)] + public string FirstName { get; set; } + + [Required] + [Display(Name = "Last Name")] + [StringLength(160)] + public string LastName { get; set; } + + [Required] + [StringLength(70, MinimumLength = 3)] + public string Address { get; set; } + + [Required] + [StringLength(40)] + public string City { get; set; } + + [Required] + [StringLength(40)] + public string State { get; set; } + + [Required] + [Display(Name = "Postal Code")] + [StringLength(10, MinimumLength = 5)] + public string PostalCode { get; set; } + + [Required] + [StringLength(40)] + public string Country { get; set; } + + [Required] + [StringLength(24)] + [DataType(DataType.PhoneNumber)] + public string Phone { get; set; } + + [Required] + [Display(Name = "Email Address")] + [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}", + ErrorMessage = "Email is not valid.")] + [DataType(DataType.EmailAddress)] + public string Email { get; set; } + + [BindNever] + [ScaffoldColumn(false)] + [Column(TypeName = "decimal(18,2)")] + public decimal Total { get; set; } + + [BindNever] + public List OrderDetails { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/OrderDetail.cs b/samples/MusicStore/Models/OrderDetail.cs new file mode 100644 index 0000000..ee94681 --- /dev/null +++ b/samples/MusicStore/Models/OrderDetail.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace MusicStore.Models +{ + public class OrderDetail + { + public int OrderDetailId { get; set; } + + public int OrderId { get; set; } + + public int AlbumId { get; set; } + + public int Quantity { get; set; } + + [Column(TypeName = "decimal(18,2)")] + public decimal UnitPrice { get; set; } + + public virtual Album Album { get; set; } + + public virtual Order Order { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Models/SampleData.cs b/samples/MusicStore/Models/SampleData.cs new file mode 100644 index 0000000..959c267 --- /dev/null +++ b/samples/MusicStore/Models/SampleData.cs @@ -0,0 +1,965 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace MusicStore.Models +{ + public static class SampleData + { + const string imgUrl = "~/Images/placeholder.png"; + const string defaultAdminUserName = "DefaultAdminUserName"; + const string defaultAdminPassword = "DefaultAdminPassword"; + + public static async Task InitializeMusicStoreDatabaseAsync(IServiceProvider serviceProvider, bool createUsers = true) + { + using (var serviceScope = serviceProvider.CreateScope()) + { + var scopeServiceProvider = serviceScope.ServiceProvider; + var db = scopeServiceProvider.GetService(); + + if (await db.Database.EnsureCreatedAsync()) + { + await InsertTestData(scopeServiceProvider); + if (createUsers) + { + await CreateAdminUser(scopeServiceProvider); + } + } + } + } + + private static async Task InsertTestData(IServiceProvider serviceProvider) + { + var albums = GetAlbums(imgUrl, Genres, Artists); + + await AddOrUpdateAsync(serviceProvider, g => g.GenreId, Genres.Select(genre => genre.Value)); + await AddOrUpdateAsync(serviceProvider, a => a.ArtistId, Artists.Select(artist => artist.Value)); + await AddOrUpdateAsync(serviceProvider, a => a.AlbumId, albums); + } + + // TODO [EF] This may be replaced by a first class mechanism in EF + private static async Task AddOrUpdateAsync( + IServiceProvider serviceProvider, + Func propertyToMatch, IEnumerable entities) + where TEntity : class + { + // Query in a separate context so that we can attach existing entities as modified + List existingData; + using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) + { + var db = serviceScope.ServiceProvider.GetService(); + existingData = db.Set().ToList(); + } + + using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) + { + var db = serviceScope.ServiceProvider.GetService(); + foreach (var item in entities) + { + db.Entry(item).State = existingData.Any(g => propertyToMatch(g).Equals(propertyToMatch(item))) + ? EntityState.Modified + : EntityState.Added; + } + + await db.SaveChangesAsync(); + } + } + + /// + /// Creates a store manager user who can manage the inventory. + /// + /// + /// + private static async Task CreateAdminUser(IServiceProvider serviceProvider) + { + var env = serviceProvider.GetService(); + + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("config.json") + .AddEnvironmentVariables(); + var configuration = builder.Build(); + + //const string adminRole = "Administrator"; + + var userManager = serviceProvider.GetService>(); + // TODO: Identity SQL does not support roles yet + //var roleManager = serviceProvider.GetService(); + //if (!await roleManager.RoleExistsAsync(adminRole)) + //{ + // await roleManager.CreateAsync(new IdentityRole(adminRole)); + //} + + var user = await userManager.FindByNameAsync(configuration[defaultAdminUserName]); + if (user == null) + { + user = new ApplicationUser { UserName = configuration[defaultAdminUserName] }; + await userManager.CreateAsync(user, configuration[defaultAdminPassword]); + //await userManager.AddToRoleAsync(user, adminRole); + await userManager.AddClaimAsync(user, new Claim("ManageStore", "Allowed")); + } + + // NOTE: For end to end testing only + var envPerfLab = configuration["PERF_LAB"]; + if (envPerfLab == "true") + { + for (int i = 0; i < 100; ++i) + { + var email = string.Format("User{0:D3}@example.com", i); + var normalUser = await userManager.FindByEmailAsync(email); + if (normalUser == null) + { + await userManager.CreateAsync(new ApplicationUser { UserName = email, Email = email }, "Password~!1"); + } + } + } + } + + private static Album[] GetAlbums(string imgUrl, Dictionary genres, Dictionary artists) + { + var albums = new Album[] + { + new Album { Title = "The Best Of The Men At Work", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Men At Work"], AlbumArtUrl = imgUrl }, + new Album { Title = "...And Justice For All", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "עד גבול האור", Genre = genres["World"], Price = 8.99M, Artist = artists["אריק אינשטיין"], AlbumArtUrl = imgUrl }, + new Album { Title = "Black Light Syndrome", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Terry Bozzio, Tony Levin & Steve Stevens"], AlbumArtUrl = imgUrl }, + new Album { Title = "10,000 Days", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl }, + new Album { Title = "11i", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Supreme Beings of Leisure"], AlbumArtUrl = imgUrl }, + new Album { Title = "1960", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Soul-Junk"], AlbumArtUrl = imgUrl }, + new Album { Title = "4x4=12 ", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["deadmau5"], AlbumArtUrl = imgUrl }, + new Album { Title = "A Copland Celebration, Vol. I", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Symphony Orchestra"], AlbumArtUrl = imgUrl }, + new Album { Title = "A Lively Mind", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Paul Oakenfold"], AlbumArtUrl = imgUrl }, + new Album { Title = "A Matter of Life and Death", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "A Real Dead One", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "A Real Live One", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "A Rush of Blood to the Head", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Coldplay"], AlbumArtUrl = imgUrl }, + new Album { Title = "A Soprano Inspired", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Britten Sinfonia, Ivor Bolton & Lesley Garrett"], AlbumArtUrl = imgUrl }, + new Album { Title = "A Winter Symphony", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "Abbey Road", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ace Of Spades", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Motörhead"], AlbumArtUrl = imgUrl }, + new Album { Title = "Achtung Baby", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "Acústico MTV", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl }, + new Album { Title = "Adams, John: The Chairman Dances", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Edo de Waart & San Francisco Symphony"], AlbumArtUrl = imgUrl }, + new Album { Title = "Adrenaline", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deftones"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ænima", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl }, + new Album { Title = "Afrociberdelia", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Science & Nação Zumbi"], AlbumArtUrl = imgUrl }, + new Album { Title = "After the Goldrush", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Neil Young"], AlbumArtUrl = imgUrl }, + new Album { Title = "Airdrawn Dagger", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Sasha"], AlbumArtUrl = imgUrl }, + new Album { Title = "Album Title Goes Here", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["deadmau5"], AlbumArtUrl = imgUrl }, + new Album { Title = "Alcohol Fueled Brewtality Live! [Disc 1]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Label Society"], AlbumArtUrl = imgUrl }, + new Album { Title = "Alcohol Fueled Brewtality Live! [Disc 2]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Label Society"], AlbumArtUrl = imgUrl }, + new Album { Title = "Alive 2007", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Daft Punk"], AlbumArtUrl = imgUrl }, + new Album { Title = "All I Ask of You", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "Amen (So Be It)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paddy Casey"], AlbumArtUrl = imgUrl }, + new Album { Title = "Animal Vehicle", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Axis of Awesome"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ao Vivo [IMPORT]", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Zeca Pagodinho"], AlbumArtUrl = imgUrl }, + new Album { Title = "Apocalyptic Love", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Slash"], AlbumArtUrl = imgUrl }, + new Album { Title = "Appetite for Destruction", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl }, + new Album { Title = "Are You Experienced?", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Jimi Hendrix"], AlbumArtUrl = imgUrl }, + new Album { Title = "Arquivo II", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl }, + new Album { Title = "Arquivo Os Paralamas Do Sucesso", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl }, + new Album { Title = "A-Sides", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Soundgarden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Audioslave", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Audioslave"], AlbumArtUrl = imgUrl }, + new Album { Title = "Automatic for the People", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["R.E.M."], AlbumArtUrl = imgUrl }, + new Album { Title = "Axé Bahia 2001", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl }, + new Album { Title = "Babel", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Mumford & Sons"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bach: Goldberg Variations", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Wilhelm Kempff"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bach: The Brandenburg Concertos", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Orchestra of The Age of Enlightenment"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bach: The Cello Suites", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Yo-Yo Ma"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bach: Toccata & Fugue in D Minor", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Ton Koopman"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bad Motorfinger", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Soundgarden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Balls to the Wall", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Accept"], AlbumArtUrl = imgUrl }, + new Album { Title = "Banadeek Ta'ala", Genre = genres["World"], Price = 8.99M, Artist = artists["Amr Diab"], AlbumArtUrl = imgUrl }, + new Album { Title = "Barbie Girl", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Aqua"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bark at the Moon (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bartok: Violin & Viola Concertos", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Yehudi Menuhin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Barulhinho Bom", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Marisa Monte"], AlbumArtUrl = imgUrl }, + new Album { Title = "BBC Sessions [Disc 1] [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "BBC Sessions [Disc 2] [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Be Here Now", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Oasis"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bedrock 11 Compiled & Mixed", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["John Digweed"], AlbumArtUrl = imgUrl }, + new Album { Title = "Berlioz: Symphonie Fantastique", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Michael Tilson Thomas"], AlbumArtUrl = imgUrl }, + new Album { Title = "Beyond Good And Evil", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Cult"], AlbumArtUrl = imgUrl }, + new Album { Title = "Big Bad Wolf ", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Armand Van Helden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Big Ones", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Aerosmith"], AlbumArtUrl = imgUrl }, + new Album { Title = "Black Album", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Black Sabbath Vol. 4 (Remaster)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Sabbath"], AlbumArtUrl = imgUrl }, + new Album { Title = "Black Sabbath", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Sabbath"], AlbumArtUrl = imgUrl }, + new Album { Title = "Black", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Blackwater Park", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Opeth"], AlbumArtUrl = imgUrl }, + new Album { Title = "Blizzard of Ozz", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { Title = "Blood", Genre = genres["Rock"], Price = 8.99M, Artist = artists["In This Moment"], AlbumArtUrl = imgUrl }, + new Album { Title = "Blue Moods", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Incognito"], AlbumArtUrl = imgUrl }, + new Album { Title = "Blue", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Weezer"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bongo Fury", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Frank Zappa & Captain Beefheart"], AlbumArtUrl = imgUrl }, + new Album { Title = "Boys & Girls", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alabama Shakes"], AlbumArtUrl = imgUrl }, + new Album { Title = "Brave New World", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "B-Sides 1980-1990", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "Bunkka", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Paul Oakenfold"], AlbumArtUrl = imgUrl }, + new Album { Title = "By The Way", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Red Hot Chili Peppers"], AlbumArtUrl = imgUrl }, + new Album { Title = "Cake: B-Sides and Rarities", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Cake"], AlbumArtUrl = imgUrl }, + new Album { Title = "Californication", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Red Hot Chili Peppers"], AlbumArtUrl = imgUrl }, + new Album { Title = "Carmina Burana", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Boston Symphony Orchestra & Seiji Ozawa"], AlbumArtUrl = imgUrl }, + new Album { Title = "Carried to Dust (Bonus Track Version)", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Calexico"], AlbumArtUrl = imgUrl }, + new Album { Title = "Carry On", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Chris Cornell"], AlbumArtUrl = imgUrl }, + new Album { Title = "Cássia Eller - Sem Limite [Disc 1]", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cássia Eller"], AlbumArtUrl = imgUrl }, + new Album { Title = "Chemical Wedding", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Bruce Dickinson"], AlbumArtUrl = imgUrl }, + new Album { Title = "Chill: Brazil (Disc 1)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Marcos Valle"], AlbumArtUrl = imgUrl }, + new Album { Title = "Chill: Brazil (Disc 2)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Antônio Carlos Jobim"], AlbumArtUrl = imgUrl }, + new Album { Title = "Chocolate Starfish And The Hot Dog Flavored Water", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Limp Bizkit"], AlbumArtUrl = imgUrl }, + new Album { Title = "Chronicle, Vol. 1", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Creedence Clearwater Revival"], AlbumArtUrl = imgUrl }, + new Album { Title = "Chronicle, Vol. 2", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Creedence Clearwater Revival"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ciao, Baby", Genre = genres["Rock"], Price = 8.99M, Artist = artists["TheStart"], AlbumArtUrl = imgUrl }, + new Album { Title = "Cidade Negra - Hits", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cidade Negra"], AlbumArtUrl = imgUrl }, + new Album { Title = "Classic Munkle: Turbo Edition", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Munkle"], AlbumArtUrl = imgUrl }, + new Album { Title = "Classics: The Best of Sarah Brightman", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "Coda", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Come Away With Me", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Norah Jones"], AlbumArtUrl = imgUrl }, + new Album { Title = "Come Taste The Band", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "Comfort Eagle", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Cake"], AlbumArtUrl = imgUrl }, + new Album { Title = "Common Reaction", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Uh Huh Her "], AlbumArtUrl = imgUrl }, + new Album { Title = "Compositores", Genre = genres["Rock"], Price = 8.99M, Artist = artists["O Terço"], AlbumArtUrl = imgUrl }, + new Album { Title = "Contraband", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Velvet Revolver"], AlbumArtUrl = imgUrl }, + new Album { Title = "Core", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Stone Temple Pilots"], AlbumArtUrl = imgUrl }, + new Album { Title = "Cornerstone", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Styx"], AlbumArtUrl = imgUrl }, + new Album { Title = "Cosmicolor", Genre = genres["Rap"], Price = 8.99M, Artist = artists["M-Flo"], AlbumArtUrl = imgUrl }, + new Album { Title = "Cross", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Justice"], AlbumArtUrl = imgUrl }, + new Album { Title = "Culture of Fear", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Thievery Corporation"], AlbumArtUrl = imgUrl }, + new Album { Title = "Da Lama Ao Caos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Science & Nação Zumbi"], AlbumArtUrl = imgUrl }, + new Album { Title = "Dakshina", Genre = genres["World"], Price = 8.99M, Artist = artists["Deva Premal"], AlbumArtUrl = imgUrl }, + new Album { Title = "Dark Side of the Moon", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl }, + new Album { Title = "Death Magnetic", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Deep End of Down", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Above the Fold"], AlbumArtUrl = imgUrl }, + new Album { Title = "Deep Purple In Rock", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "Deixa Entrar", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Falamansa"], AlbumArtUrl = imgUrl }, + new Album { Title = "Deja Vu", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Crosby, Stills, Nash, and Young"], AlbumArtUrl = imgUrl }, + new Album { Title = "Di Korpu Ku Alma", Genre = genres["World"], Price = 8.99M, Artist = artists["Lura"], AlbumArtUrl = imgUrl }, + new Album { Title = "Diary of a Madman (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { Title = "Diary of a Madman", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { Title = "Dirt", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alice in Chains"], AlbumArtUrl = imgUrl }, + new Album { Title = "Diver Down", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Djavan Ao Vivo - Vol. 02", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Djavan"], AlbumArtUrl = imgUrl }, + new Album { Title = "Djavan Ao Vivo - Vol. 1", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Djavan"], AlbumArtUrl = imgUrl }, + new Album { Title = "Drum'n'bass for Papa", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Plug"], AlbumArtUrl = imgUrl }, + new Album { Title = "Duluth", Genre = genres["Country"], Price = 8.99M, Artist = artists["Trampled By Turtles"], AlbumArtUrl = imgUrl }, + new Album { Title = "Dummy", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Portishead"], AlbumArtUrl = imgUrl }, + new Album { Title = "Duos II", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Luciana Souza/Romero Lubambo"], AlbumArtUrl = imgUrl }, + new Album { Title = "Earl Scruggs and Friends", Genre = genres["Country"], Price = 8.99M, Artist = artists["Earl Scruggs"], AlbumArtUrl = imgUrl }, + new Album { Title = "Eden", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "El Camino", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Black Keys"], AlbumArtUrl = imgUrl }, + new Album { Title = "Elegant Gypsy", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Al di Meola"], AlbumArtUrl = imgUrl }, + new Album { Title = "Elements Of Life", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Tiësto"], AlbumArtUrl = imgUrl }, + new Album { Title = "Elis Regina-Minha História", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Elis Regina"], AlbumArtUrl = imgUrl }, + new Album { Title = "Emergency On Planet Earth", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Jamiroquai"], AlbumArtUrl = imgUrl }, + new Album { Title = "Emotion", Genre = genres["World"], Price = 8.99M, Artist = artists["Papa Wemba"], AlbumArtUrl = imgUrl }, + new Album { Title = "English Renaissance", Genre = genres["Classical"], Price = 8.99M, Artist = artists["The King's Singers"], AlbumArtUrl = imgUrl }, + new Album { Title = "Every Kind of Light", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Posies"], AlbumArtUrl = imgUrl }, + new Album { Title = "Faceless", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Godsmack"], AlbumArtUrl = imgUrl }, + new Album { Title = "Facelift", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alice in Chains"], AlbumArtUrl = imgUrl }, + new Album { Title = "Fair Warning", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Fear of a Black Planet", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Public Enemy"], AlbumArtUrl = imgUrl }, + new Album { Title = "Fear Of The Dark", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Feels Like Home", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Norah Jones"], AlbumArtUrl = imgUrl }, + new Album { Title = "Fireball", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "Fly", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "For Those About To Rock We Salute You", Genre = genres["Rock"], Price = 8.99M, Artist = artists["AC/DC"], AlbumArtUrl = imgUrl }, + new Album { Title = "Four", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Blues Traveler"], AlbumArtUrl = imgUrl }, + new Album { Title = "Frank", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Amy Winehouse"], AlbumArtUrl = imgUrl }, + new Album { Title = "Further Down the Spiral", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Nine Inch Nails"], AlbumArtUrl = imgUrl }, + new Album { Title = "Garage Inc. (Disc 1)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Garage Inc. (Disc 2)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Garbage", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Garbage"], AlbumArtUrl = imgUrl }, + new Album { Title = "Good News For People Who Love Bad News", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Modest Mouse"], AlbumArtUrl = imgUrl }, + new Album { Title = "Gordon", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Barenaked Ladies"], AlbumArtUrl = imgUrl }, + new Album { Title = "Górecki: Symphony No. 3", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Adrian Leaper & Doreen de Feis"], AlbumArtUrl = imgUrl }, + new Album { Title = "Greatest Hits I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Greatest Hits II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Greatest Hits", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Duck Sauce"], AlbumArtUrl = imgUrl }, + new Album { Title = "Greatest Hits", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Lenny Kravitz"], AlbumArtUrl = imgUrl }, + new Album { Title = "Greatest Hits", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Lenny Kravitz"], AlbumArtUrl = imgUrl }, + new Album { Title = "Greatest Kiss", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Kiss"], AlbumArtUrl = imgUrl }, + new Album { Title = "Greetings from Michigan", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Sufjan Stevens"], AlbumArtUrl = imgUrl }, + new Album { Title = "Group Therapy", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Above & Beyond"], AlbumArtUrl = imgUrl }, + new Album { Title = "Handel: The Messiah (Highlights)", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Scholars Baroque Ensemble"], AlbumArtUrl = imgUrl }, + new Album { Title = "Haydn: Symphonies 99 - 104", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Royal Philharmonic Orchestra"], AlbumArtUrl = imgUrl }, + new Album { Title = "Heart of the Night", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Spyro Gyra"], AlbumArtUrl = imgUrl }, + new Album { Title = "Heart On", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Eagles of Death Metal"], AlbumArtUrl = imgUrl }, + new Album { Title = "Holy Diver", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Dio"], AlbumArtUrl = imgUrl }, + new Album { Title = "Homework", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Daft Punk"], AlbumArtUrl = imgUrl }, + new Album { Title = "Hot Rocks, 1964-1971 (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl }, + new Album { Title = "Houses Of The Holy", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "How To Dismantle An Atomic Bomb", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "Human", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Projected"], AlbumArtUrl = imgUrl }, + new Album { Title = "Hunky Dory", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Bowie"], AlbumArtUrl = imgUrl }, + new Album { Title = "Hymns", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Projected"], AlbumArtUrl = imgUrl }, + new Album { Title = "Hysteria", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Def Leppard"], AlbumArtUrl = imgUrl }, + new Album { Title = "In Absentia", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Porcupine Tree"], AlbumArtUrl = imgUrl }, + new Album { Title = "In Between", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Paul Van Dyk"], AlbumArtUrl = imgUrl }, + new Album { Title = "In Rainbows", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Radiohead"], AlbumArtUrl = imgUrl }, + new Album { Title = "In Step", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Stevie Ray Vaughan & Double Trouble"], AlbumArtUrl = imgUrl }, + new Album { Title = "In the court of the Crimson King", Genre = genres["Rock"], Price = 8.99M, Artist = artists["King Crimson"], AlbumArtUrl = imgUrl }, + new Album { Title = "In Through The Out Door", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "In Your Honor [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl }, + new Album { Title = "In Your Honor [Disc 2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl }, + new Album { Title = "Indestructible", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rancid"], AlbumArtUrl = imgUrl }, + new Album { Title = "Infinity", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Journey"], AlbumArtUrl = imgUrl }, + new Album { Title = "Into The Light", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Coverdale"], AlbumArtUrl = imgUrl }, + new Album { Title = "Introspective", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Pet Shop Boys"], AlbumArtUrl = imgUrl }, + new Album { Title = "Iron Maiden", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "ISAM", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Amon Tobin"], AlbumArtUrl = imgUrl }, + new Album { Title = "IV", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Jagged Little Pill", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Alanis Morissette"], AlbumArtUrl = imgUrl }, + new Album { Title = "Jagged Little Pill", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alanis Morissette"], AlbumArtUrl = imgUrl }, + new Album { Title = "Jorge Ben Jor 25 Anos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Jorge Ben"], AlbumArtUrl = imgUrl }, + new Album { Title = "Jota Quest-1995", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Jota Quest"], AlbumArtUrl = imgUrl }, + new Album { Title = "Kick", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["INXS"], AlbumArtUrl = imgUrl }, + new Album { Title = "Kill 'Em All", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Kind of Blue", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl }, + new Album { Title = "King For A Day Fool For A Lifetime", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Faith No More"], AlbumArtUrl = imgUrl }, + new Album { Title = "Kiss", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Carly Rae Jepsen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Last Call", Genre = genres["Country"], Price = 8.99M, Artist = artists["Cayouche"], AlbumArtUrl = imgUrl }, + new Album { Title = "Le Freak", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Chic"], AlbumArtUrl = imgUrl }, + new Album { Title = "Le Tigre", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Le Tigre"], AlbumArtUrl = imgUrl }, + new Album { Title = "Led Zeppelin I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Led Zeppelin II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Led Zeppelin III", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Let There Be Rock", Genre = genres["Rock"], Price = 8.99M, Artist = artists["AC/DC"], AlbumArtUrl = imgUrl }, + new Album { Title = "Little Earthquakes", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Tori Amos"], AlbumArtUrl = imgUrl }, + new Album { Title = "Live [Disc 1]", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl }, + new Album { Title = "Live [Disc 2]", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl }, + new Album { Title = "Live After Death", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Live At Donington 1992 (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Live At Donington 1992 (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Live on Earth", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["The Cat Empire"], AlbumArtUrl = imgUrl }, + new Album { Title = "Live On Two Legs [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl }, + new Album { Title = "Living After Midnight", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Judas Priest"], AlbumArtUrl = imgUrl }, + new Album { Title = "Living", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paddy Casey"], AlbumArtUrl = imgUrl }, + new Album { Title = "Load", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Love Changes Everything", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "MacArthur Park Suite", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Donna Summer"], AlbumArtUrl = imgUrl }, + new Album { Title = "Machine Head", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "Magical Mystery Tour", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl }, + new Album { Title = "Mais Do Mesmo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Legião Urbana"], AlbumArtUrl = imgUrl }, + new Album { Title = "Maquinarama", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Skank"], AlbumArtUrl = imgUrl }, + new Album { Title = "Marasim", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Jagjit Singh"], AlbumArtUrl = imgUrl }, + new Album { Title = "Mascagni: Cavalleria Rusticana", Genre = genres["Classical"], Price = 8.99M, Artist = artists["James Levine"], AlbumArtUrl = imgUrl }, + new Album { Title = "Master of Puppets", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Mechanics & Mathematics", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Venus Hum"], AlbumArtUrl = imgUrl }, + new Album { Title = "Mental Jewelry", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Live"], AlbumArtUrl = imgUrl }, + new Album { Title = "Metallics", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "meteora", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Linkin Park"], AlbumArtUrl = imgUrl }, + new Album { Title = "Meus Momentos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Gonzaguinha"], AlbumArtUrl = imgUrl }, + new Album { Title = "Mezmerize", Genre = genres["Metal"], Price = 8.99M, Artist = artists["System Of A Down"], AlbumArtUrl = imgUrl }, + new Album { Title = "Mezzanine", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Massive Attack"], AlbumArtUrl = imgUrl }, + new Album { Title = "Miles Ahead", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl }, + new Album { Title = "Milton Nascimento Ao Vivo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Milton Nascimento"], AlbumArtUrl = imgUrl }, + new Album { Title = "Minas", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Milton Nascimento"], AlbumArtUrl = imgUrl }, + new Album { Title = "Minha Historia", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Buarque"], AlbumArtUrl = imgUrl }, + new Album { Title = "Misplaced Childhood", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Marillion"], AlbumArtUrl = imgUrl }, + new Album { Title = "MK III The Final Concerts [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "Morning Dance", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Spyro Gyra"], AlbumArtUrl = imgUrl }, + new Album { Title = "Motley Crue Greatest Hits", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Mötley Crüe"], AlbumArtUrl = imgUrl }, + new Album { Title = "Moving Pictures", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rush"], AlbumArtUrl = imgUrl }, + new Album { Title = "Mozart: Chamber Music", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Nash Ensemble"], AlbumArtUrl = imgUrl }, + new Album { Title = "Mozart: Symphonies Nos. 40 & 41", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Berliner Philharmoniker"], AlbumArtUrl = imgUrl }, + new Album { Title = "Murder Ballads", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Nick Cave and the Bad Seeds"], AlbumArtUrl = imgUrl }, + new Album { Title = "Music For The Jilted Generation", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["The Prodigy"], AlbumArtUrl = imgUrl }, + new Album { Title = "My Generation - The Very Best Of The Who", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Who"], AlbumArtUrl = imgUrl }, + new Album { Title = "My Name is Skrillex", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Skrillex"], AlbumArtUrl = imgUrl }, + new Album { Title = "Na Pista", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cláudio Zoli"], AlbumArtUrl = imgUrl }, + new Album { Title = "Nevermind", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Nirvana"], AlbumArtUrl = imgUrl }, + new Album { Title = "New Adventures In Hi-Fi", Genre = genres["Rock"], Price = 8.99M, Artist = artists["R.E.M."], AlbumArtUrl = imgUrl }, + new Album { Title = "New Divide", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Linkin Park"], AlbumArtUrl = imgUrl }, + new Album { Title = "New York Dolls", Genre = genres["Punk"], Price = 8.99M, Artist = artists["New York Dolls"], AlbumArtUrl = imgUrl }, + new Album { Title = "News Of The World", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Nielsen: The Six Symphonies", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Göteborgs Symfoniker & Neeme Järvi"], AlbumArtUrl = imgUrl }, + new Album { Title = "Night At The Opera", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Night Castle", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Trans-Siberian Orchestra"], AlbumArtUrl = imgUrl }, + new Album { Title = "Nkolo", Genre = genres["World"], Price = 8.99M, Artist = artists["Lokua Kanza"], AlbumArtUrl = imgUrl }, + new Album { Title = "No More Tears (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { Title = "No Prayer For The Dying", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "No Security", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl }, + new Album { Title = "O Brother, Where Art Thou?", Genre = genres["Country"], Price = 8.99M, Artist = artists["Alison Krauss"], AlbumArtUrl = imgUrl }, + new Album { Title = "O Samba Poconé", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Skank"], AlbumArtUrl = imgUrl }, + new Album { Title = "O(+>", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Prince"], AlbumArtUrl = imgUrl }, + new Album { Title = "Oceania", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Smashing Pumpkins"], AlbumArtUrl = imgUrl }, + new Album { Title = "Off the Deep End", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Weird Al"], AlbumArtUrl = imgUrl }, + new Album { Title = "OK Computer", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Radiohead"], AlbumArtUrl = imgUrl }, + new Album { Title = "Olodum", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Olodum"], AlbumArtUrl = imgUrl }, + new Album { Title = "One Love", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["David Guetta"], AlbumArtUrl = imgUrl }, + new Album { Title = "Operation: Mindcrime", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Queensrÿche"], AlbumArtUrl = imgUrl }, + new Album { Title = "Opiate", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl }, + new Album { Title = "Outbreak", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Dennis Chambers"], AlbumArtUrl = imgUrl }, + new Album { Title = "Pachelbel: Canon & Gigue", Genre = genres["Classical"], Price = 8.99M, Artist = artists["English Concert & Trevor Pinnock"], AlbumArtUrl = imgUrl }, + new Album { Title = "Paid in Full", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Eric B. and Rakim"], AlbumArtUrl = imgUrl }, + new Album { Title = "Para Siempre", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Vicente Fernandez"], AlbumArtUrl = imgUrl }, + new Album { Title = "Pause", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Four Tet"], AlbumArtUrl = imgUrl }, + new Album { Title = "Peace Sells... but Who's Buying", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Megadeth"], AlbumArtUrl = imgUrl }, + new Album { Title = "Physical Graffiti [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Physical Graffiti [Disc 2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Physical Graffiti", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Piece Of Mind", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Pinkerton", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Weezer"], AlbumArtUrl = imgUrl }, + new Album { Title = "Plays Metallica By Four Cellos", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Apocalyptica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Pop", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "Powerslave", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Prenda Minha", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Caetano Veloso"], AlbumArtUrl = imgUrl }, + new Album { Title = "Presence", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Pretty Hate Machine", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Nine Inch Nails"], AlbumArtUrl = imgUrl }, + new Album { Title = "Prisoner", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Jezabels"], AlbumArtUrl = imgUrl }, + new Album { Title = "Privateering", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Mark Knopfler"], AlbumArtUrl = imgUrl }, + new Album { Title = "Prokofiev: Romeo & Juliet", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Michael Tilson Thomas"], AlbumArtUrl = imgUrl }, + new Album { Title = "Prokofiev: Symphony No.1", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sergei Prokofiev & Yuri Temirkanov"], AlbumArtUrl = imgUrl }, + new Album { Title = "PSY's Best 6th Part 1", Genre = genres["Pop"], Price = 8.99M, Artist = artists["PSY"], AlbumArtUrl = imgUrl }, + new Album { Title = "Purcell: The Fairy Queen", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Classical Players"], AlbumArtUrl = imgUrl }, + new Album { Title = "Purpendicular", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "Purple", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Stone Temple Pilots"], AlbumArtUrl = imgUrl }, + new Album { Title = "Quanta Gente Veio Ver (Live)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Gilberto Gil"], AlbumArtUrl = imgUrl }, + new Album { Title = "Quanta Gente Veio ver--Bônus De Carnaval", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Gilberto Gil"], AlbumArtUrl = imgUrl }, + new Album { Title = "Quiet Songs", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Aisha Duo"], AlbumArtUrl = imgUrl }, + new Album { Title = "Raices", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Los Tigres del Norte"], AlbumArtUrl = imgUrl }, + new Album { Title = "Raising Hell", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Run DMC"], AlbumArtUrl = imgUrl }, + new Album { Title = "Raoul and the Kings of Spain ", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tears For Fears"], AlbumArtUrl = imgUrl }, + new Album { Title = "Rattle And Hum", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "Raul Seixas", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Raul Seixas"], AlbumArtUrl = imgUrl }, + new Album { Title = "Recovery [Explicit]", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Eminem"], AlbumArtUrl = imgUrl }, + new Album { Title = "Reign In Blood", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Slayer"], AlbumArtUrl = imgUrl }, + new Album { Title = "Relayed", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Yes"], AlbumArtUrl = imgUrl }, + new Album { Title = "ReLoad", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Respighi:Pines of Rome", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Eugene Ormandy"], AlbumArtUrl = imgUrl }, + new Album { Title = "Restless and Wild", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Accept"], AlbumArtUrl = imgUrl }, + new Album { Title = "Retrospective I (1974-1980)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rush"], AlbumArtUrl = imgUrl }, + new Album { Title = "Revelations", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Audioslave"], AlbumArtUrl = imgUrl }, + new Album { Title = "Revolver", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ride the Lighting ", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ride The Lightning", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ring My Bell", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Anita Ward"], AlbumArtUrl = imgUrl }, + new Album { Title = "Riot Act", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl }, + new Album { Title = "Rise of the Phoenix", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Before the Dawn"], AlbumArtUrl = imgUrl }, + new Album { Title = "Rock In Rio [CD1]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Rock In Rio [CD2]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Rock In Rio [CD2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Roda De Funk", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Funk Como Le Gusta"], AlbumArtUrl = imgUrl }, + new Album { Title = "Room for Squares", Genre = genres["Pop"], Price = 8.99M, Artist = artists["John Mayer"], AlbumArtUrl = imgUrl }, + new Album { Title = "Root Down", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Jimmy Smith"], AlbumArtUrl = imgUrl }, + new Album { Title = "Rounds", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Four Tet"], AlbumArtUrl = imgUrl }, + new Album { Title = "Rubber Factory", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Black Keys"], AlbumArtUrl = imgUrl }, + new Album { Title = "Rust in Peace", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Megadeth"], AlbumArtUrl = imgUrl }, + new Album { Title = "Sambas De Enredo 2001", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl }, + new Album { Title = "Santana - As Years Go By", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl }, + new Album { Title = "Santana Live", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl }, + new Album { Title = "Saturday Night Fever", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Bee Gees"], AlbumArtUrl = imgUrl }, + new Album { Title = "Scary Monsters and Nice Sprites", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Skrillex"], AlbumArtUrl = imgUrl }, + new Album { Title = "Scheherazade", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Chicago Symphony Orchestra & Fritz Reiner"], AlbumArtUrl = imgUrl }, + new Album { Title = "SCRIABIN: Vers la flamme", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Christopher O'Riley"], AlbumArtUrl = imgUrl }, + new Album { Title = "Second Coming", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Stone Roses"], AlbumArtUrl = imgUrl }, + new Album { Title = "Serie Sem Limite (Disc 1)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Tim Maia"], AlbumArtUrl = imgUrl }, + new Album { Title = "Serie Sem Limite (Disc 2)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Tim Maia"], AlbumArtUrl = imgUrl }, + new Album { Title = "Serious About Men", Genre = genres["Rap"], Price = 8.99M, Artist = artists["The Rubberbandits"], AlbumArtUrl = imgUrl }, + new Album { Title = "Seventh Son of a Seventh Son", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Short Bus", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Filter"], AlbumArtUrl = imgUrl }, + new Album { Title = "Sibelius: Finlandia", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Berliner Philharmoniker"], AlbumArtUrl = imgUrl }, + new Album { Title = "Singles Collection", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Bowie"], AlbumArtUrl = imgUrl }, + new Album { Title = "Six Degrees of Inner Turbulence", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Dream Theater"], AlbumArtUrl = imgUrl }, + new Album { Title = "Slave To The Empire", Genre = genres["Metal"], Price = 8.99M, Artist = artists["T&N"], AlbumArtUrl = imgUrl }, + new Album { Title = "Slaves And Masters", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "Slouching Towards Bethlehem", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Robert James"], AlbumArtUrl = imgUrl }, + new Album { Title = "Smash", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Offspring"], AlbumArtUrl = imgUrl }, + new Album { Title = "Something Special", Genre = genres["Country"], Price = 8.99M, Artist = artists["Dolly Parton"], AlbumArtUrl = imgUrl }, + new Album { Title = "Somewhere in Time", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Song(s) You Know By Heart", Genre = genres["Country"], Price = 8.99M, Artist = artists["Jimmy Buffett"], AlbumArtUrl = imgUrl }, + new Album { Title = "Sound of Music", Genre = genres["Punk"], Price = 8.99M, Artist = artists["Adicts"], AlbumArtUrl = imgUrl }, + new Album { Title = "South American Getaway", Genre = genres["Classical"], Price = 8.99M, Artist = artists["The 12 Cellists of The Berlin Philharmonic"], AlbumArtUrl = imgUrl }, + new Album { Title = "Sozinho Remix Ao Vivo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Caetano Veloso"], AlbumArtUrl = imgUrl }, + new Album { Title = "Speak of the Devil", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { Title = "Spiritual State", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Nujabes"], AlbumArtUrl = imgUrl }, + new Album { Title = "St. Anger", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { Title = "Still Life", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Opeth"], AlbumArtUrl = imgUrl }, + new Album { Title = "Stop Making Sense", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Talking Heads"], AlbumArtUrl = imgUrl }, + new Album { Title = "Stormbringer", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "Stranger than Fiction", Genre = genres["Punk"], Price = 8.99M, Artist = artists["Bad Religion"], AlbumArtUrl = imgUrl }, + new Album { Title = "Strauss: Waltzes", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Eugene Ormandy"], AlbumArtUrl = imgUrl }, + new Album { Title = "Supermodified", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Amon Tobin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Supernatural", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl }, + new Album { Title = "Surfing with the Alien (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Joe Satriani"], AlbumArtUrl = imgUrl }, + new Album { Title = "Switched-On Bach", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Wendy Carlos"], AlbumArtUrl = imgUrl }, + new Album { Title = "Symphony", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "Szymanowski: Piano Works, Vol. 1", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Martin Roscoe"], AlbumArtUrl = imgUrl }, + new Album { Title = "Tchaikovsky: The Nutcracker", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Symphony Orchestra"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ted Nugent", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ted Nugent"], AlbumArtUrl = imgUrl }, + new Album { Title = "Teflon Don", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Rick Ross"], AlbumArtUrl = imgUrl }, + new Album { Title = "Tell Another Joke at the Ol' Choppin' Block", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Danielson Famile"], AlbumArtUrl = imgUrl }, + new Album { Title = "Temple of the Dog", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Temple of the Dog"], AlbumArtUrl = imgUrl }, + new Album { Title = "Ten", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl }, + new Album { Title = "Texas Flood", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Stevie Ray Vaughan"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Battle Rages On", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Beast Live", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paul D'Ianno"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Best Of 1980-1990", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Best of 1990–2000", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Best of Beethoven", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Nicolaus Esterhazy Sinfonia"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Best Of Billy Cobham", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Billy Cobham"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Best of Ed Motta", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Ed Motta"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Best Of Van Halen, Vol. I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Bridge", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Melanie Fiona"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Cage", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tygers of Pan Tang"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Chicago Transit Authority", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Chicago "], AlbumArtUrl = imgUrl }, + new Album { Title = "The Chronic", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Dr. Dre"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Colour And The Shape", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Crane Wife", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["The Decemberists"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Cream Of Clapton", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Cure", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Cure"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Dark Side Of The Moon", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Divine Conspiracy", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Epica"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Doors", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Doors"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Dream of the Blue Turtles", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Sting"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Essential Miles Davis [Disc 1]", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Essential Miles Davis [Disc 2]", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Final Concerts (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Final Frontier", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Head and the Heart", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Head and the Heart"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Joshua Tree", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Last Night of the Proms", Genre = genres["Classical"], Price = 8.99M, Artist = artists["BBC Concert Orchestra"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Lumineers", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Lumineers"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Number of The Beast", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Number of The Beast", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Police Greatest Hits", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Police"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Song Remains The Same (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Song Remains The Same (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Southern Harmony and Musical Companion", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Spade", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Butch Walker & The Black Widows"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Stone Roses", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Stone Roses"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Suburbs", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Arcade Fire"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Three Tenors Disc1/Disc2", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Carreras, Pavarotti, Domingo"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Trees They Grow So High", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "The Wall", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl }, + new Album { Title = "The X Factor", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Them Crooked Vultures", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Them Crooked Vultures"], AlbumArtUrl = imgUrl }, + new Album { Title = "This Is Happening", Genre = genres["Rock"], Price = 8.99M, Artist = artists["LCD Soundsystem"], AlbumArtUrl = imgUrl }, + new Album { Title = "Thunder, Lightning, Strike", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Go! Team"], AlbumArtUrl = imgUrl }, + new Album { Title = "Time to Say Goodbye", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { Title = "Time, Love & Tenderness", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Michael Bolton"], AlbumArtUrl = imgUrl }, + new Album { Title = "Tomorrow Starts Today", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Mobile"], AlbumArtUrl = imgUrl }, + new Album { Title = "Tribute", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { Title = "Tuesday Night Music Club", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Sheryl Crow"], AlbumArtUrl = imgUrl }, + new Album { Title = "Umoja", Genre = genres["Rock"], Price = 8.99M, Artist = artists["BLØF"], AlbumArtUrl = imgUrl }, + new Album { Title = "Under the Pink", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Tori Amos"], AlbumArtUrl = imgUrl }, + new Album { Title = "Undertow", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl }, + new Album { Title = "Un-Led-Ed", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Dread Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { Title = "Unplugged [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Kiss"], AlbumArtUrl = imgUrl }, + new Album { Title = "Unplugged", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl }, + new Album { Title = "Unplugged", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl }, + new Album { Title = "Untrue", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Burial"], AlbumArtUrl = imgUrl }, + new Album { Title = "Use Your Illusion I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl }, + new Album { Title = "Use Your Illusion II", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl }, + new Album { Title = "Use Your Illusion II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl }, + new Album { Title = "Van Halen III", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Van Halen", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { Title = "Version 2.0", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Garbage"], AlbumArtUrl = imgUrl }, + new Album { Title = "Vinicius De Moraes", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Vinícius De Moraes"], AlbumArtUrl = imgUrl }, + new Album { Title = "Virtual XI", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { Title = "Voodoo Lounge", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl }, + new Album { Title = "Vozes do MPB", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl }, + new Album { Title = "Vs.", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl }, + new Album { Title = "Wagner: Favourite Overtures", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sir Georg Solti & Wiener Philharmoniker"], AlbumArtUrl = imgUrl }, + new Album { Title = "Walking Into Clarksdale", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Page & Plant"], AlbumArtUrl = imgUrl }, + new Album { Title = "Wapi Yo", Genre = genres["World"], Price = 8.99M, Artist = artists["Lokua Kanza"], AlbumArtUrl = imgUrl }, + new Album { Title = "War", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "Warner 25 Anos", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Antônio Carlos Jobim"], AlbumArtUrl = imgUrl }, + new Album { Title = "Wasteland R&Btheque", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Raunchy"], AlbumArtUrl = imgUrl }, + new Album { Title = "Watermark", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Enya"], AlbumArtUrl = imgUrl }, + new Album { Title = "We Were Exploding Anyway", Genre = genres["Rock"], Price = 8.99M, Artist = artists["65daysofstatic"], AlbumArtUrl = imgUrl }, + new Album { Title = "Weill: The Seven Deadly Sins", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Orchestre de l'Opéra de Lyon"], AlbumArtUrl = imgUrl }, + new Album { Title = "White Pony", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deftones"], AlbumArtUrl = imgUrl }, + new Album { Title = "Who's Next", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Who"], AlbumArtUrl = imgUrl }, + new Album { Title = "Wish You Were Here", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl }, + new Album { Title = "With Oden on Our Side", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Amon Amarth"], AlbumArtUrl = imgUrl }, + new Album { Title = "Worlds", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Aaron Goldberg"], AlbumArtUrl = imgUrl }, + new Album { Title = "Worship Music", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Anthrax"], AlbumArtUrl = imgUrl }, + new Album { Title = "X&Y", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Coldplay"], AlbumArtUrl = imgUrl }, + new Album { Title = "Xinti", Genre = genres["World"], Price = 8.99M, Artist = artists["Sara Tavares"], AlbumArtUrl = imgUrl }, + new Album { Title = "Yano", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Yano"], AlbumArtUrl = imgUrl }, + new Album { Title = "Yesterday Once More Disc 1/Disc 2", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Carpenters"], AlbumArtUrl = imgUrl }, + new Album { Title = "Zooropa", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { Title = "Zoso", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + }; + + foreach (var album in albums) + { + album.ArtistId = album.Artist.ArtistId; + album.GenreId = album.Genre.GenreId; + } + + return albums; + } + + private static Dictionary artists; + public static Dictionary Artists + { + get + { + if (artists == null) + { + var artistsList = new Artist[] + { + new Artist { Name = "65daysofstatic" }, + new Artist { Name = "Aaron Goldberg" }, + new Artist { Name = "Above & Beyond" }, + new Artist { Name = "Above the Fold" }, + new Artist { Name = "AC/DC" }, + new Artist { Name = "Accept" }, + new Artist { Name = "Adicts" }, + new Artist { Name = "Adrian Leaper & Doreen de Feis" }, + new Artist { Name = "Aerosmith" }, + new Artist { Name = "Aisha Duo" }, + new Artist { Name = "Al di Meola" }, + new Artist { Name = "Alabama Shakes" }, + new Artist { Name = "Alanis Morissette" }, + new Artist { Name = "Alberto Turco & Nova Schola Gregoriana" }, + new Artist { Name = "Alice in Chains" }, + new Artist { Name = "Alison Krauss" }, + new Artist { Name = "Amon Amarth" }, + new Artist { Name = "Amon Tobin" }, + new Artist { Name = "Amr Diab" }, + new Artist { Name = "Amy Winehouse" }, + new Artist { Name = "Anita Ward" }, + new Artist { Name = "Anthrax" }, + new Artist { Name = "Antônio Carlos Jobim" }, + new Artist { Name = "Apocalyptica" }, + new Artist { Name = "Aqua" }, + new Artist { Name = "Armand Van Helden" }, + new Artist { Name = "Arcade Fire" }, + new Artist { Name = "Audioslave" }, + new Artist { Name = "Bad Religion" }, + new Artist { Name = "Barenaked Ladies" }, + new Artist { Name = "BBC Concert Orchestra" }, + new Artist { Name = "Bee Gees" }, + new Artist { Name = "Before the Dawn" }, + new Artist { Name = "Berliner Philharmoniker" }, + new Artist { Name = "Billy Cobham" }, + new Artist { Name = "Black Label Society" }, + new Artist { Name = "Black Sabbath" }, + new Artist { Name = "BLØF" }, + new Artist { Name = "Blues Traveler" }, + new Artist { Name = "Boston Symphony Orchestra & Seiji Ozawa" }, + new Artist { Name = "Britten Sinfonia, Ivor Bolton & Lesley Garrett" }, + new Artist { Name = "Bruce Dickinson" }, + new Artist { Name = "Buddy Guy" }, + new Artist { Name = "Burial" }, + new Artist { Name = "Butch Walker & The Black Widows" }, + new Artist { Name = "Caetano Veloso" }, + new Artist { Name = "Cake" }, + new Artist { Name = "Calexico" }, + new Artist { Name = "Carly Rae Jepsen" }, + new Artist { Name = "Carreras, Pavarotti, Domingo" }, + new Artist { Name = "Cássia Eller" }, + new Artist { Name = "Cayouche" }, + new Artist { Name = "Chic" }, + new Artist { Name = "Chicago " }, + new Artist { Name = "Chicago Symphony Orchestra & Fritz Reiner" }, + new Artist { Name = "Chico Buarque" }, + new Artist { Name = "Chico Science & Nação Zumbi" }, + new Artist { Name = "Choir Of Westminster Abbey & Simon Preston" }, + new Artist { Name = "Chris Cornell" }, + new Artist { Name = "Christopher O'Riley" }, + new Artist { Name = "Cidade Negra" }, + new Artist { Name = "Cláudio Zoli" }, + new Artist { Name = "Coldplay" }, + new Artist { Name = "Creedence Clearwater Revival" }, + new Artist { Name = "Crosby, Stills, Nash, and Young" }, + new Artist { Name = "Daft Punk" }, + new Artist { Name = "Danielson Famile" }, + new Artist { Name = "David Bowie" }, + new Artist { Name = "David Coverdale" }, + new Artist { Name = "David Guetta" }, + new Artist { Name = "deadmau5" }, + new Artist { Name = "Deep Purple" }, + new Artist { Name = "Def Leppard" }, + new Artist { Name = "Deftones" }, + new Artist { Name = "Dennis Chambers" }, + new Artist { Name = "Deva Premal" }, + new Artist { Name = "Dio" }, + new Artist { Name = "Djavan" }, + new Artist { Name = "Dolly Parton" }, + new Artist { Name = "Donna Summer" }, + new Artist { Name = "Dr. Dre" }, + new Artist { Name = "Dread Zeppelin" }, + new Artist { Name = "Dream Theater" }, + new Artist { Name = "Duck Sauce" }, + new Artist { Name = "Earl Scruggs" }, + new Artist { Name = "Ed Motta" }, + new Artist { Name = "Edo de Waart & San Francisco Symphony" }, + new Artist { Name = "Elis Regina" }, + new Artist { Name = "Eminem" }, + new Artist { Name = "English Concert & Trevor Pinnock" }, + new Artist { Name = "Enya" }, + new Artist { Name = "Epica" }, + new Artist { Name = "Eric B. and Rakim" }, + new Artist { Name = "Eric Clapton" }, + new Artist { Name = "Eugene Ormandy" }, + new Artist { Name = "Faith No More" }, + new Artist { Name = "Falamansa" }, + new Artist { Name = "Filter" }, + new Artist { Name = "Foo Fighters" }, + new Artist { Name = "Four Tet" }, + new Artist { Name = "Frank Zappa & Captain Beefheart" }, + new Artist { Name = "Fretwork" }, + new Artist { Name = "Funk Como Le Gusta" }, + new Artist { Name = "Garbage" }, + new Artist { Name = "Gerald Moore" }, + new Artist { Name = "Gilberto Gil" }, + new Artist { Name = "Godsmack" }, + new Artist { Name = "Gonzaguinha" }, + new Artist { Name = "Göteborgs Symfoniker & Neeme Järvi" }, + new Artist { Name = "Guns N' Roses" }, + new Artist { Name = "Gustav Mahler" }, + new Artist { Name = "In This Moment" }, + new Artist { Name = "Incognito" }, + new Artist { Name = "INXS" }, + new Artist { Name = "Iron Maiden" }, + new Artist { Name = "Jagjit Singh" }, + new Artist { Name = "James Levine" }, + new Artist { Name = "Jamiroquai" }, + new Artist { Name = "Jimi Hendrix" }, + new Artist { Name = "Jimmy Buffett" }, + new Artist { Name = "Jimmy Smith" }, + new Artist { Name = "Joe Satriani" }, + new Artist { Name = "John Digweed" }, + new Artist { Name = "John Mayer" }, + new Artist { Name = "Jorge Ben" }, + new Artist { Name = "Jota Quest" }, + new Artist { Name = "Journey" }, + new Artist { Name = "Judas Priest" }, + new Artist { Name = "Julian Bream" }, + new Artist { Name = "Justice" }, + new Artist { Name = "Orchestre de l'Opéra de Lyon" }, + new Artist { Name = "King Crimson" }, + new Artist { Name = "Kiss" }, + new Artist { Name = "LCD Soundsystem" }, + new Artist { Name = "Le Tigre" }, + new Artist { Name = "Led Zeppelin" }, + new Artist { Name = "Legião Urbana" }, + new Artist { Name = "Lenny Kravitz" }, + new Artist { Name = "Les Arts Florissants & William Christie" }, + new Artist { Name = "Limp Bizkit" }, + new Artist { Name = "Linkin Park" }, + new Artist { Name = "Live" }, + new Artist { Name = "Lokua Kanza" }, + new Artist { Name = "London Symphony Orchestra" }, + new Artist { Name = "Los Tigres del Norte" }, + new Artist { Name = "Luciana Souza/Romero Lubambo" }, + new Artist { Name = "Lulu Santos" }, + new Artist { Name = "Lura" }, + new Artist { Name = "Marcos Valle" }, + new Artist { Name = "Marillion" }, + new Artist { Name = "Marisa Monte" }, + new Artist { Name = "Mark Knopfler" }, + new Artist { Name = "Martin Roscoe" }, + new Artist { Name = "Massive Attack" }, + new Artist { Name = "Maurizio Pollini" }, + new Artist { Name = "Megadeth" }, + new Artist { Name = "Mela Tenenbaum, Pro Musica Prague & Richard Kapp" }, + new Artist { Name = "Melanie Fiona" }, + new Artist { Name = "Men At Work" }, + new Artist { Name = "Metallica" }, + new Artist { Name = "M-Flo" }, + new Artist { Name = "Michael Bolton" }, + new Artist { Name = "Michael Tilson Thomas" }, + new Artist { Name = "Miles Davis" }, + new Artist { Name = "Milton Nascimento" }, + new Artist { Name = "Mobile" }, + new Artist { Name = "Modest Mouse" }, + new Artist { Name = "Mötley Crüe" }, + new Artist { Name = "Motörhead" }, + new Artist { Name = "Mumford & Sons" }, + new Artist { Name = "Munkle" }, + new Artist { Name = "Nash Ensemble" }, + new Artist { Name = "Neil Young" }, + new Artist { Name = "New York Dolls" }, + new Artist { Name = "Nick Cave and the Bad Seeds" }, + new Artist { Name = "Nicolaus Esterhazy Sinfonia" }, + new Artist { Name = "Nine Inch Nails" }, + new Artist { Name = "Nirvana" }, + new Artist { Name = "Norah Jones" }, + new Artist { Name = "Nujabes" }, + new Artist { Name = "O Terço" }, + new Artist { Name = "Oasis" }, + new Artist { Name = "Olodum" }, + new Artist { Name = "Opeth" }, + new Artist { Name = "Orchestra of The Age of Enlightenment" }, + new Artist { Name = "Os Paralamas Do Sucesso" }, + new Artist { Name = "Ozzy Osbourne" }, + new Artist { Name = "Paddy Casey" }, + new Artist { Name = "Page & Plant" }, + new Artist { Name = "Papa Wemba" }, + new Artist { Name = "Paul D'Ianno" }, + new Artist { Name = "Paul Oakenfold" }, + new Artist { Name = "Paul Van Dyk" }, + new Artist { Name = "Pearl Jam" }, + new Artist { Name = "Pet Shop Boys" }, + new Artist { Name = "Pink Floyd" }, + new Artist { Name = "Plug" }, + new Artist { Name = "Porcupine Tree" }, + new Artist { Name = "Portishead" }, + new Artist { Name = "Prince" }, + new Artist { Name = "Projected" }, + new Artist { Name = "PSY" }, + new Artist { Name = "Public Enemy" }, + new Artist { Name = "Queen" }, + new Artist { Name = "Queensrÿche" }, + new Artist { Name = "R.E.M." }, + new Artist { Name = "Radiohead" }, + new Artist { Name = "Rancid" }, + new Artist { Name = "Raul Seixas" }, + new Artist { Name = "Raunchy" }, + new Artist { Name = "Red Hot Chili Peppers" }, + new Artist { Name = "Rick Ross" }, + new Artist { Name = "Robert James" }, + new Artist { Name = "London Classical Players" }, + new Artist { Name = "Royal Philharmonic Orchestra" }, + new Artist { Name = "Run DMC" }, + new Artist { Name = "Rush" }, + new Artist { Name = "Santana" }, + new Artist { Name = "Sara Tavares" }, + new Artist { Name = "Sarah Brightman" }, + new Artist { Name = "Sasha" }, + new Artist { Name = "Scholars Baroque Ensemble" }, + new Artist { Name = "Scorpions" }, + new Artist { Name = "Sergei Prokofiev & Yuri Temirkanov" }, + new Artist { Name = "Sheryl Crow" }, + new Artist { Name = "Sir Georg Solti & Wiener Philharmoniker" }, + new Artist { Name = "Skank" }, + new Artist { Name = "Skrillex" }, + new Artist { Name = "Slash" }, + new Artist { Name = "Slayer" }, + new Artist { Name = "Soul-Junk" }, + new Artist { Name = "Soundgarden" }, + new Artist { Name = "Spyro Gyra" }, + new Artist { Name = "Stevie Ray Vaughan & Double Trouble" }, + new Artist { Name = "Stevie Ray Vaughan" }, + new Artist { Name = "Sting" }, + new Artist { Name = "Stone Temple Pilots" }, + new Artist { Name = "Styx" }, + new Artist { Name = "Sufjan Stevens" }, + new Artist { Name = "Supreme Beings of Leisure" }, + new Artist { Name = "System Of A Down" }, + new Artist { Name = "T&N" }, + new Artist { Name = "Talking Heads" }, + new Artist { Name = "Tears For Fears" }, + new Artist { Name = "Ted Nugent" }, + new Artist { Name = "Temple of the Dog" }, + new Artist { Name = "Terry Bozzio, Tony Levin & Steve Stevens" }, + new Artist { Name = "The 12 Cellists of The Berlin Philharmonic" }, + new Artist { Name = "The Axis of Awesome" }, + new Artist { Name = "The Beatles" }, + new Artist { Name = "The Black Crowes" }, + new Artist { Name = "The Black Keys" }, + new Artist { Name = "The Carpenters" }, + new Artist { Name = "The Cat Empire" }, + new Artist { Name = "The Cult" }, + new Artist { Name = "The Cure" }, + new Artist { Name = "The Decemberists" }, + new Artist { Name = "The Doors" }, + new Artist { Name = "The Eagles of Death Metal" }, + new Artist { Name = "The Go! Team" }, + new Artist { Name = "The Head and the Heart" }, + new Artist { Name = "The Jezabels" }, + new Artist { Name = "The King's Singers" }, + new Artist { Name = "The Lumineers" }, + new Artist { Name = "The Offspring" }, + new Artist { Name = "The Police" }, + new Artist { Name = "The Posies" }, + new Artist { Name = "The Prodigy" }, + new Artist { Name = "The Rolling Stones" }, + new Artist { Name = "The Rubberbandits" }, + new Artist { Name = "The Smashing Pumpkins" }, + new Artist { Name = "The Stone Roses" }, + new Artist { Name = "The Who" }, + new Artist { Name = "Them Crooked Vultures" }, + new Artist { Name = "TheStart" }, + new Artist { Name = "Thievery Corporation" }, + new Artist { Name = "Tiësto" }, + new Artist { Name = "Tim Maia" }, + new Artist { Name = "Ton Koopman" }, + new Artist { Name = "Tool" }, + new Artist { Name = "Tori Amos" }, + new Artist { Name = "Trampled By Turtles" }, + new Artist { Name = "Trans-Siberian Orchestra" }, + new Artist { Name = "Tygers of Pan Tang" }, + new Artist { Name = "U2" }, + new Artist { Name = "UB40" }, + new Artist { Name = "Uh Huh Her " }, + new Artist { Name = "Van Halen" }, + new Artist { Name = "Various Artists" }, + new Artist { Name = "Velvet Revolver" }, + new Artist { Name = "Venus Hum" }, + new Artist { Name = "Vicente Fernandez" }, + new Artist { Name = "Vinícius De Moraes" }, + new Artist { Name = "Weezer" }, + new Artist { Name = "Weird Al" }, + new Artist { Name = "Wendy Carlos" }, + new Artist { Name = "Wilhelm Kempff" }, + new Artist { Name = "Yano" }, + new Artist { Name = "Yehudi Menuhin" }, + new Artist { Name = "Yes" }, + new Artist { Name = "Yo-Yo Ma" }, + new Artist { Name = "Zeca Pagodinho" }, + new Artist { Name = "אריק אינשטיין"} + }; + + artists = new Dictionary(); + foreach (Artist artist in artistsList) + { + artists.Add(artist.Name, artist); + } + } + + return artists; + } + } + + private static Dictionary genres; + public static Dictionary Genres + { + get + { + if (genres == null) + { + var genresList = new Genre[] + { + new Genre { Name = "Pop" }, + new Genre { Name = "Rock" }, + new Genre { Name = "Jazz" }, + new Genre { Name = "Metal" }, + new Genre { Name = "Electronic" }, + new Genre { Name = "Blues" }, + new Genre { Name = "Latin" }, + new Genre { Name = "Rap" }, + new Genre { Name = "Classical" }, + new Genre { Name = "Alternative" }, + new Genre { Name = "Country" }, + new Genre { Name = "R&B" }, + new Genre { Name = "Indie" }, + new Genre { Name = "Punk" }, + new Genre { Name = "World" } + }; + + genres = new Dictionary(); + + foreach (Genre genre in genresList) + { + genres.Add(genre.Name, genre); + } + } + + return genres; + } + } + } +} diff --git a/samples/MusicStore/Models/ShoppingCart.cs b/samples/MusicStore/Models/ShoppingCart.cs new file mode 100644 index 0000000..5d05325 --- /dev/null +++ b/samples/MusicStore/Models/ShoppingCart.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; + +namespace MusicStore.Models +{ + public class ShoppingCart + { + private readonly MusicStoreContext _dbContext; + private readonly string _shoppingCartId; + + private ShoppingCart(MusicStoreContext dbContext, string id) + { + _dbContext = dbContext; + _shoppingCartId = id; + } + + public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context) + => GetCart(db, GetCartId(context)); + + public static ShoppingCart GetCart(MusicStoreContext db, string cartId) + => new ShoppingCart(db, cartId); + + public async Task AddToCart(Album album) + { + // Get the matching cart and album instances + var cartItem = await _dbContext.CartItems.SingleOrDefaultAsync( + c => c.CartId == _shoppingCartId + && c.AlbumId == album.AlbumId); + + if (cartItem == null) + { + // Create a new cart item if no cart item exists + cartItem = new CartItem + { + AlbumId = album.AlbumId, + CartId = _shoppingCartId, + Count = 1, + DateCreated = DateTime.Now + }; + + _dbContext.CartItems.Add(cartItem); + } + else + { + // If the item does exist in the cart, then add one to the quantity + cartItem.Count++; + } + } + + public int RemoveFromCart(int id) + { + // Get the cart + var cartItem = _dbContext.CartItems.SingleOrDefault( + cart => cart.CartId == _shoppingCartId + && cart.CartItemId == id); + + int itemCount = 0; + + if (cartItem != null) + { + if (cartItem.Count > 1) + { + cartItem.Count--; + itemCount = cartItem.Count; + } + else + { + _dbContext.CartItems.Remove(cartItem); + } + } + + return itemCount; + } + + public async Task EmptyCart() + { + var cartItems = await _dbContext + .CartItems + .Where(cart => cart.CartId == _shoppingCartId) + .ToArrayAsync(); + + _dbContext.CartItems.RemoveRange(cartItems); + } + + public Task> GetCartItems() + { + return _dbContext + .CartItems + .Where(cart => cart.CartId == _shoppingCartId) + .Include(c => c.Album) + .ToListAsync(); + } + + public Task> GetCartAlbumTitles() + { + return _dbContext + .CartItems + .Where(cart => cart.CartId == _shoppingCartId) + .Select(c => c.Album.Title) + .OrderBy(n => n) + .ToListAsync(); + } + + public Task GetCount() + { + // Get the count of each item in the cart and sum them up + return _dbContext + .CartItems + .Where(c => c.CartId == _shoppingCartId) + .Select(c => c.Count) + .SumAsync(); + } + + public Task GetTotal() + { + // Multiply album price by count of that album to get + // the current price for each of those albums in the cart + // sum all album price totals to get the cart total + + return _dbContext + .CartItems + .Where(c => c.CartId == _shoppingCartId) + .Select(c => c.Album.Price * c.Count) + .SumAsync(); + } + + public async Task CreateOrder(Order order) + { + decimal orderTotal = 0; + + var cartItems = await GetCartItems(); + + // Iterate over the items in the cart, adding the order details for each + foreach (var item in cartItems) + { + //var album = _db.Albums.Find(item.AlbumId); + var album = await _dbContext.Albums.SingleAsync(a => a.AlbumId == item.AlbumId); + + var orderDetail = new OrderDetail + { + AlbumId = item.AlbumId, + OrderId = order.OrderId, + UnitPrice = album.Price, + Quantity = item.Count, + }; + + // Set the order total of the shopping cart + orderTotal += (item.Count * album.Price); + + _dbContext.OrderDetails.Add(orderDetail); + } + + // Set the order's total to the orderTotal count + order.Total = orderTotal; + + // Empty the shopping cart + await EmptyCart(); + + // Return the OrderId as the confirmation number + return order.OrderId; + } + + // We're using HttpContextBase to allow access to sessions. + private static string GetCartId(HttpContext context) + { + var cartId = context.Session.GetString("Session"); + + if (cartId == null) + { + //A GUID to hold the cartId. + cartId = Guid.NewGuid().ToString(); + + // Send cart Id as a cookie to the client. + context.Session.SetString("Session", cartId); + } + + return cartId; + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/MusicStore.csproj b/samples/MusicStore/MusicStore.csproj new file mode 100644 index 0000000..07dc732 --- /dev/null +++ b/samples/MusicStore/MusicStore.csproj @@ -0,0 +1,55 @@ + + + + Music store application on ASP.NET Core + netcoreapp2.1;netcoreapp2.0;net461 + $(DefineConstants);DEMO + true + true + win7-x86;win7-x64;linux-x64;osx-x64 + Debug;Release;RuntimeStore + full + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(PublishDir)$(RazorTargetName).dll + + + + + diff --git a/samples/MusicStore/Pages/PageThatThrows.cshtml b/samples/MusicStore/Pages/PageThatThrows.cshtml new file mode 100644 index 0000000..b119553 --- /dev/null +++ b/samples/MusicStore/Pages/PageThatThrows.cshtml @@ -0,0 +1,2 @@ +@page +@{ throw new InvalidOperationException(); } diff --git a/samples/MusicStore/Platform.cs b/samples/MusicStore/Platform.cs new file mode 100644 index 0000000..4124e39 --- /dev/null +++ b/samples/MusicStore/Platform.cs @@ -0,0 +1,110 @@ +using System; +using System.Runtime.InteropServices; + +namespace MusicStore +{ + internal class Platform + { + // Defined in winnt.h + private const int PRODUCT_NANO_SERVER = 0x0000006D; + private const int PRODUCT_DATACENTER_NANO_SERVER = 0x0000008F; + private const int PRODUCT_STANDARD_NANO_SERVER = 0x00000090; + + [DllImport("api-ms-win-core-sysinfo-l1-2-1.dll", SetLastError = false)] + private static extern bool GetProductInfo( + int dwOSMajorVersion, + int dwOSMinorVersion, + int dwSpMajorVersion, + int dwSpMinorVersion, + out int pdwReturnedProductType); + + private bool? _isNano; + private bool? _isWindows; + + public bool IsRunningOnWindows + { + get + { + if (_isWindows == null) + { + _isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + } + + return _isWindows.Value; + } + } + + public bool IsRunningOnNanoServer + { + get + { + if (_isNano == null) + { + var osVersion = new Version(RtlGetVersion() ?? string.Empty); + + try + { + int productType; + if (GetProductInfo(osVersion.Major, osVersion.Minor, 0, 0, out productType)) + { + _isNano = productType == PRODUCT_NANO_SERVER || + productType == PRODUCT_DATACENTER_NANO_SERVER || + productType == PRODUCT_STANDARD_NANO_SERVER; + } + else + { + _isNano = false; + } + } + catch + { + // If the API call fails, the API set is not there which means + // that we are definetely not running on Nano + _isNano = false; + } + } + + return _isNano.Value; + } + } + + // Sql client not available on mono, non-windows, or nano + public bool UseInMemoryStore + { + get + { + return !IsRunningOnWindows || IsRunningOnNanoServer; + } + } + + [StructLayout(LayoutKind.Sequential)] + internal struct RTL_OSVERSIONINFOEX + { + internal uint dwOSVersionInfoSize; + internal uint dwMajorVersion; + internal uint dwMinorVersion; + internal uint dwBuildNumber; + internal uint dwPlatformId; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + internal string szCSDVersion; + } + + // This call avoids the shimming Windows does to report old versions + [DllImport("ntdll")] + private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); + + internal static string RtlGetVersion() + { + RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX(); + osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); + if (RtlGetVersion(out osvi) == 0) + { + return $"{osvi.dwMajorVersion}.{osvi.dwMinorVersion}.{osvi.dwBuildNumber}"; + } + else + { + return null; + } + } + } +} diff --git a/samples/MusicStore/Program.cs b/samples/MusicStore/Program.cs new file mode 100644 index 0000000..07c8104 --- /dev/null +++ b/samples/MusicStore/Program.cs @@ -0,0 +1,67 @@ +using System; +using System.IO; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.HttpSys; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace MusicStore +{ + public static class Program + { + public static void Main(string[] args) + { + var config = new ConfigurationBuilder() + .AddCommandLine(args) + .AddEnvironmentVariables(prefix: "ASPNETCORE_") + .Build(); + + var builder = new WebHostBuilder() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseConfiguration(config) + .UseIISIntegration() + .UseStartup("MusicStore") + .UseDefaultServiceProvider((context, options) => { + options.ValidateScopes = true; + }); + + var environment = builder.GetSetting("environment") ?? + Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + + if (string.Equals(builder.GetSetting("server"), "Microsoft.AspNetCore.Server.HttpSys", System.StringComparison.Ordinal)) + { + if (string.Equals(environment, "NtlmAuthentication", System.StringComparison.Ordinal)) + { + // Set up NTLM authentication for WebListener like below. + // For IIS and IISExpress: Use inetmgr to setup NTLM authentication on the application vDir or + // modify the applicationHost.config to enable NTLM. + builder.UseHttpSys(options => + { + options.Authentication.Schemes = AuthenticationSchemes.NTLM; + options.Authentication.AllowAnonymous = false; + }); + } + else + { + builder.UseHttpSys(); + } + } + else + { + builder.UseKestrel(); + } + + builder.ConfigureLogging(factory => + { + factory.AddConsole(); + + var logLevel = string.Equals(environment, "Development", StringComparison.Ordinal) ? LogLevel.Information : LogLevel.Warning; + factory.SetMinimumLevel(logLevel); + }); + + var host = builder.Build(); + + host.Run(); + } + } +} diff --git a/samples/MusicStore/Properties/AppSettings.cs b/samples/MusicStore/Properties/AppSettings.cs new file mode 100644 index 0000000..6ba3600 --- /dev/null +++ b/samples/MusicStore/Properties/AppSettings.cs @@ -0,0 +1,9 @@ +namespace MusicStore +{ + public class AppSettings + { + public string SiteTitle { get; set; } + + public bool CacheDbResults { get; set; } = true; + } +} \ No newline at end of file diff --git a/samples/MusicStore/Properties/launchSettings.json b/samples/MusicStore/Properties/launchSettings.json new file mode 100644 index 0000000..a2f3822 --- /dev/null +++ b/samples/MusicStore/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:4088/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "MusicStore": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "http://localhost:5000/", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/Scripts/_references.js b/samples/MusicStore/Scripts/_references.js new file mode 100644 index 0000000..73c9e0d --- /dev/null +++ b/samples/MusicStore/Scripts/_references.js @@ -0,0 +1,8 @@ +/// +/// +/// +/// +/// +/// +/// +/// diff --git a/samples/MusicStore/Startup.cs b/samples/MusicStore/Startup.cs new file mode 100644 index 0000000..2ca1de0 --- /dev/null +++ b/samples/MusicStore/Startup.cs @@ -0,0 +1,216 @@ +using System.Globalization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Localization; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using MusicStore.Components; +using MusicStore.Models; + +namespace MusicStore +{ + public class Startup + { + private readonly Platform _platform; + + public Startup(IHostingEnvironment hostingEnvironment) + { + // Below code demonstrates usage of multiple configuration sources. For instance a setting say 'setting1' + // is found in both the registered sources, then the later source will win. By this way a Local config + // can be overridden by a different setting while deployed remotely. + var builder = new ConfigurationBuilder() + .SetBasePath(hostingEnvironment.ContentRootPath) + .AddJsonFile("config.json") + //All environment variables in the process's context flow in as configuration values. + .AddEnvironmentVariables(); + + Configuration = builder.Build(); + _platform = new Platform(); + } + + public IConfiguration Configuration { get; private set; } + + public void ConfigureServices(IServiceCollection services) + { + services.Configure(Configuration.GetSection("AppSettings")); + + // Add EF services to the services container + if (_platform.UseInMemoryStore) + { + services.AddDbContext(options => + options.UseInMemoryDatabase("Scratch")); + } + else + { + services.AddDbContext(options => + options.UseSqlServer(Configuration[StoreConfig.ConnectionStringKey.Replace("__", ":")])); + } + + // Add Identity services to the services container + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.ConfigureApplicationCookie(options => options.AccessDeniedPath = "/Home/AccessDenied"); + + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", builder => + { + builder.WithOrigins("http://example.com"); + }); + }); + + services.AddLogging(); + + // Add MVC services to the services container + services.AddMvc(); + + // Add memory cache services + services.AddMemoryCache(); + services.AddDistributedMemoryCache(); + + // Add session related services. + services.AddSession(); + + // Add the system clock service + services.AddSingleton(); + + // Configure Auth + services.AddAuthorization(options => + { + options.AddPolicy( + "ManageStore", + authBuilder => + { + authBuilder.RequireClaim("ManageStore", "Allowed"); + }); + }); + + + services.AddAuthentication() + .AddFacebook(options => + { + options.AppId = "550624398330273"; + options.AppSecret = "10e56a291d6b618da61b1e0dae3a8954"; + }) + .AddGoogle(options => + { + options.ClientId = "995291875932-0rt7417v5baevqrno24kv332b7d6d30a.apps.googleusercontent.com"; + options.ClientSecret = "J_AT57H5KH_ItmMdu0r6PfXm"; + }) + .AddTwitter(options => + { + options.ConsumerKey = "lDSPIu480ocnXYZ9DumGCDw37"; + options.ConsumerSecret = "fpo0oWRNc3vsZKlZSq1PyOSoeXlJd7NnG4Rfc94xbFXsdcc3nH"; + }) + // The MicrosoftAccount service has restrictions that prevent the use of + // http://localhost:5001/ for test applications. + // As such, here is how to change this sample to uses http://ktesting.com:5001/ instead. + + // From an admin command console first enter: + // notepad C:\Windows\System32\drivers\etc\hosts + // and add this to the file, save, and exit (and reboot?): + // 127.0.0.1 ktesting.com + + // Then you can choose to run the app as admin (see below) or add the following ACL as admin: + // netsh http add urlacl url=http://ktesting:5001/ user=[domain\user] + + // The sample app can then be run via: + // dnx . web + .AddMicrosoftAccount(options => + { + // MicrosoftAccount requires project changes + options.ClientId = "000000004012C08A"; + options.ClientSecret = "GaMQ2hCnqAC6EcDLnXsAeBVIJOLmeutL"; + }); + } + + //This method is invoked when ASPNETCORE_ENVIRONMENT is 'Development' or is not defined + //The allowed values are Development,Staging and Production + public void ConfigureDevelopment(IApplicationBuilder app) + { + // StatusCode pages to gracefully handle status codes 400-599. + app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage"); + + // Display custom error page in production when error occurs + // During development use the ErrorPage middleware to display error information in the browser + app.UseDeveloperExceptionPage(); + + app.UseDatabaseErrorPage(); + + Configure(app); + } + + //This method is invoked when ASPNETCORE_ENVIRONMENT is 'Staging' + //The allowed values are Development,Staging and Production + public void ConfigureStaging(IApplicationBuilder app) + { + // StatusCode pages to gracefully handle status codes 400-599. + app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage"); + + app.UseExceptionHandler("/Home/Error"); + + Configure(app); + } + + //This method is invoked when ASPNETCORE_ENVIRONMENT is 'Production' + //The allowed values are Development,Staging and Production + public void ConfigureProduction(IApplicationBuilder app) + { + // StatusCode pages to gracefully handle status codes 400-599. + app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage"); + + app.UseExceptionHandler("/Home/Error"); + + Configure(app); + } + + public void Configure(IApplicationBuilder app) + { + // force the en-US culture, so that the app behaves the same even on machines with different default culture + var supportedCultures = new[] { new CultureInfo("en-US") }; + + app.UseRequestLocalization(new RequestLocalizationOptions + { + DefaultRequestCulture = new RequestCulture("en-US"), + SupportedCultures = supportedCultures, + SupportedUICultures = supportedCultures + }); + + // Configure Session. + app.UseSession(); + + // Add static files to the request pipeline + app.UseStaticFiles(); + + // Add cookie-based authentication to the request pipeline + app.UseAuthentication(); + + // Add MVC to the request pipeline + app.UseMvc(routes => + { + routes.MapRoute( + name: "areaRoute", + template: "{area:exists}/{controller}/{action}", + defaults: new { action = "Index" }); + + routes.MapRoute( + name: "default", + template: "{controller}/{action}/{id?}", + defaults: new { controller = "Home", action = "Index" }); + + routes.MapRoute( + name: "api", + template: "{controller}/{id?}"); + }); + + //Populates the MusicStore sample data + SampleData.InitializeMusicStoreDatabaseAsync(app.ApplicationServices).Wait(); + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/StartupNtlmAuthentication.cs b/samples/MusicStore/StartupNtlmAuthentication.cs new file mode 100644 index 0000000..136ea1a --- /dev/null +++ b/samples/MusicStore/StartupNtlmAuthentication.cs @@ -0,0 +1,160 @@ +using System; +using System.Globalization; +using System.Security.Claims; +using System.Security.Principal; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Localization; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using MusicStore.Components; +using MusicStore.Models; + +namespace MusicStore +{ + /// + /// To make runtime to load an environment based startup class, specify the environment by the following ways: + /// 1. Drop a Microsoft.AspNetCore.Hosting.ini file in the wwwroot folder + /// 2. Add a setting in the ini file named 'ASPNETCORE_ENVIRONMENT' with value of the format 'Startup[EnvironmentName]'. + /// For example: To load a Startup class named 'StartupNtlmAuthentication' the value of the env should be + /// 'NtlmAuthentication' (eg. ASPNETCORE_ENVIRONMENT=NtlmAuthentication). Runtime adds a 'Startup' prefix to this and + /// loads 'StartupNtlmAuthentication'. + /// If no environment name is specified the default startup class loaded is 'Startup'. + /// + /// Alternative ways to specify environment are: + /// 1. Set the environment variable named SET ASPNETCORE_ENVIRONMENT=NtlmAuthentication + /// 2. For selfhost based servers pass in a command line variable named --env with this value. Eg: + /// "commands": { + /// "web": "Microsoft.AspNetCore.Hosting --server Microsoft.AspNetCore.Server.WebListener + /// --server.urls http://localhost:5002 --ASPNETCORE_ENVIRONMENT NtlmAuthentication", + /// }, + /// + public class StartupNtlmAuthentication + { + public StartupNtlmAuthentication(IHostingEnvironment hostingEnvironment) + { + // Below code demonstrates usage of multiple configuration sources. For instance a setting say 'setting1' + // is found in both the registered sources, then the later source will win. By this way a Local config + // can be overridden by a different setting while deployed remotely. + var builder = new ConfigurationBuilder() + .SetBasePath(hostingEnvironment.ContentRootPath) + .AddJsonFile("config.json") + //All environment variables in the process's context flow in as configuration values. + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfiguration Configuration { get; private set; } + + public void ConfigureServices(IServiceCollection services) + { + services.Configure(Configuration.GetSection("AppSettings")); + + // Add EF services to the services container + services.AddDbContext(options => + options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); + + // Add Identity services to the services container + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", builder => + { + builder.WithOrigins("http://example.com"); + }); + }); + + // Add MVC services to the services container + services.AddMvc(); + + // Add memory cache services + services.AddMemoryCache(); + services.AddDistributedMemoryCache(); + + // Add session related services. + services.AddSession(); + + // Add the system clock service + services.AddSingleton(); + + // Configure Auth + services.AddAuthorization(options => + { + options.AddPolicy( + "ManageStore", + authBuilder => { + authBuilder.RequireClaim("ManageStore", "Allowed"); + }); + }); + } + + public void Configure(IApplicationBuilder app) + { + // force the en-US culture, so that the app behaves the same even on machines with different default culture + var supportedCultures = new[] { new CultureInfo("en-US") }; + + app.UseRequestLocalization(new RequestLocalizationOptions + { + DefaultRequestCulture = new RequestCulture("en-US"), + SupportedCultures = supportedCultures, + SupportedUICultures = supportedCultures + }); + + app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage"); + + // Error page middleware displays a nice formatted HTML page for any unhandled exceptions in the + // request pipeline. + // Note: Not recommended for production. + app.UseDeveloperExceptionPage(); + app.UseDatabaseErrorPage(); + + app.Use(async (context, next) => + { + // Who will get admin access? For demo sake I'm listing the currently logged on user as the application + // administrator. But this can be changed to suit the needs. + var identity = (ClaimsIdentity)context.User.Identity; + + if (context.User.Identity.Name == WindowsIdentity.GetCurrent().Name) + { + identity.AddClaim(new Claim("ManageStore", "Allowed")); + } + + await next.Invoke(); + }); + + // Configure Session. + app.UseSession(); + + // Add static files to the request pipeline + app.UseStaticFiles(); + + // Add MVC to the request pipeline + app.UseMvc(routes => + { + routes.MapRoute( + name: "areaRoute", + template: "{area:exists}/{controller}/{action}", + defaults: new { action = "Index" }); + + routes.MapRoute( + name: "default", + template: "{controller}/{action}/{id?}", + defaults: new { controller = "Home", action = "Index" }); + + routes.MapRoute( + name: "api", + template: "{controller}/{id?}"); + }); + + //Populates the MusicStore sample data + SampleData.InitializeMusicStoreDatabaseAsync(app.ApplicationServices, false).Wait(); + } + } +} diff --git a/samples/MusicStore/StartupOpenIdConnect.cs b/samples/MusicStore/StartupOpenIdConnect.cs new file mode 100644 index 0000000..cb1a15a --- /dev/null +++ b/samples/MusicStore/StartupOpenIdConnect.cs @@ -0,0 +1,165 @@ +using System.Globalization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Localization; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using MusicStore.Components; +using MusicStore.Models; + +namespace MusicStore +{ + /// + /// To make runtime to load an environment based startup class, specify the environment by the following ways: + /// 1. Drop a Microsoft.AspNetCore.Hosting.ini file in the wwwroot folder + /// 2. Add a setting in the ini file named 'ASPNETCORE_ENVIRONMENT' with value of the format 'Startup[EnvironmentName]'. + /// For example: To load a Startup class named 'StartupOpenIdConnect' the value of the env should be + /// 'OpenIdConnect' (eg. ASPNETCORE_ENVIRONMENT=OpenIdConnect). Runtime adds a 'Startup' prefix to this + /// and loads 'StartupOpenIdConnect'. + /// + /// If no environment name is specified the default startup class loaded is 'Startup'. + /// Alternative ways to specify environment are: + /// 1. Set the environment variable named SET ASPNETCORE_ENVIRONMENT=OpenIdConnect + /// 2. For selfhost based servers pass in a command line variable named --env with this value. Eg: + /// "commands": { + /// "web": "Microsoft.AspNetCore.Hosting --server Microsoft.AspNetCore.Server.WebListener + /// --server.urls http://localhost:5002 --ASPNET_ENV OpenIdConnect", + /// }, + /// + public class StartupOpenIdConnect + { + private readonly Platform _platform; + + public StartupOpenIdConnect(IHostingEnvironment hostingEnvironment) + { + // Below code demonstrates usage of multiple configuration sources. For instance a setting say 'setting1' + // is found in both the registered sources, then the later source will win. By this way a Local config can + // be overridden by a different setting while deployed remotely. + var builder = new ConfigurationBuilder() + .SetBasePath(hostingEnvironment.ContentRootPath) + .AddJsonFile("config.json") + //All environment variables in the process's context flow in as configuration values. + .AddEnvironmentVariables(); + + Configuration = builder.Build(); + _platform = new Platform(); + } + + public IConfiguration Configuration { get; private set; } + + public void ConfigureServices(IServiceCollection services) + { + services.Configure(Configuration.GetSection("AppSettings")); + + // Add EF services to the services container + if (_platform.UseInMemoryStore) + { + services.AddDbContext(options => + options.UseInMemoryDatabase("Scratch")); + } + else + { + services.AddDbContext(options => + options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); + } + + // Add Identity services to the services container + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", builder => + { + builder.WithOrigins("http://example.com"); + }); + }); + + // Add MVC services to the services container + services.AddMvc(); + + // Add memory cache services + services.AddMemoryCache(); + services.AddDistributedMemoryCache(); + + // Add session related services. + services.AddSession(); + + // Add the system clock service + services.AddSingleton(); + + // Configure Auth + services.AddAuthorization(options => + { + options.AddPolicy( + "ManageStore", + authBuilder => + { + authBuilder.RequireClaim("ManageStore", "Allowed"); + }); + }); + + // Create an Azure Active directory application and copy paste the following + services.AddAuthentication().AddOpenIdConnect(options => + { + options.Authority = "https://login.windows.net/[tenantName].onmicrosoft.com"; + options.ClientId = "[ClientId]"; + options.ResponseType = OpenIdConnectResponseType.CodeIdToken; + }); + } + + public void Configure(IApplicationBuilder app) + { + // force the en-US culture, so that the app behaves the same even on machines with different default culture + var supportedCultures = new[] { new CultureInfo("en-US") }; + + app.UseRequestLocalization(new RequestLocalizationOptions + { + DefaultRequestCulture = new RequestCulture("en-US"), + SupportedCultures = supportedCultures, + SupportedUICultures = supportedCultures + }); + + app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage"); + + // Display custom error page in production when error occurs + // During development use the ErrorPage middleware to display error information in the browser + app.UseDeveloperExceptionPage(); + + app.UseDatabaseErrorPage(); + + // Configure Session. + app.UseSession(); + + // Add static files to the request pipeline + app.UseStaticFiles(); + + // Add MVC to the request pipeline + app.UseMvc(routes => + { + routes.MapRoute( + name: "areaRoute", + template: "{area:exists}/{controller}/{action}", + defaults: new { action = "Index" }); + + routes.MapRoute( + name: "default", + template: "{controller}/{action}/{id?}", + defaults: new { controller = "Home", action = "Index" }); + + routes.MapRoute( + name: "api", + template: "{controller}/{id?}"); + }); + + //Populates the MusicStore sample data + SampleData.InitializeMusicStoreDatabaseAsync(app.ApplicationServices).Wait(); + } + } +} diff --git a/samples/MusicStore/ViewModels/AlbumData.cs b/samples/MusicStore/ViewModels/AlbumData.cs new file mode 100644 index 0000000..1f8ac24 --- /dev/null +++ b/samples/MusicStore/ViewModels/AlbumData.cs @@ -0,0 +1,9 @@ +namespace MusicStore.ViewModels +{ + public class AlbumData + { + public string Title { get; set; } + + public string Url { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/ViewModels/ShoppingCartRemoveViewModel.cs b/samples/MusicStore/ViewModels/ShoppingCartRemoveViewModel.cs new file mode 100644 index 0000000..5743b27 --- /dev/null +++ b/samples/MusicStore/ViewModels/ShoppingCartRemoveViewModel.cs @@ -0,0 +1,11 @@ +namespace MusicStore.ViewModels +{ + public class ShoppingCartRemoveViewModel + { + public string Message { get; set; } + public decimal CartTotal { get; set; } + public int CartCount { get; set; } + public int ItemCount { get; set; } + public int DeleteId { get; set; } + } +} \ No newline at end of file diff --git a/samples/MusicStore/ViewModels/ShoppingCartViewModel.cs b/samples/MusicStore/ViewModels/ShoppingCartViewModel.cs new file mode 100644 index 0000000..2aa641b --- /dev/null +++ b/samples/MusicStore/ViewModels/ShoppingCartViewModel.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using MusicStore.Models; + +namespace MusicStore.ViewModels +{ + public class ShoppingCartViewModel + { + public List CartItems { get; set; } + public decimal CartTotal { get; set; } + } +} diff --git a/samples/MusicStore/Views/Account/ConfirmEmail.cshtml b/samples/MusicStore/Views/Account/ConfirmEmail.cshtml new file mode 100644 index 0000000..d8822d5 --- /dev/null +++ b/samples/MusicStore/Views/Account/ConfirmEmail.cshtml @@ -0,0 +1,10 @@ +@{ + ViewBag.Title = "Confirm Email"; +} + +

@ViewBag.Title.

+
+

+ Thank you for confirming your email. Please Click here to Log in. +

+
\ No newline at end of file diff --git a/samples/MusicStore/Views/Account/ExternalLoginConfirmation.cshtml b/samples/MusicStore/Views/Account/ExternalLoginConfirmation.cshtml new file mode 100644 index 0000000..c3c1f85 --- /dev/null +++ b/samples/MusicStore/Views/Account/ExternalLoginConfirmation.cshtml @@ -0,0 +1,34 @@ +@model ExternalLoginConfirmationViewModel +@{ + ViewBag.Title = "Register"; +} +

@ViewBag.Title.

+

Associate your @ViewBag.LoginProvider account.

+ +
+

Association Form

+
+
+ +

+ You've successfully authenticated with @ViewBag.LoginProvider. + Please enter a user name for this site below and click the Register button to finish + logging in. +

+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Account/ExternalLoginFailure.cshtml b/samples/MusicStore/Views/Account/ExternalLoginFailure.cshtml new file mode 100644 index 0000000..cb96d08 --- /dev/null +++ b/samples/MusicStore/Views/Account/ExternalLoginFailure.cshtml @@ -0,0 +1,8 @@ +@{ + ViewBag.Title = "Login Failure"; +} + +
+

@ViewBag.Title.

+

Unsuccessful login with service.

+
\ No newline at end of file diff --git a/samples/MusicStore/Views/Account/ForgotPassword.cshtml b/samples/MusicStore/Views/Account/ForgotPassword.cshtml new file mode 100644 index 0000000..37a40e9 --- /dev/null +++ b/samples/MusicStore/Views/Account/ForgotPassword.cshtml @@ -0,0 +1,28 @@ +@model ForgotPasswordViewModel +@{ + ViewBag.Title = "Forgot your password?"; +} + +

@ViewBag.Title.

+ +
+

Enter your email.

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/samples/MusicStore/Views/Account/ForgotPasswordConfirmation.cshtml b/samples/MusicStore/Views/Account/ForgotPasswordConfirmation.cshtml new file mode 100644 index 0000000..80bb848 --- /dev/null +++ b/samples/MusicStore/Views/Account/ForgotPasswordConfirmation.cshtml @@ -0,0 +1,15 @@ +@{ + ViewBag.Title = "Forgot Password Confirmation"; +} + +
+

@ViewBag.Title.

+
+
+

+ Please check your email to reset your password. +

+

+ For demo purpose only: Click here to reset the password +

+
\ No newline at end of file diff --git a/samples/MusicStore/Views/Account/Login.cshtml b/samples/MusicStore/Views/Account/Login.cshtml new file mode 100644 index 0000000..3e195b3 --- /dev/null +++ b/samples/MusicStore/Views/Account/Login.cshtml @@ -0,0 +1,60 @@ +@model LoginViewModel + +@{ + ViewBag.Title = "Log in"; +} + +

@ViewBag.Title.

+
+
+
+
+

Use a local account to log in.

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
+ + +
+
+
+
+
+ +
+
+

+ Register as a new user? +

+

+ Forgot your password? +

+
+
+
+
+
+ @await Html.PartialAsync("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl }) +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Account/Register.cshtml b/samples/MusicStore/Views/Account/Register.cshtml new file mode 100644 index 0000000..9daa6d1 --- /dev/null +++ b/samples/MusicStore/Views/Account/Register.cshtml @@ -0,0 +1,42 @@ +@model RegisterViewModel +@{ + ViewBag.Title = "Register"; +} + +

@ViewBag.Title.

+ +
+

Create a new account.

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Account/RegisterConfirmation.cshtml b/samples/MusicStore/Views/Account/RegisterConfirmation.cshtml new file mode 100644 index 0000000..1317049 --- /dev/null +++ b/samples/MusicStore/Views/Account/RegisterConfirmation.cshtml @@ -0,0 +1,15 @@ +@{ + ViewBag.Title = "Register Confirmation"; +} + +
+

@ViewBag.Title.

+
+
+

+ Please check your email to activate your account. +

+

+ Demo/testing purposes only: The sample displays the code and user id in the page: Click here to confirm your email: +

+
\ No newline at end of file diff --git a/samples/MusicStore/Views/Account/ResetPassword.cshtml b/samples/MusicStore/Views/Account/ResetPassword.cshtml new file mode 100644 index 0000000..17198fc --- /dev/null +++ b/samples/MusicStore/Views/Account/ResetPassword.cshtml @@ -0,0 +1,43 @@ +@model ResetPasswordViewModel +@{ + ViewBag.Title = "Reset password"; +} + +

@ViewBag.Title.

+ +
+

Reset your password.

+
+
+ +
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Account/ResetPasswordConfirmation.cshtml b/samples/MusicStore/Views/Account/ResetPasswordConfirmation.cshtml new file mode 100644 index 0000000..0af2ecf --- /dev/null +++ b/samples/MusicStore/Views/Account/ResetPasswordConfirmation.cshtml @@ -0,0 +1,12 @@ +@{ + ViewBag.Title = "Reset password confirmation"; +} + +
+

@ViewBag.Title.

+
+
+

+ Your password has been reset. Please Click here to log in. +

+
\ No newline at end of file diff --git a/samples/MusicStore/Views/Account/SendCode.cshtml b/samples/MusicStore/Views/Account/SendCode.cshtml new file mode 100644 index 0000000..b16de72 --- /dev/null +++ b/samples/MusicStore/Views/Account/SendCode.cshtml @@ -0,0 +1,21 @@ +@model SendCodeViewModel +@{ + ViewBag.Title = "Send Verification Code"; +} + +

@ViewBag.Title.

+ +
+ +
+
+ Select Two-Factor Authentication Provider: + + +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/samples/MusicStore/Views/Account/VerifyCode.cshtml b/samples/MusicStore/Views/Account/VerifyCode.cshtml new file mode 100644 index 0000000..00676c7 --- /dev/null +++ b/samples/MusicStore/Views/Account/VerifyCode.cshtml @@ -0,0 +1,43 @@ +@model VerifyCodeViewModel +@{ + ViewBag.Title = "Verify"; +} + +

@ViewBag.Title.

+ +
+
+ + +

Enter verification code

+

+ For DEMO only: You can type in this code in the below text box to proceed: [ @ViewBag.Code ] +
+ Please change this code to register an SMS/Email service in IdentityConfig to send a message. +

+
+
+ +
+ + +
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Account/_ExternalLoginsListPartial.cshtml b/samples/MusicStore/Views/Account/_ExternalLoginsListPartial.cshtml new file mode 100644 index 0000000..56ebf81 --- /dev/null +++ b/samples/MusicStore/Views/Account/_ExternalLoginsListPartial.cshtml @@ -0,0 +1,31 @@ +@using Microsoft.AspNetCore.Authentication +@model ExternalLoginListViewModel +@inject IAuthenticationSchemeProvider SchemeProvider +

Use another service to log in.

+
+@{ + var schemes = await SchemeProvider.GetAllSchemesAsync(); + var loginProviders = schemes.ToList(); + if (!loginProviders.Any()) + { +
+

+ There are no external authentication services configured. See this article + for details on setting up this ASP.NET application to support logging in via external services. +

+
+ } + else + { +
+
+

+ @foreach (var p in loginProviders) + { + + } +

+
+
+ } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Checkout/AddressAndPayment.cshtml b/samples/MusicStore/Views/Checkout/AddressAndPayment.cshtml new file mode 100644 index 0000000..96c6fdf --- /dev/null +++ b/samples/MusicStore/Views/Checkout/AddressAndPayment.cshtml @@ -0,0 +1,33 @@ +@model Order + +@{ + ViewBag.Title = "Address And Payment"; +} + +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} + +
+

Address And Payment

+
+
+
+ Shipping Information + + @Html.EditorForModel() +
+
+ Payment +

We're running a promotion: all music is free with the promo code: "FREE"

+ +
+ +
+
+ @Html.TextBox("PromoCode") +
+
+ + +
\ No newline at end of file diff --git a/samples/MusicStore/Views/Checkout/Complete.cshtml b/samples/MusicStore/Views/Checkout/Complete.cshtml new file mode 100644 index 0000000..14b8db5 --- /dev/null +++ b/samples/MusicStore/Views/Checkout/Complete.cshtml @@ -0,0 +1,14 @@ +@model int + +@{ + ViewBag.Title = "Checkout Complete"; +} + +

Checkout Complete

+ +

Thanks for your order! Your order number is: @Model

+ +

+ How about shopping for some more music in our + Store +

\ No newline at end of file diff --git a/samples/MusicStore/Views/Home/Index.cshtml b/samples/MusicStore/Views/Home/Index.cshtml new file mode 100644 index 0000000..2216fbb --- /dev/null +++ b/samples/MusicStore/Views/Home/Index.cshtml @@ -0,0 +1,21 @@ +@inject IOptions AppSettings +@{ + ViewBag.Title = "Home Page"; +} + +
+

@AppSettings.Value.SiteTitle

+ +
+ + \ No newline at end of file diff --git a/samples/MusicStore/Views/Manage/AddPhoneNumber.cshtml b/samples/MusicStore/Views/Manage/AddPhoneNumber.cshtml new file mode 100644 index 0000000..b89b005 --- /dev/null +++ b/samples/MusicStore/Views/Manage/AddPhoneNumber.cshtml @@ -0,0 +1,27 @@ +@model AddPhoneNumberViewModel +@{ + ViewBag.Title = "Add Phone Number"; +} + +

@ViewBag.Title.

+
+

Add a phone number.

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Manage/ChangePassword.cshtml b/samples/MusicStore/Views/Manage/ChangePassword.cshtml new file mode 100644 index 0000000..527e9be --- /dev/null +++ b/samples/MusicStore/Views/Manage/ChangePassword.cshtml @@ -0,0 +1,42 @@ +@model ChangePasswordViewModel +@{ + ViewBag.Title = "Change Password"; +} + +

@ViewBag.Title.

+ +
+

Change Password Form

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} diff --git a/samples/MusicStore/Views/Manage/Index.cshtml b/samples/MusicStore/Views/Manage/Index.cshtml new file mode 100644 index 0000000..79a2d97 --- /dev/null +++ b/samples/MusicStore/Views/Manage/Index.cshtml @@ -0,0 +1,70 @@ +@model IndexViewModel +@{ + ViewData["Title"] = "Manage your account"; +} + +

@ViewData["Title"].

+

@ViewData["StatusMessage"]

+ +
+

Change your account settings

+
+
+
Password:
+
+ @if (Model.HasPassword) + { + [  Change  ] + } + else + { + [  Create  ] + } +
+
External Logins:
+
+ @Model.Logins.Count [  Manage  ] +
+
Phone Number:
+
+

+ Phone Numbers can used as a second factor of verification in two-factor authentication. + See this article + for details on setting up this ASP.NET application to support two-factor authentication using SMS. +

+ @*@(Model.PhoneNumber ?? "None") + @if (Model.PhoneNumber != null) + { +
+ [  Change  ] +
+ [] +
+ } + else + { + [  Add  ] + }*@ +
+ +
Two-Factor Authentication:
+
+

+ There are no two-factor authentication providers configured. See this article + for setting up this application to support two-factor authentication. +

+ @*@if (Model.TwoFactor) + { +
+ Enabled [] +
+ } + else + { +
+ [] Disabled +
+ }*@ +
+
+
\ No newline at end of file diff --git a/samples/MusicStore/Views/Manage/ManageLogins.cshtml b/samples/MusicStore/Views/Manage/ManageLogins.cshtml new file mode 100644 index 0000000..d4d2625 --- /dev/null +++ b/samples/MusicStore/Views/Manage/ManageLogins.cshtml @@ -0,0 +1,53 @@ +@model ManageLoginsViewModel +@{ + ViewBag.Title = "Manage your external logins"; +} + +

@ViewBag.Title.

+ +

@ViewBag.StatusMessage

+@if (Model.CurrentLogins.Count > 0) +{ +

Registered Logins

+ + + @foreach (var account in Model.CurrentLogins) + { + + + + + } + +
@account.LoginProvider + @if (ViewBag.ShowRemoveButton) + { +
+
+ + + +
+
+ } + else + { + @:   + } +
+} +@if (Model.OtherLogins.Any()) +{ +

Add another service to log in.

+
+
+
+

+ @foreach (var p in Model.OtherLogins) + { + + } +

+
+
+} \ No newline at end of file diff --git a/samples/MusicStore/Views/Manage/SetPassword.cshtml b/samples/MusicStore/Views/Manage/SetPassword.cshtml new file mode 100644 index 0000000..55face2 --- /dev/null +++ b/samples/MusicStore/Views/Manage/SetPassword.cshtml @@ -0,0 +1,38 @@ +@model SetPasswordViewModel +@{ + ViewBag.Title = "Set Password"; +} + +

+ You do not have a local username/password for this site. Add a local + account so you can log in without an external login. +

+ +
+

Set your password

+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Manage/VerifyPhoneNumber.cshtml b/samples/MusicStore/Views/Manage/VerifyPhoneNumber.cshtml new file mode 100644 index 0000000..55d0625 --- /dev/null +++ b/samples/MusicStore/Views/Manage/VerifyPhoneNumber.cshtml @@ -0,0 +1,34 @@ +@model VerifyPhoneNumberViewModel +@{ + ViewBag.Title = "Verify Phone Number"; +} + +

@ViewBag.Title.

+ +
+ +

Enter verification code

+

+ For DEMO only: You can type in this code in the below text box to proceed: @ViewBag.Code +
+ Please change this code to register an SMS service in IdentityConfig to send a text message. +

+
+
+
+ +
+ + +
+
+
+
+ +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/AccessDenied.cshtml b/samples/MusicStore/Views/Shared/AccessDenied.cshtml new file mode 100644 index 0000000..27ca49c --- /dev/null +++ b/samples/MusicStore/Views/Shared/AccessDenied.cshtml @@ -0,0 +1,5 @@ +@{ + ViewBag.Title = "Access denied due to insufficient permissions"; +} + +

Access denied due to insufficient permissions.

\ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/Components/Announcement/Default.cshtml b/samples/MusicStore/Views/Shared/Components/Announcement/Default.cshtml new file mode 100644 index 0000000..52e11e3 --- /dev/null +++ b/samples/MusicStore/Views/Shared/Components/Announcement/Default.cshtml @@ -0,0 +1,10 @@ +@model Album + +@if (Model != null) +{ +
  • +
    + + @Model.Title +
  • +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/Components/CartSummary/Default.cshtml b/samples/MusicStore/Views/Shared/Components/CartSummary/Default.cshtml new file mode 100644 index 0000000..9e9dd03 --- /dev/null +++ b/samples/MusicStore/Views/Shared/Components/CartSummary/Default.cshtml @@ -0,0 +1,11 @@ +@if (ViewBag.CartCount > 0) +{ +
  • + + + + @ViewBag.CartCount + + +
  • +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/Components/GenreMenu/Default.cshtml b/samples/MusicStore/Views/Shared/Components/GenreMenu/Default.cshtml new file mode 100644 index 0000000..2acd0ae --- /dev/null +++ b/samples/MusicStore/Views/Shared/Components/GenreMenu/Default.cshtml @@ -0,0 +1,17 @@ +@model IEnumerable + + diff --git a/samples/MusicStore/Views/Shared/DemoLinkDisplay.cshtml b/samples/MusicStore/Views/Shared/DemoLinkDisplay.cshtml new file mode 100644 index 0000000..d4ff51b --- /dev/null +++ b/samples/MusicStore/Views/Shared/DemoLinkDisplay.cshtml @@ -0,0 +1,21 @@ +@{ + ViewBag.Title = "Demo link display page - Not for production use"; +} + +
    +

    @ViewBag.Title.

    +
    +
    +

    + Demo link display page - Not for production use. +

    + + @if (ViewBag.Link != null) + { +

    + For DEMO only: You can click this link to confirm the email: [[link]] +
    + Please change this code to register an email service in IdentityConfig to send an email. +

    + } +
    \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/Error.cshtml b/samples/MusicStore/Views/Shared/Error.cshtml new file mode 100644 index 0000000..dd26209 --- /dev/null +++ b/samples/MusicStore/Views/Shared/Error.cshtml @@ -0,0 +1,6 @@ +@{ + ViewBag.Title = "Error"; +} + +

    Error.

    +

    An error occurred while processing your request.

    \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/Lockout.cshtml b/samples/MusicStore/Views/Shared/Lockout.cshtml new file mode 100644 index 0000000..aff107a --- /dev/null +++ b/samples/MusicStore/Views/Shared/Lockout.cshtml @@ -0,0 +1,8 @@ +@{ + ViewBag.Title = "Locked Out"; +} + +
    +

    Locked out.

    +

    This account has been locked out, please try again later.

    +
    \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/StatusCodePage.cshtml b/samples/MusicStore/Views/Shared/StatusCodePage.cshtml new file mode 100644 index 0000000..53dff87 --- /dev/null +++ b/samples/MusicStore/Views/Shared/StatusCodePage.cshtml @@ -0,0 +1,6 @@ +@{ + ViewBag.Title = "Item not found"; +} + +

    Item not found.

    +

    Unable to find the item you are searching for. Please try again.

    \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/_Layout.cshtml b/samples/MusicStore/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000..d2009c0 --- /dev/null +++ b/samples/MusicStore/Views/Shared/_Layout.cshtml @@ -0,0 +1,74 @@ +@inject IOptions AppSettings + + + + + + @ViewBag.Title – @AppSettings.Value.SiteTitle + + + + + + + + + + + + + + + + + + +
    + @RenderBody() +
    + +
    + + + + + + + + + + + @RenderSection("scripts", required: false) + + \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/_LoginPartial.cshtml b/samples/MusicStore/Views/Shared/_LoginPartial.cshtml new file mode 100644 index 0000000..2595492 --- /dev/null +++ b/samples/MusicStore/Views/Shared/_LoginPartial.cshtml @@ -0,0 +1,33 @@ +@using Microsoft.AspNetCore.Identity +@using MusicStore.Models + +@inject SignInManager SignInManager +@inject UserManager UserManager + +@if (SignInManager.IsSignedIn(User)) +{ + +} +else if (User.Identity.IsAuthenticated) +{ + //This code block necessary only for NTLM authentication + +} +else +{ + +} \ No newline at end of file diff --git a/samples/MusicStore/Views/Shared/_ValidationScriptsPartial.cshtml b/samples/MusicStore/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000..abfa56e --- /dev/null +++ b/samples/MusicStore/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,14 @@ + + + + + + + + \ No newline at end of file diff --git a/samples/MusicStore/Views/ShoppingCart/Index.cshtml b/samples/MusicStore/Views/ShoppingCart/Index.cshtml new file mode 100644 index 0000000..4928fff --- /dev/null +++ b/samples/MusicStore/Views/ShoppingCart/Index.cshtml @@ -0,0 +1,106 @@ +@model MusicStore.ViewModels.ShoppingCartViewModel +@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf +@{ + ViewBag.Title = "Shopping Cart"; +} + +@functions +{ + public string GetAntiXsrfRequestToken() + { + return Xsrf.GetAndStoreTokens(Context).RequestToken; + } +} + +@section Scripts { + +} + +

    + Review your cart: +

    +

    + Checkout >> +

    +
    +
    + + + + + + + + @foreach (var item in Model.CartItems) + { + + + + + + + } + + + + + + +
    + Album Name + + Price (each) + + Quantity +
    + @item.Album.Title + + @item.Album.Price + + @item.Count + + + Remove from cart + +
    + Total + + @Model.CartTotal +
    \ No newline at end of file diff --git a/samples/MusicStore/Views/Store/Browse.cshtml b/samples/MusicStore/Views/Store/Browse.cshtml new file mode 100644 index 0000000..9b015e7 --- /dev/null +++ b/samples/MusicStore/Views/Store/Browse.cshtml @@ -0,0 +1,24 @@ +@model Genre +@{ + ViewBag.Title = "Browse Albums"; +} +
    +

    + @Model.Name Albums +

    + + +
    \ No newline at end of file diff --git a/samples/MusicStore/Views/Store/Details.cshtml b/samples/MusicStore/Views/Store/Details.cshtml new file mode 100644 index 0000000..cdcab0c --- /dev/null +++ b/samples/MusicStore/Views/Store/Details.cshtml @@ -0,0 +1,29 @@ +@model Album + +@{ + ViewBag.Title = "Album - " + Model.Title; +} + +

    @Model.Title

    + +

    + @Model.Title +

    + +
    +

    + Genre: + @Model.Genre.Name +

    +

    + Artist: + @Model.Artist.Name +

    +

    + Price: + +

    +

    + Add to cart +

    +
    \ No newline at end of file diff --git a/samples/MusicStore/Views/Store/Index.cshtml b/samples/MusicStore/Views/Store/Index.cshtml new file mode 100644 index 0000000..3a40308 --- /dev/null +++ b/samples/MusicStore/Views/Store/Index.cshtml @@ -0,0 +1,15 @@ +@model IEnumerable +@{ + ViewBag.Title = "Store"; +} +

    Browse Genres

    + +

    + Select from @Model.Count() genres: +

    +
      + @foreach (var genre in Model) + { +
    • @genre.Name
    • + } +
    \ No newline at end of file diff --git a/samples/MusicStore/Views/_ViewImports.cshtml b/samples/MusicStore/Views/_ViewImports.cshtml new file mode 100644 index 0000000..fa2866b --- /dev/null +++ b/samples/MusicStore/Views/_ViewImports.cshtml @@ -0,0 +1,5 @@ +@using MusicStore +@using MusicStore.Models +@using Microsoft.Extensions.Options +@using Microsoft.AspNetCore.Identity +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/samples/MusicStore/Views/_ViewStart.cshtml b/samples/MusicStore/Views/_ViewStart.cshtml new file mode 100644 index 0000000..ab23e9a --- /dev/null +++ b/samples/MusicStore/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "/Views/Shared/_Layout.cshtml"; +} \ No newline at end of file diff --git a/samples/MusicStore/config.json b/samples/MusicStore/config.json new file mode 100644 index 0000000..6c33b8a --- /dev/null +++ b/samples/MusicStore/config.json @@ -0,0 +1,15 @@ +{ + "AppSettings": { + "SiteTitle": "ASP.NET MVC Music Store", + "CacheDbResults": true + }, + "DefaultAdminUsername": "Administrator@test.com", + "DefaultAdminPassword": "YouShouldChangeThisPassword1!", + "Data": { + "DefaultConnection": { + // Use a shared (and running) LocalDB database when executing in IIS e.g. + // "Server=(localdb)\\.\\IIS_DB;Database=MusicStore;Trusted_Connection=False;MultipleActiveResultSets=true;User ID=iis_login;Password=********" + "ConnectionString": "Server=(localdb)\\MSSQLLocalDB;Database=MusicStore;Trusted_Connection=True;MultipleActiveResultSets=true;Connect Timeout=30;" + } + } +} \ No newline at end of file diff --git a/samples/MusicStore/wwwroot/Content/Site.css b/samples/MusicStore/wwwroot/Content/Site.css new file mode 100644 index 0000000..23c0d16 --- /dev/null +++ b/samples/MusicStore/wwwroot/Content/Site.css @@ -0,0 +1,70 @@ +body { + padding-top: 50px; + padding-bottom: 20px; +} + +/* Set padding to keep content from hitting the edges */ +.body-content { + padding-left: 15px; + padding-right: 15px; +} + +/* Set width on the form input elements since they're 100% wide by default */ +input, +select, +textarea { + max-width: 280px; +} + +/* styles for validation helpers */ +.field-validation-error { + color: #b94a48; +} + +.field-validation-valid { + display: none; +} + +input.input-validation-error { + border: 1px solid #b94a48; +} + +input[type="checkbox"].input-validation-error { + border: 0 none; +} + +.validation-summary-errors { + color: #b94a48; +} + +.validation-summary-valid { + display: none; +} + + +/* Music Store additions */ + +ul#album-list li { + height: 160px; +} + +ul#album-list li img:hover { + box-shadow: 1px 1px 7px #777; +} + +ul#album-list li img { + box-shadow: 1px 1px 5px #999; + border: none; + padding: 0; +} + +ul#album-list li a, ul#album-details li a { + text-decoration:none; +} + +ul#album-list li a:hover { + background: none; + -webkit-text-shadow: 1px 1px 2px #bbb; + text-shadow: 1px 1px 2px #bbb; + color: #363430; +} \ No newline at end of file diff --git a/samples/MusicStore/wwwroot/Content/bootstrap.css b/samples/MusicStore/wwwroot/Content/bootstrap.css new file mode 100644 index 0000000..6d6e682 --- /dev/null +++ b/samples/MusicStore/wwwroot/Content/bootstrap.css @@ -0,0 +1,6816 @@ +/* NUGET: BEGIN LICENSE TEXT + * + * Microsoft grants you the right to use these script files for the sole + * purpose of either: (i) interacting through your browser with the Microsoft + * website or online service, subject to the applicable licensing or use + * terms; or (ii) using the files as included with a Microsoft product subject + * to that product's license terms. Microsoft reserves all other rights to the + * files not expressly granted by Microsoft, whether by implication, estoppel + * or otherwise. The notices and licenses below are for informational purposes only. + * + * NUGET: END LICENSE TEXT */ +/*! + * Bootstrap v3.0.0 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world by @mdo and @fat. + */ + +/*! normalize.css v2.1.0 | MIT License | git.io/normalize */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +audio, +canvas, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +[hidden] { + display: none; +} + +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + margin: 0; +} + +a:focus { + outline: thin dotted; +} + +a:active, +a:hover { + outline: 0; +} + +h1 { + margin: 0.67em 0; + font-size: 2em; +} + +abbr[title] { + border-bottom: 1px dotted; +} + +b, +strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +hr { + height: 0; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +mark { + color: #000; + background: #ff0; +} + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +pre { + white-space: pre-wrap; +} + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + border: 0; +} + +svg:not(:root) { + overflow: hidden; +} + +figure { + margin: 0; +} + +fieldset { + padding: 0.35em 0.625em 0.75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} + +legend { + padding: 0; + border: 0; +} + +button, +input, +select, +textarea { + margin: 0; + font-family: inherit; + font-size: 100%; +} + +button, +input { + line-height: normal; +} + +button, +select { + text-transform: none; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +button[disabled], +html input[disabled] { + cursor: default; +} + +input[type="checkbox"], +input[type="radio"] { + padding: 0; + box-sizing: border-box; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 2cm .5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .table td, + .table th { + background-color: #fff !important; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} + +*, +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +html { + font-size: 62.5%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.428571429; + color: #333333; + background-color: #ffffff; +} + +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input, +select[multiple], +textarea { + background-image: none; +} + +a { + color: #428bca; + text-decoration: none; +} + +a:hover, +a:focus { + color: #2a6496; + text-decoration: underline; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +img { + vertical-align: middle; +} + +.img-responsive { + display: block; + height: auto; + max-width: 100%; +} + +.img-rounded { + border-radius: 6px; +} + +.img-thumbnail { + display: inline-block; + height: auto; + max-width: 100%; + padding: 4px; + line-height: 1.428571429; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +.img-circle { + border-radius: 50%; +} + +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eeeeee; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0 0 0 0); + border: 0; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 16.099999999999998px; + font-weight: 200; + line-height: 1.4; +} + +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} + +small { + font-size: 85%; +} + +cite { + font-style: normal; +} + +.text-muted { + color: #999999; +} + +.text-primary { + color: #428bca; +} + +.text-warning { + color: #c09853; +} + +.text-danger { + color: #b94a48; +} + +.text-success { + color: #468847; +} + +.text-info { + color: #3a87ad; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 500; + line-height: 1.1; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + margin-top: 20px; + margin-bottom: 10px; +} + +h4, +h5, +h6 { + margin-top: 10px; + margin-bottom: 10px; +} + +h1, +.h1 { + font-size: 36px; +} + +h2, +.h2 { + font-size: 30px; +} + +h3, +.h3 { + font-size: 24px; +} + +h4, +.h4 { + font-size: 18px; +} + +h5, +.h5 { + font-size: 14px; +} + +h6, +.h6 { + font-size: 12px; +} + +h1 small, +.h1 small { + font-size: 24px; +} + +h2 small, +.h2 small { + font-size: 18px; +} + +h3 small, +.h3 small, +h4 small, +.h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} + +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 1.428571429; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 0; +} + +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } + .dl-horizontal dd:before, + .dl-horizontal dd:after { + display: table; + content: " "; + } + .dl-horizontal dd:after { + clear: both; + } + .dl-horizontal dd:before, + .dl-horizontal dd:after { + display: table; + content: " "; + } + .dl-horizontal dd:after { + clear: both; + } +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote p:last-child { + margin-bottom: 0; +} + +blockquote small { + display: block; + line-height: 1.428571429; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 1.428571429; +} + +code, +pre { + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; +} + +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + white-space: nowrap; + background-color: #f9f2f4; + border-radius: 4px; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.428571429; + color: #333333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #cccccc; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.container:before, +.container:after { + display: table; + content: " "; +} + +.container:after { + clear: both; +} + +.container:before, +.container:after { + display: table; + content: " "; +} + +.container:after { + clear: both; +} + +.row { + margin-right: -15px; + margin-left: -15px; +} + +.row:before, +.row:after { + display: table; + content: " "; +} + +.row:after { + clear: both; +} + +.row:before, +.row:after { + display: table; + content: " "; +} + +.row:after { + clear: both; +} + +.col-xs-1, +.col-xs-2, +.col-xs-3, +.col-xs-4, +.col-xs-5, +.col-xs-6, +.col-xs-7, +.col-xs-8, +.col-xs-9, +.col-xs-10, +.col-xs-11, +.col-xs-12, +.col-sm-1, +.col-sm-2, +.col-sm-3, +.col-sm-4, +.col-sm-5, +.col-sm-6, +.col-sm-7, +.col-sm-8, +.col-sm-9, +.col-sm-10, +.col-sm-11, +.col-sm-12, +.col-md-1, +.col-md-2, +.col-md-3, +.col-md-4, +.col-md-5, +.col-md-6, +.col-md-7, +.col-md-8, +.col-md-9, +.col-md-10, +.col-md-11, +.col-md-12, +.col-lg-1, +.col-lg-2, +.col-lg-3, +.col-lg-4, +.col-lg-5, +.col-lg-6, +.col-lg-7, +.col-lg-8, +.col-lg-9, +.col-lg-10, +.col-lg-11, +.col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} + +.col-xs-1, +.col-xs-2, +.col-xs-3, +.col-xs-4, +.col-xs-5, +.col-xs-6, +.col-xs-7, +.col-xs-8, +.col-xs-9, +.col-xs-10, +.col-xs-11 { + float: left; +} + +.col-xs-1 { + width: 8.333333333333332%; +} + +.col-xs-2 { + width: 16.666666666666664%; +} + +.col-xs-3 { + width: 25%; +} + +.col-xs-4 { + width: 33.33333333333333%; +} + +.col-xs-5 { + width: 41.66666666666667%; +} + +.col-xs-6 { + width: 50%; +} + +.col-xs-7 { + width: 58.333333333333336%; +} + +.col-xs-8 { + width: 66.66666666666666%; +} + +.col-xs-9 { + width: 75%; +} + +.col-xs-10 { + width: 83.33333333333334%; +} + +.col-xs-11 { + width: 91.66666666666666%; +} + +.col-xs-12 { + width: 100%; +} + +@media (min-width: 768px) { + .container { + max-width: 750px; + } + .col-sm-1, + .col-sm-2, + .col-sm-3, + .col-sm-4, + .col-sm-5, + .col-sm-6, + .col-sm-7, + .col-sm-8, + .col-sm-9, + .col-sm-10, + .col-sm-11 { + float: left; + } + .col-sm-1 { + width: 8.333333333333332%; + } + .col-sm-2 { + width: 16.666666666666664%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-4 { + width: 33.33333333333333%; + } + .col-sm-5 { + width: 41.66666666666667%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-7 { + width: 58.333333333333336%; + } + .col-sm-8 { + width: 66.66666666666666%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-10 { + width: 83.33333333333334%; + } + .col-sm-11 { + width: 91.66666666666666%; + } + .col-sm-12 { + width: 100%; + } + .col-sm-push-1 { + left: 8.333333333333332%; + } + .col-sm-push-2 { + left: 16.666666666666664%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-4 { + left: 33.33333333333333%; + } + .col-sm-push-5 { + left: 41.66666666666667%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-7 { + left: 58.333333333333336%; + } + .col-sm-push-8 { + left: 66.66666666666666%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-10 { + left: 83.33333333333334%; + } + .col-sm-push-11 { + left: 91.66666666666666%; + } + .col-sm-pull-1 { + right: 8.333333333333332%; + } + .col-sm-pull-2 { + right: 16.666666666666664%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-4 { + right: 33.33333333333333%; + } + .col-sm-pull-5 { + right: 41.66666666666667%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-7 { + right: 58.333333333333336%; + } + .col-sm-pull-8 { + right: 66.66666666666666%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-10 { + right: 83.33333333333334%; + } + .col-sm-pull-11 { + right: 91.66666666666666%; + } + .col-sm-offset-1 { + margin-left: 8.333333333333332%; + } + .col-sm-offset-2 { + margin-left: 16.666666666666664%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-4 { + margin-left: 33.33333333333333%; + } + .col-sm-offset-5 { + margin-left: 41.66666666666667%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-7 { + margin-left: 58.333333333333336%; + } + .col-sm-offset-8 { + margin-left: 66.66666666666666%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-10 { + margin-left: 83.33333333333334%; + } + .col-sm-offset-11 { + margin-left: 91.66666666666666%; + } +} + +@media (min-width: 992px) { + .container { + max-width: 970px; + } + .col-md-1, + .col-md-2, + .col-md-3, + .col-md-4, + .col-md-5, + .col-md-6, + .col-md-7, + .col-md-8, + .col-md-9, + .col-md-10, + .col-md-11 { + float: left; + } + .col-md-1 { + width: 8.333333333333332%; + } + .col-md-2 { + width: 16.666666666666664%; + } + .col-md-3 { + width: 25%; + } + .col-md-4 { + width: 33.33333333333333%; + } + .col-md-5 { + width: 41.66666666666667%; + } + .col-md-6 { + width: 50%; + } + .col-md-7 { + width: 58.333333333333336%; + } + .col-md-8 { + width: 66.66666666666666%; + } + .col-md-9 { + width: 75%; + } + .col-md-10 { + width: 83.33333333333334%; + } + .col-md-11 { + width: 91.66666666666666%; + } + .col-md-12 { + width: 100%; + } + .col-md-push-0 { + left: auto; + } + .col-md-push-1 { + left: 8.333333333333332%; + } + .col-md-push-2 { + left: 16.666666666666664%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-4 { + left: 33.33333333333333%; + } + .col-md-push-5 { + left: 41.66666666666667%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-7 { + left: 58.333333333333336%; + } + .col-md-push-8 { + left: 66.66666666666666%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-10 { + left: 83.33333333333334%; + } + .col-md-push-11 { + left: 91.66666666666666%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-pull-1 { + right: 8.333333333333332%; + } + .col-md-pull-2 { + right: 16.666666666666664%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-4 { + right: 33.33333333333333%; + } + .col-md-pull-5 { + right: 41.66666666666667%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-7 { + right: 58.333333333333336%; + } + .col-md-pull-8 { + right: 66.66666666666666%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-10 { + right: 83.33333333333334%; + } + .col-md-pull-11 { + right: 91.66666666666666%; + } + .col-md-offset-0 { + margin-left: 0; + } + .col-md-offset-1 { + margin-left: 8.333333333333332%; + } + .col-md-offset-2 { + margin-left: 16.666666666666664%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-4 { + margin-left: 33.33333333333333%; + } + .col-md-offset-5 { + margin-left: 41.66666666666667%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-7 { + margin-left: 58.333333333333336%; + } + .col-md-offset-8 { + margin-left: 66.66666666666666%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-10 { + margin-left: 83.33333333333334%; + } + .col-md-offset-11 { + margin-left: 91.66666666666666%; + } +} + +@media (min-width: 1200px) { + .container { + max-width: 1170px; + } + .col-lg-1, + .col-lg-2, + .col-lg-3, + .col-lg-4, + .col-lg-5, + .col-lg-6, + .col-lg-7, + .col-lg-8, + .col-lg-9, + .col-lg-10, + .col-lg-11 { + float: left; + } + .col-lg-1 { + width: 8.333333333333332%; + } + .col-lg-2 { + width: 16.666666666666664%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-4 { + width: 33.33333333333333%; + } + .col-lg-5 { + width: 41.66666666666667%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-7 { + width: 58.333333333333336%; + } + .col-lg-8 { + width: 66.66666666666666%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-10 { + width: 83.33333333333334%; + } + .col-lg-11 { + width: 91.66666666666666%; + } + .col-lg-12 { + width: 100%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-push-1 { + left: 8.333333333333332%; + } + .col-lg-push-2 { + left: 16.666666666666664%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-4 { + left: 33.33333333333333%; + } + .col-lg-push-5 { + left: 41.66666666666667%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-7 { + left: 58.333333333333336%; + } + .col-lg-push-8 { + left: 66.66666666666666%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-10 { + left: 83.33333333333334%; + } + .col-lg-push-11 { + left: 91.66666666666666%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-pull-1 { + right: 8.333333333333332%; + } + .col-lg-pull-2 { + right: 16.666666666666664%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-4 { + right: 33.33333333333333%; + } + .col-lg-pull-5 { + right: 41.66666666666667%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-7 { + right: 58.333333333333336%; + } + .col-lg-pull-8 { + right: 66.66666666666666%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-10 { + right: 83.33333333333334%; + } + .col-lg-pull-11 { + right: 91.66666666666666%; + } + .col-lg-offset-0 { + margin-left: 0; + } + .col-lg-offset-1 { + margin-left: 8.333333333333332%; + } + .col-lg-offset-2 { + margin-left: 16.666666666666664%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-4 { + margin-left: 33.33333333333333%; + } + .col-lg-offset-5 { + margin-left: 41.66666666666667%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-7 { + margin-left: 58.333333333333336%; + } + .col-lg-offset-8 { + margin-left: 66.66666666666666%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-10 { + margin-left: 83.33333333333334%; + } + .col-lg-offset-11 { + margin-left: 91.66666666666666%; + } +} + +table { + max-width: 100%; + background-color: transparent; +} + +th { + text-align: left; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table thead > tr > th, +.table tbody > tr > th, +.table tfoot > tr > th, +.table thead > tr > td, +.table tbody > tr > td, +.table tfoot > tr > td { + padding: 8px; + line-height: 1.428571429; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #dddddd; +} + +.table caption + thead tr:first-child th, +.table colgroup + thead tr:first-child th, +.table thead:first-child tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.table-condensed thead > tr > th, +.table-condensed tbody > tr > th, +.table-condensed tfoot > tr > th, +.table-condensed thead > tr > td, +.table-condensed tbody > tr > td, +.table-condensed tfoot > tr > td { + padding: 5px; +} + +.table-bordered { + border: 1px solid #dddddd; +} + +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #dddddd; +} + +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} + +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} + +table col[class*="col-"] { + display: table-column; + float: none; +} + +table td[class*="col-"], +table th[class*="col-"] { + display: table-cell; + float: none; +} + +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} + +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td { + background-color: #d0e9c6; + border-color: #c9e2b3; +} + +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; + border-color: #eed3d7; +} + +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td { + background-color: #ebcccc; + border-color: #e6c1c7; +} + +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; + border-color: #fbeed5; +} + +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td { + background-color: #faf2cc; + border-color: #f8e5be; +} + +@media (max-width: 768px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + border: 1px solid #dddddd; + } + .table-responsive > .table { + margin-bottom: 0; + background-color: #fff; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > thead > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > thead > tr:last-child > td, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +label { + display: inline-block; + margin-bottom: 5px; + font-weight: bold; +} + +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + /* IE8-9 */ + + line-height: normal; +} + +input[type="file"] { + display: block; +} + +select[multiple], +select[size] { + height: auto; +} + +select optgroup { + font-family: inherit; + font-size: inherit; + font-style: inherit; +} + +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +input[type="number"]::-webkit-outer-spin-button, +input[type="number"]::-webkit-inner-spin-button { + height: auto; +} + +.form-control:-moz-placeholder { + color: #999999; +} + +.form-control::-moz-placeholder { + color: #999999; +} + +.form-control:-ms-input-placeholder { + color: #999999; +} + +.form-control::-webkit-input-placeholder { + color: #999999; +} + +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.428571429; + color: #555555; + vertical-align: middle; + background-color: #ffffff; + border: 1px solid #cccccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} + +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eeeeee; +} + +textarea.form-control { + height: auto; +} + +.form-group { + margin-bottom: 15px; +} + +.radio, +.checkbox { + display: block; + min-height: 20px; + padding-left: 20px; + margin-top: 10px; + margin-bottom: 10px; + vertical-align: middle; +} + +.radio label, +.checkbox label { + display: inline; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} + +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} + +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +.radio[disabled], +.radio-inline[disabled], +.checkbox[disabled], +.checkbox-inline[disabled], +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"], +fieldset[disabled] .radio, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} + +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +select.input-sm { + height: 30px; + line-height: 30px; +} + +textarea.input-sm { + height: auto; +} + +.input-lg { + height: 45px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +select.input-lg { + height: 45px; + line-height: 45px; +} + +textarea.input-lg { + height: auto; +} + +.has-warning .help-block, +.has-warning .control-label { + color: #c09853; +} + +.has-warning .form-control { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.has-warning .form-control:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.has-warning .input-group-addon { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.has-error .help-block, +.has-error .control-label { + color: #b94a48; +} + +.has-error .form-control { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.has-error .form-control:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.has-error .input-group-addon { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.has-success .help-block, +.has-success .control-label { + color: #468847; +} + +.has-success .form-control { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.has-success .form-control:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.has-success .input-group-addon { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.form-control-static { + padding-top: 7px; + margin-bottom: 0; +} + +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} + +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } +} + +.form-horizontal .control-label, +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} + +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} + +.form-horizontal .form-group:before, +.form-horizontal .form-group:after { + display: table; + content: " "; +} + +.form-horizontal .form-group:after { + clear: both; +} + +.form-horizontal .form-group:before, +.form-horizontal .form-group:after { + display: table; + content: " "; +} + +.form-horizontal .form-group:after { + clear: both; +} + +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + } +} + +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.428571429; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + border: 1px solid transparent; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; +} + +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} + +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-default { + color: #333333; + background-color: #ffffff; + border-color: #cccccc; +} + +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + color: #333333; + background-color: #ebebeb; + border-color: #adadad; +} + +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + background-image: none; +} + +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #ffffff; + border-color: #cccccc; +} + +.btn-primary { + color: #ffffff; + background-color: #428bca; + border-color: #357ebd; +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + color: #ffffff; + background-color: #3276b1; + border-color: #285e8e; +} + +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + background-image: none; +} + +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #428bca; + border-color: #357ebd; +} + +.btn-warning { + color: #ffffff; + background-color: #f0ad4e; + border-color: #eea236; +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + color: #ffffff; + background-color: #ed9c28; + border-color: #d58512; +} + +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + background-image: none; +} + +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} + +.btn-danger { + color: #ffffff; + background-color: #d9534f; + border-color: #d43f3a; +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + color: #ffffff; + background-color: #d2322d; + border-color: #ac2925; +} + +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + background-image: none; +} + +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} + +.btn-success { + color: #ffffff; + background-color: #5cb85c; + border-color: #4cae4c; +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + color: #ffffff; + background-color: #47a447; + border-color: #398439; +} + +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + background-image: none; +} + +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} + +.btn-info { + color: #ffffff; + background-color: #5bc0de; + border-color: #46b8da; +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + color: #ffffff; + background-color: #39b3d7; + border-color: #269abc; +} + +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + background-image: none; +} + +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} + +.btn-link { + font-weight: normal; + color: #428bca; + cursor: pointer; + border-radius: 0; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} + +.btn-link:hover, +.btn-link:focus { + color: #2a6496; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #999999; + text-decoration: none; +} + +.btn-lg { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +.btn-sm, +.btn-xs { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-xs { + padding: 1px 5px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + display: none; +} + +.collapse.in { + display: block; +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); +} + +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; +} + +.glyphicon-asterisk:before { + content: "\2a"; +} + +.glyphicon-plus:before { + content: "\2b"; +} + +.glyphicon-euro:before { + content: "\20ac"; +} + +.glyphicon-minus:before { + content: "\2212"; +} + +.glyphicon-cloud:before { + content: "\2601"; +} + +.glyphicon-envelope:before { + content: "\2709"; +} + +.glyphicon-pencil:before { + content: "\270f"; +} + +.glyphicon-glass:before { + content: "\e001"; +} + +.glyphicon-music:before { + content: "\e002"; +} + +.glyphicon-search:before { + content: "\e003"; +} + +.glyphicon-heart:before { + content: "\e005"; +} + +.glyphicon-star:before { + content: "\e006"; +} + +.glyphicon-star-empty:before { + content: "\e007"; +} + +.glyphicon-user:before { + content: "\e008"; +} + +.glyphicon-film:before { + content: "\e009"; +} + +.glyphicon-th-large:before { + content: "\e010"; +} + +.glyphicon-th:before { + content: "\e011"; +} + +.glyphicon-th-list:before { + content: "\e012"; +} + +.glyphicon-ok:before { + content: "\e013"; +} + +.glyphicon-remove:before { + content: "\e014"; +} + +.glyphicon-zoom-in:before { + content: "\e015"; +} + +.glyphicon-zoom-out:before { + content: "\e016"; +} + +.glyphicon-off:before { + content: "\e017"; +} + +.glyphicon-signal:before { + content: "\e018"; +} + +.glyphicon-cog:before { + content: "\e019"; +} + +.glyphicon-trash:before { + content: "\e020"; +} + +.glyphicon-home:before { + content: "\e021"; +} + +.glyphicon-file:before { + content: "\e022"; +} + +.glyphicon-time:before { + content: "\e023"; +} + +.glyphicon-road:before { + content: "\e024"; +} + +.glyphicon-download-alt:before { + content: "\e025"; +} + +.glyphicon-download:before { + content: "\e026"; +} + +.glyphicon-upload:before { + content: "\e027"; +} + +.glyphicon-inbox:before { + content: "\e028"; +} + +.glyphicon-play-circle:before { + content: "\e029"; +} + +.glyphicon-repeat:before { + content: "\e030"; +} + +.glyphicon-refresh:before { + content: "\e031"; +} + +.glyphicon-list-alt:before { + content: "\e032"; +} + +.glyphicon-flag:before { + content: "\e034"; +} + +.glyphicon-headphones:before { + content: "\e035"; +} + +.glyphicon-volume-off:before { + content: "\e036"; +} + +.glyphicon-volume-down:before { + content: "\e037"; +} + +.glyphicon-volume-up:before { + content: "\e038"; +} + +.glyphicon-qrcode:before { + content: "\e039"; +} + +.glyphicon-barcode:before { + content: "\e040"; +} + +.glyphicon-tag:before { + content: "\e041"; +} + +.glyphicon-tags:before { + content: "\e042"; +} + +.glyphicon-book:before { + content: "\e043"; +} + +.glyphicon-print:before { + content: "\e045"; +} + +.glyphicon-font:before { + content: "\e047"; +} + +.glyphicon-bold:before { + content: "\e048"; +} + +.glyphicon-italic:before { + content: "\e049"; +} + +.glyphicon-text-height:before { + content: "\e050"; +} + +.glyphicon-text-width:before { + content: "\e051"; +} + +.glyphicon-align-left:before { + content: "\e052"; +} + +.glyphicon-align-center:before { + content: "\e053"; +} + +.glyphicon-align-right:before { + content: "\e054"; +} + +.glyphicon-align-justify:before { + content: "\e055"; +} + +.glyphicon-list:before { + content: "\e056"; +} + +.glyphicon-indent-left:before { + content: "\e057"; +} + +.glyphicon-indent-right:before { + content: "\e058"; +} + +.glyphicon-facetime-video:before { + content: "\e059"; +} + +.glyphicon-picture:before { + content: "\e060"; +} + +.glyphicon-map-marker:before { + content: "\e062"; +} + +.glyphicon-adjust:before { + content: "\e063"; +} + +.glyphicon-tint:before { + content: "\e064"; +} + +.glyphicon-edit:before { + content: "\e065"; +} + +.glyphicon-share:before { + content: "\e066"; +} + +.glyphicon-check:before { + content: "\e067"; +} + +.glyphicon-move:before { + content: "\e068"; +} + +.glyphicon-step-backward:before { + content: "\e069"; +} + +.glyphicon-fast-backward:before { + content: "\e070"; +} + +.glyphicon-backward:before { + content: "\e071"; +} + +.glyphicon-play:before { + content: "\e072"; +} + +.glyphicon-pause:before { + content: "\e073"; +} + +.glyphicon-stop:before { + content: "\e074"; +} + +.glyphicon-forward:before { + content: "\e075"; +} + +.glyphicon-fast-forward:before { + content: "\e076"; +} + +.glyphicon-step-forward:before { + content: "\e077"; +} + +.glyphicon-eject:before { + content: "\e078"; +} + +.glyphicon-chevron-left:before { + content: "\e079"; +} + +.glyphicon-chevron-right:before { + content: "\e080"; +} + +.glyphicon-plus-sign:before { + content: "\e081"; +} + +.glyphicon-minus-sign:before { + content: "\e082"; +} + +.glyphicon-remove-sign:before { + content: "\e083"; +} + +.glyphicon-ok-sign:before { + content: "\e084"; +} + +.glyphicon-question-sign:before { + content: "\e085"; +} + +.glyphicon-info-sign:before { + content: "\e086"; +} + +.glyphicon-screenshot:before { + content: "\e087"; +} + +.glyphicon-remove-circle:before { + content: "\e088"; +} + +.glyphicon-ok-circle:before { + content: "\e089"; +} + +.glyphicon-ban-circle:before { + content: "\e090"; +} + +.glyphicon-arrow-left:before { + content: "\e091"; +} + +.glyphicon-arrow-right:before { + content: "\e092"; +} + +.glyphicon-arrow-up:before { + content: "\e093"; +} + +.glyphicon-arrow-down:before { + content: "\e094"; +} + +.glyphicon-share-alt:before { + content: "\e095"; +} + +.glyphicon-resize-full:before { + content: "\e096"; +} + +.glyphicon-resize-small:before { + content: "\e097"; +} + +.glyphicon-exclamation-sign:before { + content: "\e101"; +} + +.glyphicon-gift:before { + content: "\e102"; +} + +.glyphicon-leaf:before { + content: "\e103"; +} + +.glyphicon-eye-open:before { + content: "\e105"; +} + +.glyphicon-eye-close:before { + content: "\e106"; +} + +.glyphicon-warning-sign:before { + content: "\e107"; +} + +.glyphicon-plane:before { + content: "\e108"; +} + +.glyphicon-random:before { + content: "\e110"; +} + +.glyphicon-comment:before { + content: "\e111"; +} + +.glyphicon-magnet:before { + content: "\e112"; +} + +.glyphicon-chevron-up:before { + content: "\e113"; +} + +.glyphicon-chevron-down:before { + content: "\e114"; +} + +.glyphicon-retweet:before { + content: "\e115"; +} + +.glyphicon-shopping-cart:before { + content: "\e116"; +} + +.glyphicon-folder-close:before { + content: "\e117"; +} + +.glyphicon-folder-open:before { + content: "\e118"; +} + +.glyphicon-resize-vertical:before { + content: "\e119"; +} + +.glyphicon-resize-horizontal:before { + content: "\e120"; +} + +.glyphicon-hdd:before { + content: "\e121"; +} + +.glyphicon-bullhorn:before { + content: "\e122"; +} + +.glyphicon-certificate:before { + content: "\e124"; +} + +.glyphicon-thumbs-up:before { + content: "\e125"; +} + +.glyphicon-thumbs-down:before { + content: "\e126"; +} + +.glyphicon-hand-right:before { + content: "\e127"; +} + +.glyphicon-hand-left:before { + content: "\e128"; +} + +.glyphicon-hand-up:before { + content: "\e129"; +} + +.glyphicon-hand-down:before { + content: "\e130"; +} + +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} + +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} + +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} + +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} + +.glyphicon-globe:before { + content: "\e135"; +} + +.glyphicon-tasks:before { + content: "\e137"; +} + +.glyphicon-filter:before { + content: "\e138"; +} + +.glyphicon-fullscreen:before { + content: "\e140"; +} + +.glyphicon-dashboard:before { + content: "\e141"; +} + +.glyphicon-heart-empty:before { + content: "\e143"; +} + +.glyphicon-link:before { + content: "\e144"; +} + +.glyphicon-phone:before { + content: "\e145"; +} + +.glyphicon-usd:before { + content: "\e148"; +} + +.glyphicon-gbp:before { + content: "\e149"; +} + +.glyphicon-sort:before { + content: "\e150"; +} + +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} + +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} + +.glyphicon-sort-by-order:before { + content: "\e153"; +} + +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} + +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} + +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} + +.glyphicon-unchecked:before { + content: "\e157"; +} + +.glyphicon-expand:before { + content: "\e158"; +} + +.glyphicon-collapse-down:before { + content: "\e159"; +} + +.glyphicon-collapse-up:before { + content: "\e160"; +} + +.glyphicon-log-in:before { + content: "\e161"; +} + +.glyphicon-flash:before { + content: "\e162"; +} + +.glyphicon-log-out:before { + content: "\e163"; +} + +.glyphicon-new-window:before { + content: "\e164"; +} + +.glyphicon-record:before { + content: "\e165"; +} + +.glyphicon-save:before { + content: "\e166"; +} + +.glyphicon-open:before { + content: "\e167"; +} + +.glyphicon-saved:before { + content: "\e168"; +} + +.glyphicon-import:before { + content: "\e169"; +} + +.glyphicon-export:before { + content: "\e170"; +} + +.glyphicon-send:before { + content: "\e171"; +} + +.glyphicon-floppy-disk:before { + content: "\e172"; +} + +.glyphicon-floppy-saved:before { + content: "\e173"; +} + +.glyphicon-floppy-remove:before { + content: "\e174"; +} + +.glyphicon-floppy-save:before { + content: "\e175"; +} + +.glyphicon-floppy-open:before { + content: "\e176"; +} + +.glyphicon-credit-card:before { + content: "\e177"; +} + +.glyphicon-transfer:before { + content: "\e178"; +} + +.glyphicon-cutlery:before { + content: "\e179"; +} + +.glyphicon-header:before { + content: "\e180"; +} + +.glyphicon-compressed:before { + content: "\e181"; +} + +.glyphicon-earphone:before { + content: "\e182"; +} + +.glyphicon-phone-alt:before { + content: "\e183"; +} + +.glyphicon-tower:before { + content: "\e184"; +} + +.glyphicon-stats:before { + content: "\e185"; +} + +.glyphicon-sd-video:before { + content: "\e186"; +} + +.glyphicon-hd-video:before { + content: "\e187"; +} + +.glyphicon-subtitles:before { + content: "\e188"; +} + +.glyphicon-sound-stereo:before { + content: "\e189"; +} + +.glyphicon-sound-dolby:before { + content: "\e190"; +} + +.glyphicon-sound-5-1:before { + content: "\e191"; +} + +.glyphicon-sound-6-1:before { + content: "\e192"; +} + +.glyphicon-sound-7-1:before { + content: "\e193"; +} + +.glyphicon-copyright-mark:before { + content: "\e194"; +} + +.glyphicon-registration-mark:before { + content: "\e195"; +} + +.glyphicon-cloud-download:before { + content: "\e197"; +} + +.glyphicon-cloud-upload:before { + content: "\e198"; +} + +.glyphicon-tree-conifer:before { + content: "\e199"; +} + +.glyphicon-tree-deciduous:before { + content: "\e200"; +} + +.glyphicon-briefcase:before { + content: "\1f4bc"; +} + +.glyphicon-calendar:before { + content: "\1f4c5"; +} + +.glyphicon-pushpin:before { + content: "\1f4cc"; +} + +.glyphicon-paperclip:before { + content: "\1f4ce"; +} + +.glyphicon-camera:before { + content: "\1f4f7"; +} + +.glyphicon-lock:before { + content: "\1f512"; +} + +.glyphicon-bell:before { + content: "\1f514"; +} + +.glyphicon-bookmark:before { + content: "\1f516"; +} + +.glyphicon-fire:before { + content: "\1f525"; +} + +.glyphicon-wrench:before { + content: "\1f527"; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-bottom: 0 dotted; + border-left: 4px solid transparent; + content: ""; +} + +.dropdown { + position: relative; +} + +.dropdown-toggle:focus { + outline: 0; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + list-style: none; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.428571429; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #428bca; +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #428bca; + outline: 0; +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open > .dropdown-menu { + display: block; +} + +.open > a { + outline: 0; +} + +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.428571429; + color: #999999; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0 dotted; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } +} + +.btn-default .caret { + border-top-color: #333333; +} + +.btn-primary .caret, +.btn-success .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret { + border-top-color: #fff; +} + +.dropup .btn-default .caret { + border-bottom-color: #333333; +} + +.dropup .btn-primary .caret, +.dropup .btn-success .caret, +.dropup .btn-warning .caret, +.dropup .btn-danger .caret, +.dropup .btn-info .caret { + border-bottom-color: #fff; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} + +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} + +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} + +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus { + outline: none; +} + +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} + +.btn-toolbar:before, +.btn-toolbar:after { + display: table; + content: " "; +} + +.btn-toolbar:after { + clear: both; +} + +.btn-toolbar:before, +.btn-toolbar:after { + display: table; + content: " "; +} + +.btn-toolbar:after { + clear: both; +} + +.btn-toolbar .btn-group { + float: left; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group, +.btn-toolbar > .btn-group + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +.btn-group > .btn:first-child { + margin-left: 0; +} + +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.btn-group > .btn-group { + float: left; +} + +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} + +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.btn-group > .btn-group:last-child > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group-xs > .btn { + padding: 5px 10px; + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} + +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} + +.btn .caret { + margin-left: 0; +} + +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} + +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} + +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group { + display: block; + float: none; + width: 100%; + max-width: 100%; +} + +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + display: table; + content: " "; +} + +.btn-group-vertical > .btn-group:after { + clear: both; +} + +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + display: table; + content: " "; +} + +.btn-group-vertical > .btn-group:after { + clear: both; +} + +.btn-group-vertical > .btn-group > .btn { + float: none; +} + +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} + +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-right-radius: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 0; +} + +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} + +.btn-group-vertical > .btn-group:first-child > .btn:last-child, +.btn-group-vertical > .btn-group:first-child > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.btn-group-vertical > .btn-group:last-child > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.btn-group-justified { + display: table; + width: 100%; + border-collapse: separate; + table-layout: fixed; +} + +.btn-group-justified .btn { + display: table-cell; + float: none; + width: 1%; +} + +[data-toggle="buttons"] > .btn > input[type="radio"], +[data-toggle="buttons"] > .btn > input[type="checkbox"] { + display: none; +} + +.input-group { + position: relative; + display: table; + border-collapse: separate; +} + +.input-group.col { + float: none; + padding-right: 0; + padding-left: 0; +} + +.input-group .form-control { + width: 100%; + margin-bottom: 0; +} + +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 45px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 45px; + line-height: 45px; +} + +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn { + height: auto; +} + +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} + +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn { + height: auto; +} + +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} + +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} + +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} + +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + text-align: center; + background-color: #eeeeee; + border: 1px solid #cccccc; + border-radius: 4px; +} + +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} + +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} + +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} + +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group-addon:first-child { + border-right: 0; +} + +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.input-group-addon:last-child { + border-left: 0; +} + +.input-group-btn { + position: relative; + white-space: nowrap; +} + +.input-group-btn > .btn { + position: relative; +} + +.input-group-btn > .btn + .btn { + margin-left: -4px; +} + +.input-group-btn > .btn:hover, +.input-group-btn > .btn:active { + z-index: 2; +} + +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav:before, +.nav:after { + display: table; + content: " "; +} + +.nav:after { + clear: both; +} + +.nav:before, +.nav:after { + display: table; + content: " "; +} + +.nav:after { + clear: both; +} + +.nav > li { + position: relative; + display: block; +} + +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li.disabled > a { + color: #999999; +} + +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #999999; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} + +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eeeeee; + border-color: #428bca; +} + +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} + +.nav > li > a > img { + max-width: none; +} + +.nav-tabs { + border-bottom: 1px solid #dddddd; +} + +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} + +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.428571429; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #dddddd; + border-bottom-color: transparent; +} + +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} + +.nav-tabs.nav-justified > li { + float: none; +} + +.nav-tabs.nav-justified > li > a { + text-align: center; +} + +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } +} + +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-bottom: 1px solid #dddddd; +} + +.nav-tabs.nav-justified > .active > a { + border-bottom-color: #ffffff; +} + +.nav-pills > li { + float: left; +} + +.nav-pills > li > a { + border-radius: 5px; +} + +.nav-pills > li + li { + margin-left: 2px; +} + +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #ffffff; + background-color: #428bca; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} + +.nav-justified { + width: 100%; +} + +.nav-justified > li { + float: none; +} + +.nav-justified > li > a { + text-align: center; +} + +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } +} + +.nav-tabs-justified { + border-bottom: 0; +} + +.nav-tabs-justified > li > a { + margin-right: 0; + border-bottom: 1px solid #dddddd; +} + +.nav-tabs-justified > .active > a { + border-bottom-color: #ffffff; +} + +.tabbable:before, +.tabbable:after { + display: table; + content: " "; +} + +.tabbable:after { + clear: both; +} + +.tabbable:before, +.tabbable:after { + display: table; + content: " "; +} + +.tabbable:after { + clear: both; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.nav .caret { + border-top-color: #428bca; + border-bottom-color: #428bca; +} + +.nav a:hover .caret { + border-top-color: #2a6496; + border-bottom-color: #2a6496; +} + +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.navbar { + position: relative; + z-index: 1000; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} + +.navbar:before, +.navbar:after { + display: table; + content: " "; +} + +.navbar:after { + clear: both; +} + +.navbar:before, +.navbar:after { + display: table; + content: " "; +} + +.navbar:after { + clear: both; +} + +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} + +.navbar-header:before, +.navbar-header:after { + display: table; + content: " "; +} + +.navbar-header:after { + clear: both; +} + +.navbar-header:before, +.navbar-header:after { + display: table; + content: " "; +} + +.navbar-header:after { + clear: both; +} + +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} + +.navbar-collapse { + max-height: 340px; + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} + +.navbar-collapse:before, +.navbar-collapse:after { + display: table; + content: " "; +} + +.navbar-collapse:after { + clear: both; +} + +.navbar-collapse:before, +.navbar-collapse:after { + display: table; + content: " "; +} + +.navbar-collapse:after { + clear: both; +} + +.navbar-collapse.in { + overflow-y: auto; +} + +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-collapse .navbar-nav.navbar-left:first-child { + margin-left: -15px; + } + .navbar-collapse .navbar-nav.navbar-right:last-child { + margin-right: -15px; + } + .navbar-collapse .navbar-text:last-child { + margin-right: 0; + } +} + +.container > .navbar-header, +.container > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} + +@media (min-width: 768px) { + .container > .navbar-header, + .container > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} + +.navbar-static-top { + border-width: 0 0 1px; +} + +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + border-width: 0 0 1px; +} + +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} + +.navbar-fixed-top { + top: 0; + z-index: 1030; +} + +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; +} + +.navbar-brand { + float: left; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} + +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} + +@media (min-width: 768px) { + .navbar > .container .navbar-brand { + margin-left: -15px; + } +} + +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + border: 1px solid transparent; + border-radius: 4px; +} + +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} + +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} + +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} + +.navbar-nav { + margin: 7.5px -15px; +} + +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} + +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} + +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} + +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + } +} + +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); +} + +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } +} + +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} + +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} + +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.navbar-nav.pull-right > li > .dropdown-menu, +.navbar-nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} + +.navbar-text { + float: left; + margin-top: 15px; + margin-bottom: 15px; +} + +@media (min-width: 768px) { + .navbar-text { + margin-right: 15px; + margin-left: 15px; + } +} + +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} + +.navbar-default .navbar-brand { + color: #777777; +} + +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} + +.navbar-default .navbar-text { + color: #777777; +} + +.navbar-default .navbar-nav > li > a { + color: #777777; +} + +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333333; + background-color: transparent; +} + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555555; + background-color: #e7e7e7; +} + +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #cccccc; + background-color: transparent; +} + +.navbar-default .navbar-toggle { + border-color: #dddddd; +} + +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #dddddd; +} + +.navbar-default .navbar-toggle .icon-bar { + background-color: #cccccc; +} + +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e6e6e6; +} + +.navbar-default .navbar-nav > .dropdown > a:hover .caret, +.navbar-default .navbar-nav > .dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555555; + background-color: #e7e7e7; +} + +.navbar-default .navbar-nav > .open > a .caret, +.navbar-default .navbar-nav > .open > a:hover .caret, +.navbar-default .navbar-nav > .open > a:focus .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar-default .navbar-nav > .dropdown > a .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #cccccc; + background-color: transparent; + } +} + +.navbar-default .navbar-link { + color: #777777; +} + +.navbar-default .navbar-link:hover { + color: #333333; +} + +.navbar-inverse { + background-color: #222222; + border-color: #080808; +} + +.navbar-inverse .navbar-brand { + color: #999999; +} + +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .navbar-nav > li > a { + color: #999999; +} + +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #ffffff; + background-color: #080808; +} + +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444444; + background-color: transparent; +} + +.navbar-inverse .navbar-toggle { + border-color: #333333; +} + +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333333; +} + +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #ffffff; +} + +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} + +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #ffffff; + background-color: #080808; +} + +.navbar-inverse .navbar-nav > .dropdown > a:hover .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-nav > .dropdown > a .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .navbar-nav > .open > a .caret, +.navbar-inverse .navbar-nav > .open > a:hover .caret, +.navbar-inverse .navbar-nav > .open > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #999999; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #ffffff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #ffffff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444444; + background-color: transparent; + } +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover { + color: #ffffff; +} + +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; +} + +.breadcrumb > li + li:before { + padding: 0 5px; + color: #cccccc; + content: "/\00a0"; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} + +.pagination > li { + display: inline; +} + +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.428571429; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; +} + +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} + +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + background-color: #eeeeee; +} + +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #ffffff; + cursor: default; + background-color: #428bca; + border-color: #428bca; +} + +.pagination > .disabled > span, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #999999; + cursor: not-allowed; + background-color: #ffffff; + border-color: #dddddd; +} + +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; +} + +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 6px; + border-top-left-radius: 6px; +} + +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; +} + +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} + +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} + +.pager:before, +.pager:after { + display: table; + content: " "; +} + +.pager:after { + clear: both; +} + +.pager:before, +.pager:after { + display: table; + content: " "; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: not-allowed; + background-color: #ffffff; +} + +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} + +.label[href]:hover, +.label[href]:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label:empty { + display: none; +} + +.label-default { + background-color: #999999; +} + +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #808080; +} + +.label-primary { + background-color: #428bca; +} + +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #3071a9; +} + +.label-success { + background-color: #5cb85c; +} + +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} + +.label-info { + background-color: #5bc0de; +} + +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} + +.label-warning { + background-color: #f0ad4e; +} + +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} + +.label-danger { + background-color: #d9534f; +} + +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} + +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; + border-radius: 10px; +} + +.badge:empty { + display: none; +} + +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.btn .badge { + position: relative; + top: -1px; +} + +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #428bca; + background-color: #ffffff; +} + +.nav-pills > li > a > .badge { + margin-left: 3px; +} + +.jumbotron { + padding: 30px; + margin-bottom: 30px; + font-size: 21px; + font-weight: 200; + line-height: 2.1428571435; + color: inherit; + background-color: #eeeeee; +} + +.jumbotron h1 { + line-height: 1; + color: inherit; +} + +.jumbotron p { + line-height: 1.4; +} + +.container .jumbotron { + border-radius: 6px; +} + +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1 { + font-size: 63px; + } +} + +.thumbnail { + display: inline-block; + display: block; + height: auto; + max-width: 100%; + padding: 4px; + line-height: 1.428571429; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +.thumbnail > img { + display: block; + height: auto; + max-width: 100%; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #428bca; +} + +.thumbnail > img { + margin-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #333333; +} + +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} + +.alert h4 { + margin-top: 0; + color: inherit; +} + +.alert .alert-link { + font-weight: bold; +} + +.alert > p, +.alert > ul { + margin-bottom: 0; +} + +.alert > p + p { + margin-top: 5px; +} + +.alert-dismissable { + padding-right: 35px; +} + +.alert-dismissable .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success hr { + border-top-color: #c9e2b3; +} + +.alert-success .alert-link { + color: #356635; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info hr { + border-top-color: #a6e1ec; +} + +.alert-info .alert-link { + color: #2d6987; +} + +.alert-warning { + color: #c09853; + background-color: #fcf8e3; + border-color: #fbeed5; +} + +.alert-warning hr { + border-top-color: #f8e5be; +} + +.alert-warning .alert-link { + color: #a47e3c; +} + +.alert-danger { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger hr { + border-top-color: #e6c1c7; +} + +.alert-danger .alert-link { + color: #953b39; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + text-align: center; + background-color: #428bca; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress-striped .progress-bar { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} + +.progress.active .progress-bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-bar-success { + background-color: #5cb85c; +} + +.progress-striped .progress-bar-success { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-bar-info { + background-color: #5bc0de; +} + +.progress-striped .progress-bar-info { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-bar-warning { + background-color: #f0ad4e; +} + +.progress-striped .progress-bar-warning { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-bar-danger { + background-color: #d9534f; +} + +.progress-striped .progress-bar-danger { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.media, +.media-body { + overflow: hidden; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + padding-left: 0; + list-style: none; +} + +.list-group { + padding-left: 0; + margin-bottom: 20px; +} + +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #ffffff; + border: 1px solid #dddddd; +} + +.list-group-item:first-child { + border-top-right-radius: 4px; + border-top-left-radius: 4px; +} + +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} + +.list-group-item > .badge { + float: right; +} + +.list-group-item > .badge + .badge { + margin-right: 5px; +} + +a.list-group-item { + color: #555555; +} + +a.list-group-item .list-group-item-heading { + color: #333333; +} + +a.list-group-item:hover, +a.list-group-item:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #ffffff; + background-color: #428bca; + border-color: #428bca; +} + +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading { + color: inherit; +} + +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #e1edf7; +} + +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} + +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} + +.panel { + margin-bottom: 20px; + background-color: #ffffff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.panel-body { + padding: 15px; +} + +.panel-body:before, +.panel-body:after { + display: table; + content: " "; +} + +.panel-body:after { + clear: both; +} + +.panel-body:before, +.panel-body:after { + display: table; + content: " "; +} + +.panel-body:after { + clear: both; +} + +.panel > .list-group { + margin-bottom: 0; +} + +.panel > .list-group .list-group-item { + border-width: 1px 0; +} + +.panel > .list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.panel > .list-group .list-group-item:last-child { + border-bottom: 0; +} + +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} + +.panel > .table { + margin-bottom: 0; +} + +.panel > .panel-body + .table { + border-top: 1px solid #dddddd; +} + +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} + +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; +} + +.panel-title > a { + color: inherit; +} + +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #dddddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} + +.panel-group .panel { + margin-bottom: 0; + overflow: hidden; + border-radius: 4px; +} + +.panel-group .panel + .panel { + margin-top: 5px; +} + +.panel-group .panel-heading { + border-bottom: 0; +} + +.panel-group .panel-heading + .panel-collapse .panel-body { + border-top: 1px solid #dddddd; +} + +.panel-group .panel-footer { + border-top: 0; +} + +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #dddddd; +} + +.panel-default { + border-color: #dddddd; +} + +.panel-default > .panel-heading { + color: #333333; + background-color: #f5f5f5; + border-color: #dddddd; +} + +.panel-default > .panel-heading + .panel-collapse .panel-body { + border-top-color: #dddddd; +} + +.panel-default > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #dddddd; +} + +.panel-primary { + border-color: #428bca; +} + +.panel-primary > .panel-heading { + color: #ffffff; + background-color: #428bca; + border-color: #428bca; +} + +.panel-primary > .panel-heading + .panel-collapse .panel-body { + border-top-color: #428bca; +} + +.panel-primary > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #428bca; +} + +.panel-success { + border-color: #d6e9c6; +} + +.panel-success > .panel-heading { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.panel-success > .panel-heading + .panel-collapse .panel-body { + border-top-color: #d6e9c6; +} + +.panel-success > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #d6e9c6; +} + +.panel-warning { + border-color: #fbeed5; +} + +.panel-warning > .panel-heading { + color: #c09853; + background-color: #fcf8e3; + border-color: #fbeed5; +} + +.panel-warning > .panel-heading + .panel-collapse .panel-body { + border-top-color: #fbeed5; +} + +.panel-warning > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #fbeed5; +} + +.panel-danger { + border-color: #eed3d7; +} + +.panel-danger > .panel-heading { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.panel-danger > .panel-heading + .panel-collapse .panel-body { + border-top-color: #eed3d7; +} + +.panel-danger > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #eed3d7; +} + +.panel-info { + border-color: #bce8f1; +} + +.panel-info > .panel-heading { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.panel-info > .panel-heading + .panel-collapse .panel-body { + border-top-color: #bce8f1; +} + +.panel-info > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #bce8f1; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-lg { + padding: 24px; + border-radius: 6px; +} + +.well-sm { + padding: 9px; + border-radius: 3px; +} + +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open { + overflow: hidden; +} + +body.modal-open, +.modal-open .navbar-fixed-top, +.modal-open .navbar-fixed-bottom { + margin-right: 15px; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + display: none; + overflow: auto; + overflow-y: scroll; +} + +.modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform 0.3s ease-out; + -moz-transition: -moz-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; +} + +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} + +.modal-dialog { + z-index: 1050; + width: auto; + padding: 10px; + margin-right: auto; + margin-left: auto; +} + +.modal-content { + position: relative; + background-color: #ffffff; + border: 1px solid #999999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} + +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} + +.modal-header { + min-height: 16.428571429px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} + +.modal-header .close { + margin-top: -2px; +} + +.modal-title { + margin: 0; + line-height: 1.428571429; +} + +.modal-body { + position: relative; + padding: 20px; +} + +.modal-footer { + padding: 19px 20px 20px; + margin-top: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +@media screen and (min-width: 768px) { + .modal-dialog { + right: auto; + left: 50%; + width: 600px; + padding-top: 30px; + padding-bottom: 30px; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 12px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.top-right .tooltip-arrow { + right: 5px; + bottom: 0; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; + content: " "; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; + content: " "; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; + content: " "; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; + content: " "; +} + +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + height: auto; + max-width: 100%; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.left { + background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%)); + background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} + +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%)); + background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + left: 50%; + z-index: 5; + display: inline-block; +} + +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + font-family: serif; +} + +.carousel-control .icon-prev:before { + content: '\2039'; +} + +.carousel-control .icon-next:before { + content: '\203a'; +} + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} + +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + border: 1px solid #ffffff; + border-radius: 10px; +} + +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #ffffff; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} + +.carousel-caption .btn { + text-shadow: none; +} + +@media screen and (min-width: 768px) { + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + margin-left: -15px; + font-size: 30px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} + +.clearfix:before, +.clearfix:after { + display: table; + content: " "; +} + +.clearfix:after { + clear: both; +} + +.pull-right { + float: right !important; +} + +.pull-left { + float: left !important; +} + +.hide { + display: none !important; +} + +.show { + display: block !important; +} + +.invisible { + visibility: hidden; +} + +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.affix { + position: fixed; +} + +@-ms-viewport { + width: device-width; +} + +@media screen and (max-width: 400px) { + @-ms-viewport { + width: 320px; + } +} + +.hidden { + display: none !important; + visibility: hidden !important; +} + +.visible-xs { + display: none !important; +} + +tr.visible-xs { + display: none !important; +} + +th.visible-xs, +td.visible-xs { + display: none !important; +} + +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-xs.visible-sm { + display: block !important; + } + tr.visible-xs.visible-sm { + display: table-row !important; + } + th.visible-xs.visible-sm, + td.visible-xs.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-xs.visible-md { + display: block !important; + } + tr.visible-xs.visible-md { + display: table-row !important; + } + th.visible-xs.visible-md, + td.visible-xs.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-xs.visible-lg { + display: block !important; + } + tr.visible-xs.visible-lg { + display: table-row !important; + } + th.visible-xs.visible-lg, + td.visible-xs.visible-lg { + display: table-cell !important; + } +} + +.visible-sm { + display: none !important; +} + +tr.visible-sm { + display: none !important; +} + +th.visible-sm, +td.visible-sm { + display: none !important; +} + +@media (max-width: 767px) { + .visible-sm.visible-xs { + display: block !important; + } + tr.visible-sm.visible-xs { + display: table-row !important; + } + th.visible-sm.visible-xs, + td.visible-sm.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-sm.visible-md { + display: block !important; + } + tr.visible-sm.visible-md { + display: table-row !important; + } + th.visible-sm.visible-md, + td.visible-sm.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-sm.visible-lg { + display: block !important; + } + tr.visible-sm.visible-lg { + display: table-row !important; + } + th.visible-sm.visible-lg, + td.visible-sm.visible-lg { + display: table-cell !important; + } +} + +.visible-md { + display: none !important; +} + +tr.visible-md { + display: none !important; +} + +th.visible-md, +td.visible-md { + display: none !important; +} + +@media (max-width: 767px) { + .visible-md.visible-xs { + display: block !important; + } + tr.visible-md.visible-xs { + display: table-row !important; + } + th.visible-md.visible-xs, + td.visible-md.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-md.visible-sm { + display: block !important; + } + tr.visible-md.visible-sm { + display: table-row !important; + } + th.visible-md.visible-sm, + td.visible-md.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-md.visible-lg { + display: block !important; + } + tr.visible-md.visible-lg { + display: table-row !important; + } + th.visible-md.visible-lg, + td.visible-md.visible-lg { + display: table-cell !important; + } +} + +.visible-lg { + display: none !important; +} + +tr.visible-lg { + display: none !important; +} + +th.visible-lg, +td.visible-lg { + display: none !important; +} + +@media (max-width: 767px) { + .visible-lg.visible-xs { + display: block !important; + } + tr.visible-lg.visible-xs { + display: table-row !important; + } + th.visible-lg.visible-xs, + td.visible-lg.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-lg.visible-sm { + display: block !important; + } + tr.visible-lg.visible-sm { + display: table-row !important; + } + th.visible-lg.visible-sm, + td.visible-lg.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-lg.visible-md { + display: block !important; + } + tr.visible-lg.visible-md { + display: table-row !important; + } + th.visible-lg.visible-md, + td.visible-lg.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} + +.hidden-xs { + display: block !important; +} + +tr.hidden-xs { + display: table-row !important; +} + +th.hidden-xs, +td.hidden-xs { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } + tr.hidden-xs { + display: none !important; + } + th.hidden-xs, + td.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-xs.hidden-sm { + display: none !important; + } + tr.hidden-xs.hidden-sm { + display: none !important; + } + th.hidden-xs.hidden-sm, + td.hidden-xs.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-xs.hidden-md { + display: none !important; + } + tr.hidden-xs.hidden-md { + display: none !important; + } + th.hidden-xs.hidden-md, + td.hidden-xs.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-xs.hidden-lg { + display: none !important; + } + tr.hidden-xs.hidden-lg { + display: none !important; + } + th.hidden-xs.hidden-lg, + td.hidden-xs.hidden-lg { + display: none !important; + } +} + +.hidden-sm { + display: block !important; +} + +tr.hidden-sm { + display: table-row !important; +} + +th.hidden-sm, +td.hidden-sm { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-sm.hidden-xs { + display: none !important; + } + tr.hidden-sm.hidden-xs { + display: none !important; + } + th.hidden-sm.hidden-xs, + td.hidden-sm.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } + tr.hidden-sm { + display: none !important; + } + th.hidden-sm, + td.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-sm.hidden-md { + display: none !important; + } + tr.hidden-sm.hidden-md { + display: none !important; + } + th.hidden-sm.hidden-md, + td.hidden-sm.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-sm.hidden-lg { + display: none !important; + } + tr.hidden-sm.hidden-lg { + display: none !important; + } + th.hidden-sm.hidden-lg, + td.hidden-sm.hidden-lg { + display: none !important; + } +} + +.hidden-md { + display: block !important; +} + +tr.hidden-md { + display: table-row !important; +} + +th.hidden-md, +td.hidden-md { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-md.hidden-xs { + display: none !important; + } + tr.hidden-md.hidden-xs { + display: none !important; + } + th.hidden-md.hidden-xs, + td.hidden-md.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-md.hidden-sm { + display: none !important; + } + tr.hidden-md.hidden-sm { + display: none !important; + } + th.hidden-md.hidden-sm, + td.hidden-md.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } + tr.hidden-md { + display: none !important; + } + th.hidden-md, + td.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-md.hidden-lg { + display: none !important; + } + tr.hidden-md.hidden-lg { + display: none !important; + } + th.hidden-md.hidden-lg, + td.hidden-md.hidden-lg { + display: none !important; + } +} + +.hidden-lg { + display: block !important; +} + +tr.hidden-lg { + display: table-row !important; +} + +th.hidden-lg, +td.hidden-lg { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-lg.hidden-xs { + display: none !important; + } + tr.hidden-lg.hidden-xs { + display: none !important; + } + th.hidden-lg.hidden-xs, + td.hidden-lg.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-lg.hidden-sm { + display: none !important; + } + tr.hidden-lg.hidden-sm { + display: none !important; + } + th.hidden-lg.hidden-sm, + td.hidden-lg.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-lg.hidden-md { + display: none !important; + } + tr.hidden-lg.hidden-md { + display: none !important; + } + th.hidden-lg.hidden-md, + td.hidden-lg.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } + tr.hidden-lg { + display: none !important; + } + th.hidden-lg, + td.hidden-lg { + display: none !important; + } +} + +.visible-print { + display: none !important; +} + +tr.visible-print { + display: none !important; +} + +th.visible-print, +td.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: block !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } + .hidden-print { + display: none !important; + } + tr.hidden-print { + display: none !important; + } + th.hidden-print, + td.hidden-print { + display: none !important; + } +} \ No newline at end of file diff --git a/samples/MusicStore/wwwroot/Content/bootstrap.min.css b/samples/MusicStore/wwwroot/Content/bootstrap.min.css new file mode 100644 index 0000000..df89a50 --- /dev/null +++ b/samples/MusicStore/wwwroot/Content/bootstrap.min.css @@ -0,0 +1,20 @@ +/* NUGET: BEGIN LICENSE TEXT + * + * Microsoft grants you the right to use these script files for the sole + * purpose of either: (i) interacting through your browser with the Microsoft + * website or online service, subject to the applicable licensing or use + * terms; or (ii) using the files as included with a Microsoft product subject + * to that product's license terms. Microsoft reserves all other rights to the + * files not expressly granted by Microsoft, whether by implication, estoppel + * or otherwise. The notices and licenses below are for informational purposes only. + * + * NUGET: END LICENSE TEXT */ +/*! + * Bootstrap v3.0.0 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world by @mdo and @fat. + *//*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:2cm .5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}button,input,select[multiple],textarea{background-image:none}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16.099999999999998px;font-weight:200;line-height:1.4}@media(min-width:768px){.lead{font-size:21px}}small{font-size:85%}cite{font-style:normal}.text-muted{color:#999}.text-primary{color:#428bca}.text-warning{color:#c09853}.text-danger{color:#b94a48}.text-success{color:#468847}.text-info{color:#3a87ad}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{margin-top:20px;margin-bottom:10px}h4,h5,h6{margin-top:10px;margin-bottom:10px}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}h1 small,.h1 small{font-size:24px}h2 small,.h2 small{font-size:18px}h3 small,.h3 small,h4 small,.h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small{display:block;line-height:1.428571429;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:1.428571429}code,pre{font-family:Monaco,Menlo,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11{float:left}.col-xs-1{width:8.333333333333332%}.col-xs-2{width:16.666666666666664%}.col-xs-3{width:25%}.col-xs-4{width:33.33333333333333%}.col-xs-5{width:41.66666666666667%}.col-xs-6{width:50%}.col-xs-7{width:58.333333333333336%}.col-xs-8{width:66.66666666666666%}.col-xs-9{width:75%}.col-xs-10{width:83.33333333333334%}.col-xs-11{width:91.66666666666666%}.col-xs-12{width:100%}@media(min-width:768px){.container{max-width:750px}.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11{float:left}.col-sm-1{width:8.333333333333332%}.col-sm-2{width:16.666666666666664%}.col-sm-3{width:25%}.col-sm-4{width:33.33333333333333%}.col-sm-5{width:41.66666666666667%}.col-sm-6{width:50%}.col-sm-7{width:58.333333333333336%}.col-sm-8{width:66.66666666666666%}.col-sm-9{width:75%}.col-sm-10{width:83.33333333333334%}.col-sm-11{width:91.66666666666666%}.col-sm-12{width:100%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-3{left:25%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-6{left:50%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-9{left:75%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-11{left:91.66666666666666%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-3{right:25%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-6{right:50%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-9{right:75%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-11{margin-left:91.66666666666666%}}@media(min-width:992px){.container{max-width:970px}.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11{float:left}.col-md-1{width:8.333333333333332%}.col-md-2{width:16.666666666666664%}.col-md-3{width:25%}.col-md-4{width:33.33333333333333%}.col-md-5{width:41.66666666666667%}.col-md-6{width:50%}.col-md-7{width:58.333333333333336%}.col-md-8{width:66.66666666666666%}.col-md-9{width:75%}.col-md-10{width:83.33333333333334%}.col-md-11{width:91.66666666666666%}.col-md-12{width:100%}.col-md-push-0{left:auto}.col-md-push-1{left:8.333333333333332%}.col-md-push-2{left:16.666666666666664%}.col-md-push-3{left:25%}.col-md-push-4{left:33.33333333333333%}.col-md-push-5{left:41.66666666666667%}.col-md-push-6{left:50%}.col-md-push-7{left:58.333333333333336%}.col-md-push-8{left:66.66666666666666%}.col-md-push-9{left:75%}.col-md-push-10{left:83.33333333333334%}.col-md-push-11{left:91.66666666666666%}.col-md-pull-0{right:auto}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-3{right:25%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-6{right:50%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-9{right:75%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-11{right:91.66666666666666%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-11{margin-left:91.66666666666666%}}@media(min-width:1200px){.container{max-width:1170px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11{float:left}.col-lg-1{width:8.333333333333332%}.col-lg-2{width:16.666666666666664%}.col-lg-3{width:25%}.col-lg-4{width:33.33333333333333%}.col-lg-5{width:41.66666666666667%}.col-lg-6{width:50%}.col-lg-7{width:58.333333333333336%}.col-lg-8{width:66.66666666666666%}.col-lg-9{width:75%}.col-lg-10{width:83.33333333333334%}.col-lg-11{width:91.66666666666666%}.col-lg-12{width:100%}.col-lg-push-0{left:auto}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-3{left:25%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-6{left:50%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-9{left:75%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-11{left:91.66666666666666%}.col-lg-pull-0{right:auto}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-3{right:25%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-6{right:50%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-9{right:75%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-11{margin-left:91.66666666666666%}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table thead>tr>th,.table tbody>tr>th,.table tfoot>tr>th,.table thead>tr>td,.table tbody>tr>td,.table tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table caption+thead tr:first-child th,.table colgroup+thead tr:first-child th,.table thead:first-child tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed thead>tr>th,.table-condensed tbody>tr>th,.table-condensed tfoot>tr>th,.table-condensed thead>tr>td,.table-condensed tbody>tr>td,.table-condensed tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8;border-color:#d6e9c6}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td{background-color:#d0e9c6;border-color:#c9e2b3}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede;border-color:#eed3d7}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td{background-color:#ebcccc;border-color:#e6c1c7}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3;border-color:#fbeed5}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td{background-color:#faf2cc;border-color:#f8e5be}@media(max-width:768px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0;background-color:#fff}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>thead>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>thead>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm{height:auto}.input-lg{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:45px;line-height:45px}textarea.input-lg{height:auto}.has-warning .help-block,.has-warning .control-label{color:#c09853}.has-warning .form-control{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.has-warning .input-group-addon{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.has-error .help-block,.has-error .control-label{color:#b94a48}.has-error .form-control{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.has-error .input-group-addon{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.has-success .help-block,.has-success .control-label{color:#468847}.has-success .form-control{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.has-success .input-group-addon{color:#468847;background-color:#dff0d8;border-color:#468847}.form-control-static{padding-top:7px;margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-link{font-weight:normal;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-print:before{content:"\e045"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-briefcase:before{content:"\1f4bc"}.glyphicon-calendar:before{content:"\1f4c5"}.glyphicon-pushpin:before{content:"\1f4cc"}.glyphicon-paperclip:before{content:"\1f4ce"}.glyphicon-camera:before{content:"\1f4f7"}.glyphicon-lock:before{content:"\1f512"}.glyphicon-bell:before{content:"\1f514"}.glyphicon-bookmark:before{content:"\1f516"}.glyphicon-fire:before{content:"\1f525"}.glyphicon-wrench:before{content:"\1f527"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0 dotted;border-left:4px solid transparent;content:""}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#fff;text-decoration:none;background-color:#428bca}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0 dotted;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.btn-default .caret{border-top-color:#333}.btn-primary .caret,.btn-success .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret{border-top-color:#fff}.dropup .btn-default .caret{border-bottom-color:#333}.dropup .btn-primary .caret,.dropup .btn-success .caret,.dropup .btn-warning .caret,.dropup .btn-danger .caret,.dropup .btn-info .caret{border-bottom-color:#fff}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:5px 10px;padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified .btn{display:table-cell;float:none;width:1%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group.col{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:45px;line-height:45px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}}.nav-tabs.nav-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs.nav-justified>.active>a{border-bottom-color:#fff}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:5px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs-justified>.active>a{border-bottom-color:#fff}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.nav .caret{border-top-color:#428bca;border-bottom-color:#428bca}.nav a:hover .caret{border-top-color:#2a6496;border-bottom-color:#2a6496}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;z-index:1000;min-height:50px;margin-bottom:20px;border:1px solid transparent}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:4px}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-collapse .navbar-nav.navbar-left:first-child{margin-left:-15px}.navbar-collapse .navbar-nav.navbar-right:last-child{margin-right:-15px}.navbar-collapse .navbar-text:last-child{margin-right:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;border-width:0 0 1px}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;z-index:1030}.navbar-fixed-bottom{bottom:0;margin-bottom:0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;border:1px solid transparent;border-radius:4px}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}@media(min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-text{float:left;margin-top:15px;margin-bottom:15px}@media(min-width:768px){.navbar-text{margin-right:15px;margin-left:15px}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e6e6e6}.navbar-default .navbar-nav>.dropdown>a:hover .caret,.navbar-default .navbar-nav>.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.open>a .caret,.navbar-default .navbar-nav>.open>a:hover .caret,.navbar-default .navbar-nav>.open>a:focus .caret{border-top-color:#555;border-bottom-color:#555}.navbar-default .navbar-nav>.dropdown>a .caret{border-top-color:#777;border-bottom-color:#777}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-nav>.dropdown>a .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .navbar-nav>.open>a .caret,.navbar-inverse .navbar-nav>.open>a:hover .caret,.navbar-inverse .navbar-nav>.open>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.badge:empty{display:none}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.btn .badge{position:relative;top:-1px}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.jumbotron h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.thumbnail{display:inline-block;display:block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img{display:block;height:auto;max-width:100%}a.thumbnail:hover,a.thumbnail:focus{border-color:#428bca}.thumbnail>img{margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#356635}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#2d6987}.alert-warning{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.alert-warning hr{border-top-color:#f8e5be}.alert-warning .alert-link{color:#a47e3c}.alert-danger{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger hr{border-top-color:#e6c1c7}.alert-danger .alert-link{color:#953b39}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table{margin-bottom:0}.panel>.panel-body+.table{border-top:1px solid #ddd}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-title{margin-top:0;margin-bottom:0;font-size:16px}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-warning{border-color:#fbeed5}.panel-warning>.panel-heading{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#fbeed5}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#fbeed5}.panel-danger{border-color:#eed3d7}.panel-danger>.panel-heading{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#eed3d7}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#eed3d7}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}body.modal-open,.modal-open .navbar-fixed-top,.modal-open .navbar-fixed-bottom{margin-right:15px}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{z-index:1050;width:auto;padding:10px;margin-right:auto;margin-left:auto}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.modal-dialog{right:auto;left:50%;width:600px;padding-top:30px;padding-bottom:30px}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.carousel-control.left{background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.5)),to(rgba(0,0,0,0.0001)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.5) 0),color-stop(rgba(0,0,0,0.0001) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.0001)),to(rgba(0,0,0,0.5)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.0001) 0),color-stop(rgba(0,0,0,0.5) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1)}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;left:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.affix{position:fixed}@-ms-viewport{width:device-width}@media screen and (max-width:400px){@-ms-viewport{width:320px}}.hidden{display:none!important;visibility:hidden!important}.visible-xs{display:none!important}tr.visible-xs{display:none!important}th.visible-xs,td.visible-xs{display:none!important}@media(max-width:767px){.visible-xs{display:block!important}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}tr.visible-xs.visible-sm{display:table-row!important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}tr.visible-xs.visible-md{display:table-row!important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block!important}tr.visible-xs.visible-lg{display:table-row!important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell!important}}.visible-sm{display:none!important}tr.visible-sm{display:none!important}th.visible-sm,td.visible-sm{display:none!important}@media(max-width:767px){.visible-sm.visible-xs{display:block!important}tr.visible-sm.visible-xs{display:table-row!important}th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block!important}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}tr.visible-sm.visible-md{display:table-row!important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block!important}tr.visible-sm.visible-lg{display:table-row!important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell!important}}.visible-md{display:none!important}tr.visible-md{display:none!important}th.visible-md,td.visible-md{display:none!important}@media(max-width:767px){.visible-md.visible-xs{display:block!important}tr.visible-md.visible-xs{display:table-row!important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}tr.visible-md.visible-sm{display:table-row!important}th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block!important}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-md.visible-lg{display:block!important}tr.visible-md.visible-lg{display:table-row!important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell!important}}.visible-lg{display:none!important}tr.visible-lg{display:none!important}th.visible-lg,td.visible-lg{display:none!important}@media(max-width:767px){.visible-lg.visible-xs{display:block!important}tr.visible-lg.visible-xs{display:table-row!important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}tr.visible-lg.visible-sm{display:table-row!important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}tr.visible-lg.visible-md{display:table-row!important}th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-lg{display:block!important}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}.hidden-xs{display:block!important}tr.hidden-xs{display:table-row!important}th.hidden-xs,td.hidden-xs{display:table-cell!important}@media(max-width:767px){.hidden-xs{display:none!important}tr.hidden-xs{display:none!important}th.hidden-xs,td.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm{display:none!important}tr.hidden-xs.hidden-sm{display:none!important}th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md{display:none!important}tr.hidden-xs.hidden-md{display:none!important}th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-xs.hidden-lg{display:none!important}tr.hidden-xs.hidden-lg{display:none!important}th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none!important}}.hidden-sm{display:block!important}tr.hidden-sm{display:table-row!important}th.hidden-sm,td.hidden-sm{display:table-cell!important}@media(max-width:767px){.hidden-sm.hidden-xs{display:none!important}tr.hidden-sm.hidden-xs{display:none!important}th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}tr.hidden-sm{display:none!important}th.hidden-sm,td.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md{display:none!important}tr.hidden-sm.hidden-md{display:none!important}th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-sm.hidden-lg{display:none!important}tr.hidden-sm.hidden-lg{display:none!important}th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none!important}}.hidden-md{display:block!important}tr.hidden-md{display:table-row!important}th.hidden-md,td.hidden-md{display:table-cell!important}@media(max-width:767px){.hidden-md.hidden-xs{display:none!important}tr.hidden-md.hidden-xs{display:none!important}th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm{display:none!important}tr.hidden-md.hidden-sm{display:none!important}th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}tr.hidden-md{display:none!important}th.hidden-md,td.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-md.hidden-lg{display:none!important}tr.hidden-md.hidden-lg{display:none!important}th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none!important}}.hidden-lg{display:block!important}tr.hidden-lg{display:table-row!important}th.hidden-lg,td.hidden-lg{display:table-cell!important}@media(max-width:767px){.hidden-lg.hidden-xs{display:none!important}tr.hidden-lg.hidden-xs{display:none!important}th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm{display:none!important}tr.hidden-lg.hidden-sm{display:none!important}th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md{display:none!important}tr.hidden-lg.hidden-md{display:none!important}th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-lg{display:none!important}tr.hidden-lg{display:none!important}th.hidden-lg,td.hidden-lg{display:none!important}}.visible-print{display:none!important}tr.visible-print{display:none!important}th.visible-print,td.visible-print{display:none!important}@media print{.visible-print{display:block!important}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}.hidden-print{display:none!important}tr.hidden-print{display:none!important}th.hidden-print,td.hidden-print{display:none!important}} \ No newline at end of file diff --git a/samples/MusicStore/wwwroot/Images/home-showcase.png b/samples/MusicStore/wwwroot/Images/home-showcase.png new file mode 100644 index 0000000000000000000000000000000000000000..258c19d3cd29d8e94fc95877682f45f3190dcb72 GIT binary patch literal 254130 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 literal 0 HcmV?d00001 diff --git a/samples/MusicStore/wwwroot/Images/logo.png b/samples/MusicStore/wwwroot/Images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d334c8625625b78836bb729ed9b7a10fa04bb702 GIT binary patch literal 2963 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 + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/MusicStore/wwwroot/Images/placeholder.png b/samples/MusicStore/wwwroot/Images/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..1f73dbb43dacaf0c118d1369eda94b9a33770129 GIT binary patch literal 1221 zcmeAS@N?(olHy`uVBq!ia0vp^DIm2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR48ZW?|$fB%2S`uZt1wr;lH<}z>ngu{oO)1J!-^}2Pm9F~!joA)%v zH*~qz-Z1Ow$=*+Xa^1XN?`0yTHq&QL)O(B2va+%jVcAQ9nj^v*f>!eE5b6H?<8R%i zmm<>A^+Btzd-5+e@SW_m(8J)y(Rc6UrsW!1Okk#Y_z#{L^XoYdT)SrW^N;_HZD(J-vbtYue|Y2L0KMry ze_rHbSiL%1M@KJl2HVj`!D;E@aaHGM&WzM@KR(4PRZML9o<6-<&lRSn7QVlieq-Cw z>-TF;zq=>LaPuP1#DW=7YyB2Rm<=uL=L9f7-m{={hF-4}YQb=+CmY)0X(~CYiGgPfBNscsI zmRa<=`TI$I-DD}YlZ`61wc&gF^rt;n`1?2T-MznGmVUkYM&st27b{C&maN(-!}V2& ztJggK{=bY(Ti0%%e(}tSmHW^3Y>87BDirG6aed-_j$gj9Gs1r@tDB~#R&=(1>uDb! zf!o{SzH=zOaG!>p#usBx`h!aN<%>d5ZSDT^*?rurFBd;6zFl)=rro~VyZz+u-z^jP k`u{>TO14FI`+tUWXGJdYoeKH`EOHn;UHx3vIVCg!0BIX0 + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/MusicStore/wwwroot/Scripts/bootstrap.js b/samples/MusicStore/wwwroot/Scripts/bootstrap.js new file mode 100644 index 0000000..5aa9982 --- /dev/null +++ b/samples/MusicStore/wwwroot/Scripts/bootstrap.js @@ -0,0 +1,2014 @@ +/* NUGET: BEGIN LICENSE TEXT + * + * Microsoft grants you the right to use these script files for the sole + * purpose of either: (i) interacting through your browser with the Microsoft + * website or online service, subject to the applicable licensing or use + * terms; or (ii) using the files as included with a Microsoft product subject + * to that product's license terms. Microsoft reserves all other rights to the + * files not expressly granted by Microsoft, whether by implication, estoppel + * or otherwise. Insofar as a script file is dual licensed under GPL, + * Microsoft neither took the code under GPL nor distributes it thereunder but + * under the terms set out in this paragraph. All notices and licenses + * below are for informational purposes only. + * + * NUGET: END LICENSE TEXT */ + +/** +* bootstrap.js v3.0.0 by @fat and @mdo +* Copyright 2013 Twitter Inc. +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +if (!jQuery) { throw new Error("Bootstrap requires jQuery") } + +/* ======================================================================== + * Bootstrap: transition.js v3.0.0 + * http://twbs.github.com/bootstrap/javascript.html#transitions + * ======================================================================== + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== */ + + ++function ($) { "use strict"; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false, $el = this + $(this).one($.support.transition.end, function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + }) + +}(window.jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.0.0 + * http://twbs.github.com/bootstrap/javascript.html#alerts + * ======================================================================== + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== */ + + ++function ($) { "use strict"; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.hasClass('alert') ? $this : $this.parent() + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent.trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one($.support.transition.end, removeElement) + .emulateTransitionEnd(150) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + var old = $.fn.alert + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(window.jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.0.0 + * http://twbs.github.com/bootstrap/javascript.html#buttons + * ======================================================================== + * Copyright 2013 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== */ + + ++function ($) { "use strict"; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + } + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state = state + 'Text' + + if (!data.resetText) $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d); + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + .prop('checked', !this.$element.hasClass('active')) + .trigger('change') + if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active') + } + + this.$element.toggleClass('active') + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + var old = $.fn.button + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + e.preventDefault() + }) + +}(window.jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.0.0 + * http://twbs.github.com/bootstrap/javascript.html#carousel + * ======================================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== */ + + ++function ($) { "use strict"; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = + this.sliding = + this.interval = + this.$active = + this.$items = null + + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.DEFAULTS = { + interval: 5000 + , pause: 'hover' + , wrap: true + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getActiveIndex = function () { + this.$active = this.$element.find('.item.active') + this.$items = this.$active.parent().children() + + return this.$items.index(this.$active) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getActiveIndex() + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid', function () { that.to(pos) }) + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || $active[type]() + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var fallback = type == 'next' ? 'first' : 'last' + var that = this + + if (!$next.length) { + if (!this.options.wrap) return + $next = this.$element.find('.item')[fallback]() + } + + this.sliding = true + + isCycling && this.pause() + + var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction }) + + if ($next.hasClass('active')) return + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + this.$element.one('slid', function () { + var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) + $nextIndicator && $nextIndicator.addClass('active') + }) + } + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + .emulateTransitionEnd(600) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var $this = $(this), href + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + $target.carousel(options) + + if (slideIndex = $this.attr('data-slide-to')) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + }) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + $carousel.carousel($carousel.data()) + }) + }) + +}(window.jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.0.0 + * http://twbs.github.com/bootstrap/javascript.html#collapse + * ======================================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== */ + + ++function ($) { "use strict"; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.transitioning = null + + if (this.options.parent) this.$parent = $(this.options.parent) + if (this.options.toggle) this.toggle() + } + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var actives = this.$parent && this.$parent.find('> .panel > .in') + + if (actives && actives.length) { + var hasData = actives.data('bs.collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing') + [dimension](0) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('in') + [dimension]('auto') + this.transitioning = 0 + this.$element.trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one($.support.transition.end, $.proxy(complete, this)) + .emulateTransitionEnd(350) + [dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element + [dimension](this.$element[dimension]()) + [0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse') + .removeClass('in') + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .trigger('hidden.bs.collapse') + .removeClass('collapsing') + .addClass('collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one($.support.transition.end, $.proxy(complete, this)) + .emulateTransitionEnd(350) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + var old = $.fn.collapse + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + var target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + var $target = $(target) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + var parent = $this.attr('data-parent') + var $parent = parent && $(parent) + + if (!data || !data.transitioning) { + if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed') + $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + } + + $target.collapse(option) + }) + +}(window.jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.0.0 + * http://twbs.github.com/bootstrap/javascript.html#dropdowns + * ======================================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== */ + + ++function ($) { "use strict"; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle=dropdown]' + var Dropdown = function (element) { + var $el = $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we we use a backdrop because click events don't delegate + $('