├── LICENSE ├── bootstrap-tabcollapse.js ├── bower.json ├── example ├── example.html └── lib │ ├── css │ └── bootstrap │ │ └── bootstrap.css │ └── js │ ├── bootstrap │ └── bootstrap.js │ ├── jquery-1.10.1.min.js │ └── jquery-migrate-1.2.1.min.js └── readme.md /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 flatlogic.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /bootstrap-tabcollapse.js: -------------------------------------------------------------------------------- 1 | !function ($) { 2 | 3 | "use strict"; 4 | 5 | // TABCOLLAPSE CLASS DEFINITION 6 | // ====================== 7 | 8 | var TabCollapse = function (el, options) { 9 | this.options = options; 10 | this.$tabs = $(el); 11 | 12 | this._accordionVisible = false; //content is attached to tabs at first 13 | this._initAccordion(); 14 | this._checkStateOnResize(); 15 | 16 | 17 | // checkState() has gone to setTimeout for making it possible to attach listeners to 18 | // shown-accordion.bs.tabcollapse event on page load. 19 | // See https://github.com/flatlogic/bootstrap-tabcollapse/issues/23 20 | var that = this; 21 | setTimeout(function() { 22 | that.checkState(); 23 | }, 0); 24 | }; 25 | 26 | TabCollapse.DEFAULTS = { 27 | accordionClass: 'visible-xs', 28 | tabsClass: 'hidden-xs', 29 | accordionTemplate: function(heading, groupId, parentId, active) { 30 | return '
' + 31 | '
' + 32 | '

' + 33 | '

' + 34 | '
' + 35 | '
' + 36 | '
' + 37 | '
' + 38 | '
' + 39 | '
' 40 | 41 | } 42 | }; 43 | 44 | TabCollapse.prototype.checkState = function(){ 45 | if (this.$tabs.is(':visible') && this._accordionVisible){ 46 | this.showTabs(); 47 | this._accordionVisible = false; 48 | } else if (this.$accordion.is(':visible') && !this._accordionVisible){ 49 | this.showAccordion(); 50 | this._accordionVisible = true; 51 | } 52 | }; 53 | 54 | TabCollapse.prototype.showTabs = function(){ 55 | var view = this; 56 | this.$tabs.trigger($.Event('show-tabs.bs.tabcollapse')); 57 | 58 | var $panelHeadings = this.$accordion.find('.js-tabcollapse-panel-heading').detach(); 59 | 60 | $panelHeadings.each(function() { 61 | var $panelHeading = $(this), 62 | $parentLi = $panelHeading.data('bs.tabcollapse.parentLi'); 63 | 64 | var $oldHeading = view._panelHeadingToTabHeading($panelHeading); 65 | 66 | $parentLi.removeClass('active'); 67 | if ($parentLi.parent().hasClass('dropdown-menu') && !$parentLi.siblings('li').hasClass('active')) { 68 | $parentLi.parent().parent().removeClass('active'); 69 | } 70 | 71 | if (!$oldHeading.hasClass('collapsed')) { 72 | $parentLi.addClass('active'); 73 | if ($parentLi.parent().hasClass('dropdown-menu')) { 74 | $parentLi.parent().parent().addClass('active'); 75 | } 76 | } else { 77 | $oldHeading.removeClass('collapsed'); 78 | } 79 | 80 | $parentLi.append($panelHeading); 81 | }); 82 | 83 | if (!$('li').hasClass('active')) { 84 | $('li').first().addClass('active') 85 | } 86 | 87 | var $panelBodies = this.$accordion.find('.js-tabcollapse-panel-body'); 88 | $panelBodies.each(function(){ 89 | var $panelBody = $(this), 90 | $tabPane = $panelBody.data('bs.tabcollapse.tabpane'); 91 | $tabPane.append($panelBody.contents().detach()); 92 | }); 93 | this.$accordion.html(''); 94 | 95 | if(this.options.updateLinks) { 96 | var $tabContents = this.getTabContentElement(); 97 | $tabContents.find('[data-toggle-was="tab"], [data-toggle-was="pill"]').each(function() { 98 | var $el = $(this); 99 | var href = $el.attr('href').replace(/-collapse$/g, ''); 100 | $el.attr({ 101 | 'data-toggle': $el.attr('data-toggle-was'), 102 | 'data-toggle-was': '', 103 | 'data-parent': '', 104 | href: href 105 | }); 106 | }); 107 | } 108 | 109 | this.$tabs.trigger($.Event('shown-tabs.bs.tabcollapse')); 110 | }; 111 | 112 | TabCollapse.prototype.getTabContentElement = function(){ 113 | var $tabContents = $(this.options.tabContentSelector); 114 | if($tabContents.length === 0) { 115 | $tabContents = this.$tabs.siblings('.tab-content'); 116 | } 117 | return $tabContents; 118 | }; 119 | 120 | TabCollapse.prototype.showAccordion = function(){ 121 | this.$tabs.trigger($.Event('show-accordion.bs.tabcollapse')); 122 | 123 | var $headings = this.$tabs.find('li:not(.dropdown) [data-toggle="tab"], li:not(.dropdown) [data-toggle="pill"]'), 124 | view = this; 125 | $headings.each(function(){ 126 | var $heading = $(this), 127 | $parentLi = $heading.parent(); 128 | $heading.data('bs.tabcollapse.parentLi', $parentLi); 129 | view.$accordion.append(view._createAccordionGroup(view.$accordion.attr('id'), $heading.detach())); 130 | }); 131 | 132 | if(this.options.updateLinks) { 133 | var parentId = this.$accordion.attr('id'); 134 | var $selector = this.$accordion.find('.js-tabcollapse-panel-body'); 135 | $selector.find('[data-toggle="tab"], [data-toggle="pill"]').each(function() { 136 | var $el = $(this); 137 | var href = $el.attr('href') + '-collapse'; 138 | $el.attr({ 139 | 'data-toggle-was': $el.attr('data-toggle'), 140 | 'data-toggle': 'collapse', 141 | 'data-parent': '#' + parentId, 142 | href: href 143 | }); 144 | }); 145 | } 146 | 147 | this.$tabs.trigger($.Event('shown-accordion.bs.tabcollapse')); 148 | }; 149 | 150 | TabCollapse.prototype._panelHeadingToTabHeading = function($heading) { 151 | var href = $heading.attr('href').replace(/-collapse$/g, ''); 152 | $heading.attr({ 153 | 'data-toggle': 'tab', 154 | 'href': href, 155 | 'data-parent': '' 156 | }); 157 | return $heading; 158 | }; 159 | 160 | TabCollapse.prototype._tabHeadingToPanelHeading = function($heading, groupId, parentId, active) { 161 | $heading.addClass('js-tabcollapse-panel-heading ' + (active ? '' : 'collapsed')); 162 | $heading.attr({ 163 | 'data-toggle': 'collapse', 164 | 'data-parent': '#' + parentId, 165 | 'href': '#' + groupId 166 | }); 167 | return $heading; 168 | }; 169 | 170 | TabCollapse.prototype._checkStateOnResize = function(){ 171 | var view = this; 172 | $(window).resize(function(){ 173 | clearTimeout(view._resizeTimeout); 174 | view._resizeTimeout = setTimeout(function(){ 175 | view.checkState(); 176 | }, 100); 177 | }); 178 | }; 179 | 180 | 181 | TabCollapse.prototype._initAccordion = function(){ 182 | var randomString = function() { 183 | var result = "", 184 | possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 185 | for( var i=0; i < 5; i++ ) { 186 | result += possible.charAt(Math.floor(Math.random() * possible.length)); 187 | } 188 | return result; 189 | }; 190 | 191 | var srcId = this.$tabs.attr('id'), 192 | accordionId = (srcId ? srcId : randomString()) + '-accordion'; 193 | 194 | this.$accordion = $('
'); 195 | this.$tabs.after(this.$accordion); 196 | this.$tabs.addClass(this.options.tabsClass); 197 | this.getTabContentElement().addClass(this.options.tabsClass); 198 | }; 199 | 200 | TabCollapse.prototype._createAccordionGroup = function(parentId, $heading){ 201 | var tabSelector = $heading.attr('data-target'), 202 | active = $heading.data('bs.tabcollapse.parentLi').is('.active'); 203 | 204 | if (!tabSelector) { 205 | tabSelector = $heading.attr('href'); 206 | tabSelector = tabSelector && tabSelector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7 207 | } 208 | 209 | var $tabPane = $(tabSelector), 210 | groupId = $tabPane.attr('id') + '-collapse', 211 | $panel = $(this.options.accordionTemplate($heading, groupId, parentId, active)); 212 | $panel.find('.panel-heading > .panel-title').append(this._tabHeadingToPanelHeading($heading, groupId, parentId, active)); 213 | $panel.find('.panel-body').append($tabPane.contents().detach()) 214 | .data('bs.tabcollapse.tabpane', $tabPane); 215 | 216 | return $panel; 217 | }; 218 | 219 | 220 | 221 | // TABCOLLAPSE PLUGIN DEFINITION 222 | // ======================= 223 | 224 | $.fn.tabCollapse = function (option) { 225 | return this.each(function () { 226 | var $this = $(this); 227 | var data = $this.data('bs.tabcollapse'); 228 | var options = $.extend({}, TabCollapse.DEFAULTS, $this.data(), typeof option === 'object' && option); 229 | 230 | if (!data) $this.data('bs.tabcollapse', new TabCollapse(this, options)); 231 | }); 232 | }; 233 | 234 | $.fn.tabCollapse.Constructor = TabCollapse; 235 | 236 | 237 | }(window.jQuery); 238 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap-tabcollapse", 3 | "main": "bootstrap-tabcollapse.js", 4 | "version": "0.2.7", 5 | "homepage": "https://github.com/flatlogic/bootstrap-tabcollapse", 6 | "authors": [ 7 | "okendoken (http://flatlogic.com)" 8 | ], 9 | "description": "Bootstrap plugin that switches bootstrap tabs component to collapse component for small screens.", 10 | "keywords": [ 11 | "bootstrap", 12 | "tabs", 13 | "collapse", 14 | "responsive" 15 | ], 16 | "license": "MIT", 17 | "dependencies": { 18 | }, 19 | "ignore": [ 20 | "**/.*", 21 | "bower_components", 22 | "example" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /example/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bootstrap tabcollapse.js 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 24 |
25 |
26 |

Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.

27 |
28 |
29 |

Light Blue - is a next generation admin template based on the latest Metro design. There are few reasons we want to tell you, why we have created it: 30 | We didn't like the darkness of most of admin templates, so we created this light one. We didn't like the high contrast of most of admin templates, so we created this unobtrusive one. 31 | We searched for a solution of how to make widgets look like real widgets, so we decided that deep background - is what makes widgets look real.

32 | 33 |
34 | 37 | 40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 58 | 59 | -------------------------------------------------------------------------------- /example/lib/js/bootstrap/bootstrap.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.4 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | if (typeof jQuery === 'undefined') { 8 | throw new Error('Bootstrap\'s JavaScript requires jQuery') 9 | } 10 | 11 | +function ($) { 12 | 'use strict'; 13 | var version = $.fn.jquery.split(' ')[0].split('.') 14 | if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { 15 | throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') 16 | } 17 | }(jQuery); 18 | 19 | /* ======================================================================== 20 | * Bootstrap: transition.js v3.3.4 21 | * http://getbootstrap.com/javascript/#transitions 22 | * ======================================================================== 23 | * Copyright 2011-2015 Twitter, Inc. 24 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 25 | * ======================================================================== */ 26 | 27 | 28 | +function ($) { 29 | 'use strict'; 30 | 31 | // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 32 | // ============================================================ 33 | 34 | function transitionEnd() { 35 | var el = document.createElement('bootstrap') 36 | 37 | var transEndEventNames = { 38 | WebkitTransition : 'webkitTransitionEnd', 39 | MozTransition : 'transitionend', 40 | OTransition : 'oTransitionEnd otransitionend', 41 | transition : 'transitionend' 42 | } 43 | 44 | for (var name in transEndEventNames) { 45 | if (el.style[name] !== undefined) { 46 | return { end: transEndEventNames[name] } 47 | } 48 | } 49 | 50 | return false // explicit for ie8 ( ._.) 51 | } 52 | 53 | // http://blog.alexmaccaw.com/css-transitions 54 | $.fn.emulateTransitionEnd = function (duration) { 55 | var called = false 56 | var $el = this 57 | $(this).one('bsTransitionEnd', function () { called = true }) 58 | var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 59 | setTimeout(callback, duration) 60 | return this 61 | } 62 | 63 | $(function () { 64 | $.support.transition = transitionEnd() 65 | 66 | if (!$.support.transition) return 67 | 68 | $.event.special.bsTransitionEnd = { 69 | bindType: $.support.transition.end, 70 | delegateType: $.support.transition.end, 71 | handle: function (e) { 72 | if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 73 | } 74 | } 75 | }) 76 | 77 | }(jQuery); 78 | 79 | /* ======================================================================== 80 | * Bootstrap: alert.js v3.3.4 81 | * http://getbootstrap.com/javascript/#alerts 82 | * ======================================================================== 83 | * Copyright 2011-2015 Twitter, Inc. 84 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 85 | * ======================================================================== */ 86 | 87 | 88 | +function ($) { 89 | 'use strict'; 90 | 91 | // ALERT CLASS DEFINITION 92 | // ====================== 93 | 94 | var dismiss = '[data-dismiss="alert"]' 95 | var Alert = function (el) { 96 | $(el).on('click', dismiss, this.close) 97 | } 98 | 99 | Alert.VERSION = '3.3.4' 100 | 101 | Alert.TRANSITION_DURATION = 150 102 | 103 | Alert.prototype.close = function (e) { 104 | var $this = $(this) 105 | var selector = $this.attr('data-target') 106 | 107 | if (!selector) { 108 | selector = $this.attr('href') 109 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 110 | } 111 | 112 | var $parent = $(selector) 113 | 114 | if (e) e.preventDefault() 115 | 116 | if (!$parent.length) { 117 | $parent = $this.closest('.alert') 118 | } 119 | 120 | $parent.trigger(e = $.Event('close.bs.alert')) 121 | 122 | if (e.isDefaultPrevented()) return 123 | 124 | $parent.removeClass('in') 125 | 126 | function removeElement() { 127 | // detach from parent, fire event then clean up data 128 | $parent.detach().trigger('closed.bs.alert').remove() 129 | } 130 | 131 | $.support.transition && $parent.hasClass('fade') ? 132 | $parent 133 | .one('bsTransitionEnd', removeElement) 134 | .emulateTransitionEnd(Alert.TRANSITION_DURATION) : 135 | removeElement() 136 | } 137 | 138 | 139 | // ALERT PLUGIN DEFINITION 140 | // ======================= 141 | 142 | function Plugin(option) { 143 | return this.each(function () { 144 | var $this = $(this) 145 | var data = $this.data('bs.alert') 146 | 147 | if (!data) $this.data('bs.alert', (data = new Alert(this))) 148 | if (typeof option == 'string') data[option].call($this) 149 | }) 150 | } 151 | 152 | var old = $.fn.alert 153 | 154 | $.fn.alert = Plugin 155 | $.fn.alert.Constructor = Alert 156 | 157 | 158 | // ALERT NO CONFLICT 159 | // ================= 160 | 161 | $.fn.alert.noConflict = function () { 162 | $.fn.alert = old 163 | return this 164 | } 165 | 166 | 167 | // ALERT DATA-API 168 | // ============== 169 | 170 | $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 171 | 172 | }(jQuery); 173 | 174 | /* ======================================================================== 175 | * Bootstrap: button.js v3.3.4 176 | * http://getbootstrap.com/javascript/#buttons 177 | * ======================================================================== 178 | * Copyright 2011-2015 Twitter, Inc. 179 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 180 | * ======================================================================== */ 181 | 182 | 183 | +function ($) { 184 | 'use strict'; 185 | 186 | // BUTTON PUBLIC CLASS DEFINITION 187 | // ============================== 188 | 189 | var Button = function (element, options) { 190 | this.$element = $(element) 191 | this.options = $.extend({}, Button.DEFAULTS, options) 192 | this.isLoading = false 193 | } 194 | 195 | Button.VERSION = '3.3.4' 196 | 197 | Button.DEFAULTS = { 198 | loadingText: 'loading...' 199 | } 200 | 201 | Button.prototype.setState = function (state) { 202 | var d = 'disabled' 203 | var $el = this.$element 204 | var val = $el.is('input') ? 'val' : 'html' 205 | var data = $el.data() 206 | 207 | state = state + 'Text' 208 | 209 | if (data.resetText == null) $el.data('resetText', $el[val]()) 210 | 211 | // push to event loop to allow forms to submit 212 | setTimeout($.proxy(function () { 213 | $el[val](data[state] == null ? this.options[state] : data[state]) 214 | 215 | if (state == 'loadingText') { 216 | this.isLoading = true 217 | $el.addClass(d).attr(d, d) 218 | } else if (this.isLoading) { 219 | this.isLoading = false 220 | $el.removeClass(d).removeAttr(d) 221 | } 222 | }, this), 0) 223 | } 224 | 225 | Button.prototype.toggle = function () { 226 | var changed = true 227 | var $parent = this.$element.closest('[data-toggle="buttons"]') 228 | 229 | if ($parent.length) { 230 | var $input = this.$element.find('input') 231 | if ($input.prop('type') == 'radio') { 232 | if ($input.prop('checked') && this.$element.hasClass('active')) changed = false 233 | else $parent.find('.active').removeClass('active') 234 | } 235 | if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') 236 | } else { 237 | this.$element.attr('aria-pressed', !this.$element.hasClass('active')) 238 | } 239 | 240 | if (changed) this.$element.toggleClass('active') 241 | } 242 | 243 | 244 | // BUTTON PLUGIN DEFINITION 245 | // ======================== 246 | 247 | function Plugin(option) { 248 | return this.each(function () { 249 | var $this = $(this) 250 | var data = $this.data('bs.button') 251 | var options = typeof option == 'object' && option 252 | 253 | if (!data) $this.data('bs.button', (data = new Button(this, options))) 254 | 255 | if (option == 'toggle') data.toggle() 256 | else if (option) data.setState(option) 257 | }) 258 | } 259 | 260 | var old = $.fn.button 261 | 262 | $.fn.button = Plugin 263 | $.fn.button.Constructor = Button 264 | 265 | 266 | // BUTTON NO CONFLICT 267 | // ================== 268 | 269 | $.fn.button.noConflict = function () { 270 | $.fn.button = old 271 | return this 272 | } 273 | 274 | 275 | // BUTTON DATA-API 276 | // =============== 277 | 278 | $(document) 279 | .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 280 | var $btn = $(e.target) 281 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 282 | Plugin.call($btn, 'toggle') 283 | e.preventDefault() 284 | }) 285 | .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { 286 | $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) 287 | }) 288 | 289 | }(jQuery); 290 | 291 | /* ======================================================================== 292 | * Bootstrap: carousel.js v3.3.4 293 | * http://getbootstrap.com/javascript/#carousel 294 | * ======================================================================== 295 | * Copyright 2011-2015 Twitter, Inc. 296 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 297 | * ======================================================================== */ 298 | 299 | 300 | +function ($) { 301 | 'use strict'; 302 | 303 | // CAROUSEL CLASS DEFINITION 304 | // ========================= 305 | 306 | var Carousel = function (element, options) { 307 | this.$element = $(element) 308 | this.$indicators = this.$element.find('.carousel-indicators') 309 | this.options = options 310 | this.paused = null 311 | this.sliding = null 312 | this.interval = null 313 | this.$active = null 314 | this.$items = null 315 | 316 | this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) 317 | 318 | this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element 319 | .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) 320 | .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) 321 | } 322 | 323 | Carousel.VERSION = '3.3.4' 324 | 325 | Carousel.TRANSITION_DURATION = 600 326 | 327 | Carousel.DEFAULTS = { 328 | interval: 5000, 329 | pause: 'hover', 330 | wrap: true, 331 | keyboard: true 332 | } 333 | 334 | Carousel.prototype.keydown = function (e) { 335 | if (/input|textarea/i.test(e.target.tagName)) return 336 | switch (e.which) { 337 | case 37: this.prev(); break 338 | case 39: this.next(); break 339 | default: return 340 | } 341 | 342 | e.preventDefault() 343 | } 344 | 345 | Carousel.prototype.cycle = function (e) { 346 | e || (this.paused = false) 347 | 348 | this.interval && clearInterval(this.interval) 349 | 350 | this.options.interval 351 | && !this.paused 352 | && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 353 | 354 | return this 355 | } 356 | 357 | Carousel.prototype.getItemIndex = function (item) { 358 | this.$items = item.parent().children('.item') 359 | return this.$items.index(item || this.$active) 360 | } 361 | 362 | Carousel.prototype.getItemForDirection = function (direction, active) { 363 | var activeIndex = this.getItemIndex(active) 364 | var willWrap = (direction == 'prev' && activeIndex === 0) 365 | || (direction == 'next' && activeIndex == (this.$items.length - 1)) 366 | if (willWrap && !this.options.wrap) return active 367 | var delta = direction == 'prev' ? -1 : 1 368 | var itemIndex = (activeIndex + delta) % this.$items.length 369 | return this.$items.eq(itemIndex) 370 | } 371 | 372 | Carousel.prototype.to = function (pos) { 373 | var that = this 374 | var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) 375 | 376 | if (pos > (this.$items.length - 1) || pos < 0) return 377 | 378 | if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" 379 | if (activeIndex == pos) return this.pause().cycle() 380 | 381 | return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) 382 | } 383 | 384 | Carousel.prototype.pause = function (e) { 385 | e || (this.paused = true) 386 | 387 | if (this.$element.find('.next, .prev').length && $.support.transition) { 388 | this.$element.trigger($.support.transition.end) 389 | this.cycle(true) 390 | } 391 | 392 | this.interval = clearInterval(this.interval) 393 | 394 | return this 395 | } 396 | 397 | Carousel.prototype.next = function () { 398 | if (this.sliding) return 399 | return this.slide('next') 400 | } 401 | 402 | Carousel.prototype.prev = function () { 403 | if (this.sliding) return 404 | return this.slide('prev') 405 | } 406 | 407 | Carousel.prototype.slide = function (type, next) { 408 | var $active = this.$element.find('.item.active') 409 | var $next = next || this.getItemForDirection(type, $active) 410 | var isCycling = this.interval 411 | var direction = type == 'next' ? 'left' : 'right' 412 | var that = this 413 | 414 | if ($next.hasClass('active')) return (this.sliding = false) 415 | 416 | var relatedTarget = $next[0] 417 | var slideEvent = $.Event('slide.bs.carousel', { 418 | relatedTarget: relatedTarget, 419 | direction: direction 420 | }) 421 | this.$element.trigger(slideEvent) 422 | if (slideEvent.isDefaultPrevented()) return 423 | 424 | this.sliding = true 425 | 426 | isCycling && this.pause() 427 | 428 | if (this.$indicators.length) { 429 | this.$indicators.find('.active').removeClass('active') 430 | var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) 431 | $nextIndicator && $nextIndicator.addClass('active') 432 | } 433 | 434 | var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" 435 | if ($.support.transition && this.$element.hasClass('slide')) { 436 | $next.addClass(type) 437 | $next[0].offsetWidth // force reflow 438 | $active.addClass(direction) 439 | $next.addClass(direction) 440 | $active 441 | .one('bsTransitionEnd', function () { 442 | $next.removeClass([type, direction].join(' ')).addClass('active') 443 | $active.removeClass(['active', direction].join(' ')) 444 | that.sliding = false 445 | setTimeout(function () { 446 | that.$element.trigger(slidEvent) 447 | }, 0) 448 | }) 449 | .emulateTransitionEnd(Carousel.TRANSITION_DURATION) 450 | } else { 451 | $active.removeClass('active') 452 | $next.addClass('active') 453 | this.sliding = false 454 | this.$element.trigger(slidEvent) 455 | } 456 | 457 | isCycling && this.cycle() 458 | 459 | return this 460 | } 461 | 462 | 463 | // CAROUSEL PLUGIN DEFINITION 464 | // ========================== 465 | 466 | function Plugin(option) { 467 | return this.each(function () { 468 | var $this = $(this) 469 | var data = $this.data('bs.carousel') 470 | var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) 471 | var action = typeof option == 'string' ? option : options.slide 472 | 473 | if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) 474 | if (typeof option == 'number') data.to(option) 475 | else if (action) data[action]() 476 | else if (options.interval) data.pause().cycle() 477 | }) 478 | } 479 | 480 | var old = $.fn.carousel 481 | 482 | $.fn.carousel = Plugin 483 | $.fn.carousel.Constructor = Carousel 484 | 485 | 486 | // CAROUSEL NO CONFLICT 487 | // ==================== 488 | 489 | $.fn.carousel.noConflict = function () { 490 | $.fn.carousel = old 491 | return this 492 | } 493 | 494 | 495 | // CAROUSEL DATA-API 496 | // ================= 497 | 498 | var clickHandler = function (e) { 499 | var href 500 | var $this = $(this) 501 | var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 502 | if (!$target.hasClass('carousel')) return 503 | var options = $.extend({}, $target.data(), $this.data()) 504 | var slideIndex = $this.attr('data-slide-to') 505 | if (slideIndex) options.interval = false 506 | 507 | Plugin.call($target, options) 508 | 509 | if (slideIndex) { 510 | $target.data('bs.carousel').to(slideIndex) 511 | } 512 | 513 | e.preventDefault() 514 | } 515 | 516 | $(document) 517 | .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) 518 | .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) 519 | 520 | $(window).on('load', function () { 521 | $('[data-ride="carousel"]').each(function () { 522 | var $carousel = $(this) 523 | Plugin.call($carousel, $carousel.data()) 524 | }) 525 | }) 526 | 527 | }(jQuery); 528 | 529 | /* ======================================================================== 530 | * Bootstrap: collapse.js v3.3.4 531 | * http://getbootstrap.com/javascript/#collapse 532 | * ======================================================================== 533 | * Copyright 2011-2015 Twitter, Inc. 534 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 535 | * ======================================================================== */ 536 | 537 | 538 | +function ($) { 539 | 'use strict'; 540 | 541 | // COLLAPSE PUBLIC CLASS DEFINITION 542 | // ================================ 543 | 544 | var Collapse = function (element, options) { 545 | this.$element = $(element) 546 | this.options = $.extend({}, Collapse.DEFAULTS, options) 547 | this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + 548 | '[data-toggle="collapse"][data-target="#' + element.id + '"]') 549 | this.transitioning = null 550 | 551 | if (this.options.parent) { 552 | this.$parent = this.getParent() 553 | } else { 554 | this.addAriaAndCollapsedClass(this.$element, this.$trigger) 555 | } 556 | 557 | if (this.options.toggle) this.toggle() 558 | } 559 | 560 | Collapse.VERSION = '3.3.4' 561 | 562 | Collapse.TRANSITION_DURATION = 350 563 | 564 | Collapse.DEFAULTS = { 565 | toggle: true 566 | } 567 | 568 | Collapse.prototype.dimension = function () { 569 | var hasWidth = this.$element.hasClass('width') 570 | return hasWidth ? 'width' : 'height' 571 | } 572 | 573 | Collapse.prototype.show = function () { 574 | if (this.transitioning || this.$element.hasClass('in')) return 575 | 576 | var activesData 577 | var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') 578 | 579 | if (actives && actives.length) { 580 | activesData = actives.data('bs.collapse') 581 | if (activesData && activesData.transitioning) return 582 | } 583 | 584 | var startEvent = $.Event('show.bs.collapse') 585 | this.$element.trigger(startEvent) 586 | if (startEvent.isDefaultPrevented()) return 587 | 588 | if (actives && actives.length) { 589 | Plugin.call(actives, 'hide') 590 | activesData || actives.data('bs.collapse', null) 591 | } 592 | 593 | var dimension = this.dimension() 594 | 595 | this.$element 596 | .removeClass('collapse') 597 | .addClass('collapsing')[dimension](0) 598 | .attr('aria-expanded', true) 599 | 600 | this.$trigger 601 | .removeClass('collapsed') 602 | .attr('aria-expanded', true) 603 | 604 | this.transitioning = 1 605 | 606 | var complete = function () { 607 | this.$element 608 | .removeClass('collapsing') 609 | .addClass('collapse in')[dimension]('') 610 | this.transitioning = 0 611 | this.$element 612 | .trigger('shown.bs.collapse') 613 | } 614 | 615 | if (!$.support.transition) return complete.call(this) 616 | 617 | var scrollSize = $.camelCase(['scroll', dimension].join('-')) 618 | 619 | this.$element 620 | .one('bsTransitionEnd', $.proxy(complete, this)) 621 | .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) 622 | } 623 | 624 | Collapse.prototype.hide = function () { 625 | if (this.transitioning || !this.$element.hasClass('in')) return 626 | 627 | var startEvent = $.Event('hide.bs.collapse') 628 | this.$element.trigger(startEvent) 629 | if (startEvent.isDefaultPrevented()) return 630 | 631 | var dimension = this.dimension() 632 | 633 | this.$element[dimension](this.$element[dimension]())[0].offsetHeight 634 | 635 | this.$element 636 | .addClass('collapsing') 637 | .removeClass('collapse in') 638 | .attr('aria-expanded', false) 639 | 640 | this.$trigger 641 | .addClass('collapsed') 642 | .attr('aria-expanded', false) 643 | 644 | this.transitioning = 1 645 | 646 | var complete = function () { 647 | this.transitioning = 0 648 | this.$element 649 | .removeClass('collapsing') 650 | .addClass('collapse') 651 | .trigger('hidden.bs.collapse') 652 | } 653 | 654 | if (!$.support.transition) return complete.call(this) 655 | 656 | this.$element 657 | [dimension](0) 658 | .one('bsTransitionEnd', $.proxy(complete, this)) 659 | .emulateTransitionEnd(Collapse.TRANSITION_DURATION) 660 | } 661 | 662 | Collapse.prototype.toggle = function () { 663 | this[this.$element.hasClass('in') ? 'hide' : 'show']() 664 | } 665 | 666 | Collapse.prototype.getParent = function () { 667 | return $(this.options.parent) 668 | .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') 669 | .each($.proxy(function (i, element) { 670 | var $element = $(element) 671 | this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) 672 | }, this)) 673 | .end() 674 | } 675 | 676 | Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { 677 | var isOpen = $element.hasClass('in') 678 | 679 | $element.attr('aria-expanded', isOpen) 680 | $trigger 681 | .toggleClass('collapsed', !isOpen) 682 | .attr('aria-expanded', isOpen) 683 | } 684 | 685 | function getTargetFromTrigger($trigger) { 686 | var href 687 | var target = $trigger.attr('data-target') 688 | || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 689 | 690 | return $(target) 691 | } 692 | 693 | 694 | // COLLAPSE PLUGIN DEFINITION 695 | // ========================== 696 | 697 | function Plugin(option) { 698 | return this.each(function () { 699 | var $this = $(this) 700 | var data = $this.data('bs.collapse') 701 | var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 702 | 703 | if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false 704 | if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 705 | if (typeof option == 'string') data[option]() 706 | }) 707 | } 708 | 709 | var old = $.fn.collapse 710 | 711 | $.fn.collapse = Plugin 712 | $.fn.collapse.Constructor = Collapse 713 | 714 | 715 | // COLLAPSE NO CONFLICT 716 | // ==================== 717 | 718 | $.fn.collapse.noConflict = function () { 719 | $.fn.collapse = old 720 | return this 721 | } 722 | 723 | 724 | // COLLAPSE DATA-API 725 | // ================= 726 | 727 | $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 728 | var $this = $(this) 729 | 730 | if (!$this.attr('data-target')) e.preventDefault() 731 | 732 | var $target = getTargetFromTrigger($this) 733 | var data = $target.data('bs.collapse') 734 | var option = data ? 'toggle' : $this.data() 735 | 736 | Plugin.call($target, option) 737 | }) 738 | 739 | }(jQuery); 740 | 741 | /* ======================================================================== 742 | * Bootstrap: dropdown.js v3.3.4 743 | * http://getbootstrap.com/javascript/#dropdowns 744 | * ======================================================================== 745 | * Copyright 2011-2015 Twitter, Inc. 746 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 747 | * ======================================================================== */ 748 | 749 | 750 | +function ($) { 751 | 'use strict'; 752 | 753 | // DROPDOWN CLASS DEFINITION 754 | // ========================= 755 | 756 | var backdrop = '.dropdown-backdrop' 757 | var toggle = '[data-toggle="dropdown"]' 758 | var Dropdown = function (element) { 759 | $(element).on('click.bs.dropdown', this.toggle) 760 | } 761 | 762 | Dropdown.VERSION = '3.3.4' 763 | 764 | Dropdown.prototype.toggle = function (e) { 765 | var $this = $(this) 766 | 767 | if ($this.is('.disabled, :disabled')) return 768 | 769 | var $parent = getParent($this) 770 | var isActive = $parent.hasClass('open') 771 | 772 | clearMenus() 773 | 774 | if (!isActive) { 775 | if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 776 | // if mobile we use a backdrop because click events don't delegate 777 | $('