sonic-screwdriver 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile.lock +26 -2
  4. data/README.md +156 -23
  5. data/bin/sonic +8 -1
  6. data/docs/.gitignore +4 -0
  7. data/docs/CNAME +1 -0
  8. data/docs/Gemfile +3 -0
  9. data/docs/LICENSE +21 -0
  10. data/docs/README.md +21 -0
  11. data/docs/_config.yml +69 -0
  12. data/docs/_docs/commands.md +10 -0
  13. data/docs/_docs/how-it-works.md +34 -0
  14. data/docs/_docs/install.md +75 -0
  15. data/docs/_docs/next-steps.md +18 -0
  16. data/docs/_docs/settings.md +73 -0
  17. data/docs/_docs/sonic-ecs-exec.md +7 -0
  18. data/docs/_docs/sonic-ecs-run.md +7 -0
  19. data/docs/_docs/sonic-execute.md +7 -0
  20. data/docs/_docs/sonic-help.md +7 -0
  21. data/docs/_docs/sonic-list.md +7 -0
  22. data/docs/_docs/sonic-ssh.md +7 -0
  23. data/docs/_docs/tutorial-ecs-exec.md +69 -0
  24. data/docs/_docs/tutorial-ecs-run.md +94 -0
  25. data/docs/_docs/tutorial-execute.md +38 -0
  26. data/docs/_docs/tutorial-ssh.md +119 -0
  27. data/docs/_docs/tutorial.md +11 -0
  28. data/docs/_docs/why.md +27 -0
  29. data/docs/_includes/about.html +19 -0
  30. data/docs/_includes/commands.html +28 -0
  31. data/docs/_includes/contact.html +17 -0
  32. data/docs/_includes/contact_disqus.html +16 -0
  33. data/docs/_includes/contact_static.html +17 -0
  34. data/docs/_includes/content.html +21 -0
  35. data/docs/_includes/css/bootstrap.min.css +7 -0
  36. data/docs/_includes/css/main.css +481 -0
  37. data/docs/_includes/css/quotes.css +102 -0
  38. data/docs/_includes/css/sonic.css +163 -0
  39. data/docs/_includes/css/syntax.css +60 -0
  40. data/docs/_includes/css/table.css +53 -0
  41. data/docs/_includes/css/timeline.css +201 -0
  42. data/docs/_includes/edit-on-github.html +11 -0
  43. data/docs/_includes/example.html +21 -0
  44. data/docs/_includes/footer.html +49 -0
  45. data/docs/_includes/head.html +32 -0
  46. data/docs/_includes/header.html +15 -0
  47. data/docs/_includes/js.html +28 -0
  48. data/docs/_includes/js_disqus.html +21 -0
  49. data/docs/_includes/modals.html +40 -0
  50. data/docs/_includes/nav.html +27 -0
  51. data/docs/_includes/quotes.html +19 -0
  52. data/docs/_includes/subnav.html +35 -0
  53. data/docs/_includes/ufo-ship-options.md +13 -0
  54. data/docs/_includes/uses.html +19 -0
  55. data/docs/_layouts/default.html +11 -0
  56. data/docs/_layouts/style.css +6 -0
  57. data/docs/articles.md +5 -0
  58. data/docs/css/font-awesome/css/font-awesome.css +1566 -0
  59. data/docs/css/font-awesome/css/font-awesome.min.css +4 -0
  60. data/docs/css/font-awesome/fonts/FontAwesome.otf +0 -0
  61. data/docs/css/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  62. data/docs/css/font-awesome/fonts/fontawesome-webfont.svg +504 -0
  63. data/docs/css/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  64. data/docs/css/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  65. data/docs/docs.md +21 -0
  66. data/docs/img/logos/boltops-logo-full.png +0 -0
  67. data/docs/img/logos/boltops-logo.png +0 -0
  68. data/docs/img/sonic-screwdriver.jpg +0 -0
  69. data/docs/img/tutorials/ec2-console-public-ip.png +0 -0
  70. data/docs/img/ufo.jpg +0 -0
  71. data/docs/index.html +9 -0
  72. data/docs/js/bootstrap.js +2114 -0
  73. data/docs/js/bootstrap.min.js +6 -0
  74. data/docs/js/cbpAnimatedHeader.js +44 -0
  75. data/docs/js/cbpAnimatedHeader.min.js +11 -0
  76. data/docs/js/classie.js +80 -0
  77. data/docs/js/contact_me.js +70 -0
  78. data/docs/js/contact_me_static.js +23 -0
  79. data/docs/js/freelancer.js +37 -0
  80. data/docs/js/jqBootstrapValidation.js +912 -0
  81. data/docs/js/jquery-1.11.0.js +4 -0
  82. data/docs/js/jquery.easing.min.js +44 -0
  83. data/docs/js/nav.js +53 -0
  84. data/docs/quick-start.md +39 -0
  85. data/docs/style.css +3 -0
  86. data/lib/bash_scripts/docker-exec.sh +15 -0
  87. data/lib/bash_scripts/docker-run.sh +15 -0
  88. data/lib/sonic.rb +11 -2
  89. data/lib/sonic/aws_services.rb +19 -0
  90. data/lib/sonic/cli.rb +37 -8
  91. data/lib/sonic/cli/help.rb +123 -3
  92. data/lib/sonic/default/settings.yml +12 -0
  93. data/lib/sonic/docker.rb +128 -0
  94. data/lib/sonic/execute.rb +131 -0
  95. data/lib/sonic/list.rb +85 -0
  96. data/lib/sonic/settings.rb +80 -0
  97. data/lib/sonic/ssh.rb +136 -0
  98. data/lib/sonic/ssh/ec2_tag.rb +59 -0
  99. data/lib/sonic/ssh/identifier_detector.rb +145 -0
  100. data/lib/sonic/ui.rb +26 -0
  101. data/lib/sonic/version.rb +2 -2
  102. data/qa.md +21 -0
  103. data/sonic.gemspec +3 -1
  104. data/spec/fixtures/home/.gitkeep +0 -0
  105. data/spec/fixtures/project/.gitkeep +0 -0
  106. data/spec/fixtures/project/command.txt +2 -0
  107. data/spec/lib/cli_spec.rb +16 -6
  108. data/spec/lib/sonic/execute_spec.rb +35 -0
  109. data/spec/spec_helper.rb +5 -3
  110. metadata +133 -3
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Bootstrap v3.2.0 (http://getbootstrap.com)
3
+ * Copyright 2011-2014 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+ 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('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(i.filter(":focus"));38==b.keyCode&&j>0&&j--,40==b.keyCode&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f+', [role="menu"], [role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$backdrop=this.isShown=null,this.scrollbarWidth=0,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.2.0",c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var c=this,d=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(d),this.isShown||d.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.$body.addClass("modal-open"),this.setScrollbar(),this.escape(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var d=a.support.transition&&c.$element.hasClass("fade");c.$element.parent().length||c.$element.appendTo(c.$body),c.$element.show().scrollTop(0),d&&c.$element[0].offsetWidth,c.$element.addClass("in").attr("aria-hidden",!1),c.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:b});d?c.$element.find(".modal-dialog").one("bsTransitionEnd",function(){c.$element.trigger("focus").trigger(e)}).emulateTransitionEnd(300):c.$element.trigger("focus").trigger(e)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.$body.removeClass("modal-open"),this.resetScrollbar(),this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keyup.dismiss.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;if(this.$backdrop=a('<div class="modal-backdrop '+d+'" />').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;e?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(150):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var f=function(){c.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",f).emulateTransitionEnd(150):f()}else b&&b()},c.prototype.checkScrollbar=function(){document.body.clientWidth>=window.innerWidth||(this.scrollbarWidth=this.scrollbarWidth||this.measureScrollbar())},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.scrollbarWidth&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.2.0",c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var c=a.contains(document.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!c)return;var d=this,e=this.tip(),f=this.getUID(this.type);this.setContent(),e.attr("id",f),this.$element.attr("aria-describedby",f),this.options.animation&&e.addClass("fade");var g="function"==typeof this.options.placement?this.options.placement.call(this,e[0],this.$element[0]):this.options.placement,h=/\s?auto?\s?/i,i=h.test(g);i&&(g=g.replace(h,"")||"top"),e.detach().css({top:0,left:0,display:"block"}).addClass(g).data("bs."+this.type,this),this.options.container?e.appendTo(this.options.container):e.insertAfter(this.$element);var j=this.getPosition(),k=e[0].offsetWidth,l=e[0].offsetHeight;if(i){var m=g,n=this.$element.parent(),o=this.getPosition(n);g="bottom"==g&&j.top+j.height+l-o.scroll>o.height?"top":"top"==g&&j.top-o.scroll-l<0?"bottom":"right"==g&&j.right+k>o.width?"left":"left"==g&&j.left-k<o.left?"right":g,e.removeClass(m).addClass(g)}var p=this.getCalculatedOffset(g,j,k,l);this.applyPlacement(p,g);var q=function(){d.$element.trigger("shown.bs."+d.type),d.hoverState=null};a.support.transition&&this.$tip.hasClass("fade")?e.one("bsTransitionEnd",q).emulateTransitionEnd(150):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=k.left?2*k.left-e+i:2*k.top-f+j,m=k.left?"left":"top",n=k.left?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(l,d[0][n],m)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(){function b(){"in"!=c.hoverState&&d.detach(),c.$element.trigger("hidden.bs."+c.type)}var c=this,d=this.tip(),e=a.Event("hide.bs."+this.type);return this.$element.removeAttr("aria-describedby"),this.$element.trigger(e),e.isDefaultPrevented()?void 0:(d.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d.one("bsTransitionEnd",b).emulateTransitionEnd(150):b(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName;return a.extend({},"function"==typeof c.getBoundingClientRect?c.getBoundingClientRect():null,{scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop(),width:d?a(window).width():b.outerWidth(),height:d?a(window).height():b.outerHeight()},d?{top:0,left:0}:b.offset())},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){clearTimeout(this.timeout),this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.2.0",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").empty()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.2.0",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.2.0",c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.closest("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},c.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one("bsTransitionEnd",e).emulateTransitionEnd(150):e(),f.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(c){c.preventDefault(),b.call(a(this),"show")})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.2.0",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=a(document).height(),d=this.$target.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=b-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){null!=this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:b-this.$element.height()-h}))}}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},d.offsetBottom&&(d.offset.bottom=d.offsetBottom),d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
@@ -0,0 +1,44 @@
1
+ /**
2
+ * cbpAnimatedHeader.js v1.0.0
3
+ * http://www.codrops.com
4
+ *
5
+ * Licensed under the MIT license.
6
+ * http://www.opensource.org/licenses/mit-license.php
7
+ *
8
+ * Copyright 2013, Codrops
9
+ * http://www.codrops.com
10
+ */
11
+ var cbpAnimatedHeader = (function() {
12
+
13
+ var docElem = document.documentElement,
14
+ header = document.querySelector( '.navbar-fixed-top' ),
15
+ didScroll = false,
16
+ changeHeaderOn = 300;
17
+
18
+ function init() {
19
+ window.addEventListener( 'scroll', function( event ) {
20
+ if( !didScroll ) {
21
+ didScroll = true;
22
+ setTimeout( scrollPage, 250 );
23
+ }
24
+ }, false );
25
+ }
26
+
27
+ function scrollPage() {
28
+ var sy = scrollY();
29
+ if ( sy >= changeHeaderOn ) {
30
+ classie.add( header, 'navbar-shrink' );
31
+ }
32
+ else {
33
+ classie.remove( header, 'navbar-shrink' );
34
+ }
35
+ didScroll = false;
36
+ }
37
+
38
+ function scrollY() {
39
+ return window.pageYOffset || docElem.scrollTop;
40
+ }
41
+
42
+ init();
43
+
44
+ })();
@@ -0,0 +1,11 @@
1
+ /**
2
+ * cbpAnimatedHeader.min.js v1.0.0
3
+ * http://www.codrops.com
4
+ *
5
+ * Licensed under the MIT license.
6
+ * http://www.opensource.org/licenses/mit-license.php
7
+ *
8
+ * Copyright 2013, Codrops
9
+ * http://www.codrops.com
10
+ */
11
+ var cbpAnimatedHeader=(function(){var b=document.documentElement,g=document.querySelector(".cbp-af-header"),e=false,a=300;function f(){window.addEventListener("scroll",function(h){if(!e){e=true;setTimeout(d,250)}},false)}function d(){var h=c();if(h>=a){classie.add(g,"cbp-af-header-shrink")}else{classie.remove(g,"cbp-af-header-shrink")}e=false}function c(){return window.pageYOffset||b.scrollTop}f()})();
@@ -0,0 +1,80 @@
1
+ /*!
2
+ * classie - class helper functions
3
+ * from bonzo https://github.com/ded/bonzo
4
+ *
5
+ * classie.has( elem, 'my-class' ) -> true/false
6
+ * classie.add( elem, 'my-new-class' )
7
+ * classie.remove( elem, 'my-unwanted-class' )
8
+ * classie.toggle( elem, 'my-class' )
9
+ */
10
+
11
+ /*jshint browser: true, strict: true, undef: true */
12
+ /*global define: false */
13
+
14
+ ( function( window ) {
15
+
16
+ 'use strict';
17
+
18
+ // class helper functions from bonzo https://github.com/ded/bonzo
19
+
20
+ function classReg( className ) {
21
+ return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
22
+ }
23
+
24
+ // classList support for class management
25
+ // altho to be fair, the api sucks because it won't accept multiple classes at once
26
+ var hasClass, addClass, removeClass;
27
+
28
+ if ( 'classList' in document.documentElement ) {
29
+ hasClass = function( elem, c ) {
30
+ return elem.classList.contains( c );
31
+ };
32
+ addClass = function( elem, c ) {
33
+ elem.classList.add( c );
34
+ };
35
+ removeClass = function( elem, c ) {
36
+ elem.classList.remove( c );
37
+ };
38
+ }
39
+ else {
40
+ hasClass = function( elem, c ) {
41
+ return classReg( c ).test( elem.className );
42
+ };
43
+ addClass = function( elem, c ) {
44
+ if ( !hasClass( elem, c ) ) {
45
+ elem.className = elem.className + ' ' + c;
46
+ }
47
+ };
48
+ removeClass = function( elem, c ) {
49
+ elem.className = elem.className.replace( classReg( c ), ' ' );
50
+ };
51
+ }
52
+
53
+ function toggleClass( elem, c ) {
54
+ var fn = hasClass( elem, c ) ? removeClass : addClass;
55
+ fn( elem, c );
56
+ }
57
+
58
+ var classie = {
59
+ // full names
60
+ hasClass: hasClass,
61
+ addClass: addClass,
62
+ removeClass: removeClass,
63
+ toggleClass: toggleClass,
64
+ // short names
65
+ has: hasClass,
66
+ add: addClass,
67
+ remove: removeClass,
68
+ toggle: toggleClass
69
+ };
70
+
71
+ // transport
72
+ if ( typeof define === 'function' && define.amd ) {
73
+ // AMD
74
+ define( classie );
75
+ } else {
76
+ // browser global
77
+ window.classie = classie;
78
+ }
79
+
80
+ })( window );
@@ -0,0 +1,70 @@
1
+ $(function() {
2
+
3
+ $("input,textarea").jqBootstrapValidation({
4
+ preventSubmit: true,
5
+ submitError: function($form, event, errors) {
6
+ // additional error messages or events
7
+ },
8
+ submitSuccess: function($form, event) {
9
+ event.preventDefault(); // prevent default submit behaviour
10
+ // get values from FORM
11
+ var name = $("input#name").val();
12
+ var email = $("input#email").val();
13
+ var phone = $("input#phone").val();
14
+ var message = $("textarea#message").val();
15
+ var firstName = name; // For Success/Failure Message
16
+ // Check for white space in name for Success/Fail message
17
+ if (firstName.indexOf(' ') >= 0) {
18
+ firstName = name.split(' ').slice(0, -1).join(' ');
19
+ }
20
+ $.ajax({
21
+ url: "././mail/contact_me.php",
22
+ type: "POST",
23
+ data: {
24
+ name: name,
25
+ phone: phone,
26
+ email: email,
27
+ message: message
28
+ },
29
+ cache: false,
30
+ success: function() {
31
+ // Success message
32
+ $('#success').html("<div class='alert alert-success'>");
33
+ $('#success > .alert-success').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;")
34
+ .append("</button>");
35
+ $('#success > .alert-success')
36
+ .append("<strong>Your message has been sent. </strong>");
37
+ $('#success > .alert-success')
38
+ .append('</div>');
39
+
40
+ //clear all fields
41
+ $('#contactForm').trigger("reset");
42
+ },
43
+ error: function() {
44
+ // Fail message
45
+ $('#success').html("<div class='alert alert-danger'>");
46
+ $('#success > .alert-danger').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;")
47
+ .append("</button>");
48
+ $('#success > .alert-danger').append("<strong>Sorry, it seems that my mail server is not responding. Please try again later!");
49
+ $('#success > .alert-danger').append('</div>');
50
+ //clear all fields
51
+ $('#contactForm').trigger("reset");
52
+ },
53
+ })
54
+ },
55
+ filter: function() {
56
+ return $(this).is(":visible");
57
+ },
58
+ });
59
+
60
+ $("a[data-toggle=\"tab\"]").click(function(e) {
61
+ e.preventDefault();
62
+ $(this).tab("show");
63
+ });
64
+ });
65
+
66
+
67
+ /*When clicking on Full hide fail/success boxes */
68
+ $('#name').focus(function() {
69
+ $('#success').html('');
70
+ });
@@ -0,0 +1,23 @@
1
+ $(function() {
2
+
3
+ $("input,textarea").jqBootstrapValidation({
4
+ preventSubmit: true,
5
+ submitError: function($form, event, errors) {
6
+ // additional error messages or events
7
+ },
8
+
9
+ filter: function() {
10
+ return $(this).is(":visible");
11
+ },
12
+ });
13
+
14
+ $("a[data-toggle=\"tab\"]").click(function(e) {
15
+ e.preventDefault();
16
+ $(this).tab("show");
17
+ });
18
+ });
19
+
20
+ /*When clicking on Full hide fail/success boxes */
21
+ $('#name').focus(function() {
22
+ $('#success').html('');
23
+ });
@@ -0,0 +1,37 @@
1
+ /*!
2
+ * Start Bootstrap - Freelancer Bootstrap Theme (http://startbootstrap.com)
3
+ * Code licensed under the Apache License v2.0.
4
+ * For details, see http://www.apache.org/licenses/LICENSE-2.0.
5
+ */
6
+
7
+ // jQuery for page scrolling feature - requires jQuery Easing plugin
8
+ $(function() {
9
+ $('.page-scroll a').bind('click', function(event) {
10
+ var $anchor = $(this);
11
+ $('html, body').stop().animate({
12
+ scrollTop: $($anchor.attr('href')).offset().top
13
+ }, 1500, 'easeInOutExpo');
14
+ event.preventDefault();
15
+ });
16
+ });
17
+
18
+ // Floating label headings for the contact form
19
+ $(function() {
20
+ $("body").on("input propertychange", ".floating-label-form-group", function(e) {
21
+ $(this).toggleClass("floating-label-form-group-with-value", !! $(e.target).val());
22
+ }).on("focus", ".floating-label-form-group", function() {
23
+ $(this).addClass("floating-label-form-group-with-focus");
24
+ }).on("blur", ".floating-label-form-group", function() {
25
+ $(this).removeClass("floating-label-form-group-with-focus");
26
+ });
27
+ });
28
+
29
+ // Highlight the top nav as scrolling occurs
30
+ $('body').scrollspy({
31
+ target: '.navbar-fixed-top'
32
+ })
33
+
34
+ // Closes the Responsive Menu on Menu Item Click
35
+ $('.navbar-collapse ul li a').click(function() {
36
+ $('.navbar-toggle:visible').click();
37
+ });
@@ -0,0 +1,912 @@
1
+ /* jqBootstrapValidation
2
+ * A plugin for automating validation on Twitter Bootstrap formatted forms.
3
+ *
4
+ * v1.3.6
5
+ *
6
+ * License: MIT <http://opensource.org/licenses/mit-license.php> - see LICENSE file
7
+ *
8
+ * http://ReactiveRaven.github.com/jqBootstrapValidation/
9
+ */
10
+
11
+ (function( $ ){
12
+
13
+ var createdElements = [];
14
+
15
+ var defaults = {
16
+ options: {
17
+ prependExistingHelpBlock: false,
18
+ sniffHtml: true, // sniff for 'required', 'maxlength', etc
19
+ preventSubmit: true, // stop the form submit event from firing if validation fails
20
+ submitError: false, // function called if there is an error when trying to submit
21
+ submitSuccess: false, // function called just before a successful submit event is sent to the server
22
+ semanticallyStrict: false, // set to true to tidy up generated HTML output
23
+ autoAdd: {
24
+ helpBlocks: true
25
+ },
26
+ filter: function () {
27
+ // return $(this).is(":visible"); // only validate elements you can see
28
+ return true; // validate everything
29
+ }
30
+ },
31
+ methods: {
32
+ init : function( options ) {
33
+
34
+ var settings = $.extend(true, {}, defaults);
35
+
36
+ settings.options = $.extend(true, settings.options, options);
37
+
38
+ var $siblingElements = this;
39
+
40
+ var uniqueForms = $.unique(
41
+ $siblingElements.map( function () {
42
+ return $(this).parents("form")[0];
43
+ }).toArray()
44
+ );
45
+
46
+ $(uniqueForms).bind("submit", function (e) {
47
+ var $form = $(this);
48
+ var warningsFound = 0;
49
+ var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter);
50
+ $inputs.trigger("submit.validation").trigger("validationLostFocus.validation");
51
+
52
+ $inputs.each(function (i, el) {
53
+ var $this = $(el),
54
+ $controlGroup = $this.parents(".control-group").first();
55
+ if (
56
+ $controlGroup.hasClass("warning")
57
+ ) {
58
+ $controlGroup.removeClass("warning").addClass("error");
59
+ warningsFound++;
60
+ }
61
+ });
62
+
63
+ $inputs.trigger("validationLostFocus.validation");
64
+
65
+ if (warningsFound) {
66
+ if (settings.options.preventSubmit) {
67
+ e.preventDefault();
68
+ }
69
+ $form.addClass("error");
70
+ if ($.isFunction(settings.options.submitError)) {
71
+ settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true));
72
+ }
73
+ } else {
74
+ $form.removeClass("error");
75
+ if ($.isFunction(settings.options.submitSuccess)) {
76
+ settings.options.submitSuccess($form, e);
77
+ }
78
+ }
79
+ });
80
+
81
+ return this.each(function(){
82
+
83
+ // Get references to everything we're interested in
84
+ var $this = $(this),
85
+ $controlGroup = $this.parents(".control-group").first(),
86
+ $helpBlock = $controlGroup.find(".help-block").first(),
87
+ $form = $this.parents("form").first(),
88
+ validatorNames = [];
89
+
90
+ // create message container if not exists
91
+ if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) {
92
+ $helpBlock = $('<div class="help-block" />');
93
+ $controlGroup.find('.controls').append($helpBlock);
94
+ createdElements.push($helpBlock[0]);
95
+ }
96
+
97
+ // =============================================================
98
+ // SNIFF HTML FOR VALIDATORS
99
+ // =============================================================
100
+
101
+ // *snort sniff snuffle*
102
+
103
+ if (settings.options.sniffHtml) {
104
+ var message = "";
105
+ // ---------------------------------------------------------
106
+ // PATTERN
107
+ // ---------------------------------------------------------
108
+ if ($this.attr("pattern") !== undefined) {
109
+ message = "Not in the expected format<!-- data-validation-pattern-message to override -->";
110
+ if ($this.data("validationPatternMessage")) {
111
+ message = $this.data("validationPatternMessage");
112
+ }
113
+ $this.data("validationPatternMessage", message);
114
+ $this.data("validationPatternRegex", $this.attr("pattern"));
115
+ }
116
+ // ---------------------------------------------------------
117
+ // MAX
118
+ // ---------------------------------------------------------
119
+ if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) {
120
+ var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax"));
121
+ message = "Too high: Maximum of '" + max + "'<!-- data-validation-max-message to override -->";
122
+ if ($this.data("validationMaxMessage")) {
123
+ message = $this.data("validationMaxMessage");
124
+ }
125
+ $this.data("validationMaxMessage", message);
126
+ $this.data("validationMaxMax", max);
127
+ }
128
+ // ---------------------------------------------------------
129
+ // MIN
130
+ // ---------------------------------------------------------
131
+ if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) {
132
+ var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin"));
133
+ message = "Too low: Minimum of '" + min + "'<!-- data-validation-min-message to override -->";
134
+ if ($this.data("validationMinMessage")) {
135
+ message = $this.data("validationMinMessage");
136
+ }
137
+ $this.data("validationMinMessage", message);
138
+ $this.data("validationMinMin", min);
139
+ }
140
+ // ---------------------------------------------------------
141
+ // MAXLENGTH
142
+ // ---------------------------------------------------------
143
+ if ($this.attr("maxlength") !== undefined) {
144
+ message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->";
145
+ if ($this.data("validationMaxlengthMessage")) {
146
+ message = $this.data("validationMaxlengthMessage");
147
+ }
148
+ $this.data("validationMaxlengthMessage", message);
149
+ $this.data("validationMaxlengthMaxlength", $this.attr("maxlength"));
150
+ }
151
+ // ---------------------------------------------------------
152
+ // MINLENGTH
153
+ // ---------------------------------------------------------
154
+ if ($this.attr("minlength") !== undefined) {
155
+ message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->";
156
+ if ($this.data("validationMinlengthMessage")) {
157
+ message = $this.data("validationMinlengthMessage");
158
+ }
159
+ $this.data("validationMinlengthMessage", message);
160
+ $this.data("validationMinlengthMinlength", $this.attr("minlength"));
161
+ }
162
+ // ---------------------------------------------------------
163
+ // REQUIRED
164
+ // ---------------------------------------------------------
165
+ if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) {
166
+ message = settings.builtInValidators.required.message;
167
+ if ($this.data("validationRequiredMessage")) {
168
+ message = $this.data("validationRequiredMessage");
169
+ }
170
+ $this.data("validationRequiredMessage", message);
171
+ }
172
+ // ---------------------------------------------------------
173
+ // NUMBER
174
+ // ---------------------------------------------------------
175
+ if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") {
176
+ message = settings.builtInValidators.number.message;
177
+ if ($this.data("validationNumberMessage")) {
178
+ message = $this.data("validationNumberMessage");
179
+ }
180
+ $this.data("validationNumberMessage", message);
181
+ }
182
+ // ---------------------------------------------------------
183
+ // EMAIL
184
+ // ---------------------------------------------------------
185
+ if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") {
186
+ message = "Not a valid email address<!-- data-validation-validemail-message to override -->";
187
+ if ($this.data("validationValidemailMessage")) {
188
+ message = $this.data("validationValidemailMessage");
189
+ } else if ($this.data("validationEmailMessage")) {
190
+ message = $this.data("validationEmailMessage");
191
+ }
192
+ $this.data("validationValidemailMessage", message);
193
+ }
194
+ // ---------------------------------------------------------
195
+ // MINCHECKED
196
+ // ---------------------------------------------------------
197
+ if ($this.attr("minchecked") !== undefined) {
198
+ message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->";
199
+ if ($this.data("validationMincheckedMessage")) {
200
+ message = $this.data("validationMincheckedMessage");
201
+ }
202
+ $this.data("validationMincheckedMessage", message);
203
+ $this.data("validationMincheckedMinchecked", $this.attr("minchecked"));
204
+ }
205
+ // ---------------------------------------------------------
206
+ // MAXCHECKED
207
+ // ---------------------------------------------------------
208
+ if ($this.attr("maxchecked") !== undefined) {
209
+ message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required<!-- data-validation-maxchecked-message to override -->";
210
+ if ($this.data("validationMaxcheckedMessage")) {
211
+ message = $this.data("validationMaxcheckedMessage");
212
+ }
213
+ $this.data("validationMaxcheckedMessage", message);
214
+ $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked"));
215
+ }
216
+ }
217
+
218
+ // =============================================================
219
+ // COLLECT VALIDATOR NAMES
220
+ // =============================================================
221
+
222
+ // Get named validators
223
+ if ($this.data("validation") !== undefined) {
224
+ validatorNames = $this.data("validation").split(",");
225
+ }
226
+
227
+ // Get extra ones defined on the element's data attributes
228
+ $.each($this.data(), function (i, el) {
229
+ var parts = i.replace(/([A-Z])/g, ",$1").split(",");
230
+ if (parts[0] === "validation" && parts[1]) {
231
+ validatorNames.push(parts[1]);
232
+ }
233
+ });
234
+
235
+ // =============================================================
236
+ // NORMALISE VALIDATOR NAMES
237
+ // =============================================================
238
+
239
+ var validatorNamesToInspect = validatorNames;
240
+ var newValidatorNamesToInspect = [];
241
+
242
+ do // repeatedly expand 'shortcut' validators into their real validators
243
+ {
244
+ // Uppercase only the first letter of each name
245
+ $.each(validatorNames, function (i, el) {
246
+ validatorNames[i] = formatValidatorName(el);
247
+ });
248
+
249
+ // Remove duplicate validator names
250
+ validatorNames = $.unique(validatorNames);
251
+
252
+ // Pull out the new validator names from each shortcut
253
+ newValidatorNamesToInspect = [];
254
+ $.each(validatorNamesToInspect, function(i, el) {
255
+ if ($this.data("validation" + el + "Shortcut") !== undefined) {
256
+ // Are these custom validators?
257
+ // Pull them out!
258
+ $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) {
259
+ newValidatorNamesToInspect.push(el2);
260
+ });
261
+ } else if (settings.builtInValidators[el.toLowerCase()]) {
262
+ // Is this a recognised built-in?
263
+ // Pull it out!
264
+ var validator = settings.builtInValidators[el.toLowerCase()];
265
+ if (validator.type.toLowerCase() === "shortcut") {
266
+ $.each(validator.shortcut.split(","), function (i, el) {
267
+ el = formatValidatorName(el);
268
+ newValidatorNamesToInspect.push(el);
269
+ validatorNames.push(el);
270
+ });
271
+ }
272
+ }
273
+ });
274
+
275
+ validatorNamesToInspect = newValidatorNamesToInspect;
276
+
277
+ } while (validatorNamesToInspect.length > 0)
278
+
279
+ // =============================================================
280
+ // SET UP VALIDATOR ARRAYS
281
+ // =============================================================
282
+
283
+ var validators = {};
284
+
285
+ $.each(validatorNames, function (i, el) {
286
+ // Set up the 'override' message
287
+ var message = $this.data("validation" + el + "Message");
288
+ var hasOverrideMessage = (message !== undefined);
289
+ var foundValidator = false;
290
+ message =
291
+ (
292
+ message
293
+ ? message
294
+ : "'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->"
295
+ )
296
+ ;
297
+
298
+ $.each(
299
+ settings.validatorTypes,
300
+ function (validatorType, validatorTemplate) {
301
+ if (validators[validatorType] === undefined) {
302
+ validators[validatorType] = [];
303
+ }
304
+ if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) {
305
+ validators[validatorType].push(
306
+ $.extend(
307
+ true,
308
+ {
309
+ name: formatValidatorName(validatorTemplate.name),
310
+ message: message
311
+ },
312
+ validatorTemplate.init($this, el)
313
+ )
314
+ );
315
+ foundValidator = true;
316
+ }
317
+ }
318
+ );
319
+
320
+ if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) {
321
+
322
+ var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]);
323
+ if (hasOverrideMessage) {
324
+ validator.message = message;
325
+ }
326
+ var validatorType = validator.type.toLowerCase();
327
+
328
+ if (validatorType === "shortcut") {
329
+ foundValidator = true;
330
+ } else {
331
+ $.each(
332
+ settings.validatorTypes,
333
+ function (validatorTemplateType, validatorTemplate) {
334
+ if (validators[validatorTemplateType] === undefined) {
335
+ validators[validatorTemplateType] = [];
336
+ }
337
+ if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) {
338
+ $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]);
339
+ validators[validatorType].push(
340
+ $.extend(
341
+ validator,
342
+ validatorTemplate.init($this, el)
343
+ )
344
+ );
345
+ foundValidator = true;
346
+ }
347
+ }
348
+ );
349
+ }
350
+ }
351
+
352
+ if (! foundValidator) {
353
+ $.error("Cannot find validation info for '" + el + "'");
354
+ }
355
+ });
356
+
357
+ // =============================================================
358
+ // STORE FALLBACK VALUES
359
+ // =============================================================
360
+
361
+ $helpBlock.data(
362
+ "original-contents",
363
+ (
364
+ $helpBlock.data("original-contents")
365
+ ? $helpBlock.data("original-contents")
366
+ : $helpBlock.html()
367
+ )
368
+ );
369
+
370
+ $helpBlock.data(
371
+ "original-role",
372
+ (
373
+ $helpBlock.data("original-role")
374
+ ? $helpBlock.data("original-role")
375
+ : $helpBlock.attr("role")
376
+ )
377
+ );
378
+
379
+ $controlGroup.data(
380
+ "original-classes",
381
+ (
382
+ $controlGroup.data("original-clases")
383
+ ? $controlGroup.data("original-classes")
384
+ : $controlGroup.attr("class")
385
+ )
386
+ );
387
+
388
+ $this.data(
389
+ "original-aria-invalid",
390
+ (
391
+ $this.data("original-aria-invalid")
392
+ ? $this.data("original-aria-invalid")
393
+ : $this.attr("aria-invalid")
394
+ )
395
+ );
396
+
397
+ // =============================================================
398
+ // VALIDATION
399
+ // =============================================================
400
+
401
+ $this.bind(
402
+ "validation.validation",
403
+ function (event, params) {
404
+
405
+ var value = getValue($this);
406
+
407
+ // Get a list of the errors to apply
408
+ var errorsFound = [];
409
+
410
+ $.each(validators, function (validatorType, validatorTypeArray) {
411
+ if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) {
412
+ $.each(validatorTypeArray, function (i, validator) {
413
+ if (settings.validatorTypes[validatorType].validate($this, value, validator)) {
414
+ errorsFound.push(validator.message);
415
+ }
416
+ });
417
+ }
418
+ });
419
+
420
+ return errorsFound;
421
+ }
422
+ );
423
+
424
+ $this.bind(
425
+ "getValidators.validation",
426
+ function () {
427
+ return validators;
428
+ }
429
+ );
430
+
431
+ // =============================================================
432
+ // WATCH FOR CHANGES
433
+ // =============================================================
434
+ $this.bind(
435
+ "submit.validation",
436
+ function () {
437
+ return $this.triggerHandler("change.validation", {submitting: true});
438
+ }
439
+ );
440
+ $this.bind(
441
+ [
442
+ "keyup",
443
+ "focus",
444
+ "blur",
445
+ "click",
446
+ "keydown",
447
+ "keypress",
448
+ "change"
449
+ ].join(".validation ") + ".validation",
450
+ function (e, params) {
451
+
452
+ var value = getValue($this);
453
+
454
+ var errorsFound = [];
455
+
456
+ $controlGroup.find("input,textarea,select").each(function (i, el) {
457
+ var oldCount = errorsFound.length;
458
+ $.each($(el).triggerHandler("validation.validation", params), function (j, message) {
459
+ errorsFound.push(message);
460
+ });
461
+ if (errorsFound.length > oldCount) {
462
+ $(el).attr("aria-invalid", "true");
463
+ } else {
464
+ var original = $this.data("original-aria-invalid");
465
+ $(el).attr("aria-invalid", (original !== undefined ? original : false));
466
+ }
467
+ });
468
+
469
+ $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation");
470
+
471
+ errorsFound = $.unique(errorsFound.sort());
472
+
473
+ // Were there any errors?
474
+ if (errorsFound.length) {
475
+ // Better flag it up as a warning.
476
+ $controlGroup.removeClass("success error").addClass("warning");
477
+
478
+ // How many errors did we find?
479
+ if (settings.options.semanticallyStrict && errorsFound.length === 1) {
480
+ // Only one? Being strict? Just output it.
481
+ $helpBlock.html(errorsFound[0] +
482
+ ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
483
+ } else {
484
+ // Multiple? Being sloppy? Glue them together into an UL.
485
+ $helpBlock.html("<ul role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" +
486
+ ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
487
+ }
488
+ } else {
489
+ $controlGroup.removeClass("warning error success");
490
+ if (value.length > 0) {
491
+ $controlGroup.addClass("success");
492
+ }
493
+ $helpBlock.html($helpBlock.data("original-contents"));
494
+ }
495
+
496
+ if (e.type === "blur") {
497
+ $controlGroup.removeClass("success");
498
+ }
499
+ }
500
+ );
501
+ $this.bind("validationLostFocus.validation", function () {
502
+ $controlGroup.removeClass("success");
503
+ });
504
+ });
505
+ },
506
+ destroy : function( ) {
507
+
508
+ return this.each(
509
+ function() {
510
+
511
+ var
512
+ $this = $(this),
513
+ $controlGroup = $this.parents(".control-group").first(),
514
+ $helpBlock = $controlGroup.find(".help-block").first();
515
+
516
+ // remove our events
517
+ $this.unbind('.validation'); // events are namespaced.
518
+ // reset help text
519
+ $helpBlock.html($helpBlock.data("original-contents"));
520
+ // reset classes
521
+ $controlGroup.attr("class", $controlGroup.data("original-classes"));
522
+ // reset aria
523
+ $this.attr("aria-invalid", $this.data("original-aria-invalid"));
524
+ // reset role
525
+ $helpBlock.attr("role", $this.data("original-role"));
526
+ // remove all elements we created
527
+ if (createdElements.indexOf($helpBlock[0]) > -1) {
528
+ $helpBlock.remove();
529
+ }
530
+
531
+ }
532
+ );
533
+
534
+ },
535
+ collectErrors : function(includeEmpty) {
536
+
537
+ var errorMessages = {};
538
+ this.each(function (i, el) {
539
+ var $el = $(el);
540
+ var name = $el.attr("name");
541
+ var errors = $el.triggerHandler("validation.validation", {includeEmpty: true});
542
+ errorMessages[name] = $.extend(true, errors, errorMessages[name]);
543
+ });
544
+
545
+ $.each(errorMessages, function (i, el) {
546
+ if (el.length === 0) {
547
+ delete errorMessages[i];
548
+ }
549
+ });
550
+
551
+ return errorMessages;
552
+
553
+ },
554
+ hasErrors: function() {
555
+
556
+ var errorMessages = [];
557
+
558
+ this.each(function (i, el) {
559
+ errorMessages = errorMessages.concat(
560
+ $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : []
561
+ );
562
+ });
563
+
564
+ return (errorMessages.length > 0);
565
+ },
566
+ override : function (newDefaults) {
567
+ defaults = $.extend(true, defaults, newDefaults);
568
+ }
569
+ },
570
+ validatorTypes: {
571
+ callback: {
572
+ name: "callback",
573
+ init: function ($this, name) {
574
+ return {
575
+ validatorName: name,
576
+ callback: $this.data("validation" + name + "Callback"),
577
+ lastValue: $this.val(),
578
+ lastValid: true,
579
+ lastFinished: true
580
+ };
581
+ },
582
+ validate: function ($this, value, validator) {
583
+ if (validator.lastValue === value && validator.lastFinished) {
584
+ return !validator.lastValid;
585
+ }
586
+
587
+ if (validator.lastFinished === true)
588
+ {
589
+ validator.lastValue = value;
590
+ validator.lastValid = true;
591
+ validator.lastFinished = false;
592
+
593
+ var rrjqbvValidator = validator;
594
+ var rrjqbvThis = $this;
595
+ executeFunctionByName(
596
+ validator.callback,
597
+ window,
598
+ $this,
599
+ value,
600
+ function (data) {
601
+ if (rrjqbvValidator.lastValue === data.value) {
602
+ rrjqbvValidator.lastValid = data.valid;
603
+ if (data.message) {
604
+ rrjqbvValidator.message = data.message;
605
+ }
606
+ rrjqbvValidator.lastFinished = true;
607
+ rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message);
608
+ // Timeout is set to avoid problems with the events being considered 'already fired'
609
+ setTimeout(function () {
610
+ rrjqbvThis.trigger("change.validation");
611
+ }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
612
+ }
613
+ }
614
+ );
615
+ }
616
+
617
+ return false;
618
+
619
+ }
620
+ },
621
+ ajax: {
622
+ name: "ajax",
623
+ init: function ($this, name) {
624
+ return {
625
+ validatorName: name,
626
+ url: $this.data("validation" + name + "Ajax"),
627
+ lastValue: $this.val(),
628
+ lastValid: true,
629
+ lastFinished: true
630
+ };
631
+ },
632
+ validate: function ($this, value, validator) {
633
+ if (""+validator.lastValue === ""+value && validator.lastFinished === true) {
634
+ return validator.lastValid === false;
635
+ }
636
+
637
+ if (validator.lastFinished === true)
638
+ {
639
+ validator.lastValue = value;
640
+ validator.lastValid = true;
641
+ validator.lastFinished = false;
642
+ $.ajax({
643
+ url: validator.url,
644
+ data: "value=" + value + "&field=" + $this.attr("name"),
645
+ dataType: "json",
646
+ success: function (data) {
647
+ if (""+validator.lastValue === ""+data.value) {
648
+ validator.lastValid = !!(data.valid);
649
+ if (data.message) {
650
+ validator.message = data.message;
651
+ }
652
+ validator.lastFinished = true;
653
+ $this.data("validation" + validator.validatorName + "Message", validator.message);
654
+ // Timeout is set to avoid problems with the events being considered 'already fired'
655
+ setTimeout(function () {
656
+ $this.trigger("change.validation");
657
+ }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
658
+ }
659
+ },
660
+ failure: function () {
661
+ validator.lastValid = true;
662
+ validator.message = "ajax call failed";
663
+ validator.lastFinished = true;
664
+ $this.data("validation" + validator.validatorName + "Message", validator.message);
665
+ // Timeout is set to avoid problems with the events being considered 'already fired'
666
+ setTimeout(function () {
667
+ $this.trigger("change.validation");
668
+ }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
669
+ }
670
+ });
671
+ }
672
+
673
+ return false;
674
+
675
+ }
676
+ },
677
+ regex: {
678
+ name: "regex",
679
+ init: function ($this, name) {
680
+ return {regex: regexFromString($this.data("validation" + name + "Regex"))};
681
+ },
682
+ validate: function ($this, value, validator) {
683
+ return (!validator.regex.test(value) && ! validator.negative)
684
+ || (validator.regex.test(value) && validator.negative);
685
+ }
686
+ },
687
+ required: {
688
+ name: "required",
689
+ init: function ($this, name) {
690
+ return {};
691
+ },
692
+ validate: function ($this, value, validator) {
693
+ return !!(value.length === 0 && ! validator.negative)
694
+ || !!(value.length > 0 && validator.negative);
695
+ },
696
+ blockSubmit: true
697
+ },
698
+ match: {
699
+ name: "match",
700
+ init: function ($this, name) {
701
+ var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first();
702
+ element.bind("validation.validation", function () {
703
+ $this.trigger("change.validation", {submitting: true});
704
+ });
705
+ return {"element": element};
706
+ },
707
+ validate: function ($this, value, validator) {
708
+ return (value !== validator.element.val() && ! validator.negative)
709
+ || (value === validator.element.val() && validator.negative);
710
+ },
711
+ blockSubmit: true
712
+ },
713
+ max: {
714
+ name: "max",
715
+ init: function ($this, name) {
716
+ return {max: $this.data("validation" + name + "Max")};
717
+ },
718
+ validate: function ($this, value, validator) {
719
+ return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative)
720
+ || (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative);
721
+ }
722
+ },
723
+ min: {
724
+ name: "min",
725
+ init: function ($this, name) {
726
+ return {min: $this.data("validation" + name + "Min")};
727
+ },
728
+ validate: function ($this, value, validator) {
729
+ return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative)
730
+ || (parseFloat(value) >= parseFloat(validator.min) && validator.negative);
731
+ }
732
+ },
733
+ maxlength: {
734
+ name: "maxlength",
735
+ init: function ($this, name) {
736
+ return {maxlength: $this.data("validation" + name + "Maxlength")};
737
+ },
738
+ validate: function ($this, value, validator) {
739
+ return ((value.length > validator.maxlength) && ! validator.negative)
740
+ || ((value.length <= validator.maxlength) && validator.negative);
741
+ }
742
+ },
743
+ minlength: {
744
+ name: "minlength",
745
+ init: function ($this, name) {
746
+ return {minlength: $this.data("validation" + name + "Minlength")};
747
+ },
748
+ validate: function ($this, value, validator) {
749
+ return ((value.length < validator.minlength) && ! validator.negative)
750
+ || ((value.length >= validator.minlength) && validator.negative);
751
+ }
752
+ },
753
+ maxchecked: {
754
+ name: "maxchecked",
755
+ init: function ($this, name) {
756
+ var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
757
+ elements.bind("click.validation", function () {
758
+ $this.trigger("change.validation", {includeEmpty: true});
759
+ });
760
+ return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements};
761
+ },
762
+ validate: function ($this, value, validator) {
763
+ return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative)
764
+ || (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative);
765
+ },
766
+ blockSubmit: true
767
+ },
768
+ minchecked: {
769
+ name: "minchecked",
770
+ init: function ($this, name) {
771
+ var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
772
+ elements.bind("click.validation", function () {
773
+ $this.trigger("change.validation", {includeEmpty: true});
774
+ });
775
+ return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements};
776
+ },
777
+ validate: function ($this, value, validator) {
778
+ return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative)
779
+ || (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative);
780
+ },
781
+ blockSubmit: true
782
+ }
783
+ },
784
+ builtInValidators: {
785
+ email: {
786
+ name: "Email",
787
+ type: "shortcut",
788
+ shortcut: "validemail"
789
+ },
790
+ validemail: {
791
+ name: "Validemail",
792
+ type: "regex",
793
+ regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}",
794
+ message: "Not a valid email address<!-- data-validation-validemail-message to override -->"
795
+ },
796
+ passwordagain: {
797
+ name: "Passwordagain",
798
+ type: "match",
799
+ match: "password",
800
+ message: "Does not match the given password<!-- data-validator-paswordagain-message to override -->"
801
+ },
802
+ positive: {
803
+ name: "Positive",
804
+ type: "shortcut",
805
+ shortcut: "number,positivenumber"
806
+ },
807
+ negative: {
808
+ name: "Negative",
809
+ type: "shortcut",
810
+ shortcut: "number,negativenumber"
811
+ },
812
+ number: {
813
+ name: "Number",
814
+ type: "regex",
815
+ regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?",
816
+ message: "Must be a number<!-- data-validator-number-message to override -->"
817
+ },
818
+ integer: {
819
+ name: "Integer",
820
+ type: "regex",
821
+ regex: "[+-]?\\\d+",
822
+ message: "No decimal places allowed<!-- data-validator-integer-message to override -->"
823
+ },
824
+ positivenumber: {
825
+ name: "Positivenumber",
826
+ type: "min",
827
+ min: 0,
828
+ message: "Must be a positive number<!-- data-validator-positivenumber-message to override -->"
829
+ },
830
+ negativenumber: {
831
+ name: "Negativenumber",
832
+ type: "max",
833
+ max: 0,
834
+ message: "Must be a negative number<!-- data-validator-negativenumber-message to override -->"
835
+ },
836
+ required: {
837
+ name: "Required",
838
+ type: "required",
839
+ message: "This is required<!-- data-validator-required-message to override -->"
840
+ },
841
+ checkone: {
842
+ name: "Checkone",
843
+ type: "minchecked",
844
+ minchecked: 1,
845
+ message: "Check at least one option<!-- data-validation-checkone-message to override -->"
846
+ }
847
+ }
848
+ };
849
+
850
+ var formatValidatorName = function (name) {
851
+ return name
852
+ .toLowerCase()
853
+ .replace(
854
+ /(^|\s)([a-z])/g ,
855
+ function(m,p1,p2) {
856
+ return p1+p2.toUpperCase();
857
+ }
858
+ )
859
+ ;
860
+ };
861
+
862
+ var getValue = function ($this) {
863
+ // Extract the value we're talking about
864
+ var value = $this.val();
865
+ var type = $this.attr("type");
866
+ if (type === "checkbox") {
867
+ value = ($this.is(":checked") ? value : "");
868
+ }
869
+ if (type === "radio") {
870
+ value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : "");
871
+ }
872
+ return value;
873
+ };
874
+
875
+ function regexFromString(inputstring) {
876
+ return new RegExp("^" + inputstring + "$");
877
+ }
878
+
879
+ /**
880
+ * Thanks to Jason Bunting via StackOverflow.com
881
+ *
882
+ * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910
883
+ * Short link: http://tinyurl.com/executeFunctionByName
884
+ **/
885
+ function executeFunctionByName(functionName, context /*, args*/) {
886
+ var args = Array.prototype.slice.call(arguments).splice(2);
887
+ var namespaces = functionName.split(".");
888
+ var func = namespaces.pop();
889
+ for(var i = 0; i < namespaces.length; i++) {
890
+ context = context[namespaces[i]];
891
+ }
892
+ return context[func].apply(this, args);
893
+ }
894
+
895
+ $.fn.jqBootstrapValidation = function( method ) {
896
+
897
+ if ( defaults.methods[method] ) {
898
+ return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
899
+ } else if ( typeof method === 'object' || ! method ) {
900
+ return defaults.methods.init.apply( this, arguments );
901
+ } else {
902
+ $.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' );
903
+ return null;
904
+ }
905
+
906
+ };
907
+
908
+ $.jqBootstrapValidation = function (options) {
909
+ $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments);
910
+ };
911
+
912
+ })( jQuery );