2 * Bootstrap v3.3.6 (http://getbootstrap.com)
3 * Copyright 2011-2015 Twitter, Inc.
4 * Licensed under the MIT license
7 if (typeof jQuery
=== 'undefined') {
8 throw new Error('Bootstrap\'s JavaScript requires jQuery')
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) || (version
[0] > 2)) {
15 throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')
19 /* ========================================================================
20 * Bootstrap: transition.js v3.3.6
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 * ======================================================================== */
31 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
32 // ============================================================
34 function transitionEnd() {
35 var el
= document
.createElement('bootstrap')
37 var transEndEventNames
= {
38 WebkitTransition
: 'webkitTransitionEnd',
39 MozTransition
: 'transitionend',
40 OTransition
: 'oTransitionEnd otransitionend',
41 transition
: 'transitionend'
44 for (var name
in transEndEventNames
) {
45 if (el
.style
[name
] !== undefined) {
46 return { end
: transEndEventNames
[name
] }
50 return false // explicit for ie8 ( ._.)
53 // http://blog.alexmaccaw.com/css-transitions
54 $.fn
.emulateTransitionEnd = function (duration
) {
57 $(this).one('bsTransitionEnd', function () { called
= true })
58 var callback = function () { if (!called
) $($el
).trigger($.support
.transition
.end
) }
59 setTimeout(callback
, duration
)
64 $.support
.transition
= transitionEnd()
66 if (!$.support
.transition
) return
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
)
79 /* ========================================================================
80 * Bootstrap: alert.js v3.3.6
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 * ======================================================================== */
91 // ALERT CLASS DEFINITION
92 // ======================
94 var dismiss
= '[data-dismiss="alert"]'
95 var Alert = function (el
) {
96 $(el
).on('click', dismiss
, this.close
)
99 Alert
.VERSION
= '3.3.6'
101 Alert
.TRANSITION_DURATION
= 150
103 Alert
.prototype.close = function (e
) {
105 var selector
= $this.attr('data-target')
108 selector
= $this.attr('href')
109 selector
= selector
&& selector
.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
112 var $parent
= $(selector
)
114 if (e
) e
.preventDefault()
116 if (!$parent
.length
) {
117 $parent
= $this.closest('.alert')
120 $parent
.trigger(e
= $.Event('close.bs.alert'))
122 if (e
.isDefaultPrevented()) return
124 $parent
.removeClass('in')
126 function removeElement() {
127 // detach from parent, fire event then clean up data
128 $parent
.detach().trigger('closed.bs.alert').remove()
131 $.support
.transition
&& $parent
.hasClass('fade') ?
133 .one('bsTransitionEnd', removeElement
)
134 .emulateTransitionEnd(Alert
.TRANSITION_DURATION
) :
139 // ALERT PLUGIN DEFINITION
140 // =======================
142 function Plugin(option
) {
143 return this.each(function () {
145 var data
= $this.data('bs.alert')
147 if (!data
) $this.data('bs.alert', (data
= new Alert(this)))
148 if (typeof option
== 'string') data
[option
].call($this)
155 $.fn
.alert
.Constructor
= Alert
161 $.fn
.alert
.noConflict = function () {
170 $(document
).on('click.bs.alert.data-api', dismiss
, Alert
.prototype.close
)
174 /* ========================================================================
175 * Bootstrap: button.js v3.3.6
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 * ======================================================================== */
186 // BUTTON PUBLIC CLASS DEFINITION
187 // ==============================
189 var Button = function (element
, options
) {
190 this.$element
= $(element
)
191 this.options
= $.extend({}, Button
.DEFAULTS
, options
)
192 this.isLoading
= false
195 Button
.VERSION
= '3.3.6'
198 loadingText
: 'loading...'
201 Button
.prototype.setState = function (state
) {
203 var $el
= this.$element
204 var val
= $el
.is('input') ? 'val' : 'html'
205 var data
= $el
.data()
209 if (data
.resetText
== null) $el
.data('resetText', $el
[val
]())
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
])
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
)
225 Button
.prototype.toggle = function () {
227 var $parent
= this.$element
.closest('[data-toggle="buttons"]')
229 if ($parent
.length
) {
230 var $input
= this.$element
.find('input')
231 if ($input
.prop('type') == 'radio') {
232 if ($input
.prop('checked')) changed
= false
233 $parent
.find('.active').removeClass('active')
234 this.$element
.addClass('active')
235 } else if ($input
.prop('type') == 'checkbox') {
236 if (($input
.prop('checked')) !== this.$element
.hasClass('active')) changed
= false
237 this.$element
.toggleClass('active')
239 $input
.prop('checked', this.$element
.hasClass('active'))
240 if (changed
) $input
.trigger('change')
242 this.$element
.attr('aria-pressed', !this.$element
.hasClass('active'))
243 this.$element
.toggleClass('active')
248 // BUTTON PLUGIN DEFINITION
249 // ========================
251 function Plugin(option
) {
252 return this.each(function () {
254 var data
= $this.data('bs.button')
255 var options
= typeof option
== 'object' && option
257 if (!data
) $this.data('bs.button', (data
= new Button(this, options
)))
259 if (option
== 'toggle') data
.toggle()
260 else if (option
) data
.setState(option
)
264 var old
= $.fn
.button
267 $.fn
.button
.Constructor
= Button
270 // BUTTON NO CONFLICT
271 // ==================
273 $.fn
.button
.noConflict = function () {
283 .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e
) {
284 var $btn
= $(e
.target
)
285 if (!$btn
.hasClass('btn')) $btn
= $btn
.closest('.btn')
286 Plugin
.call($btn
, 'toggle')
287 if (!($(e
.target
).is('input[type="radio"]') || $(e
.target
).is('input[type="checkbox"]'))) e
.preventDefault()
289 .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e
) {
290 $(e
.target
).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e
.type
))
295 /* ========================================================================
296 * Bootstrap: carousel.js v3.3.6
297 * http://getbootstrap.com/javascript/#carousel
298 * ========================================================================
299 * Copyright 2011-2015 Twitter, Inc.
300 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
301 * ======================================================================== */
307 // CAROUSEL CLASS DEFINITION
308 // =========================
310 var Carousel = function (element
, options
) {
311 this.$element
= $(element
)
312 this.$indicators
= this.$element
.find('.carousel-indicators')
313 this.options
= options
320 this.options
.keyboard
&& this.$element
.on('keydown.bs.carousel', $.proxy(this.keydown
, this))
322 this.options
.pause
== 'hover' && !('ontouchstart' in document
.documentElement
) && this.$element
323 .on('mouseenter.bs.carousel', $.proxy(this.pause
, this))
324 .on('mouseleave.bs.carousel', $.proxy(this.cycle
, this))
327 Carousel
.VERSION
= '3.3.6'
329 Carousel
.TRANSITION_DURATION
= 600
331 Carousel
.DEFAULTS
= {
338 Carousel
.prototype.keydown = function (e
) {
339 if (/input|textarea/i.test(e
.target
.tagName
)) return
341 case 37: this.prev(); break
342 case 39: this.next(); break
349 Carousel
.prototype.cycle = function (e
) {
350 e
|| (this.paused
= false)
352 this.interval
&& clearInterval(this.interval
)
354 this.options
.interval
356 && (this.interval
= setInterval($.proxy(this.next
, this), this.options
.interval
))
361 Carousel
.prototype.getItemIndex = function (item
) {
362 this.$items
= item
.parent().children('.item')
363 return this.$items
.index(item
|| this.$active
)
366 Carousel
.prototype.getItemForDirection = function (direction
, active
) {
367 var activeIndex
= this.getItemIndex(active
)
368 var willWrap
= (direction
== 'prev' && activeIndex
=== 0)
369 || (direction
== 'next' && activeIndex
== (this.$items
.length
- 1))
370 if (willWrap
&& !this.options
.wrap
) return active
371 var delta
= direction
== 'prev' ? -1 : 1
372 var itemIndex
= (activeIndex
+ delta
) % this.$items
.length
373 return this.$items
.eq(itemIndex
)
376 Carousel
.prototype.to = function (pos
) {
378 var activeIndex
= this.getItemIndex(this.$active
= this.$element
.find('.item.active'))
380 if (pos
> (this.$items
.length
- 1) || pos
< 0) return
382 if (this.sliding
) return this.$element
.one('slid.bs.carousel', function () { that
.to(pos
) }) // yes, "slid"
383 if (activeIndex
== pos
) return this.pause().cycle()
385 return this.slide(pos
> activeIndex
? 'next' : 'prev', this.$items
.eq(pos
))
388 Carousel
.prototype.pause = function (e
) {
389 e
|| (this.paused
= true)
391 if (this.$element
.find('.next, .prev').length
&& $.support
.transition
) {
392 this.$element
.trigger($.support
.transition
.end
)
396 this.interval
= clearInterval(this.interval
)
401 Carousel
.prototype.next = function () {
402 if (this.sliding
) return
403 return this.slide('next')
406 Carousel
.prototype.prev = function () {
407 if (this.sliding
) return
408 return this.slide('prev')
411 Carousel
.prototype.slide = function (type
, next
) {
412 var $active
= this.$element
.find('.item.active')
413 var $next
= next
|| this.getItemForDirection(type
, $active
)
414 var isCycling
= this.interval
415 var direction
= type
== 'next' ? 'left' : 'right'
418 if ($next
.hasClass('active')) return (this.sliding
= false)
420 var relatedTarget
= $next
[0]
421 var slideEvent
= $.Event('slide.bs.carousel', {
422 relatedTarget
: relatedTarget
,
425 this.$element
.trigger(slideEvent
)
426 if (slideEvent
.isDefaultPrevented()) return
430 isCycling
&& this.pause()
432 if (this.$indicators
.length
) {
433 this.$indicators
.find('.active').removeClass('active')
434 var $nextIndicator
= $(this.$indicators
.children()[this.getItemIndex($next
)])
435 $nextIndicator
&& $nextIndicator
.addClass('active')
438 var slidEvent
= $.Event('slid.bs.carousel', { relatedTarget
: relatedTarget
, direction
: direction
}) // yes, "slid"
439 if ($.support
.transition
&& this.$element
.hasClass('slide')) {
441 $next
[0].offsetWidth
// force reflow
442 $active
.addClass(direction
)
443 $next
.addClass(direction
)
445 .one('bsTransitionEnd', function () {
446 $next
.removeClass([type
, direction
].join(' ')).addClass('active')
447 $active
.removeClass(['active', direction
].join(' '))
449 setTimeout(function () {
450 that
.$element
.trigger(slidEvent
)
453 .emulateTransitionEnd(Carousel
.TRANSITION_DURATION
)
455 $active
.removeClass('active')
456 $next
.addClass('active')
458 this.$element
.trigger(slidEvent
)
461 isCycling
&& this.cycle()
467 // CAROUSEL PLUGIN DEFINITION
468 // ==========================
470 function Plugin(option
) {
471 return this.each(function () {
473 var data
= $this.data('bs.carousel')
474 var options
= $.extend({}, Carousel
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
475 var action
= typeof option
== 'string' ? option
: options
.slide
477 if (!data
) $this.data('bs.carousel', (data
= new Carousel(this, options
)))
478 if (typeof option
== 'number') data
.to(option
)
479 else if (action
) data
[action
]()
480 else if (options
.interval
) data
.pause().cycle()
484 var old
= $.fn
.carousel
486 $.fn
.carousel
= Plugin
487 $.fn
.carousel
.Constructor
= Carousel
490 // CAROUSEL NO CONFLICT
491 // ====================
493 $.fn
.carousel
.noConflict = function () {
502 var clickHandler = function (e
) {
505 var $target
= $($this.attr('data-target') || (href
= $this.attr('href')) && href
.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
506 if (!$target
.hasClass('carousel')) return
507 var options
= $.extend({}, $target
.data(), $this.data())
508 var slideIndex
= $this.attr('data-slide-to')
509 if (slideIndex
) options
.interval
= false
511 Plugin
.call($target
, options
)
514 $target
.data('bs.carousel').to(slideIndex
)
521 .on('click.bs.carousel.data-api', '[data-slide]', clickHandler
)
522 .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler
)
524 $(window
).on('load', function () {
525 $('[data-ride="carousel"]').each(function () {
526 var $carousel
= $(this)
527 Plugin
.call($carousel
, $carousel
.data())
533 /* ========================================================================
534 * Bootstrap: collapse.js v3.3.6
535 * http://getbootstrap.com/javascript/#collapse
536 * ========================================================================
537 * Copyright 2011-2015 Twitter, Inc.
538 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
539 * ======================================================================== */
545 // COLLAPSE PUBLIC CLASS DEFINITION
546 // ================================
548 var Collapse = function (element
, options
) {
549 this.$element
= $(element
)
550 this.options
= $.extend({}, Collapse
.DEFAULTS
, options
)
551 this.$trigger
= $('[data-toggle="collapse"][href="#' + element
.id
+ '"],' +
552 '[data-toggle="collapse"][data-target="#' + element
.id
+ '"]')
553 this.transitioning
= null
555 if (this.options
.parent
) {
556 this.$parent
= this.getParent()
558 this.addAriaAndCollapsedClass(this.$element
, this.$trigger
)
561 if (this.options
.toggle
) this.toggle()
564 Collapse
.VERSION
= '3.3.6'
566 Collapse
.TRANSITION_DURATION
= 350
568 Collapse
.DEFAULTS
= {
572 Collapse
.prototype.dimension = function () {
573 var hasWidth
= this.$element
.hasClass('width')
574 return hasWidth
? 'width' : 'height'
577 Collapse
.prototype.show = function () {
578 if (this.transitioning
|| this.$element
.hasClass('in')) return
581 var actives
= this.$parent
&& this.$parent
.children('.panel').children('.in, .collapsing')
583 if (actives
&& actives
.length
) {
584 activesData
= actives
.data('bs.collapse')
585 if (activesData
&& activesData
.transitioning
) return
588 var startEvent
= $.Event('show.bs.collapse')
589 this.$element
.trigger(startEvent
)
590 if (startEvent
.isDefaultPrevented()) return
592 if (actives
&& actives
.length
) {
593 Plugin
.call(actives
, 'hide')
594 activesData
|| actives
.data('bs.collapse', null)
597 var dimension
= this.dimension()
600 .removeClass('collapse')
601 .addClass('collapsing')[dimension
](0)
602 .attr('aria-expanded', true)
605 .removeClass('collapsed')
606 .attr('aria-expanded', true)
608 this.transitioning
= 1
610 var complete = function () {
612 .removeClass('collapsing')
613 .addClass('collapse in')[dimension
]('')
614 this.transitioning
= 0
616 .trigger('shown.bs.collapse')
619 if (!$.support
.transition
) return complete
.call(this)
621 var scrollSize
= $.camelCase(['scroll', dimension
].join('-'))
624 .one('bsTransitionEnd', $.proxy(complete
, this))
625 .emulateTransitionEnd(Collapse
.TRANSITION_DURATION
)[dimension
](this.$element
[0][scrollSize
])
628 Collapse
.prototype.hide = function () {
629 if (this.transitioning
|| !this.$element
.hasClass('in')) return
631 var startEvent
= $.Event('hide.bs.collapse')
632 this.$element
.trigger(startEvent
)
633 if (startEvent
.isDefaultPrevented()) return
635 var dimension
= this.dimension()
637 this.$element
[dimension
](this.$element
[dimension
]())[0].offsetHeight
640 .addClass('collapsing')
641 .removeClass('collapse in')
642 .attr('aria-expanded', false)
645 .addClass('collapsed')
646 .attr('aria-expanded', false)
648 this.transitioning
= 1
650 var complete = function () {
651 this.transitioning
= 0
653 .removeClass('collapsing')
654 .addClass('collapse')
655 .trigger('hidden.bs.collapse')
658 if (!$.support
.transition
) return complete
.call(this)
662 .one('bsTransitionEnd', $.proxy(complete
, this))
663 .emulateTransitionEnd(Collapse
.TRANSITION_DURATION
)
666 Collapse
.prototype.toggle = function () {
667 this[this.$element
.hasClass('in') ? 'hide' : 'show']()
670 Collapse
.prototype.getParent = function () {
671 return $(this.options
.parent
)
672 .find('[data-toggle="collapse"][data-parent="' + this.options
.parent
+ '"]')
673 .each($.proxy(function (i
, element
) {
674 var $element
= $(element
)
675 this.addAriaAndCollapsedClass(getTargetFromTrigger($element
), $element
)
680 Collapse
.prototype.addAriaAndCollapsedClass = function ($element
, $trigger
) {
681 var isOpen
= $element
.hasClass('in')
683 $element
.attr('aria-expanded', isOpen
)
685 .toggleClass('collapsed', !isOpen
)
686 .attr('aria-expanded', isOpen
)
689 function getTargetFromTrigger($trigger
) {
691 var target
= $trigger
.attr('data-target')
692 || (href
= $trigger
.attr('href')) && href
.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
698 // COLLAPSE PLUGIN DEFINITION
699 // ==========================
701 function Plugin(option
) {
702 return this.each(function () {
704 var data
= $this.data('bs.collapse')
705 var options
= $.extend({}, Collapse
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
707 if (!data
&& options
.toggle
&& /show|hide/.test(option
)) options
.toggle
= false
708 if (!data
) $this.data('bs.collapse', (data
= new Collapse(this, options
)))
709 if (typeof option
== 'string') data
[option
]()
713 var old
= $.fn
.collapse
715 $.fn
.collapse
= Plugin
716 $.fn
.collapse
.Constructor
= Collapse
719 // COLLAPSE NO CONFLICT
720 // ====================
722 $.fn
.collapse
.noConflict = function () {
731 $(document
).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e
) {
734 if (!$this.attr('data-target')) e
.preventDefault()
736 var $target
= getTargetFromTrigger($this)
737 var data
= $target
.data('bs.collapse')
738 var option
= data
? 'toggle' : $this.data()
740 Plugin
.call($target
, option
)
745 /* ========================================================================
746 * Bootstrap: dropdown.js v3.3.6
747 * http://getbootstrap.com/javascript/#dropdowns
748 * ========================================================================
749 * Copyright 2011-2015 Twitter, Inc.
750 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
751 * ======================================================================== */
757 // DROPDOWN CLASS DEFINITION
758 // =========================
760 var backdrop
= '.dropdown-backdrop'
761 var toggle
= '[data-toggle="dropdown"]'
762 var Dropdown = function (element
) {
763 $(element
).on('click.bs.dropdown', this.toggle
)
766 Dropdown
.VERSION
= '3.3.6'
768 function getParent($this) {
769 var selector
= $this.attr('data-target')
772 selector
= $this.attr('href')
773 selector
= selector
&& /#[A-Za-z]/.test(selector
) && selector
.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
776 var $parent
= selector
&& $(selector
)
778 return $parent
&& $parent
.length
? $parent
: $this.parent()
781 function clearMenus(e
) {
782 if (e
&& e
.which
=== 3) return
784 $(toggle
).each(function () {
786 var $parent
= getParent($this)
787 var relatedTarget
= { relatedTarget
: this }
789 if (!$parent
.hasClass('open')) return
791 if (e
&& e
.type
== 'click' && /input|textarea/i.test(e
.target
.tagName
) && $.contains($parent
[0], e
.target
)) return
793 $parent
.trigger(e
= $.Event('hide.bs.dropdown', relatedTarget
))
795 if (e
.isDefaultPrevented()) return
797 $this.attr('aria-expanded', 'false')
798 $parent
.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget
))
802 Dropdown
.prototype.toggle = function (e
) {
805 if ($this.is('.disabled, :disabled')) return
807 var $parent
= getParent($this)
808 var isActive
= $parent
.hasClass('open')
813 if ('ontouchstart' in document
.documentElement
&& !$parent
.closest('.navbar-nav').length
) {
814 // if mobile we use a backdrop because click events don't delegate
815 $(document
.createElement('div'))
816 .addClass('dropdown-backdrop')
817 .insertAfter($(this))
818 .on('click', clearMenus
)
821 var relatedTarget
= { relatedTarget
: this }
822 $parent
.trigger(e
= $.Event('show.bs.dropdown', relatedTarget
))
824 if (e
.isDefaultPrevented()) return
828 .attr('aria-expanded', 'true')
832 .trigger($.Event('shown.bs.dropdown', relatedTarget
))
838 Dropdown
.prototype.keydown = function (e
) {
839 if (!/(38|40|27|32)/.test(e
.which
) || /input|textarea/i.test(e
.target
.tagName
)) return
846 if ($this.is('.disabled, :disabled')) return
848 var $parent
= getParent($this)
849 var isActive
= $parent
.hasClass('open')
851 if (!isActive
&& e
.which
!= 27 || isActive
&& e
.which
== 27) {
852 if (e
.which
== 27) $parent
.find(toggle
).trigger('focus')
853 return $this.trigger('click')
856 var desc
= ' li:not(.disabled):visible a'
857 var $items
= $parent
.find('.dropdown-menu' + desc
)
859 if (!$items
.length
) return
861 var index
= $items
.index(e
.target
)
863 if (e
.which
== 38 && index
> 0) index
-- // up
864 if (e
.which
== 40 && index
< $items
.length
- 1) index
++ // down
865 if (!~index
) index
= 0
867 $items
.eq(index
).trigger('focus')
871 // DROPDOWN PLUGIN DEFINITION
872 // ==========================
874 function Plugin(option
) {
875 return this.each(function () {
877 var data
= $this.data('bs.dropdown')
879 if (!data
) $this.data('bs.dropdown', (data
= new Dropdown(this)))
880 if (typeof option
== 'string') data
[option
].call($this)
884 var old
= $.fn
.dropdown
886 $.fn
.dropdown
= Plugin
887 $.fn
.dropdown
.Constructor
= Dropdown
890 // DROPDOWN NO CONFLICT
891 // ====================
893 $.fn
.dropdown
.noConflict = function () {
899 // APPLY TO STANDARD DROPDOWN ELEMENTS
900 // ===================================
903 .on('click.bs.dropdown.data-api', clearMenus
)
904 .on('click.bs.dropdown.data-api', '.dropdown form', function (e
) { e
.stopPropagation() })
905 .on('click.bs.dropdown.data-api', toggle
, Dropdown
.prototype.toggle
)
906 .on('keydown.bs.dropdown.data-api', toggle
, Dropdown
.prototype.keydown
)
907 .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown
.prototype.keydown
)
911 /* ========================================================================
912 * Bootstrap: modal.js v3.3.6
913 * http://getbootstrap.com/javascript/#modals
914 * ========================================================================
915 * Copyright 2011-2015 Twitter, Inc.
916 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
917 * ======================================================================== */
923 // MODAL CLASS DEFINITION
924 // ======================
926 var Modal = function (element
, options
) {
927 this.options
= options
928 this.$body
= $(document
.body
)
929 this.$element
= $(element
)
930 this.$dialog
= this.$element
.find('.modal-dialog')
931 this.$backdrop
= null
933 this.originalBodyPad
= null
934 this.scrollbarWidth
= 0
935 this.ignoreBackdropClick
= false
937 if (this.options
.remote
) {
939 .find('.modal-content')
940 .load(this.options
.remote
, $.proxy(function () {
941 this.$element
.trigger('loaded.bs.modal')
946 Modal
.VERSION
= '3.3.6'
948 Modal
.TRANSITION_DURATION
= 300
949 Modal
.BACKDROP_TRANSITION_DURATION
= 150
957 Modal
.prototype.toggle = function (_relatedTarget
) {
958 return this.isShown
? this.hide() : this.show(_relatedTarget
)
961 Modal
.prototype.show = function (_relatedTarget
) {
963 var e
= $.Event('show.bs.modal', { relatedTarget
: _relatedTarget
})
965 this.$element
.trigger(e
)
967 if (this.isShown
|| e
.isDefaultPrevented()) return
971 this.checkScrollbar()
973 this.$body
.addClass('modal-open')
978 this.$element
.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide
, this))
980 this.$dialog
.on('mousedown.dismiss.bs.modal', function () {
981 that
.$element
.one('mouseup.dismiss.bs.modal', function (e
) {
982 if ($(e
.target
).is(that
.$element
)) that
.ignoreBackdropClick
= true
986 this.backdrop(function () {
987 var transition
= $.support
.transition
&& that
.$element
.hasClass('fade')
989 if (!that
.$element
.parent().length
) {
990 that
.$element
.appendTo(that
.$body
) // don't move modals dom position
1000 that
.$element
[0].offsetWidth
// force reflow
1003 that
.$element
.addClass('in')
1007 var e
= $.Event('shown.bs.modal', { relatedTarget
: _relatedTarget
})
1010 that
.$dialog
// wait for modal to slide in
1011 .one('bsTransitionEnd', function () {
1012 that
.$element
.trigger('focus').trigger(e
)
1014 .emulateTransitionEnd(Modal
.TRANSITION_DURATION
) :
1015 that
.$element
.trigger('focus').trigger(e
)
1019 Modal
.prototype.hide = function (e
) {
1020 if (e
) e
.preventDefault()
1022 e
= $.Event('hide.bs.modal')
1024 this.$element
.trigger(e
)
1026 if (!this.isShown
|| e
.isDefaultPrevented()) return
1028 this.isShown
= false
1033 $(document
).off('focusin.bs.modal')
1037 .off('click.dismiss.bs.modal')
1038 .off('mouseup.dismiss.bs.modal')
1040 this.$dialog
.off('mousedown.dismiss.bs.modal')
1042 $.support
.transition
&& this.$element
.hasClass('fade') ?
1044 .one('bsTransitionEnd', $.proxy(this.hideModal
, this))
1045 .emulateTransitionEnd(Modal
.TRANSITION_DURATION
) :
1049 Modal
.prototype.enforceFocus = function () {
1051 .off('focusin.bs.modal') // guard against infinite focus loop
1052 .on('focusin.bs.modal', $.proxy(function (e
) {
1053 if (this.$element
[0] !== e
.target
&& !this.$element
.has(e
.target
).length
) {
1054 this.$element
.trigger('focus')
1059 Modal
.prototype.escape = function () {
1060 if (this.isShown
&& this.options
.keyboard
) {
1061 this.$element
.on('keydown.dismiss.bs.modal', $.proxy(function (e
) {
1062 e
.which
== 27 && this.hide()
1064 } else if (!this.isShown
) {
1065 this.$element
.off('keydown.dismiss.bs.modal')
1069 Modal
.prototype.resize = function () {
1071 $(window
).on('resize.bs.modal', $.proxy(this.handleUpdate
, this))
1073 $(window
).off('resize.bs.modal')
1077 Modal
.prototype.hideModal = function () {
1079 this.$element
.hide()
1080 this.backdrop(function () {
1081 that
.$body
.removeClass('modal-open')
1082 that
.resetAdjustments()
1083 that
.resetScrollbar()
1084 that
.$element
.trigger('hidden.bs.modal')
1088 Modal
.prototype.removeBackdrop = function () {
1089 this.$backdrop
&& this.$backdrop
.remove()
1090 this.$backdrop
= null
1093 Modal
.prototype.backdrop = function (callback
) {
1095 var animate
= this.$element
.hasClass('fade') ? 'fade' : ''
1097 if (this.isShown
&& this.options
.backdrop
) {
1098 var doAnimate
= $.support
.transition
&& animate
1100 this.$backdrop
= $(document
.createElement('div'))
1101 .addClass('modal-backdrop ' + animate
)
1102 .appendTo(this.$body
)
1104 this.$element
.on('click.dismiss.bs.modal', $.proxy(function (e
) {
1105 if (this.ignoreBackdropClick
) {
1106 this.ignoreBackdropClick
= false
1109 if (e
.target
!== e
.currentTarget
) return
1110 this.options
.backdrop
== 'static'
1111 ? this.$element
[0].focus()
1115 if (doAnimate
) this.$backdrop
[0].offsetWidth
// force reflow
1117 this.$backdrop
.addClass('in')
1119 if (!callback
) return
1123 .one('bsTransitionEnd', callback
)
1124 .emulateTransitionEnd(Modal
.BACKDROP_TRANSITION_DURATION
) :
1127 } else if (!this.isShown
&& this.$backdrop
) {
1128 this.$backdrop
.removeClass('in')
1130 var callbackRemove = function () {
1131 that
.removeBackdrop()
1132 callback
&& callback()
1134 $.support
.transition
&& this.$element
.hasClass('fade') ?
1136 .one('bsTransitionEnd', callbackRemove
)
1137 .emulateTransitionEnd(Modal
.BACKDROP_TRANSITION_DURATION
) :
1140 } else if (callback
) {
1145 // these following methods are used to handle overflowing modals
1147 Modal
.prototype.handleUpdate = function () {
1151 Modal
.prototype.adjustDialog = function () {
1152 var modalIsOverflowing
= this.$element
[0].scrollHeight
> document
.documentElement
.clientHeight
1155 paddingLeft
: !this.bodyIsOverflowing
&& modalIsOverflowing
? this.scrollbarWidth
: '',
1156 paddingRight
: this.bodyIsOverflowing
&& !modalIsOverflowing
? this.scrollbarWidth
: ''
1160 Modal
.prototype.resetAdjustments = function () {
1167 Modal
.prototype.checkScrollbar = function () {
1168 var fullWindowWidth
= window
.innerWidth
1169 if (!fullWindowWidth
) { // workaround for missing window.innerWidth in IE8
1170 var documentElementRect
= document
.documentElement
.getBoundingClientRect()
1171 fullWindowWidth
= documentElementRect
.right
- Math
.abs(documentElementRect
.left
)
1173 this.bodyIsOverflowing
= document
.body
.clientWidth
< fullWindowWidth
1174 this.scrollbarWidth
= this.measureScrollbar()
1177 Modal
.prototype.setScrollbar = function () {
1178 var bodyPad
= parseInt((this.$body
.css('padding-right') || 0), 10)
1179 this.originalBodyPad
= document
.body
.style
.paddingRight
|| ''
1180 if (this.bodyIsOverflowing
) this.$body
.css('padding-right', bodyPad
+ this.scrollbarWidth
)
1183 Modal
.prototype.resetScrollbar = function () {
1184 this.$body
.css('padding-right', this.originalBodyPad
)
1187 Modal
.prototype.measureScrollbar = function () { // thx walsh
1188 var scrollDiv
= document
.createElement('div')
1189 scrollDiv
.className
= 'modal-scrollbar-measure'
1190 this.$body
.append(scrollDiv
)
1191 var scrollbarWidth
= scrollDiv
.offsetWidth
- scrollDiv
.clientWidth
1192 this.$body
[0].removeChild(scrollDiv
)
1193 return scrollbarWidth
1197 // MODAL PLUGIN DEFINITION
1198 // =======================
1200 function Plugin(option
, _relatedTarget
) {
1201 return this.each(function () {
1203 var data
= $this.data('bs.modal')
1204 var options
= $.extend({}, Modal
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
1206 if (!data
) $this.data('bs.modal', (data
= new Modal(this, options
)))
1207 if (typeof option
== 'string') data
[option
](_relatedTarget
)
1208 else if (options
.show
) data
.show(_relatedTarget
)
1212 var old
= $.fn
.modal
1215 $.fn
.modal
.Constructor
= Modal
1218 // MODAL NO CONFLICT
1219 // =================
1221 $.fn
.modal
.noConflict = function () {
1230 $(document
).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e
) {
1232 var href
= $this.attr('href')
1233 var $target
= $($this.attr('data-target') || (href
&& href
.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
1234 var option
= $target
.data('bs.modal') ? 'toggle' : $.extend({ remote
: !/#/.test(href
) && href
}, $target
.data(), $this.data())
1236 if ($this.is('a')) e
.preventDefault()
1238 $target
.one('show.bs.modal', function (showEvent
) {
1239 if (showEvent
.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
1240 $target
.one('hidden.bs.modal', function () {
1241 $this.is(':visible') && $this.trigger('focus')
1244 Plugin
.call($target
, option
, this)
1249 /* ========================================================================
1250 * Bootstrap: tooltip.js v3.3.6
1251 * http://getbootstrap.com/javascript/#tooltip
1252 * Inspired by the original jQuery.tipsy by Jason Frame
1253 * ========================================================================
1254 * Copyright 2011-2015 Twitter, Inc.
1255 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1256 * ======================================================================== */
1262 // TOOLTIP PUBLIC CLASS DEFINITION
1263 // ===============================
1265 var Tooltip = function (element
, options
) {
1270 this.hoverState
= null
1271 this.$element
= null
1274 this.init('tooltip', element
, options
)
1277 Tooltip
.VERSION
= '3.3.6'
1279 Tooltip
.TRANSITION_DURATION
= 150
1281 Tooltip
.DEFAULTS
= {
1285 template
: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
1286 trigger
: 'hover focus',
1297 Tooltip
.prototype.init = function (type
, element
, options
) {
1300 this.$element
= $(element
)
1301 this.options
= this.getOptions(options
)
1302 this.$viewport
= this.options
.viewport
&& $($.isFunction(this.options
.viewport
) ? this.options
.viewport
.call(this, this.$element
) : (this.options
.viewport
.selector
|| this.options
.viewport
))
1303 this.inState
= { click
: false, hover
: false, focus
: false }
1305 if (this.$element
[0] instanceof document
.constructor && !this.options
.selector
) {
1306 throw new Error('`selector` option must be specified when initializing ' + this.type
+ ' on the window.document object!')
1309 var triggers
= this.options
.trigger
.split(' ')
1311 for (var i
= triggers
.length
; i
--;) {
1312 var trigger
= triggers
[i
]
1314 if (trigger
== 'click') {
1315 this.$element
.on('click.' + this.type
, this.options
.selector
, $.proxy(this.toggle
, this))
1316 } else if (trigger
!= 'manual') {
1317 var eventIn
= trigger
== 'hover' ? 'mouseenter' : 'focusin'
1318 var eventOut
= trigger
== 'hover' ? 'mouseleave' : 'focusout'
1320 this.$element
.on(eventIn
+ '.' + this.type
, this.options
.selector
, $.proxy(this.enter
, this))
1321 this.$element
.on(eventOut
+ '.' + this.type
, this.options
.selector
, $.proxy(this.leave
, this))
1325 this.options
.selector
?
1326 (this._options
= $.extend({}, this.options
, { trigger
: 'manual', selector
: '' })) :
1330 Tooltip
.prototype.getDefaults = function () {
1331 return Tooltip
.DEFAULTS
1334 Tooltip
.prototype.getOptions = function (options
) {
1335 options
= $.extend({}, this.getDefaults(), this.$element
.data(), options
)
1337 if (options
.delay
&& typeof options
.delay
== 'number') {
1339 show
: options
.delay
,
1347 Tooltip
.prototype.getDelegateOptions = function () {
1349 var defaults
= this.getDefaults()
1351 this._options
&& $.each(this._options
, function (key
, value
) {
1352 if (defaults
[key
] != value
) options
[key
] = value
1358 Tooltip
.prototype.enter = function (obj
) {
1359 var self
= obj
instanceof this.constructor ?
1360 obj
: $(obj
.currentTarget
).data('bs.' + this.type
)
1363 self
= new this.constructor(obj
.currentTarget
, this.getDelegateOptions())
1364 $(obj
.currentTarget
).data('bs.' + this.type
, self
)
1367 if (obj
instanceof $.Event
) {
1368 self
.inState
[obj
.type
== 'focusin' ? 'focus' : 'hover'] = true
1371 if (self
.tip().hasClass('in') || self
.hoverState
== 'in') {
1372 self
.hoverState
= 'in'
1376 clearTimeout(self
.timeout
)
1378 self
.hoverState
= 'in'
1380 if (!self
.options
.delay
|| !self
.options
.delay
.show
) return self
.show()
1382 self
.timeout
= setTimeout(function () {
1383 if (self
.hoverState
== 'in') self
.show()
1384 }, self
.options
.delay
.show
)
1387 Tooltip
.prototype.isInStateTrue = function () {
1388 for (var key
in this.inState
) {
1389 if (this.inState
[key
]) return true
1395 Tooltip
.prototype.leave = function (obj
) {
1396 var self
= obj
instanceof this.constructor ?
1397 obj
: $(obj
.currentTarget
).data('bs.' + this.type
)
1400 self
= new this.constructor(obj
.currentTarget
, this.getDelegateOptions())
1401 $(obj
.currentTarget
).data('bs.' + this.type
, self
)
1404 if (obj
instanceof $.Event
) {
1405 self
.inState
[obj
.type
== 'focusout' ? 'focus' : 'hover'] = false
1408 if (self
.isInStateTrue()) return
1410 clearTimeout(self
.timeout
)
1412 self
.hoverState
= 'out'
1414 if (!self
.options
.delay
|| !self
.options
.delay
.hide
) return self
.hide()
1416 self
.timeout
= setTimeout(function () {
1417 if (self
.hoverState
== 'out') self
.hide()
1418 }, self
.options
.delay
.hide
)
1421 Tooltip
.prototype.show = function () {
1422 var e
= $.Event('show.bs.' + this.type
)
1424 if (this.hasContent() && this.enabled
) {
1425 this.$element
.trigger(e
)
1427 var inDom
= $.contains(this.$element
[0].ownerDocument
.documentElement
, this.$element
[0])
1428 if (e
.isDefaultPrevented() || !inDom
) return
1431 var $tip
= this.tip()
1433 var tipId
= this.getUID(this.type
)
1436 $tip
.attr('id', tipId
)
1437 this.$element
.attr('aria-describedby', tipId
)
1439 if (this.options
.animation
) $tip
.addClass('fade')
1441 var placement
= typeof this.options
.placement
== 'function' ?
1442 this.options
.placement
.call(this, $tip
[0], this.$element
[0]) :
1443 this.options
.placement
1445 var autoToken
= /\s?auto?\s?/i
1446 var autoPlace
= autoToken
.test(placement
)
1447 if (autoPlace
) placement
= placement
.replace(autoToken
, '') || 'top'
1451 .css({ top
: 0, left
: 0, display
: 'block' })
1452 .addClass(placement
)
1453 .data('bs.' + this.type
, this)
1455 this.options
.container
? $tip
.appendTo(this.options
.container
) : $tip
.insertAfter(this.$element
)
1456 this.$element
.trigger('inserted.bs.' + this.type
)
1458 var pos
= this.getPosition()
1459 var actualWidth
= $tip
[0].offsetWidth
1460 var actualHeight
= $tip
[0].offsetHeight
1463 var orgPlacement
= placement
1464 var viewportDim
= this.getPosition(this.$viewport
)
1466 placement
= placement
== 'bottom' && pos
.bottom
+ actualHeight
> viewportDim
.bottom
? 'top' :
1467 placement
== 'top' && pos
.top
- actualHeight
< viewportDim
.top
? 'bottom' :
1468 placement
== 'right' && pos
.right
+ actualWidth
> viewportDim
.width
? 'left' :
1469 placement
== 'left' && pos
.left
- actualWidth
< viewportDim
.left
? 'right' :
1473 .removeClass(orgPlacement
)
1474 .addClass(placement
)
1477 var calculatedOffset
= this.getCalculatedOffset(placement
, pos
, actualWidth
, actualHeight
)
1479 this.applyPlacement(calculatedOffset
, placement
)
1481 var complete = function () {
1482 var prevHoverState
= that
.hoverState
1483 that
.$element
.trigger('shown.bs.' + that
.type
)
1484 that
.hoverState
= null
1486 if (prevHoverState
== 'out') that
.leave(that
)
1489 $.support
.transition
&& this.$tip
.hasClass('fade') ?
1491 .one('bsTransitionEnd', complete
)
1492 .emulateTransitionEnd(Tooltip
.TRANSITION_DURATION
) :
1497 Tooltip
.prototype.applyPlacement = function (offset
, placement
) {
1498 var $tip
= this.tip()
1499 var width
= $tip
[0].offsetWidth
1500 var height
= $tip
[0].offsetHeight
1502 // manually read margins because getBoundingClientRect includes difference
1503 var marginTop
= parseInt($tip
.css('margin-top'), 10)
1504 var marginLeft
= parseInt($tip
.css('margin-left'), 10)
1506 // we must check for NaN for ie 8/9
1507 if (isNaN(marginTop
)) marginTop
= 0
1508 if (isNaN(marginLeft
)) marginLeft
= 0
1510 offset
.top
+= marginTop
1511 offset
.left
+= marginLeft
1513 // $.fn.offset doesn't round pixel values
1514 // so we use setOffset directly with our own function B-0
1515 $.offset
.setOffset($tip
[0], $.extend({
1516 using: function (props
) {
1518 top
: Math
.round(props
.top
),
1519 left
: Math
.round(props
.left
)
1526 // check to see if placing tip in new offset caused the tip to resize itself
1527 var actualWidth
= $tip
[0].offsetWidth
1528 var actualHeight
= $tip
[0].offsetHeight
1530 if (placement
== 'top' && actualHeight
!= height
) {
1531 offset
.top
= offset
.top
+ height
- actualHeight
1534 var delta
= this.getViewportAdjustedDelta(placement
, offset
, actualWidth
, actualHeight
)
1536 if (delta
.left
) offset
.left
+= delta
.left
1537 else offset
.top
+= delta
.top
1539 var isVertical
= /top|bottom/.test(placement
)
1540 var arrowDelta
= isVertical
? delta
.left
* 2 - width
+ actualWidth
: delta
.top
* 2 - height
+ actualHeight
1541 var arrowOffsetPosition
= isVertical
? 'offsetWidth' : 'offsetHeight'
1544 this.replaceArrow(arrowDelta
, $tip
[0][arrowOffsetPosition
], isVertical
)
1547 Tooltip
.prototype.replaceArrow = function (delta
, dimension
, isVertical
) {
1549 .css(isVertical
? 'left' : 'top', 50 * (1 - delta
/ dimension
) + '%')
1550 .css(isVertical
? 'top' : 'left', '')
1553 Tooltip
.prototype.setContent = function () {
1554 var $tip
= this.tip()
1555 var title
= this.getTitle()
1557 $tip
.find('.tooltip-inner')[this.options
.html
? 'html' : 'text'](title
)
1558 $tip
.removeClass('fade in top bottom left right')
1561 Tooltip
.prototype.hide = function (callback
) {
1563 var $tip
= $(this.$tip
)
1564 var e
= $.Event('hide.bs.' + this.type
)
1566 function complete() {
1567 if (that
.hoverState
!= 'in') $tip
.detach()
1569 .removeAttr('aria-describedby')
1570 .trigger('hidden.bs.' + that
.type
)
1571 callback
&& callback()
1574 this.$element
.trigger(e
)
1576 if (e
.isDefaultPrevented()) return
1578 $tip
.removeClass('in')
1580 $.support
.transition
&& $tip
.hasClass('fade') ?
1582 .one('bsTransitionEnd', complete
)
1583 .emulateTransitionEnd(Tooltip
.TRANSITION_DURATION
) :
1586 this.hoverState
= null
1591 Tooltip
.prototype.fixTitle = function () {
1592 var $e
= this.$element
1593 if ($e
.attr('title') || typeof $e
.attr('data-original-title') != 'string') {
1594 $e
.attr('data-original-title', $e
.attr('title') || '').attr('title', '')
1598 Tooltip
.prototype.hasContent = function () {
1599 return this.getTitle()
1602 Tooltip
.prototype.getPosition = function ($element
) {
1603 $element
= $element
|| this.$element
1605 var el
= $element
[0]
1606 var isBody
= el
.tagName
== 'BODY'
1608 var elRect
= el
.getBoundingClientRect()
1609 if (elRect
.width
== null) {
1610 // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
1611 elRect
= $.extend({}, elRect
, { width
: elRect
.right
- elRect
.left
, height
: elRect
.bottom
- elRect
.top
})
1613 var elOffset
= isBody
? { top
: 0, left
: 0 } : $element
.offset()
1614 var scroll
= { scroll
: isBody
? document
.documentElement
.scrollTop
|| document
.body
.scrollTop
: $element
.scrollTop() }
1615 var outerDims
= isBody
? { width
: $(window
).width(), height
: $(window
).height() } : null
1617 return $.extend({}, elRect
, scroll
, outerDims
, elOffset
)
1620 Tooltip
.prototype.getCalculatedOffset = function (placement
, pos
, actualWidth
, actualHeight
) {
1621 return placement
== 'bottom' ? { top
: pos
.top
+ pos
.height
, left
: pos
.left
+ pos
.width
/ 2 - actualWidth
/ 2 } :
1622 placement
== 'top' ? { top
: pos
.top
- actualHeight
, left
: pos
.left
+ pos
.width
/ 2 - actualWidth
/ 2 } :
1623 placement
== 'left' ? { top
: pos
.top
+ pos
.height
/ 2 - actualHeight
/ 2, left
: pos
.left
- actualWidth
} :
1624 /* placement == 'right' */ { top
: pos
.top
+ pos
.height
/ 2 - actualHeight
/ 2, left
: pos
.left
+ pos
.width
}
1628 Tooltip
.prototype.getViewportAdjustedDelta = function (placement
, pos
, actualWidth
, actualHeight
) {
1629 var delta
= { top
: 0, left
: 0 }
1630 if (!this.$viewport
) return delta
1632 var viewportPadding
= this.options
.viewport
&& this.options
.viewport
.padding
|| 0
1633 var viewportDimensions
= this.getPosition(this.$viewport
)
1635 if (/right|left/.test(placement
)) {
1636 var topEdgeOffset
= pos
.top
- viewportPadding
- viewportDimensions
.scroll
1637 var bottomEdgeOffset
= pos
.top
+ viewportPadding
- viewportDimensions
.scroll
+ actualHeight
1638 if (topEdgeOffset
< viewportDimensions
.top
) { // top overflow
1639 delta
.top
= viewportDimensions
.top
- topEdgeOffset
1640 } else if (bottomEdgeOffset
> viewportDimensions
.top
+ viewportDimensions
.height
) { // bottom overflow
1641 delta
.top
= viewportDimensions
.top
+ viewportDimensions
.height
- bottomEdgeOffset
1644 var leftEdgeOffset
= pos
.left
- viewportPadding
1645 var rightEdgeOffset
= pos
.left
+ viewportPadding
+ actualWidth
1646 if (leftEdgeOffset
< viewportDimensions
.left
) { // left overflow
1647 delta
.left
= viewportDimensions
.left
- leftEdgeOffset
1648 } else if (rightEdgeOffset
> viewportDimensions
.right
) { // right overflow
1649 delta
.left
= viewportDimensions
.left
+ viewportDimensions
.width
- rightEdgeOffset
1656 Tooltip
.prototype.getTitle = function () {
1658 var $e
= this.$element
1659 var o
= this.options
1661 title
= $e
.attr('data-original-title')
1662 || (typeof o
.title
== 'function' ? o
.title
.call($e
[0]) : o
.title
)
1667 Tooltip
.prototype.getUID = function (prefix
) {
1668 do prefix
+= ~~(Math
.random() * 1000000)
1669 while (document
.getElementById(prefix
))
1673 Tooltip
.prototype.tip = function () {
1675 this.$tip
= $(this.options
.template
)
1676 if (this.$tip
.length
!= 1) {
1677 throw new Error(this.type
+ ' `template` option must consist of exactly 1 top-level element!')
1683 Tooltip
.prototype.arrow = function () {
1684 return (this.$arrow
= this.$arrow
|| this.tip().find('.tooltip-arrow'))
1687 Tooltip
.prototype.enable = function () {
1691 Tooltip
.prototype.disable = function () {
1692 this.enabled
= false
1695 Tooltip
.prototype.toggleEnabled = function () {
1696 this.enabled
= !this.enabled
1699 Tooltip
.prototype.toggle = function (e
) {
1702 self
= $(e
.currentTarget
).data('bs.' + this.type
)
1704 self
= new this.constructor(e
.currentTarget
, this.getDelegateOptions())
1705 $(e
.currentTarget
).data('bs.' + this.type
, self
)
1710 self
.inState
.click
= !self
.inState
.click
1711 if (self
.isInStateTrue()) self
.enter(self
)
1712 else self
.leave(self
)
1714 self
.tip().hasClass('in') ? self
.leave(self
) : self
.enter(self
)
1718 Tooltip
.prototype.destroy = function () {
1720 clearTimeout(this.timeout
)
1721 this.hide(function () {
1722 that
.$element
.off('.' + that
.type
).removeData('bs.' + that
.type
)
1728 that
.$viewport
= null
1733 // TOOLTIP PLUGIN DEFINITION
1734 // =========================
1736 function Plugin(option
) {
1737 return this.each(function () {
1739 var data
= $this.data('bs.tooltip')
1740 var options
= typeof option
== 'object' && option
1742 if (!data
&& /destroy|hide/.test(option
)) return
1743 if (!data
) $this.data('bs.tooltip', (data
= new Tooltip(this, options
)))
1744 if (typeof option
== 'string') data
[option
]()
1748 var old
= $.fn
.tooltip
1750 $.fn
.tooltip
= Plugin
1751 $.fn
.tooltip
.Constructor
= Tooltip
1754 // TOOLTIP NO CONFLICT
1755 // ===================
1757 $.fn
.tooltip
.noConflict = function () {
1764 /* ========================================================================
1765 * Bootstrap: popover.js v3.3.6
1766 * http://getbootstrap.com/javascript/#popovers
1767 * ========================================================================
1768 * Copyright 2011-2015 Twitter, Inc.
1769 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1770 * ======================================================================== */
1776 // POPOVER PUBLIC CLASS DEFINITION
1777 // ===============================
1779 var Popover = function (element
, options
) {
1780 this.init('popover', element
, options
)
1783 if (!$.fn
.tooltip
) throw new Error('Popover requires tooltip.js')
1785 Popover
.VERSION
= '3.3.6'
1787 Popover
.DEFAULTS
= $.extend({}, $.fn
.tooltip
.Constructor
.DEFAULTS
, {
1791 template
: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1795 // NOTE: POPOVER EXTENDS tooltip.js
1796 // ================================
1798 Popover
.prototype = $.extend({}, $.fn
.tooltip
.Constructor
.prototype)
1800 Popover
.prototype.constructor = Popover
1802 Popover
.prototype.getDefaults = function () {
1803 return Popover
.DEFAULTS
1806 Popover
.prototype.setContent = function () {
1807 var $tip
= this.tip()
1808 var title
= this.getTitle()
1809 var content
= this.getContent()
1811 $tip
.find('.popover-title')[this.options
.html
? 'html' : 'text'](title
)
1812 $tip
.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
1813 this.options
.html
? (typeof content
== 'string' ? 'html' : 'append') : 'text'
1816 $tip
.removeClass('fade top bottom left right in')
1818 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
1819 // this manually by checking the contents.
1820 if (!$tip
.find('.popover-title').html()) $tip
.find('.popover-title').hide()
1823 Popover
.prototype.hasContent = function () {
1824 return this.getTitle() || this.getContent()
1827 Popover
.prototype.getContent = function () {
1828 var $e
= this.$element
1829 var o
= this.options
1831 return $e
.attr('data-content')
1832 || (typeof o
.content
== 'function' ?
1833 o
.content
.call($e
[0]) :
1837 Popover
.prototype.arrow = function () {
1838 return (this.$arrow
= this.$arrow
|| this.tip().find('.arrow'))
1842 // POPOVER PLUGIN DEFINITION
1843 // =========================
1845 function Plugin(option
) {
1846 return this.each(function () {
1848 var data
= $this.data('bs.popover')
1849 var options
= typeof option
== 'object' && option
1851 if (!data
&& /destroy|hide/.test(option
)) return
1852 if (!data
) $this.data('bs.popover', (data
= new Popover(this, options
)))
1853 if (typeof option
== 'string') data
[option
]()
1857 var old
= $.fn
.popover
1859 $.fn
.popover
= Plugin
1860 $.fn
.popover
.Constructor
= Popover
1863 // POPOVER NO CONFLICT
1864 // ===================
1866 $.fn
.popover
.noConflict = function () {
1873 /* ========================================================================
1874 * Bootstrap: scrollspy.js v3.3.6
1875 * http://getbootstrap.com/javascript/#scrollspy
1876 * ========================================================================
1877 * Copyright 2011-2015 Twitter, Inc.
1878 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1879 * ======================================================================== */
1885 // SCROLLSPY CLASS DEFINITION
1886 // ==========================
1888 function ScrollSpy(element
, options
) {
1889 this.$body
= $(document
.body
)
1890 this.$scrollElement
= $(element
).is(document
.body
) ? $(window
) : $(element
)
1891 this.options
= $.extend({}, ScrollSpy
.DEFAULTS
, options
)
1892 this.selector
= (this.options
.target
|| '') + ' .nav li > a'
1895 this.activeTarget
= null
1896 this.scrollHeight
= 0
1898 this.$scrollElement
.on('scroll.bs.scrollspy', $.proxy(this.process
, this))
1903 ScrollSpy
.VERSION
= '3.3.6'
1905 ScrollSpy
.DEFAULTS
= {
1909 ScrollSpy
.prototype.getScrollHeight = function () {
1910 return this.$scrollElement
[0].scrollHeight
|| Math
.max(this.$body
[0].scrollHeight
, document
.documentElement
.scrollHeight
)
1913 ScrollSpy
.prototype.refresh = function () {
1915 var offsetMethod
= 'offset'
1920 this.scrollHeight
= this.getScrollHeight()
1922 if (!$.isWindow(this.$scrollElement
[0])) {
1923 offsetMethod
= 'position'
1924 offsetBase
= this.$scrollElement
.scrollTop()
1928 .find(this.selector
)
1931 var href
= $el
.data('target') || $el
.attr('href')
1932 var $href
= /^#./.test(href
) && $(href
)
1936 && $href
.is(':visible')
1937 && [[$href
[offsetMethod
]().top
+ offsetBase
, href
]]) || null
1939 .sort(function (a
, b
) { return a
[0] - b
[0] })
1941 that
.offsets
.push(this[0])
1942 that
.targets
.push(this[1])
1946 ScrollSpy
.prototype.process = function () {
1947 var scrollTop
= this.$scrollElement
.scrollTop() + this.options
.offset
1948 var scrollHeight
= this.getScrollHeight()
1949 var maxScroll
= this.options
.offset
+ scrollHeight
- this.$scrollElement
.height()
1950 var offsets
= this.offsets
1951 var targets
= this.targets
1952 var activeTarget
= this.activeTarget
1955 if (this.scrollHeight
!= scrollHeight
) {
1959 if (scrollTop
>= maxScroll
) {
1960 return activeTarget
!= (i
= targets
[targets
.length
- 1]) && this.activate(i
)
1963 if (activeTarget
&& scrollTop
< offsets
[0]) {
1964 this.activeTarget
= null
1968 for (i
= offsets
.length
; i
--;) {
1969 activeTarget
!= targets
[i
]
1970 && scrollTop
>= offsets
[i
]
1971 && (offsets
[i
+ 1] === undefined || scrollTop
< offsets
[i
+ 1])
1972 && this.activate(targets
[i
])
1976 ScrollSpy
.prototype.activate = function (target
) {
1977 this.activeTarget
= target
1981 var selector
= this.selector
+
1982 '[data-target="' + target
+ '"],' +
1983 this.selector
+ '[href="' + target
+ '"]'
1985 var active
= $(selector
)
1989 if (active
.parent('.dropdown-menu').length
) {
1991 .closest('li.dropdown')
1995 active
.trigger('activate.bs.scrollspy')
1998 ScrollSpy
.prototype.clear = function () {
2000 .parentsUntil(this.options
.target
, '.active')
2001 .removeClass('active')
2005 // SCROLLSPY PLUGIN DEFINITION
2006 // ===========================
2008 function Plugin(option
) {
2009 return this.each(function () {
2011 var data
= $this.data('bs.scrollspy')
2012 var options
= typeof option
== 'object' && option
2014 if (!data
) $this.data('bs.scrollspy', (data
= new ScrollSpy(this, options
)))
2015 if (typeof option
== 'string') data
[option
]()
2019 var old
= $.fn
.scrollspy
2021 $.fn
.scrollspy
= Plugin
2022 $.fn
.scrollspy
.Constructor
= ScrollSpy
2025 // SCROLLSPY NO CONFLICT
2026 // =====================
2028 $.fn
.scrollspy
.noConflict = function () {
2029 $.fn
.scrollspy
= old
2034 // SCROLLSPY DATA-API
2035 // ==================
2037 $(window
).on('load.bs.scrollspy.data-api', function () {
2038 $('[data-spy="scroll"]').each(function () {
2040 Plugin
.call($spy
, $spy
.data())
2046 /* ========================================================================
2047 * Bootstrap: tab.js v3.3.6
2048 * http://getbootstrap.com/javascript/#tabs
2049 * ========================================================================
2050 * Copyright 2011-2015 Twitter, Inc.
2051 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2052 * ======================================================================== */
2058 // TAB CLASS DEFINITION
2059 // ====================
2061 var Tab = function (element
) {
2062 // jscs:disable requireDollarBeforejQueryAssignment
2063 this.element
= $(element
)
2064 // jscs:enable requireDollarBeforejQueryAssignment
2067 Tab
.VERSION
= '3.3.6'
2069 Tab
.TRANSITION_DURATION
= 150
2071 Tab
.prototype.show = function () {
2072 var $this = this.element
2073 var $ul
= $this.closest('ul:not(.dropdown-menu)')
2074 var selector
= $this.data('target')
2077 selector
= $this.attr('href')
2078 selector
= selector
&& selector
.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
2081 if ($this.parent('li').hasClass('active')) return
2083 var $previous
= $ul
.find('.active:last a')
2084 var hideEvent
= $.Event('hide.bs.tab', {
2085 relatedTarget
: $this[0]
2087 var showEvent
= $.Event('show.bs.tab', {
2088 relatedTarget
: $previous
[0]
2091 $previous
.trigger(hideEvent
)
2092 $this.trigger(showEvent
)
2094 if (showEvent
.isDefaultPrevented() || hideEvent
.isDefaultPrevented()) return
2096 var $target
= $(selector
)
2098 this.activate($this.closest('li'), $ul
)
2099 this.activate($target
, $target
.parent(), function () {
2101 type
: 'hidden.bs.tab',
2102 relatedTarget
: $this[0]
2105 type
: 'shown.bs.tab',
2106 relatedTarget
: $previous
[0]
2111 Tab
.prototype.activate = function (element
, container
, callback
) {
2112 var $active
= container
.find('> .active')
2113 var transition
= callback
2114 && $.support
.transition
2115 && ($active
.length
&& $active
.hasClass('fade') || !!container
.find('> .fade').length
)
2119 .removeClass('active')
2120 .find('> .dropdown-menu > .active')
2121 .removeClass('active')
2123 .find('[data-toggle="tab"]')
2124 .attr('aria-expanded', false)
2128 .find('[data-toggle="tab"]')
2129 .attr('aria-expanded', true)
2132 element
[0].offsetWidth
// reflow for transition
2133 element
.addClass('in')
2135 element
.removeClass('fade')
2138 if (element
.parent('.dropdown-menu').length
) {
2140 .closest('li.dropdown')
2143 .find('[data-toggle="tab"]')
2144 .attr('aria-expanded', true)
2147 callback
&& callback()
2150 $active
.length
&& transition
?
2152 .one('bsTransitionEnd', next
)
2153 .emulateTransitionEnd(Tab
.TRANSITION_DURATION
) :
2156 $active
.removeClass('in')
2160 // TAB PLUGIN DEFINITION
2161 // =====================
2163 function Plugin(option
) {
2164 return this.each(function () {
2166 var data
= $this.data('bs.tab')
2168 if (!data
) $this.data('bs.tab', (data
= new Tab(this)))
2169 if (typeof option
== 'string') data
[option
]()
2176 $.fn
.tab
.Constructor
= Tab
2182 $.fn
.tab
.noConflict = function () {
2191 var clickHandler = function (e
) {
2193 Plugin
.call($(this), 'show')
2197 .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler
)
2198 .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler
)
2202 /* ========================================================================
2203 * Bootstrap: affix.js v3.3.6
2204 * http://getbootstrap.com/javascript/#affix
2205 * ========================================================================
2206 * Copyright 2011-2015 Twitter, Inc.
2207 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2208 * ======================================================================== */
2214 // AFFIX CLASS DEFINITION
2215 // ======================
2217 var Affix = function (element
, options
) {
2218 this.options
= $.extend({}, Affix
.DEFAULTS
, options
)
2220 this.$target
= $(this.options
.target
)
2221 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition
, this))
2222 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop
, this))
2224 this.$element
= $(element
)
2227 this.pinnedOffset
= null
2229 this.checkPosition()
2232 Affix
.VERSION
= '3.3.6'
2234 Affix
.RESET
= 'affix affix-top affix-bottom'
2241 Affix
.prototype.getState = function (scrollHeight
, height
, offsetTop
, offsetBottom
) {
2242 var scrollTop
= this.$target
.scrollTop()
2243 var position
= this.$element
.offset()
2244 var targetHeight
= this.$target
.height()
2246 if (offsetTop
!= null && this.affixed
== 'top') return scrollTop
< offsetTop
? 'top' : false
2248 if (this.affixed
== 'bottom') {
2249 if (offsetTop
!= null) return (scrollTop
+ this.unpin
<= position
.top
) ? false : 'bottom'
2250 return (scrollTop
+ targetHeight
<= scrollHeight
- offsetBottom
) ? false : 'bottom'
2253 var initializing
= this.affixed
== null
2254 var colliderTop
= initializing
? scrollTop
: position
.top
2255 var colliderHeight
= initializing
? targetHeight
: height
2257 if (offsetTop
!= null && scrollTop
<= offsetTop
) return 'top'
2258 if (offsetBottom
!= null && (colliderTop
+ colliderHeight
>= scrollHeight
- offsetBottom
)) return 'bottom'
2263 Affix
.prototype.getPinnedOffset = function () {
2264 if (this.pinnedOffset
) return this.pinnedOffset
2265 this.$element
.removeClass(Affix
.RESET
).addClass('affix')
2266 var scrollTop
= this.$target
.scrollTop()
2267 var position
= this.$element
.offset()
2268 return (this.pinnedOffset
= position
.top
- scrollTop
)
2271 Affix
.prototype.checkPositionWithEventLoop = function () {
2272 setTimeout($.proxy(this.checkPosition
, this), 1)
2275 Affix
.prototype.checkPosition = function () {
2276 if (!this.$element
.is(':visible')) return
2278 var height
= this.$element
.height()
2279 var offset
= this.options
.offset
2280 var offsetTop
= offset
.top
2281 var offsetBottom
= offset
.bottom
2282 var scrollHeight
= Math
.max($(document
).height(), $(document
.body
).height())
2284 if (typeof offset
!= 'object') offsetBottom
= offsetTop
= offset
2285 if (typeof offsetTop
== 'function') offsetTop
= offset
.top(this.$element
)
2286 if (typeof offsetBottom
== 'function') offsetBottom
= offset
.bottom(this.$element
)
2288 var affix
= this.getState(scrollHeight
, height
, offsetTop
, offsetBottom
)
2290 if (this.affixed
!= affix
) {
2291 if (this.unpin
!= null) this.$element
.css('top', '')
2293 var affixType
= 'affix' + (affix
? '-' + affix
: '')
2294 var e
= $.Event(affixType
+ '.bs.affix')
2296 this.$element
.trigger(e
)
2298 if (e
.isDefaultPrevented()) return
2300 this.affixed
= affix
2301 this.unpin
= affix
== 'bottom' ? this.getPinnedOffset() : null
2304 .removeClass(Affix
.RESET
)
2305 .addClass(affixType
)
2306 .trigger(affixType
.replace('affix', 'affixed') + '.bs.affix')
2309 if (affix
== 'bottom') {
2310 this.$element
.offset({
2311 top
: scrollHeight
- height
- offsetBottom
2317 // AFFIX PLUGIN DEFINITION
2318 // =======================
2320 function Plugin(option
) {
2321 return this.each(function () {
2323 var data
= $this.data('bs.affix')
2324 var options
= typeof option
== 'object' && option
2326 if (!data
) $this.data('bs.affix', (data
= new Affix(this, options
)))
2327 if (typeof option
== 'string') data
[option
]()
2331 var old
= $.fn
.affix
2334 $.fn
.affix
.Constructor
= Affix
2337 // AFFIX NO CONFLICT
2338 // =================
2340 $.fn
.affix
.noConflict = function () {
2349 $(window
).on('load', function () {
2350 $('[data-spy="affix"]').each(function () {
2352 var data
= $spy
.data()
2354 data
.offset
= data
.offset
|| {}
2356 if (data
.offsetBottom
!= null) data
.offset
.bottom
= data
.offsetBottom
2357 if (data
.offsetTop
!= null) data
.offset
.top
= data
.offsetTop
2359 Plugin
.call($spy
, data
)