From 654631966ee4eeec020ed08050910c9022707491 Mon Sep 17 00:00:00 2001 From: James South Date: Sun, 16 Feb 2014 16:48:58 +0000 Subject: [PATCH] Adding Mvc5 Test Former-commit-id: 987f70d48f171d5287cc9c3822dfea0346e53a24 --- .gitignore | 4 - ....csproj => ImageProcessor.Web_NET4.csproj} | 0 src/ImageProcessor.sln | 23 +- src/TestWebsites/.gitignore | 3 + ...te.csproj => Test_Website_MVC_NET4.csproj} | 32 +- .../App_Start/BundleConfig.cs | 31 + .../App_Start/FilterConfig.cs | 13 + .../App_Start/RouteConfig.cs | 23 + .../App_Start/Startup.Auth.cs | 38 + .../Test_Website_MVC5_NET45/Content/Site.css | 42 + .../Content/bootstrap.css.REMOVED.git-id | 1 + .../Content/bootstrap.min.css.REMOVED.git-id | 1 + .../Controllers/AccountController.cs | 408 ++++ .../Controllers/HomeController.cs | 30 + .../NET45/Test_Website_MVC5_NET45/Global.asax | 1 + .../Test_Website_MVC5_NET45/Global.asax.cs | 21 + .../Models/AccountViewModels.cs | 63 + .../Models/IdentityModels.cs | 17 + .../Project_Readme.html | 151 ++ .../Properties/AssemblyInfo.cs | 35 + .../Scripts/_references.js | Bin 0 -> 396 bytes .../Scripts/bootstrap.js | 2014 +++++++++++++++++ .../Scripts/bootstrap.min.js | 21 + ...uery-1.10.2.intellisense.js.REMOVED.git-id | 1 + .../Scripts/jquery-1.10.2.js.REMOVED.git-id | 1 + .../jquery-1.10.2.min.js.REMOVED.git-id | 1 + .../jquery-1.10.2.min.map.REMOVED.git-id | 1 + .../Scripts/jquery.validate-vsdoc.js | 1302 +++++++++++ .../Scripts/jquery.validate.js | 1245 ++++++++++ .../Scripts/jquery.validate.min.js | 16 + .../Scripts/jquery.validate.unobtrusive.js | 344 +++ .../jquery.validate.unobtrusive.min.js | 19 + .../Scripts/modernizr-2.6.2.js | 1393 ++++++++++++ .../Scripts/respond.js | 340 +++ .../Scripts/respond.min.js | 20 + .../NET45/Test_Website_MVC5_NET45/Startup.cs | 14 + .../Test_Website_MVC5_NET45.csproj | 275 +++ .../Account/ExternalLoginConfirmation.cshtml | 36 + .../Views/Account/ExternalLoginFailure.cshtml | 6 + .../Views/Account/Login.cshtml | 58 + .../Views/Account/Manage.cshtml | 29 + .../Views/Account/Register.cshtml | 41 + .../Account/_ChangePasswordPartial.cshtml | 36 + .../Account/_ExternalLoginsListPartial.cshtml | 31 + .../Account/_RemoveAccountPartial.cshtml | 34 + .../Views/Account/_SetPasswordPartial.cshtml | 32 + .../Views/Home/About.cshtml | 7 + .../Views/Home/Contact.cshtml | 17 + .../Views/Home/Index.cshtml | 32 + .../Views/Shared/Error.cshtml | 9 + .../Views/Shared/_Layout.cshtml | 44 + .../Views/Shared/_LoginPartial.cshtml | 22 + .../Test_Website_MVC5_NET45/Views/Web.config | 35 + .../Views/_ViewStart.cshtml | 3 + .../Test_Website_MVC5_NET45/Web.Debug.config | 30 + .../Web.Release.config | 31 + .../NET45/Test_Website_MVC5_NET45/Web.config | 74 + .../config/imageprocessor/cache.config | 3 + .../config/imageprocessor/processing.config | 43 + .../config/imageprocessor/security.config | 14 + .../NET45/Test_Website_MVC5_NET45/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_Website_MVC5_NET45/packages.config | 31 + ...5.csproj => Test_Website_MVC_NET45.csproj} | 28 - .../gifts/cmyk.png.REMOVED.git-id | 1 - .../NET45/Test_Website_NET45/packages.config | 4 - .../Test_Website_Webforms_NET45.csproj | 80 +- src/packages/repositories.config | 1 + 71 files changed, 8842 insertions(+), 142 deletions(-) rename src/ImageProcessor.Web/NET4/{ImageProcessor.Web.csproj => ImageProcessor.Web_NET4.csproj} (100%) create mode 100644 src/TestWebsites/.gitignore rename src/TestWebsites/NET4/{Test_Website.csproj => Test_Website_MVC_NET4.csproj} (89%) create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/BundleConfig.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/FilterConfig.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/RouteConfig.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/Startup.Auth.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/Site.css create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/bootstrap.css.REMOVED.git-id create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/bootstrap.min.css.REMOVED.git-id create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Controllers/AccountController.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Controllers/HomeController.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Global.asax create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Global.asax.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Models/AccountViewModels.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Models/IdentityModels.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Project_Readme.html create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Properties/AssemblyInfo.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/_references.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/bootstrap.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/bootstrap.min.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery-1.10.2.intellisense.js.REMOVED.git-id create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery-1.10.2.js.REMOVED.git-id create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery-1.10.2.min.js.REMOVED.git-id create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery-1.10.2.min.map.REMOVED.git-id create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery.validate-vsdoc.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery.validate.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery.validate.min.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery.validate.unobtrusive.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/jquery.validate.unobtrusive.min.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/modernizr-2.6.2.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/respond.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/respond.min.js create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Startup.cs create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Test_Website_MVC5_NET45.csproj create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/ExternalLoginConfirmation.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/ExternalLoginFailure.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/Login.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/Manage.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/Register.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/_ChangePasswordPartial.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/_ExternalLoginsListPartial.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/_RemoveAccountPartial.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Account/_SetPasswordPartial.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Home/About.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Home/Contact.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Home/Index.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Shared/Error.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Shared/_Layout.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Shared/_LoginPartial.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/Web.config create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Views/_ViewStart.cshtml create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Web.Debug.config create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Web.Release.config create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/Web.config create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/config/imageprocessor/cache.config create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/config/imageprocessor/processing.config create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/config/imageprocessor/security.config create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/favicon.ico create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/fonts/glyphicons-halflings-regular.eot create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/fonts/glyphicons-halflings-regular.svg create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/fonts/glyphicons-halflings-regular.ttf create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/fonts/glyphicons-halflings-regular.woff create mode 100644 src/TestWebsites/NET45/Test_Website_MVC5_NET45/packages.config rename src/TestWebsites/NET45/Test_Website_NET45/{Test_Website_NET45.csproj => Test_Website_MVC_NET45.csproj} (81%) delete mode 100644 src/TestWebsites/NET45/Test_Website_NET45/gifts/cmyk.png.REMOVED.git-id diff --git a/.gitignore b/.gitignore index f2915d97f..a9a634616 100644 --- a/.gitignore +++ b/.gitignore @@ -163,7 +163,3 @@ pip-log.txt # Mac crap .DS_Store - -# cached images -**/cache/ -#Test_Websites/**/Images/ \ No newline at end of file diff --git a/src/ImageProcessor.Web/NET4/ImageProcessor.Web.csproj b/src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj similarity index 100% rename from src/ImageProcessor.Web/NET4/ImageProcessor.Web.csproj rename to src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj diff --git a/src/ImageProcessor.sln b/src/ImageProcessor.sln index 2c2d93d2a..2860e061c 100644 --- a/src/ImageProcessor.sln +++ b/src/ImageProcessor.sln @@ -22,16 +22,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Tests", "Ima EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web.Tests", "Web.Test\Web.Tests.csproj", "{23CE0FC0-9E59-4C93-A604-A4A98A6284D1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Website", "TestWebsites\NET4\Test_Website.csproj", "{30327C08-7574-4D7E-AC95-6A58753C6855}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Website_MVC_NET4", "TestWebsites\NET4\Test_Website_MVC_NET4.csproj", "{30327C08-7574-4D7E-AC95-6A58753C6855}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Website_NET45", "TestWebsites\NET45\Test_Website_NET45\Test_Website_NET45.csproj", "{F6A208E9-C18F-43E9-B051-3C6EED30FDAF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Website_MVC_NET45", "TestWebsites\NET45\Test_Website_NET45\Test_Website_MVC_NET45.csproj", "{F6A208E9-C18F-43E9-B051-3C6EED30FDAF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web", "ImageProcessor.Web\NET4\ImageProcessor.Web.csproj", "{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web_NET4", "ImageProcessor.Web\NET4\ImageProcessor.Web_NET4.csproj", "{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web_NET45", "ImageProcessor.Web\NET45\ImageProcessor.Web_NET45.csproj", "{D011A778-59C8-4BFA-A770-C350216BF161}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Website_Webforms_NET45", "TestWebsites\NET45\Test_Website_Webforms_NET45\Test_Website_Webforms_NET45.csproj", "{8DA47D8C-DB1A-4D82-843F-896AB9C3B3D2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Website_MVC5_NET45", "TestWebsites\NET45\Test_Website_MVC5_NET45\Test_Website_MVC5_NET45.csproj", "{210AFC40-E24E-4B1D-BF3E-331C2138D5D9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution All|Any CPU = All|Any CPU @@ -170,6 +172,21 @@ Global {8DA47D8C-DB1A-4D82-843F-896AB9C3B3D2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {8DA47D8C-DB1A-4D82-843F-896AB9C3B3D2}.Release|Mixed Platforms.Build.0 = Release|Any CPU {8DA47D8C-DB1A-4D82-843F-896AB9C3B3D2}.Release|x86.ActiveCfg = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.All|Any CPU.ActiveCfg = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.All|Any CPU.Build.0 = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.All|Mixed Platforms.ActiveCfg = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.All|Mixed Platforms.Build.0 = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.All|x86.ActiveCfg = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Debug|x86.ActiveCfg = Debug|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Release|Any CPU.Build.0 = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {210AFC40-E24E-4B1D-BF3E-331C2138D5D9}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/TestWebsites/.gitignore b/src/TestWebsites/.gitignore new file mode 100644 index 000000000..8df228928 --- /dev/null +++ b/src/TestWebsites/.gitignore @@ -0,0 +1,3 @@ +# Cached images and test image copies +**/cache/ +**/images diff --git a/src/TestWebsites/NET4/Test_Website.csproj b/src/TestWebsites/NET4/Test_Website_MVC_NET4.csproj similarity index 89% rename from src/TestWebsites/NET4/Test_Website.csproj rename to src/TestWebsites/NET4/Test_Website_MVC_NET4.csproj index 896017f0e..8a92fd9da 100644 --- a/src/TestWebsites/NET4/Test_Website.csproj +++ b/src/TestWebsites/NET4/Test_Website_MVC_NET4.csproj @@ -108,34 +108,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer @@ -155,9 +127,9 @@ - + {4f7050f2-465f-4e10-8db2-2fb97ac6aa43} - ImageProcessor.Web + ImageProcessor.Web_NET4 {3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E} diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/BundleConfig.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/BundleConfig.cs new file mode 100644 index 000000000..f7303e1ac --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/BundleConfig.cs @@ -0,0 +1,31 @@ +using System.Web; +using System.Web.Optimization; + +namespace Test_Website_MVC5_NET45 +{ + public class BundleConfig + { + // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 + public static void RegisterBundles(BundleCollection bundles) + { + bundles.Add(new ScriptBundle("~/bundles/jquery").Include( + "~/Scripts/jquery-{version}.js")); + + bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( + "~/Scripts/jquery.validate*")); + + // Use the development version of Modernizr to develop with and learn from. Then, when you're + // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. + bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( + "~/Scripts/modernizr-*")); + + bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( + "~/Scripts/bootstrap.js", + "~/Scripts/respond.js")); + + bundles.Add(new StyleBundle("~/Content/css").Include( + "~/Content/bootstrap.css", + "~/Content/site.css")); + } + } +} diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/FilterConfig.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/FilterConfig.cs new file mode 100644 index 000000000..5eabb7f28 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/FilterConfig.cs @@ -0,0 +1,13 @@ +using System.Web; +using System.Web.Mvc; + +namespace Test_Website_MVC5_NET45 +{ + public class FilterConfig + { + public static void RegisterGlobalFilters(GlobalFilterCollection filters) + { + filters.Add(new HandleErrorAttribute()); + } + } +} diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/RouteConfig.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/RouteConfig.cs new file mode 100644 index 000000000..d80f45e97 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/RouteConfig.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; + +namespace Test_Website_MVC5_NET45 +{ + public class RouteConfig + { + public static void RegisterRoutes(RouteCollection routes) + { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } + ); + } + } +} diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/Startup.Auth.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/Startup.Auth.cs new file mode 100644 index 000000000..60c5fdf1c --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/App_Start/Startup.Auth.cs @@ -0,0 +1,38 @@ +using Microsoft.AspNet.Identity; +using Microsoft.Owin; +using Microsoft.Owin.Security.Cookies; +using Owin; + +namespace Test_Website_MVC5_NET45 +{ + public partial class Startup + { + // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 + public void ConfigureAuth(IAppBuilder app) + { + // Enable the application to use a cookie to store information for the signed in user + app.UseCookieAuthentication(new CookieAuthenticationOptions + { + AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, + LoginPath = new PathString("/Account/Login") + }); + // Use a cookie to temporarily store information about a user logging in with a third party login provider + app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); + + // Uncomment the following lines to enable logging in with third party login providers + //app.UseMicrosoftAccountAuthentication( + // clientId: "", + // clientSecret: ""); + + //app.UseTwitterAuthentication( + // consumerKey: "", + // consumerSecret: ""); + + //app.UseFacebookAuthentication( + // appId: "", + // appSecret: ""); + + //app.UseGoogleAuthentication(); + } + } +} \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/Site.css b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/Site.css new file mode 100644 index 000000000..ad542f375 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/Site.css @@ -0,0 +1,42 @@ +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; +} \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/bootstrap.css.REMOVED.git-id b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/bootstrap.css.REMOVED.git-id new file mode 100644 index 000000000..4ee247a2a --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/bootstrap.css.REMOVED.git-id @@ -0,0 +1 @@ +6d6e68281ddecfe6611fbb2c9f79306e69359cab \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/bootstrap.min.css.REMOVED.git-id b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/bootstrap.min.css.REMOVED.git-id new file mode 100644 index 000000000..8c6c0bf8a --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Content/bootstrap.min.css.REMOVED.git-id @@ -0,0 +1 @@ +df89a5030f2192f2efc2eef1e625b588903b735e \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Controllers/AccountController.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Controllers/AccountController.cs new file mode 100644 index 000000000..ef7514e03 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Controllers/AccountController.cs @@ -0,0 +1,408 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using System.Web; +using System.Web.Mvc; +using Microsoft.AspNet.Identity; +using Microsoft.AspNet.Identity.EntityFramework; +using Microsoft.Owin.Security; +using Test_Website_MVC5_NET45.Models; + +namespace Test_Website_MVC5_NET45.Controllers +{ + [Authorize] + public class AccountController : Controller + { + public AccountController() + : this(new UserManager(new UserStore(new ApplicationDbContext()))) + { + } + + public AccountController(UserManager userManager) + { + UserManager = userManager; + } + + public UserManager UserManager { get; private set; } + + // + // GET: /Account/Login + [AllowAnonymous] + public ActionResult Login(string returnUrl) + { + ViewBag.ReturnUrl = returnUrl; + return View(); + } + + // + // POST: /Account/Login + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Login(LoginViewModel model, string returnUrl) + { + if (ModelState.IsValid) + { + var user = await UserManager.FindAsync(model.UserName, model.Password); + if (user != null) + { + await SignInAsync(user, model.RememberMe); + return RedirectToLocal(returnUrl); + } + else + { + ModelState.AddModelError("", "Invalid username or password."); + } + } + + // If we got this far, something failed, redisplay form + return View(model); + } + + // + // GET: /Account/Register + [AllowAnonymous] + public ActionResult Register() + { + return View(); + } + + // + // POST: /Account/Register + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Register(RegisterViewModel model) + { + if (ModelState.IsValid) + { + var user = new ApplicationUser() { UserName = model.UserName }; + var result = await UserManager.CreateAsync(user, model.Password); + if (result.Succeeded) + { + await SignInAsync(user, isPersistent: false); + return RedirectToAction("Index", "Home"); + } + else + { + AddErrors(result); + } + } + + // If we got this far, something failed, redisplay form + return View(model); + } + + // + // POST: /Account/Disassociate + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Disassociate(string loginProvider, string providerKey) + { + ManageMessageId? message = null; + IdentityResult result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey)); + if (result.Succeeded) + { + message = ManageMessageId.RemoveLoginSuccess; + } + else + { + message = ManageMessageId.Error; + } + return RedirectToAction("Manage", new { Message = message }); + } + + // + // GET: /Account/Manage + public ActionResult Manage(ManageMessageId? message) + { + ViewBag.StatusMessage = + message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." + : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set." + : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed." + : message == ManageMessageId.Error ? "An error has occurred." + : ""; + ViewBag.HasLocalPassword = HasPassword(); + ViewBag.ReturnUrl = Url.Action("Manage"); + return View(); + } + + // + // POST: /Account/Manage + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Manage(ManageUserViewModel model) + { + bool hasPassword = HasPassword(); + ViewBag.HasLocalPassword = hasPassword; + ViewBag.ReturnUrl = Url.Action("Manage"); + if (hasPassword) + { + if (ModelState.IsValid) + { + IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword); + if (result.Succeeded) + { + return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess }); + } + else + { + AddErrors(result); + } + } + } + else + { + // User does not have a password so remove any validation errors caused by a missing OldPassword field + ModelState state = ModelState["OldPassword"]; + if (state != null) + { + state.Errors.Clear(); + } + + if (ModelState.IsValid) + { + IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword); + if (result.Succeeded) + { + return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess }); + } + else + { + AddErrors(result); + } + } + } + + // If we got this far, something failed, redisplay form + return View(model); + } + + // + // POST: /Account/ExternalLogin + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public ActionResult ExternalLogin(string provider, string returnUrl) + { + // Request a redirect to the external login provider + return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl })); + } + + // + // GET: /Account/ExternalLoginCallback + [AllowAnonymous] + public async Task ExternalLoginCallback(string returnUrl) + { + var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); + if (loginInfo == null) + { + return RedirectToAction("Login"); + } + + // Sign in the user with this external login provider if the user already has a login + var user = await UserManager.FindAsync(loginInfo.Login); + if (user != null) + { + await SignInAsync(user, isPersistent: false); + return RedirectToLocal(returnUrl); + } + else + { + // If the user does not have an account, then prompt the user to create an account + ViewBag.ReturnUrl = returnUrl; + ViewBag.LoginProvider = loginInfo.Login.LoginProvider; + return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = loginInfo.DefaultUserName }); + } + } + + // + // POST: /Account/LinkLogin + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult LinkLogin(string provider) + { + // Request a redirect to the external login provider to link a login for the current user + return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account"), User.Identity.GetUserId()); + } + + // + // GET: /Account/LinkLoginCallback + public async Task LinkLoginCallback() + { + var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId()); + if (loginInfo == null) + { + return RedirectToAction("Manage", new { Message = ManageMessageId.Error }); + } + var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login); + if (result.Succeeded) + { + return RedirectToAction("Manage"); + } + return RedirectToAction("Manage", new { Message = ManageMessageId.Error }); + } + + // + // POST: /Account/ExternalLoginConfirmation + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) + { + if (User.Identity.IsAuthenticated) + { + return RedirectToAction("Manage"); + } + + if (ModelState.IsValid) + { + // Get the information about the user from the external login provider + var info = await AuthenticationManager.GetExternalLoginInfoAsync(); + if (info == null) + { + return View("ExternalLoginFailure"); + } + var user = new ApplicationUser() { UserName = model.UserName }; + var result = await UserManager.CreateAsync(user); + if (result.Succeeded) + { + result = await UserManager.AddLoginAsync(user.Id, info.Login); + if (result.Succeeded) + { + await SignInAsync(user, isPersistent: false); + return RedirectToLocal(returnUrl); + } + } + AddErrors(result); + } + + ViewBag.ReturnUrl = returnUrl; + return View(model); + } + + // + // POST: /Account/LogOff + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult LogOff() + { + AuthenticationManager.SignOut(); + return RedirectToAction("Index", "Home"); + } + + // + // GET: /Account/ExternalLoginFailure + [AllowAnonymous] + public ActionResult ExternalLoginFailure() + { + return View(); + } + + [ChildActionOnly] + public ActionResult RemoveAccountList() + { + var linkedAccounts = UserManager.GetLogins(User.Identity.GetUserId()); + ViewBag.ShowRemoveButton = HasPassword() || linkedAccounts.Count > 1; + return (ActionResult)PartialView("_RemoveAccountPartial", linkedAccounts); + } + + protected override void Dispose(bool disposing) + { + if (disposing && UserManager != null) + { + UserManager.Dispose(); + UserManager = null; + } + base.Dispose(disposing); + } + + #region Helpers + // Used for XSRF protection when adding external logins + private const string XsrfKey = "XsrfId"; + + private IAuthenticationManager AuthenticationManager + { + get + { + return HttpContext.GetOwinContext().Authentication; + } + } + + private async Task SignInAsync(ApplicationUser user, bool isPersistent) + { + AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); + var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); + AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity); + } + + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { + ModelState.AddModelError("", error); + } + } + + private bool HasPassword() + { + var user = UserManager.FindById(User.Identity.GetUserId()); + if (user != null) + { + return user.PasswordHash != null; + } + return false; + } + + public enum ManageMessageId + { + ChangePasswordSuccess, + SetPasswordSuccess, + RemoveLoginSuccess, + Error + } + + private ActionResult RedirectToLocal(string returnUrl) + { + if (Url.IsLocalUrl(returnUrl)) + { + return Redirect(returnUrl); + } + else + { + return RedirectToAction("Index", "Home"); + } + } + + private class ChallengeResult : HttpUnauthorizedResult + { + public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null) + { + } + + public ChallengeResult(string provider, string redirectUri, string userId) + { + LoginProvider = provider; + RedirectUri = redirectUri; + UserId = userId; + } + + public string LoginProvider { get; set; } + public string RedirectUri { get; set; } + public string UserId { get; set; } + + public override void ExecuteResult(ControllerContext context) + { + var properties = new AuthenticationProperties() { RedirectUri = RedirectUri }; + if (UserId != null) + { + properties.Dictionary[XsrfKey] = UserId; + } + context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); + } + } + #endregion + } +} \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Controllers/HomeController.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Controllers/HomeController.cs new file mode 100644 index 000000000..5080a1bf5 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Controllers/HomeController.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace Test_Website_MVC5_NET45.Controllers +{ + public class HomeController : Controller + { + public ActionResult Index() + { + return View(); + } + + public ActionResult About() + { + ViewBag.Message = "Your application description page."; + + return View(); + } + + public ActionResult Contact() + { + ViewBag.Message = "Your contact page."; + + return View(); + } + } +} \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Global.asax b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Global.asax new file mode 100644 index 000000000..98f5cf943 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="Test_Website_MVC5_NET45.MvcApplication" Language="C#" %> diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Global.asax.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Global.asax.cs new file mode 100644 index 000000000..a0aa5366f --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Global.asax.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Optimization; +using System.Web.Routing; + +namespace Test_Website_MVC5_NET45 +{ + public class MvcApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + AreaRegistration.RegisterAllAreas(); + FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); + RouteConfig.RegisterRoutes(RouteTable.Routes); + BundleConfig.RegisterBundles(BundleTable.Bundles); + } + } +} diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Models/AccountViewModels.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Models/AccountViewModels.cs new file mode 100644 index 000000000..6c841db43 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Models/AccountViewModels.cs @@ -0,0 +1,63 @@ +using System.ComponentModel.DataAnnotations; + +namespace Test_Website_MVC5_NET45.Models +{ + public class ExternalLoginConfirmationViewModel + { + [Required] + [Display(Name = "User name")] + public string UserName { get; set; } + } + + public class ManageUserViewModel + { + [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 LoginViewModel + { + [Required] + [Display(Name = "User name")] + public string UserName { 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] + [Display(Name = "User name")] + public string UserName { 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; } + } +} diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Models/IdentityModels.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Models/IdentityModels.cs new file mode 100644 index 000000000..6f0ec8d06 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Models/IdentityModels.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNet.Identity.EntityFramework; + +namespace Test_Website_MVC5_NET45.Models +{ + // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. + public class ApplicationUser : IdentityUser + { + } + + public class ApplicationDbContext : IdentityDbContext + { + public ApplicationDbContext() + : base("DefaultConnection") + { + } + } +} \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Project_Readme.html b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Project_Readme.html new file mode 100644 index 000000000..cb9e79386 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Project_Readme.html @@ -0,0 +1,151 @@ + + + + + Your ASP.NET application + + + + + + +
+
+

This application consists of:

+
    +
  • Sample pages showing basic nav between Home, About, and Contact
  • +
  • Theming using Bootstrap
  • +
  • Authentication, if selected, shows how to register and sign in
  • +
  • ASP.NET features managed using NuGet
  • +
+
+ + + + + +
+

Get help

+ +
+
+ + + \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Properties/AssemblyInfo.cs b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..bde14ea74 --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Test_Website_MVC5_NET45")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Test_Website_MVC5_NET45")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b611b339-de6d-4308-a532-79f2749956d3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/_references.js b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/_references.js new file mode 100644 index 0000000000000000000000000000000000000000..518a95992a99e9a3b60c01f77668ad6fb1fcbf08 GIT binary patch literal 396 zcmbu5F%H5o3`O6J#2qU30%c$V?vj!qsGxzQ3~+eh$E-|Lk!35kpTGTnEhw*IgX7LX zB=ewWufHJgXgMqLY?&#aR239e>e?}7V*Ou2Qsy8lz7T?{t|AN^t@|Rnw|viur|N1} u%vsBd?=<^Aa>vbdC26l|#A;ZMrnb@>r9RufJSgw-Ah`NpcLHYpnGd@HB literal 0 HcmV?d00001 diff --git a/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/bootstrap.js b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/Scripts/bootstrap.js new file mode 100644 index 000000000..5aa9982ed --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_MVC5_NET45/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 + $('