diff --git a/Teknik/App_Start/BundleConfig.cs b/Teknik/App_Start/BundleConfig.cs index 7f5da16..8a80b3f 100644 --- a/Teknik/App_Start/BundleConfig.cs +++ b/Teknik/App_Start/BundleConfig.cs @@ -10,32 +10,27 @@ namespace Teknik { BundleTable.EnableOptimizations = true; - bundles.Add(new ScriptBundle("~/bundles/jquery").Include( - "~/Scripts/jquery-{version}.js")); + bundles.Add(new StyleBundle("~/Content/Common").Include( + "~/Content/bootstrap.css", + "~/Content/font-awesome.css", + "~/Content/teknik.css")); - bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( - "~/Scripts/jquery.validate*")); + bundles.Add(new ScriptBundle("~/bundles/common").Include( + "~/Scripts/jquery-{version}.js", + "~/Scripts/jquery.validate*", + "~/Scripts/common.js", + "~/Scripts/bootstrap.js", + "~/Scripts/bootstrap-select.js", + "~/Scripts/respond.js")); // 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 ScriptBundle("~/bundles/markdown").Include( "~/Scripts/PageDown/Markdown.Converter.js", "~/Scripts/PageDown/Markdown.Sanitizer.js")); - - bundles.Add(new ScriptBundle("~/bundles/common").Include( - "~/Scripts/common.js")); - - bundles.Add(new StyleBundle("~/Content/Common").Include( - "~/Content/bootstrap.css", - "~/Content/font-awesome.css", - "~/Content/teknik.css")); } } } diff --git a/Teknik/Areas/Home/HomeAreaRegistration.cs b/Teknik/Areas/Home/HomeAreaRegistration.cs index 88e6fbc..d3134e6 100644 --- a/Teknik/Areas/Home/HomeAreaRegistration.cs +++ b/Teknik/Areas/Home/HomeAreaRegistration.cs @@ -48,6 +48,11 @@ namespace Teknik.Areas.Home // Register Style Bundles BundleTable.Bundles.Add(new StyleBundle("~/Content/home").Include( "~/Areas/Home/Content/Home.css")); + + // Register Script Bundles + BundleTable.Bundles.Add(new ScriptBundle("~/bundles/home").Include( + "~/Scripts/PageDown/Markdown.Converter.js", + "~/Scripts/PageDown/Markdown.Sanitizer.js")); } } } \ No newline at end of file diff --git a/Teknik/Areas/Home/Views/Home/Index.cshtml b/Teknik/Areas/Home/Views/Home/Index.cshtml index 83d4ea0..74c0fbb 100644 --- a/Teknik/Areas/Home/Views/Home/Index.cshtml +++ b/Teknik/Areas/Home/Views/Home/Index.cshtml @@ -3,6 +3,7 @@ @using Teknik.Areas.Blog.Models @Styles.Render("~/Content/home") +@Scripts.Render("~/bundles/home")
diff --git a/Teknik/Areas/Profile/Controllers/ProfileController.cs b/Teknik/Areas/Profile/Controllers/ProfileController.cs index f5cd289..e8d5956 100644 --- a/Teknik/Areas/Profile/Controllers/ProfileController.cs +++ b/Teknik/Areas/Profile/Controllers/ProfileController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data.Entity; using System.Linq; using System.Web; using System.Web.Mvc; @@ -22,10 +23,41 @@ namespace Teknik.Areas.Profile.Controllers [AllowAnonymous] public ActionResult Index(string username) { - ViewBag.Title = Config.Title + " - Profile"; - ViewBag.Message = "View Your Profile"; + if (string.IsNullOrEmpty(username)) + { + username = User.Identity.Name; + } + + ProfileViewModel model = null; + ViewBag.Title = "User Does Not Exist - " + Config.Title; + ViewBag.Message = "The User does not exist"; + + User user = db.Users.Where(u => u.Username == username).First(); - return View(new ProfileViewModel()); + if (user != null) + { + ViewBag.Title = username + "'s Profile - " + Config.Title; + ViewBag.Message = "Viewing " + username + "'s Profile"; + + model = new ProfileViewModel(); + model.UserID = user.UserId; + model.Username = user.Username; + model.Email = string.Format("{0}@{1}", user.Username, Config.Host); + model.JoinDate = user.JoinDate; + model.LastSeen = user.LastSeen; + model.About = user.About; + model.Website = user.Website; + model.Quote = user.Quote; + + // fill in Blog details + Blog.Models.Blog blog = db.Blogs.Where(b => b.UserId == user.UserId && b.BlogId != Constants.SERVERBLOGID).First(); + if (blog != null) + { + model.BlogTitle = blog.Title; + model.BlogDescription = blog.Description; + } + } + return View(model); } [HttpGet] @@ -120,5 +152,65 @@ namespace Teknik.Areas.Profile.Controllers return Json(new { error = "You must include all fields." }); } + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Edit(string curPass, string newPass, string newPassConfirm, string website, string quote, string about, string blogTitle, string blogDesc) + { + if (ModelState.IsValid) + { + User user = db.Users.Where(u => u.Username == User.Identity.Name).First(); + if (user != null) + { + Blog.Models.Blog blog = db.Blogs.Where(b => b.UserId == user.UserId && b.BlogId != Constants.SERVERBLOGID).First(); + if (blog != null) + { + // Changing Password? + if (!string.IsNullOrEmpty(curPass) && (!string.IsNullOrEmpty(newPass) || !string.IsNullOrEmpty(newPassConfirm))) + { + // Old Password Valid? + if (SHA384.Hash(User.Identity.Name, curPass) != user.HashedPassword) + { + return Json(new { error = "Invalid Original Password." }); + } + // The New Password Match? + if (newPass != newPassConfirm) + { + return Json(new { error = "New Password Must Match." }); + } + user.HashedPassword = SHA384.Hash(User.Identity.Name, newPass); + } + user.Website = website; + user.Quote = quote; + user.About = about; + + blog.Title = blogTitle; + blog.Description = blogDesc; + + db.Entry(blog).State = EntityState.Modified; + db.Entry(user).State = EntityState.Modified; + db.SaveChanges(); + return Json(new { result = true }); + } + } + } + return Json(new { error = "Unable to save profile." }); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Delete(int postID) + { + if (ModelState.IsValid) + { + User user = db.Users.Where(u => u.Username == User.Identity.Name).First(); + if (user != null) + { + db.Users.Remove(user); + db.SaveChanges(); + return Redirect(Url.SubRouteUrl("www", "Home.Index")); + } + } + return Json(new { error = "Unable to delete user." }); + } } } \ No newline at end of file diff --git a/Teknik/Areas/Profile/Models/User.cs b/Teknik/Areas/Profile/Models/User.cs index 2637160..4d2fee3 100644 --- a/Teknik/Areas/Profile/Models/User.cs +++ b/Teknik/Areas/Profile/Models/User.cs @@ -19,6 +19,12 @@ namespace Teknik.Areas.Profile.Models public List Groups { get; set; } + public string About { get; set; } + + public string Website { get; set; } + + public string Quote { get; set; } + public User() { Username = String.Empty; @@ -26,6 +32,9 @@ namespace Teknik.Areas.Profile.Models JoinDate = DateTime.Now; LastSeen = DateTime.Now; Groups = new List(); + About = string.Empty; + Website = string.Empty; + Quote = string.Empty; } } } \ No newline at end of file diff --git a/Teknik/Areas/Profile/ProfileAreaRegistration.cs b/Teknik/Areas/Profile/ProfileAreaRegistration.cs index da5b5f6..561a5da 100644 --- a/Teknik/Areas/Profile/ProfileAreaRegistration.cs +++ b/Teknik/Areas/Profile/ProfileAreaRegistration.cs @@ -1,4 +1,5 @@ using System.Web.Mvc; +using System.Web.Optimization; namespace Teknik.Areas.Profile { @@ -45,7 +46,7 @@ namespace Teknik.Areas.Profile context.MapSubdomainRoute( "Profile.Action", // Route name "dev", - "Profile/{controller}/{action}", // URL with parameters + "Profile/Action/{action}", // URL with parameters new { controller = "Profile", action = "Index" }, // Parameter defaults new[] { typeof(Controllers.ProfileController).Namespace } ); @@ -80,10 +81,19 @@ namespace Teknik.Areas.Profile context.MapSubdomainRoute( "Profile.Action", // Route name "profile", - "{controller}/{action}", // URL with parameters + "Action/{action}", // URL with parameters new { controller = "Profile", action = "Index" }, // Parameter defaults new[] { typeof(Controllers.ProfileController).Namespace } ); + + // Register Script Bundle + BundleTable.Bundles.Add(new ScriptBundle("~/bundles/profile").Include( + "~/Scripts/bootbox/bootbox.min.js", + "~/Scripts/PageDown/Markdown.Converter.js", + "~/Scripts/PageDown/Markdown.Sanitizer.js", + "~/Scripts/bootstrap/markdown/bootstrap-markdown.js", + "~/Scripts/jquery.blockUI.js", + "~/Areas/Profile/Scripts/Profile.js")); } } } \ No newline at end of file diff --git a/Teknik/Areas/Profile/Scripts/Profile.js b/Teknik/Areas/Profile/Scripts/Profile.js new file mode 100644 index 0000000..f5e0175 --- /dev/null +++ b/Teknik/Areas/Profile/Scripts/Profile.js @@ -0,0 +1,61 @@ +$(document).ready(function () { + $('#delete_account').click(function () { + bootbox.confirm("Are you sure you want to delete your account?", function (result) { + if (result) { + $.ajax({ + type: "POST", + url: deleteUserURL, + success: function (html) { + if (html.result) { + window.location.reload(); + } + else { + $("#top_msg").css('display', 'inline', 'important'); + $("#top_msg").html('
Unable to delete your account. Please contact an Administrator.
'); + } + } + }); + } + }); + }); + + $("#update_submit").click(function () { + // Start Updating Animation + $.blockUI({ message: '

Updating...

' }); + + current_password = $("#update_password_current").val(); + password = $("#update_password").val(); + password_confirm = $("#update_password_confirm").val(); + website = $("#update_website").val(); + quote = $("#update_quote").val(); + about = $("#update_about").val(); + blog_title = $("#update_blog_title").val(); + blog_desc = $("#update_blog_description").val(); + $.ajax({ + type: "POST", + url: editUserURL, + data: { + curPass: current_password, + newPass: password, + newPassConfirm: password_confirm, + website: website, + quote: quote, + about: about, + blogTitle: blog_title, + blogDesc: blog_desc + }, + success: function (html) { + if (html.result) { + $.unblockUI(); + window.location.reload(); + } + else { + $.unblockUI(); + $("#top_msg").css('display', 'inline', 'important'); + $("#top_msg").html('
' + html.error + '
'); + } + } + }); + return false; + }); +}); \ No newline at end of file diff --git a/Teknik/Areas/Profile/ViewModels/LoginViewModel.cs b/Teknik/Areas/Profile/ViewModels/LoginViewModel.cs index 2801065..e1b9cbd 100644 --- a/Teknik/Areas/Profile/ViewModels/LoginViewModel.cs +++ b/Teknik/Areas/Profile/ViewModels/LoginViewModel.cs @@ -27,21 +27,5 @@ namespace Teknik.Areas.Profile.ViewModels public bool RememberMe { get; set; } public string ReturnUrl { get; set; } - - public bool IsValid() - { - return IsValid(Username, Password); - } - - public bool IsValid(string username, string password) - { - var myUser = db.Users.Where(b => b.Username == username).FirstOrDefault(); - - if (myUser != null && !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password)) - { - return (myUser.HashedPassword == SHA384.Hash(username, password)); - } - return false; - } } } \ No newline at end of file diff --git a/Teknik/Areas/Profile/ViewModels/ProfileViewModel.cs b/Teknik/Areas/Profile/ViewModels/ProfileViewModel.cs index 34c7d3d..66f3cc0 100644 --- a/Teknik/Areas/Profile/ViewModels/ProfileViewModel.cs +++ b/Teknik/Areas/Profile/ViewModels/ProfileViewModel.cs @@ -8,5 +8,24 @@ namespace Teknik.Areas.Profile.ViewModels { public class ProfileViewModel : ViewModelBase { + public int UserID { get; set; } + + public string Username { get; set; } + + public string Email { get; set; } + + public DateTime JoinDate { get; set; } + + public DateTime LastSeen { get; set; } + + public string About { get; set; } + + public string Website { get; set; } + + public string Quote { get; set; } + + public string BlogTitle { get; set; } + + public string BlogDescription { get; set; } } } \ No newline at end of file diff --git a/Teknik/Areas/Profile/ViewModels/RegisterViewModel.cs b/Teknik/Areas/Profile/ViewModels/RegisterViewModel.cs index 4dfc810..96a384e 100644 --- a/Teknik/Areas/Profile/ViewModels/RegisterViewModel.cs +++ b/Teknik/Areas/Profile/ViewModels/RegisterViewModel.cs @@ -9,8 +9,6 @@ namespace Teknik.Areas.Profile.ViewModels { public class RegisterViewModel : ViewModelBase { - private TeknikEntities db = new TeknikEntities(); - [Required] [Display(Name = "Username")] public string Username { get; set; } diff --git a/Teknik/Areas/Profile/Views/Profile/Index.cshtml b/Teknik/Areas/Profile/Views/Profile/Index.cshtml index 70ee289..63fa308 100644 --- a/Teknik/Areas/Profile/Views/Profile/Index.cshtml +++ b/Teknik/Areas/Profile/Views/Profile/Index.cshtml @@ -1 +1,212 @@ -@model Teknik.Areas.Profile.ViewModels.ProfileViewModel \ No newline at end of file +@model Teknik.Areas.Profile.ViewModels.ProfileViewModel + + + +@Scripts.Render("~/bundles/profile") + +@{ + bool OwnProfile = (Model.Username == User.Identity.Name); +} + +
+ @if (Model != null) + { +
+

@Model.Username>

+
+
+
+
    +
  • Profile
  • +
  • Joined @Model.JoinDate.ToString("MMMM dd, yyyy")
  • + @if (OwnProfile && User.Identity.IsAuthenticated) + { +
  • Last Seen @Model.LastSeen.ToString("MMMM dd, yyyy")
  • + } +
  • Email @Model.Email
  • + @if (!string.IsNullOrEmpty(Model.BlogTitle)) + { +
  • Blog @Model.BlogTitle
  • + } +
  • Git Public Repos
  • + @if (OwnProfile) + { +
  • + } +
+ @if (!string.IsNullOrEmpty(Model.Website)) + { +
+
Website
+ +
+ } + @if (!string.IsNullOrEmpty(Model.Quote)) + { +
+
Quote
+
@Model.Quote
+
+ } +
+
+ @if (!string.IsNullOrEmpty(Model.About) && OwnProfile) + { + + } +
+ @if (!string.IsNullOrEmpty(Model.About)) + { +
+ +
@Model.About
+
+ } + @if (OwnProfile) + { +
+
+ + +
+
+

Profile Settings

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

Blog Settings

+
+
+
+
+
+ + +
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+
+ } +
+ +
+
+ } + else + { +
+
+

Sorry, but I couldn't find that user.

+
+
+ } +
\ No newline at end of file diff --git a/Teknik/Scripts/_references.js b/Teknik/Scripts/_references.js index 0d0a3bb..87d58e0 100644 Binary files a/Teknik/Scripts/_references.js and b/Teknik/Scripts/_references.js differ diff --git a/Teknik/Scripts/bootstrap/select/bootstrap-select.js b/Teknik/Scripts/bootstrap-select.js similarity index 100% rename from Teknik/Scripts/bootstrap/select/bootstrap-select.js rename to Teknik/Scripts/bootstrap-select.js diff --git a/Teknik/Scripts/bootstrap/bootstrap.min.js b/Teknik/Scripts/bootstrap/bootstrap.min.js deleted file mode 100644 index 7c1561a..0000000 --- a/Teknik/Scripts/bootstrap/bootstrap.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Bootstrap v3.2.0 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.2.0",d.prototype.close=function(b){function c(){f.detach().trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",c).emulateTransitionEnd(150):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.2.0",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),d[e](null==f[b]?this.options[b]:f[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b).on("keydown.bs.carousel",a.proxy(this.keydown,this)),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.2.0",c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},c.prototype.keydown=function(a){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.to=function(b){var c=this,d=this.getItemIndex(this.$active=this.$element.find(".item.active"));return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=e[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:g});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,f&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(e)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:g});return a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one("bsTransitionEnd",function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger(m)),f&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(b=!b),e||d.data("bs.collapse",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};c.VERSION="3.2.0",c.DEFAULTS={toggle:!0},c.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},c.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var c=a.Event("show.bs.collapse");if(this.$element.trigger(c),!c.isDefaultPrevented()){var d=this.$parent&&this.$parent.find("> .panel > .in");if(d&&d.length){var e=d.data("bs.collapse");if(e&&e.transitioning)return;b.call(d,"hide"),e||d.data("bs.collapse",null)}var f=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[f](0),this.transitioning=1;var g=function(){this.$element.removeClass("collapsing").addClass("collapse in")[f](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return g.call(this);var h=a.camelCase(["scroll",f].join("-"));this.$element.one("bsTransitionEnd",a.proxy(g,this)).emulateTransitionEnd(350)[f](this.$element[0][h])}}},c.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},c.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var d=a.fn.collapse;a.fn.collapse=b,a.fn.collapse.Constructor=c,a.fn.collapse.noConflict=function(){return a.fn.collapse=d,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(c){var d,e=a(this),f=e.attr("data-target")||c.preventDefault()||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),g=a(f),h=g.data("bs.collapse"),i=h?"toggle":e.data(),j=e.attr("data-parent"),k=j&&a(j);h&&h.transitioning||(k&&k.find('[data-toggle="collapse"][data-parent="'+j+'"]').not(e).addClass("collapsed"),e[g.hasClass("in")?"addClass":"removeClass"]("collapsed")),b.call(g,i)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.2.0",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('