2 * Bootstrap v3.3.7 (http://getbootstrap.com)
3 * Copyright 2011-2016 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] > 3)) {
15 throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
19 /* ========================================================================
20 * Bootstrap: transition.js v3.3.7
21 * http://getbootstrap.com/javascript/#transitions
22 * ========================================================================
23 * Copyright 2011-2016 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.7
81 * http://getbootstrap.com/javascript/#alerts
82 * ========================================================================
83 * Copyright 2011-2016 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.7'
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
=== '#' ? [] : 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.7
176 * http://getbootstrap.com/javascript/#buttons
177 * ========================================================================
178 * Copyright 2011-2016 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.7'
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
).prop(d
, true)
218 } else if (this.isLoading
) {
219 this.isLoading
= false
220 $el
.removeClass(d
).removeAttr(d
).prop(d
, false)
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
).closest('.btn')
285 Plugin
.call($btn
, 'toggle')
286 if (!($(e
.target
).is('input[type="radio"], input[type="checkbox"]'))) {
287 // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
289 // The target component still receive the focus
290 if ($btn
.is('input,button')) $btn
.trigger('focus')
291 else $btn
.find('input:visible,button:visible').first().trigger('focus')
294 .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e
) {
295 $(e
.target
).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e
.type
))
300 /* ========================================================================
301 * Bootstrap: carousel.js v3.3.7
302 * http://getbootstrap.com/javascript/#carousel
303 * ========================================================================
304 * Copyright 2011-2016 Twitter, Inc.
305 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
306 * ======================================================================== */
312 // CAROUSEL CLASS DEFINITION
313 // =========================
315 var Carousel = function (element
, options
) {
316 this.$element
= $(element
)
317 this.$indicators
= this.$element
.find('.carousel-indicators')
318 this.options
= options
325 this.options
.keyboard
&& this.$element
.on('keydown.bs.carousel', $.proxy(this.keydown
, this))
327 this.options
.pause
== 'hover' && !('ontouchstart' in document
.documentElement
) && this.$element
328 .on('mouseenter.bs.carousel', $.proxy(this.pause
, this))
329 .on('mouseleave.bs.carousel', $.proxy(this.cycle
, this))
332 Carousel
.VERSION
= '3.3.7'
334 Carousel
.TRANSITION_DURATION
= 600
336 Carousel
.DEFAULTS
= {
343 Carousel
.prototype.keydown = function (e
) {
344 if (/input|textarea/i.test(e
.target
.tagName
)) return
346 case 37: this.prev(); break
347 case 39: this.next(); break
354 Carousel
.prototype.cycle = function (e
) {
355 e
|| (this.paused
= false)
357 this.interval
&& clearInterval(this.interval
)
359 this.options
.interval
361 && (this.interval
= setInterval($.proxy(this.next
, this), this.options
.interval
))
366 Carousel
.prototype.getItemIndex = function (item
) {
367 this.$items
= item
.parent().children('.item')
368 return this.$items
.index(item
|| this.$active
)
371 Carousel
.prototype.getItemForDirection = function (direction
, active
) {
372 var activeIndex
= this.getItemIndex(active
)
373 var willWrap
= (direction
== 'prev' && activeIndex
=== 0)
374 || (direction
== 'next' && activeIndex
== (this.$items
.length
- 1))
375 if (willWrap
&& !this.options
.wrap
) return active
376 var delta
= direction
== 'prev' ? -1 : 1
377 var itemIndex
= (activeIndex
+ delta
) % this.$items
.length
378 return this.$items
.eq(itemIndex
)
381 Carousel
.prototype.to = function (pos
) {
383 var activeIndex
= this.getItemIndex(this.$active
= this.$element
.find('.item.active'))
385 if (pos
> (this.$items
.length
- 1) || pos
< 0) return
387 if (this.sliding
) return this.$element
.one('slid.bs.carousel', function () { that
.to(pos
) }) // yes, "slid"
388 if (activeIndex
== pos
) return this.pause().cycle()
390 return this.slide(pos
> activeIndex
? 'next' : 'prev', this.$items
.eq(pos
))
393 Carousel
.prototype.pause = function (e
) {
394 e
|| (this.paused
= true)
396 if (this.$element
.find('.next, .prev').length
&& $.support
.transition
) {
397 this.$element
.trigger($.support
.transition
.end
)
401 this.interval
= clearInterval(this.interval
)
406 Carousel
.prototype.next = function () {
407 if (this.sliding
) return
408 return this.slide('next')
411 Carousel
.prototype.prev = function () {
412 if (this.sliding
) return
413 return this.slide('prev')
416 Carousel
.prototype.slide = function (type
, next
) {
417 var $active
= this.$element
.find('.item.active')
418 var $next
= next
|| this.getItemForDirection(type
, $active
)
419 var isCycling
= this.interval
420 var direction
= type
== 'next' ? 'left' : 'right'
423 if ($next
.hasClass('active')) return (this.sliding
= false)
425 var relatedTarget
= $next
[0]
426 var slideEvent
= $.Event('slide.bs.carousel', {
427 relatedTarget: relatedTarget
,
430 this.$element
.trigger(slideEvent
)
431 if (slideEvent
.isDefaultPrevented()) return
435 isCycling
&& this.pause()
437 if (this.$indicators
.length
) {
438 this.$indicators
.find('.active').removeClass('active')
439 var $nextIndicator
= $(this.$indicators
.children()[this.getItemIndex($next
)])
440 $nextIndicator
&& $nextIndicator
.addClass('active')
443 var slidEvent
= $.Event('slid.bs.carousel', { relatedTarget: relatedTarget
, direction: direction
}) // yes, "slid"
444 if ($.support
.transition
&& this.$element
.hasClass('slide')) {
446 $next
[0].offsetWidth
// force reflow
447 $active
.addClass(direction
)
448 $next
.addClass(direction
)
450 .one('bsTransitionEnd', function () {
451 $next
.removeClass([type
, direction
].join(' ')).addClass('active')
452 $active
.removeClass(['active', direction
].join(' '))
454 setTimeout(function () {
455 that
.$element
.trigger(slidEvent
)
458 .emulateTransitionEnd(Carousel
.TRANSITION_DURATION
)
460 $active
.removeClass('active')
461 $next
.addClass('active')
463 this.$element
.trigger(slidEvent
)
466 isCycling
&& this.cycle()
472 // CAROUSEL PLUGIN DEFINITION
473 // ==========================
475 function Plugin(option
) {
476 return this.each(function () {
478 var data
= $this.data('bs.carousel')
479 var options
= $.extend({}, Carousel
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
480 var action
= typeof option
== 'string' ? option : options
.slide
482 if (!data
) $this.data('bs.carousel', (data
= new Carousel(this, options
)))
483 if (typeof option
== 'number') data
.to(option
)
484 else if (action
) data
[action
]()
485 else if (options
.interval
) data
.pause().cycle()
489 var old
= $.fn
.carousel
491 $.fn
.carousel
= Plugin
492 $.fn
.carousel
.Constructor
= Carousel
495 // CAROUSEL NO CONFLICT
496 // ====================
498 $.fn
.carousel
.noConflict = function () {
507 var clickHandler = function (e
) {
510 var $target
= $($this.attr('data-target') || (href
= $this.attr('href')) && href
.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
511 if (!$target
.hasClass('carousel')) return
512 var options
= $.extend({}, $target
.data(), $this.data())
513 var slideIndex
= $this.attr('data-slide-to')
514 if (slideIndex
) options
.interval
= false
516 Plugin
.call($target
, options
)
519 $target
.data('bs.carousel').to(slideIndex
)
526 .on('click.bs.carousel.data-api', '[data-slide]', clickHandler
)
527 .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler
)
529 $(window
).on('load', function () {
530 $('[data-ride="carousel"]').each(function () {
531 var $carousel
= $(this)
532 Plugin
.call($carousel
, $carousel
.data())
538 /* ========================================================================
539 * Bootstrap: collapse.js v3.3.7
540 * http://getbootstrap.com/javascript/#collapse
541 * ========================================================================
542 * Copyright 2011-2016 Twitter, Inc.
543 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
544 * ======================================================================== */
546 /* jshint latedef: false */
551 // COLLAPSE PUBLIC CLASS DEFINITION
552 // ================================
554 var Collapse = function (element
, options
) {
555 this.$element
= $(element
)
556 this.options
= $.extend({}, Collapse
.DEFAULTS
, options
)
557 this.$trigger
= $('[data-toggle="collapse"][href="#' + element
.id
+ '"],' +
558 '[data-toggle="collapse"][data-target="#' + element
.id
+ '"]')
559 this.transitioning
= null
561 if (this.options
.parent
) {
562 this.$parent
= this.getParent()
564 this.addAriaAndCollapsedClass(this.$element
, this.$trigger
)
567 if (this.options
.toggle
) this.toggle()
570 Collapse
.VERSION
= '3.3.7'
572 Collapse
.TRANSITION_DURATION
= 350
574 Collapse
.DEFAULTS
= {
578 Collapse
.prototype.dimension = function () {
579 var hasWidth
= this.$element
.hasClass('width')
580 return hasWidth
? 'width' : 'height'
583 Collapse
.prototype.show = function () {
584 if (this.transitioning
|| this.$element
.hasClass('in')) return
587 var actives
= this.$parent
&& this.$parent
.children('.panel').children('.in, .collapsing')
589 if (actives
&& actives
.length
) {
590 activesData
= actives
.data('bs.collapse')
591 if (activesData
&& activesData
.transitioning
) return
594 var startEvent
= $.Event('show.bs.collapse')
595 this.$element
.trigger(startEvent
)
596 if (startEvent
.isDefaultPrevented()) return
598 if (actives
&& actives
.length
) {
599 Plugin
.call(actives
, 'hide')
600 activesData
|| actives
.data('bs.collapse', null)
603 var dimension
= this.dimension()
606 .removeClass('collapse')
607 .addClass('collapsing')[dimension
](0)
608 .attr('aria-expanded', true)
611 .removeClass('collapsed')
612 .attr('aria-expanded', true)
614 this.transitioning
= 1
616 var complete = function () {
618 .removeClass('collapsing')
619 .addClass('collapse in')[dimension
]('')
620 this.transitioning
= 0
622 .trigger('shown.bs.collapse')
625 if (!$.support
.transition
) return complete
.call(this)
627 var scrollSize
= $.camelCase(['scroll', dimension
].join('-'))
630 .one('bsTransitionEnd', $.proxy(complete
, this))
631 .emulateTransitionEnd(Collapse
.TRANSITION_DURATION
)[dimension
](this.$element
[0][scrollSize
])
634 Collapse
.prototype.hide = function () {
635 if (this.transitioning
|| !this.$element
.hasClass('in')) return
637 var startEvent
= $.Event('hide.bs.collapse')
638 this.$element
.trigger(startEvent
)
639 if (startEvent
.isDefaultPrevented()) return
641 var dimension
= this.dimension()
643 this.$element
[dimension
](this.$element
[dimension
]())[0].offsetHeight
646 .addClass('collapsing')
647 .removeClass('collapse in')
648 .attr('aria-expanded', false)
651 .addClass('collapsed')
652 .attr('aria-expanded', false)
654 this.transitioning
= 1
656 var complete = function () {
657 this.transitioning
= 0
659 .removeClass('collapsing')
660 .addClass('collapse')
661 .trigger('hidden.bs.collapse')
664 if (!$.support
.transition
) return complete
.call(this)
668 .one('bsTransitionEnd', $.proxy(complete
, this))
669 .emulateTransitionEnd(Collapse
.TRANSITION_DURATION
)
672 Collapse
.prototype.toggle = function () {
673 this[this.$element
.hasClass('in') ? 'hide' : 'show']()
676 Collapse
.prototype.getParent = function () {
677 return $(this.options
.parent
)
678 .find('[data-toggle="collapse"][data-parent="' + this.options
.parent
+ '"]')
679 .each($.proxy(function (i
, element
) {
680 var $element
= $(element
)
681 this.addAriaAndCollapsedClass(getTargetFromTrigger($element
), $element
)
686 Collapse
.prototype.addAriaAndCollapsedClass = function ($element
, $trigger
) {
687 var isOpen
= $element
.hasClass('in')
689 $element
.attr('aria-expanded', isOpen
)
691 .toggleClass('collapsed', !isOpen
)
692 .attr('aria-expanded', isOpen
)
695 function getTargetFromTrigger($trigger
) {
697 var target
= $trigger
.attr('data-target')
698 || (href
= $trigger
.attr('href')) && href
.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
704 // COLLAPSE PLUGIN DEFINITION
705 // ==========================
707 function Plugin(option
) {
708 return this.each(function () {
710 var data
= $this.data('bs.collapse')
711 var options
= $.extend({}, Collapse
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
713 if (!data
&& options
.toggle
&& /show|hide/.test(option
)) options
.toggle
= false
714 if (!data
) $this.data('bs.collapse', (data
= new Collapse(this, options
)))
715 if (typeof option
== 'string') data
[option
]()
719 var old
= $.fn
.collapse
721 $.fn
.collapse
= Plugin
722 $.fn
.collapse
.Constructor
= Collapse
725 // COLLAPSE NO CONFLICT
726 // ====================
728 $.fn
.collapse
.noConflict = function () {
737 $(document
).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e
) {
740 if (!$this.attr('data-target')) e
.preventDefault()
742 var $target
= getTargetFromTrigger($this)
743 var data
= $target
.data('bs.collapse')
744 var option
= data
? 'toggle' : $this.data()
746 Plugin
.call($target
, option
)
751 /* ========================================================================
752 * Bootstrap: dropdown.js v3.3.7
753 * http://getbootstrap.com/javascript/#dropdowns
754 * ========================================================================
755 * Copyright 2011-2016 Twitter, Inc.
756 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
757 * ======================================================================== */
763 // DROPDOWN CLASS DEFINITION
764 // =========================
766 var backdrop
= '.dropdown-backdrop'
767 var toggle
= '[data-toggle="dropdown"]'
768 var Dropdown = function (element
) {
769 $(element
).on('click.bs.dropdown', this.toggle
)
772 Dropdown
.VERSION
= '3.3.7'
774 function getParent($this) {
775 var selector
= $this.attr('data-target')
778 selector
= $this.attr('href')
779 selector
= selector
&& /#[A-Za-z]/.test(selector
) && selector
.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
782 var $parent
= selector
&& $(selector
)
784 return $parent
&& $parent
.length
? $parent : $this.parent()
787 function clearMenus(e
) {
788 if (e
&& e
.which
=== 3) return
790 $(toggle
).each(function () {
792 var $parent
= getParent($this)
793 var relatedTarget
= { relatedTarget: this }
795 if (!$parent
.hasClass('open')) return
797 if (e
&& e
.type
== 'click' && /input|textarea/i.test(e
.target
.tagName
) && $.contains($parent
[0], e
.target
)) return
799 $parent
.trigger(e
= $.Event('hide.bs.dropdown', relatedTarget
))
801 if (e
.isDefaultPrevented()) return
803 $this.attr('aria-expanded', 'false')
804 $parent
.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget
))
808 Dropdown
.prototype.toggle = function (e
) {
811 if ($this.is('.disabled, :disabled')) return
813 var $parent
= getParent($this)
814 var isActive
= $parent
.hasClass('open')
819 if ('ontouchstart' in document
.documentElement
&& !$parent
.closest('.navbar-nav').length
) {
820 // if mobile we use a backdrop because click events don't delegate
821 $(document
.createElement('div'))
822 .addClass('dropdown-backdrop')
823 .insertAfter($(this))
824 .on('click', clearMenus
)
827 var relatedTarget
= { relatedTarget: this }
828 $parent
.trigger(e
= $.Event('show.bs.dropdown', relatedTarget
))
830 if (e
.isDefaultPrevented()) return
834 .attr('aria-expanded', 'true')
838 .trigger($.Event('shown.bs.dropdown', relatedTarget
))
844 Dropdown
.prototype.keydown = function (e
) {
845 if (!/(38|40|27|32)/.test(e
.which
) || /input|textarea/i.test(e
.target
.tagName
)) return
852 if ($this.is('.disabled, :disabled')) return
854 var $parent
= getParent($this)
855 var isActive
= $parent
.hasClass('open')
857 if (!isActive
&& e
.which
!= 27 || isActive
&& e
.which
== 27) {
858 if (e
.which
== 27) $parent
.find(toggle
).trigger('focus')
859 return $this.trigger('click')
862 var desc
= ' li:not(.disabled):visible a'
863 var $items
= $parent
.find('.dropdown-menu' + desc
)
865 if (!$items
.length
) return
867 var index
= $items
.index(e
.target
)
869 if (e
.which
== 38 && index
> 0) index
-- // up
870 if (e
.which
== 40 && index
< $items
.length
- 1) index
++ // down
871 if (!~index
) index
= 0
873 $items
.eq(index
).trigger('focus')
877 // DROPDOWN PLUGIN DEFINITION
878 // ==========================
880 function Plugin(option
) {
881 return this.each(function () {
883 var data
= $this.data('bs.dropdown')
885 if (!data
) $this.data('bs.dropdown', (data
= new Dropdown(this)))
886 if (typeof option
== 'string') data
[option
].call($this)
890 var old
= $.fn
.dropdown
892 $.fn
.dropdown
= Plugin
893 $.fn
.dropdown
.Constructor
= Dropdown
896 // DROPDOWN NO CONFLICT
897 // ====================
899 $.fn
.dropdown
.noConflict = function () {
905 // APPLY TO STANDARD DROPDOWN ELEMENTS
906 // ===================================
909 .on('click.bs.dropdown.data-api', clearMenus
)
910 .on('click.bs.dropdown.data-api', '.dropdown form', function (e
) { e
.stopPropagation() })
911 .on('click.bs.dropdown.data-api', toggle
, Dropdown
.prototype.toggle
)
912 .on('keydown.bs.dropdown.data-api', toggle
, Dropdown
.prototype.keydown
)
913 .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown
.prototype.keydown
)
917 /* ========================================================================
918 * Bootstrap: modal.js v3.3.7
919 * http://getbootstrap.com/javascript/#modals
920 * ========================================================================
921 * Copyright 2011-2016 Twitter, Inc.
922 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
923 * ======================================================================== */
929 // MODAL CLASS DEFINITION
930 // ======================
932 var Modal = function (element
, options
) {
933 this.options
= options
934 this.$body
= $(document
.body
)
935 this.$element
= $(element
)
936 this.$dialog
= this.$element
.find('.modal-dialog')
937 this.$backdrop
= null
939 this.originalBodyPad
= null
940 this.scrollbarWidth
= 0
941 this.ignoreBackdropClick
= false
943 if (this.options
.remote
) {
945 .find('.modal-content')
946 .load(this.options
.remote
, $.proxy(function () {
947 this.$element
.trigger('loaded.bs.modal')
952 Modal
.VERSION
= '3.3.7'
954 Modal
.TRANSITION_DURATION
= 300
955 Modal
.BACKDROP_TRANSITION_DURATION
= 150
963 Modal
.prototype.toggle = function (_relatedTarget
) {
964 return this.isShown
? this.hide() : this.show(_relatedTarget
)
967 Modal
.prototype.show = function (_relatedTarget
) {
969 var e
= $.Event('show.bs.modal', { relatedTarget: _relatedTarget
})
971 this.$element
.trigger(e
)
973 if (this.isShown
|| e
.isDefaultPrevented()) return
977 this.checkScrollbar()
979 this.$body
.addClass('modal-open')
984 this.$element
.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide
, this))
986 this.$dialog
.on('mousedown.dismiss.bs.modal', function () {
987 that
.$element
.one('mouseup.dismiss.bs.modal', function (e
) {
988 if ($(e
.target
).is(that
.$element
)) that
.ignoreBackdropClick
= true
992 this.backdrop(function () {
993 var transition
= $.support
.transition
&& that
.$element
.hasClass('fade')
995 if (!that
.$element
.parent().length
) {
996 that
.$element
.appendTo(that
.$body
) // don't move modals dom position
1006 that
.$element
[0].offsetWidth
// force reflow
1009 that
.$element
.addClass('in')
1013 var e
= $.Event('shown.bs.modal', { relatedTarget: _relatedTarget
})
1016 that
.$dialog
// wait for modal to slide in
1017 .one('bsTransitionEnd', function () {
1018 that
.$element
.trigger('focus').trigger(e
)
1020 .emulateTransitionEnd(Modal
.TRANSITION_DURATION
) :
1021 that
.$element
.trigger('focus').trigger(e
)
1025 Modal
.prototype.hide = function (e
) {
1026 if (e
) e
.preventDefault()
1028 e
= $.Event('hide.bs.modal')
1030 this.$element
.trigger(e
)
1032 if (!this.isShown
|| e
.isDefaultPrevented()) return
1034 this.isShown
= false
1039 $(document
).off('focusin.bs.modal')
1043 .off('click.dismiss.bs.modal')
1044 .off('mouseup.dismiss.bs.modal')
1046 this.$dialog
.off('mousedown.dismiss.bs.modal')
1048 $.support
.transition
&& this.$element
.hasClass('fade') ?
1050 .one('bsTransitionEnd', $.proxy(this.hideModal
, this))
1051 .emulateTransitionEnd(Modal
.TRANSITION_DURATION
) :
1055 Modal
.prototype.enforceFocus = function () {
1057 .off('focusin.bs.modal') // guard against infinite focus loop
1058 .on('focusin.bs.modal', $.proxy(function (e
) {
1059 if (document
!== e
.target
&&
1060 this.$element
[0] !== e
.target
&&
1061 !this.$element
.has(e
.target
).length
) {
1062 this.$element
.trigger('focus')
1067 Modal
.prototype.escape = function () {
1068 if (this.isShown
&& this.options
.keyboard
) {
1069 this.$element
.on('keydown.dismiss.bs.modal', $.proxy(function (e
) {
1070 e
.which
== 27 && this.hide()
1072 } else if (!this.isShown
) {
1073 this.$element
.off('keydown.dismiss.bs.modal')
1077 Modal
.prototype.resize = function () {
1079 $(window
).on('resize.bs.modal', $.proxy(this.handleUpdate
, this))
1081 $(window
).off('resize.bs.modal')
1085 Modal
.prototype.hideModal = function () {
1087 this.$element
.hide()
1088 this.backdrop(function () {
1089 that
.$body
.removeClass('modal-open')
1090 that
.resetAdjustments()
1091 that
.resetScrollbar()
1092 that
.$element
.trigger('hidden.bs.modal')
1096 Modal
.prototype.removeBackdrop = function () {
1097 this.$backdrop
&& this.$backdrop
.remove()
1098 this.$backdrop
= null
1101 Modal
.prototype.backdrop = function (callback
) {
1103 var animate
= this.$element
.hasClass('fade') ? 'fade' : ''
1105 if (this.isShown
&& this.options
.backdrop
) {
1106 var doAnimate
= $.support
.transition
&& animate
1108 this.$backdrop
= $(document
.createElement('div'))
1109 .addClass('modal-backdrop ' + animate
)
1110 .appendTo(this.$body
)
1112 this.$element
.on('click.dismiss.bs.modal', $.proxy(function (e
) {
1113 if (this.ignoreBackdropClick
) {
1114 this.ignoreBackdropClick
= false
1117 if (e
.target
!== e
.currentTarget
) return
1118 this.options
.backdrop
== 'static'
1119 ? this.$element
[0].focus()
1123 if (doAnimate
) this.$backdrop
[0].offsetWidth
// force reflow
1125 this.$backdrop
.addClass('in')
1127 if (!callback
) return
1131 .one('bsTransitionEnd', callback
)
1132 .emulateTransitionEnd(Modal
.BACKDROP_TRANSITION_DURATION
) :
1135 } else if (!this.isShown
&& this.$backdrop
) {
1136 this.$backdrop
.removeClass('in')
1138 var callbackRemove = function () {
1139 that
.removeBackdrop()
1140 callback
&& callback()
1142 $.support
.transition
&& this.$element
.hasClass('fade') ?
1144 .one('bsTransitionEnd', callbackRemove
)
1145 .emulateTransitionEnd(Modal
.BACKDROP_TRANSITION_DURATION
) :
1148 } else if (callback
) {
1153 // these following methods are used to handle overflowing modals
1155 Modal
.prototype.handleUpdate = function () {
1159 Modal
.prototype.adjustDialog = function () {
1160 var modalIsOverflowing
= this.$element
[0].scrollHeight
> document
.documentElement
.clientHeight
1163 paddingLeft: !this.bodyIsOverflowing
&& modalIsOverflowing
? this.scrollbarWidth : '',
1164 paddingRight: this.bodyIsOverflowing
&& !modalIsOverflowing
? this.scrollbarWidth : ''
1168 Modal
.prototype.resetAdjustments = function () {
1175 Modal
.prototype.checkScrollbar = function () {
1176 var fullWindowWidth
= window
.innerWidth
1177 if (!fullWindowWidth
) { // workaround for missing window.innerWidth in IE8
1178 var documentElementRect
= document
.documentElement
.getBoundingClientRect()
1179 fullWindowWidth
= documentElementRect
.right
- Math
.abs(documentElementRect
.left
)
1181 this.bodyIsOverflowing
= document
.body
.clientWidth
< fullWindowWidth
1182 this.scrollbarWidth
= this.measureScrollbar()
1185 Modal
.prototype.setScrollbar = function () {
1186 var bodyPad
= parseInt((this.$body
.css('padding-right') || 0), 10)
1187 this.originalBodyPad
= document
.body
.style
.paddingRight
|| ''
1188 if (this.bodyIsOverflowing
) this.$body
.css('padding-right', bodyPad
+ this.scrollbarWidth
)
1191 Modal
.prototype.resetScrollbar = function () {
1192 this.$body
.css('padding-right', this.originalBodyPad
)
1195 Modal
.prototype.measureScrollbar = function () { // thx walsh
1196 var scrollDiv
= document
.createElement('div')
1197 scrollDiv
.className
= 'modal-scrollbar-measure'
1198 this.$body
.append(scrollDiv
)
1199 var scrollbarWidth
= scrollDiv
.offsetWidth
- scrollDiv
.clientWidth
1200 this.$body
[0].removeChild(scrollDiv
)
1201 return scrollbarWidth
1205 // MODAL PLUGIN DEFINITION
1206 // =======================
1208 function Plugin(option
, _relatedTarget
) {
1209 return this.each(function () {
1211 var data
= $this.data('bs.modal')
1212 var options
= $.extend({}, Modal
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
1214 if (!data
) $this.data('bs.modal', (data
= new Modal(this, options
)))
1215 if (typeof option
== 'string') data
[option
](_relatedTarget
)
1216 else if (options
.show
) data
.show(_relatedTarget
)
1220 var old
= $.fn
.modal
1223 $.fn
.modal
.Constructor
= Modal
1226 // MODAL NO CONFLICT
1227 // =================
1229 $.fn
.modal
.noConflict = function () {
1238 $(document
).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e
) {
1240 var href
= $this.attr('href')
1241 var $target
= $($this.attr('data-target') || (href
&& href
.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
1242 var option
= $target
.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href
) && href
}, $target
.data(), $this.data())
1244 if ($this.is('a')) e
.preventDefault()
1246 $target
.one('show.bs.modal', function (showEvent
) {
1247 if (showEvent
.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
1248 $target
.one('hidden.bs.modal', function () {
1249 $this.is(':visible') && $this.trigger('focus')
1252 Plugin
.call($target
, option
, this)
1257 /* ========================================================================
1258 * Bootstrap: tooltip.js v3.3.7
1259 * http://getbootstrap.com/javascript/#tooltip
1260 * Inspired by the original jQuery.tipsy by Jason Frame
1261 * ========================================================================
1262 * Copyright 2011-2016 Twitter, Inc.
1263 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1264 * ======================================================================== */
1270 // TOOLTIP PUBLIC CLASS DEFINITION
1271 // ===============================
1273 var Tooltip = function (element
, options
) {
1278 this.hoverState
= null
1279 this.$element
= null
1282 this.init('tooltip', element
, options
)
1285 Tooltip
.VERSION
= '3.3.7'
1287 Tooltip
.TRANSITION_DURATION
= 150
1289 Tooltip
.DEFAULTS
= {
1293 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
1294 trigger: 'hover focus',
1305 Tooltip
.prototype.init = function (type
, element
, options
) {
1308 this.$element
= $(element
)
1309 this.options
= this.getOptions(options
)
1310 this.$viewport
= this.options
.viewport
&& $($.isFunction(this.options
.viewport
) ? this.options
.viewport
.call(this, this.$element
) : (this.options
.viewport
.selector
|| this.options
.viewport
))
1311 this.inState
= { click: false, hover: false, focus: false }
1313 if (this.$element
[0] instanceof document
.constructor && !this.options
.selector
) {
1314 throw new Error('`selector` option must be specified when initializing ' + this.type
+ ' on the window.document object!')
1317 var triggers
= this.options
.trigger
.split(' ')
1319 for (var i
= triggers
.length
; i
--;) {
1320 var trigger
= triggers
[i
]
1322 if (trigger
== 'click') {
1323 this.$element
.on('click.' + this.type
, this.options
.selector
, $.proxy(this.toggle
, this))
1324 } else if (trigger
!= 'manual') {
1325 var eventIn
= trigger
== 'hover' ? 'mouseenter' : 'focusin'
1326 var eventOut
= trigger
== 'hover' ? 'mouseleave' : 'focusout'
1328 this.$element
.on(eventIn
+ '.' + this.type
, this.options
.selector
, $.proxy(this.enter
, this))
1329 this.$element
.on(eventOut
+ '.' + this.type
, this.options
.selector
, $.proxy(this.leave
, this))
1333 this.options
.selector
?
1334 (this._options
= $.extend({}, this.options
, { trigger: 'manual', selector: '' })) :
1338 Tooltip
.prototype.getDefaults = function () {
1339 return Tooltip
.DEFAULTS
1342 Tooltip
.prototype.getOptions = function (options
) {
1343 options
= $.extend({}, this.getDefaults(), this.$element
.data(), options
)
1345 if (options
.delay
&& typeof options
.delay
== 'number') {
1347 show: options
.delay
,
1355 Tooltip
.prototype.getDelegateOptions = function () {
1357 var defaults
= this.getDefaults()
1359 this._options
&& $.each(this._options
, function (key
, value
) {
1360 if (defaults
[key
] != value
) options
[key
] = value
1366 Tooltip
.prototype.enter = function (obj
) {
1367 var self
= obj
instanceof this.constructor ?
1368 obj : $(obj
.currentTarget
).data('bs.' + this.type
)
1371 self
= new this.constructor(obj
.currentTarget
, this.getDelegateOptions())
1372 $(obj
.currentTarget
).data('bs.' + this.type
, self
)
1375 if (obj
instanceof $.Event
) {
1376 self
.inState
[obj
.type
== 'focusin' ? 'focus' : 'hover'] = true
1379 if (self
.tip().hasClass('in') || self
.hoverState
== 'in') {
1380 self
.hoverState
= 'in'
1384 clearTimeout(self
.timeout
)
1386 self
.hoverState
= 'in'
1388 if (!self
.options
.delay
|| !self
.options
.delay
.show
) return self
.show()
1390 self
.timeout
= setTimeout(function () {
1391 if (self
.hoverState
== 'in') self
.show()
1392 }, self
.options
.delay
.show
)
1395 Tooltip
.prototype.isInStateTrue = function () {
1396 for (var key
in this.inState
) {
1397 if (this.inState
[key
]) return true
1403 Tooltip
.prototype.leave = function (obj
) {
1404 var self
= obj
instanceof this.constructor ?
1405 obj : $(obj
.currentTarget
).data('bs.' + this.type
)
1408 self
= new this.constructor(obj
.currentTarget
, this.getDelegateOptions())
1409 $(obj
.currentTarget
).data('bs.' + this.type
, self
)
1412 if (obj
instanceof $.Event
) {
1413 self
.inState
[obj
.type
== 'focusout' ? 'focus' : 'hover'] = false
1416 if (self
.isInStateTrue()) return
1418 clearTimeout(self
.timeout
)
1420 self
.hoverState
= 'out'
1422 if (!self
.options
.delay
|| !self
.options
.delay
.hide
) return self
.hide()
1424 self
.timeout
= setTimeout(function () {
1425 if (self
.hoverState
== 'out') self
.hide()
1426 }, self
.options
.delay
.hide
)
1429 Tooltip
.prototype.show = function () {
1430 var e
= $.Event('show.bs.' + this.type
)
1432 if (this.hasContent() && this.enabled
) {
1433 this.$element
.trigger(e
)
1435 var inDom
= $.contains(this.$element
[0].ownerDocument
.documentElement
, this.$element
[0])
1436 if (e
.isDefaultPrevented() || !inDom
) return
1439 var $tip
= this.tip()
1441 var tipId
= this.getUID(this.type
)
1444 $tip
.attr('id', tipId
)
1445 this.$element
.attr('aria-describedby', tipId
)
1447 if (this.options
.animation
) $tip
.addClass('fade')
1449 var placement
= typeof this.options
.placement
== 'function' ?
1450 this.options
.placement
.call(this, $tip
[0], this.$element
[0]) :
1451 this.options
.placement
1453 var autoToken
= /\s?auto?\s?/i
1454 var autoPlace
= autoToken
.test(placement
)
1455 if (autoPlace
) placement
= placement
.replace(autoToken
, '') || 'top'
1459 .css({ top: 0, left: 0, display: 'block' })
1460 .addClass(placement
)
1461 .data('bs.' + this.type
, this)
1463 this.options
.container
? $tip
.appendTo(this.options
.container
) : $tip
.insertAfter(this.$element
)
1464 this.$element
.trigger('inserted.bs.' + this.type
)
1466 var pos
= this.getPosition()
1467 var actualWidth
= $tip
[0].offsetWidth
1468 var actualHeight
= $tip
[0].offsetHeight
1471 var orgPlacement
= placement
1472 var viewportDim
= this.getPosition(this.$viewport
)
1474 placement
= placement
== 'bottom' && pos
.bottom
+ actualHeight
> viewportDim
.bottom
? 'top' :
1475 placement
== 'top' && pos
.top
- actualHeight
< viewportDim
.top
? 'bottom' :
1476 placement
== 'right' && pos
.right
+ actualWidth
> viewportDim
.width
? 'left' :
1477 placement
== 'left' && pos
.left
- actualWidth
< viewportDim
.left
? 'right' :
1481 .removeClass(orgPlacement
)
1482 .addClass(placement
)
1485 var calculatedOffset
= this.getCalculatedOffset(placement
, pos
, actualWidth
, actualHeight
)
1487 this.applyPlacement(calculatedOffset
, placement
)
1489 var complete = function () {
1490 var prevHoverState
= that
.hoverState
1491 that
.$element
.trigger('shown.bs.' + that
.type
)
1492 that
.hoverState
= null
1494 if (prevHoverState
== 'out') that
.leave(that
)
1497 $.support
.transition
&& this.$tip
.hasClass('fade') ?
1499 .one('bsTransitionEnd', complete
)
1500 .emulateTransitionEnd(Tooltip
.TRANSITION_DURATION
) :
1505 Tooltip
.prototype.applyPlacement = function (offset
, placement
) {
1506 var $tip
= this.tip()
1507 var width
= $tip
[0].offsetWidth
1508 var height
= $tip
[0].offsetHeight
1510 // manually read margins because getBoundingClientRect includes difference
1511 var marginTop
= parseInt($tip
.css('margin-top'), 10)
1512 var marginLeft
= parseInt($tip
.css('margin-left'), 10)
1514 // we must check for NaN for ie 8/9
1515 if (isNaN(marginTop
)) marginTop
= 0
1516 if (isNaN(marginLeft
)) marginLeft
= 0
1518 offset
.top
+= marginTop
1519 offset
.left
+= marginLeft
1521 // $.fn.offset doesn't round pixel values
1522 // so we use setOffset directly with our own function B-0
1523 $.offset
.setOffset($tip
[0], $.extend({
1524 using: function (props
) {
1526 top: Math
.round(props
.top
),
1527 left: Math
.round(props
.left
)
1534 // check to see if placing tip in new offset caused the tip to resize itself
1535 var actualWidth
= $tip
[0].offsetWidth
1536 var actualHeight
= $tip
[0].offsetHeight
1538 if (placement
== 'top' && actualHeight
!= height
) {
1539 offset
.top
= offset
.top
+ height
- actualHeight
1542 var delta
= this.getViewportAdjustedDelta(placement
, offset
, actualWidth
, actualHeight
)
1544 if (delta
.left
) offset
.left
+= delta
.left
1545 else offset
.top
+= delta
.top
1547 var isVertical
= /top|bottom/.test(placement
)
1548 var arrowDelta
= isVertical
? delta
.left
* 2 - width
+ actualWidth : delta
.top
* 2 - height
+ actualHeight
1549 var arrowOffsetPosition
= isVertical
? 'offsetWidth' : 'offsetHeight'
1552 this.replaceArrow(arrowDelta
, $tip
[0][arrowOffsetPosition
], isVertical
)
1555 Tooltip
.prototype.replaceArrow = function (delta
, dimension
, isVertical
) {
1557 .css(isVertical
? 'left' : 'top', 50 * (1 - delta
/ dimension
) + '%')
1558 .css(isVertical
? 'top' : 'left', '')
1561 Tooltip
.prototype.setContent = function () {
1562 var $tip
= this.tip()
1563 var title
= this.getTitle()
1565 $tip
.find('.tooltip-inner')[this.options
.html
? 'html' : 'text'](title
)
1566 $tip
.removeClass('fade in top bottom left right')
1569 Tooltip
.prototype.hide = function (callback
) {
1571 var $tip
= $(this.$tip
)
1572 var e
= $.Event('hide.bs.' + this.type
)
1574 function complete() {
1575 if (that
.hoverState
!= 'in') $tip
.detach()
1576 if (that
.$element
) { // TODO: Check whether guarding this code with this `if` is really necessary.
1578 .removeAttr('aria-describedby')
1579 .trigger('hidden.bs.' + that
.type
)
1581 callback
&& callback()
1584 this.$element
.trigger(e
)
1586 if (e
.isDefaultPrevented()) return
1588 $tip
.removeClass('in')
1590 $.support
.transition
&& $tip
.hasClass('fade') ?
1592 .one('bsTransitionEnd', complete
)
1593 .emulateTransitionEnd(Tooltip
.TRANSITION_DURATION
) :
1596 this.hoverState
= null
1601 Tooltip
.prototype.fixTitle = function () {
1602 var $e
= this.$element
1603 if ($e
.attr('title') || typeof $e
.attr('data-original-title') != 'string') {
1604 $e
.attr('data-original-title', $e
.attr('title') || '').attr('title', '')
1608 Tooltip
.prototype.hasContent = function () {
1609 return this.getTitle()
1612 Tooltip
.prototype.getPosition = function ($element
) {
1613 $element
= $element
|| this.$element
1615 var el
= $element
[0]
1616 var isBody
= el
.tagName
== 'BODY'
1618 var elRect
= el
.getBoundingClientRect()
1619 if (elRect
.width
== null) {
1620 // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
1621 elRect
= $.extend({}, elRect
, { width: elRect
.right
- elRect
.left
, height: elRect
.bottom
- elRect
.top
})
1623 var isSvg
= window
.SVGElement
&& el
instanceof window
.SVGElement
1624 // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
1625 // See https://github.com/twbs/bootstrap/issues/20280
1626 var elOffset
= isBody
? { top: 0, left: 0 } : (isSvg
? null : $element
.offset())
1627 var scroll
= { scroll: isBody
? document
.documentElement
.scrollTop
|| document
.body
.scrollTop : $element
.scrollTop() }
1628 var outerDims
= isBody
? { width: $(window
).width(), height: $(window
).height() } : null
1630 return $.extend({}, elRect
, scroll
, outerDims
, elOffset
)
1633 Tooltip
.prototype.getCalculatedOffset = function (placement
, pos
, actualWidth
, actualHeight
) {
1634 return placement
== 'bottom' ? { top: pos
.top
+ pos
.height
, left: pos
.left
+ pos
.width
/ 2 - actualWidth
/ 2 } :
1635 placement
== 'top' ? { top: pos
.top
- actualHeight
, left: pos
.left
+ pos
.width
/ 2 - actualWidth
/ 2 } :
1636 placement
== 'left' ? { top: pos
.top
+ pos
.height
/ 2 - actualHeight
/ 2, left: pos
.left
- actualWidth
} :
1637 /* placement == 'right' */ { top: pos
.top
+ pos
.height
/ 2 - actualHeight
/ 2, left: pos
.left
+ pos
.width
}
1641 Tooltip
.prototype.getViewportAdjustedDelta = function (placement
, pos
, actualWidth
, actualHeight
) {
1642 var delta
= { top: 0, left: 0 }
1643 if (!this.$viewport
) return delta
1645 var viewportPadding
= this.options
.viewport
&& this.options
.viewport
.padding
|| 0
1646 var viewportDimensions
= this.getPosition(this.$viewport
)
1648 if (/right|left/.test(placement
)) {
1649 var topEdgeOffset
= pos
.top
- viewportPadding
- viewportDimensions
.scroll
1650 var bottomEdgeOffset
= pos
.top
+ viewportPadding
- viewportDimensions
.scroll
+ actualHeight
1651 if (topEdgeOffset
< viewportDimensions
.top
) { // top overflow
1652 delta
.top
= viewportDimensions
.top
- topEdgeOffset
1653 } else if (bottomEdgeOffset
> viewportDimensions
.top
+ viewportDimensions
.height
) { // bottom overflow
1654 delta
.top
= viewportDimensions
.top
+ viewportDimensions
.height
- bottomEdgeOffset
1657 var leftEdgeOffset
= pos
.left
- viewportPadding
1658 var rightEdgeOffset
= pos
.left
+ viewportPadding
+ actualWidth
1659 if (leftEdgeOffset
< viewportDimensions
.left
) { // left overflow
1660 delta
.left
= viewportDimensions
.left
- leftEdgeOffset
1661 } else if (rightEdgeOffset
> viewportDimensions
.right
) { // right overflow
1662 delta
.left
= viewportDimensions
.left
+ viewportDimensions
.width
- rightEdgeOffset
1669 Tooltip
.prototype.getTitle = function () {
1671 var $e
= this.$element
1672 var o
= this.options
1674 title
= $e
.attr('data-original-title')
1675 || (typeof o
.title
== 'function' ? o
.title
.call($e
[0]) : o
.title
)
1680 Tooltip
.prototype.getUID = function (prefix
) {
1681 do prefix
+= ~~(Math
.random() * 1000000)
1682 while (document
.getElementById(prefix
))
1686 Tooltip
.prototype.tip = function () {
1688 this.$tip
= $(this.options
.template
)
1689 if (this.$tip
.length
!= 1) {
1690 throw new Error(this.type
+ ' `template` option must consist of exactly 1 top-level element!')
1696 Tooltip
.prototype.arrow = function () {
1697 return (this.$arrow
= this.$arrow
|| this.tip().find('.tooltip-arrow'))
1700 Tooltip
.prototype.enable = function () {
1704 Tooltip
.prototype.disable = function () {
1705 this.enabled
= false
1708 Tooltip
.prototype.toggleEnabled = function () {
1709 this.enabled
= !this.enabled
1712 Tooltip
.prototype.toggle = function (e
) {
1715 self
= $(e
.currentTarget
).data('bs.' + this.type
)
1717 self
= new this.constructor(e
.currentTarget
, this.getDelegateOptions())
1718 $(e
.currentTarget
).data('bs.' + this.type
, self
)
1723 self
.inState
.click
= !self
.inState
.click
1724 if (self
.isInStateTrue()) self
.enter(self
)
1725 else self
.leave(self
)
1727 self
.tip().hasClass('in') ? self
.leave(self
) : self
.enter(self
)
1731 Tooltip
.prototype.destroy = function () {
1733 clearTimeout(this.timeout
)
1734 this.hide(function () {
1735 that
.$element
.off('.' + that
.type
).removeData('bs.' + that
.type
)
1741 that
.$viewport
= null
1742 that
.$element
= null
1747 // TOOLTIP PLUGIN DEFINITION
1748 // =========================
1750 function Plugin(option
) {
1751 return this.each(function () {
1753 var data
= $this.data('bs.tooltip')
1754 var options
= typeof option
== 'object' && option
1756 if (!data
&& /destroy|hide/.test(option
)) return
1757 if (!data
) $this.data('bs.tooltip', (data
= new Tooltip(this, options
)))
1758 if (typeof option
== 'string') data
[option
]()
1762 var old
= $.fn
.tooltip
1764 $.fn
.tooltip
= Plugin
1765 $.fn
.tooltip
.Constructor
= Tooltip
1768 // TOOLTIP NO CONFLICT
1769 // ===================
1771 $.fn
.tooltip
.noConflict = function () {
1778 /* ========================================================================
1779 * Bootstrap: popover.js v3.3.7
1780 * http://getbootstrap.com/javascript/#popovers
1781 * ========================================================================
1782 * Copyright 2011-2016 Twitter, Inc.
1783 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1784 * ======================================================================== */
1790 // POPOVER PUBLIC CLASS DEFINITION
1791 // ===============================
1793 var Popover = function (element
, options
) {
1794 this.init('popover', element
, options
)
1797 if (!$.fn
.tooltip
) throw new Error('Popover requires tooltip.js')
1799 Popover
.VERSION
= '3.3.7'
1801 Popover
.DEFAULTS
= $.extend({}, $.fn
.tooltip
.Constructor
.DEFAULTS
, {
1805 template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1809 // NOTE: POPOVER EXTENDS tooltip.js
1810 // ================================
1812 Popover
.prototype = $.extend({}, $.fn
.tooltip
.Constructor
.prototype)
1814 Popover
.prototype.constructor = Popover
1816 Popover
.prototype.getDefaults = function () {
1817 return Popover
.DEFAULTS
1820 Popover
.prototype.setContent = function () {
1821 var $tip
= this.tip()
1822 var title
= this.getTitle()
1823 var content
= this.getContent()
1825 $tip
.find('.popover-title')[this.options
.html
? 'html' : 'text'](title
)
1826 $tip
.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
1827 this.options
.html
? (typeof content
== 'string' ? 'html' : 'append') : 'text'
1830 $tip
.removeClass('fade top bottom left right in')
1832 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
1833 // this manually by checking the contents.
1834 if (!$tip
.find('.popover-title').html()) $tip
.find('.popover-title').hide()
1837 Popover
.prototype.hasContent = function () {
1838 return this.getTitle() || this.getContent()
1841 Popover
.prototype.getContent = function () {
1842 var $e
= this.$element
1843 var o
= this.options
1845 return $e
.attr('data-content')
1846 || (typeof o
.content
== 'function' ?
1847 o
.content
.call($e
[0]) :
1851 Popover
.prototype.arrow = function () {
1852 return (this.$arrow
= this.$arrow
|| this.tip().find('.arrow'))
1856 // POPOVER PLUGIN DEFINITION
1857 // =========================
1859 function Plugin(option
) {
1860 return this.each(function () {
1862 var data
= $this.data('bs.popover')
1863 var options
= typeof option
== 'object' && option
1865 if (!data
&& /destroy|hide/.test(option
)) return
1866 if (!data
) $this.data('bs.popover', (data
= new Popover(this, options
)))
1867 if (typeof option
== 'string') data
[option
]()
1871 var old
= $.fn
.popover
1873 $.fn
.popover
= Plugin
1874 $.fn
.popover
.Constructor
= Popover
1877 // POPOVER NO CONFLICT
1878 // ===================
1880 $.fn
.popover
.noConflict = function () {
1887 /* ========================================================================
1888 * Bootstrap: scrollspy.js v3.3.7
1889 * http://getbootstrap.com/javascript/#scrollspy
1890 * ========================================================================
1891 * Copyright 2011-2016 Twitter, Inc.
1892 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1893 * ======================================================================== */
1899 // SCROLLSPY CLASS DEFINITION
1900 // ==========================
1902 function ScrollSpy(element
, options
) {
1903 this.$body
= $(document
.body
)
1904 this.$scrollElement
= $(element
).is(document
.body
) ? $(window
) : $(element
)
1905 this.options
= $.extend({}, ScrollSpy
.DEFAULTS
, options
)
1906 this.selector
= (this.options
.target
|| '') + ' .nav li > a'
1909 this.activeTarget
= null
1910 this.scrollHeight
= 0
1912 this.$scrollElement
.on('scroll.bs.scrollspy', $.proxy(this.process
, this))
1917 ScrollSpy
.VERSION
= '3.3.7'
1919 ScrollSpy
.DEFAULTS
= {
1923 ScrollSpy
.prototype.getScrollHeight = function () {
1924 return this.$scrollElement
[0].scrollHeight
|| Math
.max(this.$body
[0].scrollHeight
, document
.documentElement
.scrollHeight
)
1927 ScrollSpy
.prototype.refresh = function () {
1929 var offsetMethod
= 'offset'
1934 this.scrollHeight
= this.getScrollHeight()
1936 if (!$.isWindow(this.$scrollElement
[0])) {
1937 offsetMethod
= 'position'
1938 offsetBase
= this.$scrollElement
.scrollTop()
1942 .find(this.selector
)
1945 var href
= $el
.data('target') || $el
.attr('href')
1946 var $href
= /^#./.test(href
) && $(href
)
1950 && $href
.is(':visible')
1951 && [[$href
[offsetMethod
]().top
+ offsetBase
, href
]]) || null
1953 .sort(function (a
, b
) { return a
[0] - b
[0] })
1955 that
.offsets
.push(this[0])
1956 that
.targets
.push(this[1])
1960 ScrollSpy
.prototype.process = function () {
1961 var scrollTop
= this.$scrollElement
.scrollTop() + this.options
.offset
1962 var scrollHeight
= this.getScrollHeight()
1963 var maxScroll
= this.options
.offset
+ scrollHeight
- this.$scrollElement
.height()
1964 var offsets
= this.offsets
1965 var targets
= this.targets
1966 var activeTarget
= this.activeTarget
1969 if (this.scrollHeight
!= scrollHeight
) {
1973 if (scrollTop
>= maxScroll
) {
1974 return activeTarget
!= (i
= targets
[targets
.length
- 1]) && this.activate(i
)
1977 if (activeTarget
&& scrollTop
< offsets
[0]) {
1978 this.activeTarget
= null
1982 for (i
= offsets
.length
; i
--;) {
1983 activeTarget
!= targets
[i
]
1984 && scrollTop
>= offsets
[i
]
1985 && (offsets
[i
+ 1] === undefined || scrollTop
< offsets
[i
+ 1])
1986 && this.activate(targets
[i
])
1990 ScrollSpy
.prototype.activate = function (target
) {
1991 this.activeTarget
= target
1995 var selector
= this.selector
+
1996 '[data-target="' + target
+ '"],' +
1997 this.selector
+ '[href="' + target
+ '"]'
1999 var active
= $(selector
)
2003 if (active
.parent('.dropdown-menu').length
) {
2005 .closest('li.dropdown')
2009 active
.trigger('activate.bs.scrollspy')
2012 ScrollSpy
.prototype.clear = function () {
2014 .parentsUntil(this.options
.target
, '.active')
2015 .removeClass('active')
2019 // SCROLLSPY PLUGIN DEFINITION
2020 // ===========================
2022 function Plugin(option
) {
2023 return this.each(function () {
2025 var data
= $this.data('bs.scrollspy')
2026 var options
= typeof option
== 'object' && option
2028 if (!data
) $this.data('bs.scrollspy', (data
= new ScrollSpy(this, options
)))
2029 if (typeof option
== 'string') data
[option
]()
2033 var old
= $.fn
.scrollspy
2035 $.fn
.scrollspy
= Plugin
2036 $.fn
.scrollspy
.Constructor
= ScrollSpy
2039 // SCROLLSPY NO CONFLICT
2040 // =====================
2042 $.fn
.scrollspy
.noConflict = function () {
2043 $.fn
.scrollspy
= old
2048 // SCROLLSPY DATA-API
2049 // ==================
2051 $(window
).on('load.bs.scrollspy.data-api', function () {
2052 $('[data-spy="scroll"]').each(function () {
2054 Plugin
.call($spy
, $spy
.data())
2060 /* ========================================================================
2061 * Bootstrap: tab.js v3.3.7
2062 * http://getbootstrap.com/javascript/#tabs
2063 * ========================================================================
2064 * Copyright 2011-2016 Twitter, Inc.
2065 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2066 * ======================================================================== */
2072 // TAB CLASS DEFINITION
2073 // ====================
2075 var Tab = function (element
) {
2076 // jscs:disable requireDollarBeforejQueryAssignment
2077 this.element
= $(element
)
2078 // jscs:enable requireDollarBeforejQueryAssignment
2081 Tab
.VERSION
= '3.3.7'
2083 Tab
.TRANSITION_DURATION
= 150
2085 Tab
.prototype.show = function () {
2086 var $this = this.element
2087 var $ul
= $this.closest('ul:not(.dropdown-menu)')
2088 var selector
= $this.data('target')
2091 selector
= $this.attr('href')
2092 selector
= selector
&& selector
.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
2095 if ($this.parent('li').hasClass('active')) return
2097 var $previous
= $ul
.find('.active:last a')
2098 var hideEvent
= $.Event('hide.bs.tab', {
2099 relatedTarget: $this[0]
2101 var showEvent
= $.Event('show.bs.tab', {
2102 relatedTarget: $previous
[0]
2105 $previous
.trigger(hideEvent
)
2106 $this.trigger(showEvent
)
2108 if (showEvent
.isDefaultPrevented() || hideEvent
.isDefaultPrevented()) return
2110 var $target
= $(selector
)
2112 this.activate($this.closest('li'), $ul
)
2113 this.activate($target
, $target
.parent(), function () {
2115 type: 'hidden.bs.tab',
2116 relatedTarget: $this[0]
2119 type: 'shown.bs.tab',
2120 relatedTarget: $previous
[0]
2125 Tab
.prototype.activate = function (element
, container
, callback
) {
2126 var $active
= container
.find('> .active')
2127 var transition
= callback
2128 && $.support
.transition
2129 && ($active
.length
&& $active
.hasClass('fade') || !!container
.find('> .fade').length
)
2133 .removeClass('active')
2134 .find('> .dropdown-menu > .active')
2135 .removeClass('active')
2137 .find('[data-toggle="tab"]')
2138 .attr('aria-expanded', false)
2142 .find('[data-toggle="tab"]')
2143 .attr('aria-expanded', true)
2146 element
[0].offsetWidth
// reflow for transition
2147 element
.addClass('in')
2149 element
.removeClass('fade')
2152 if (element
.parent('.dropdown-menu').length
) {
2154 .closest('li.dropdown')
2157 .find('[data-toggle="tab"]')
2158 .attr('aria-expanded', true)
2161 callback
&& callback()
2164 $active
.length
&& transition
?
2166 .one('bsTransitionEnd', next
)
2167 .emulateTransitionEnd(Tab
.TRANSITION_DURATION
) :
2170 $active
.removeClass('in')
2174 // TAB PLUGIN DEFINITION
2175 // =====================
2177 function Plugin(option
) {
2178 return this.each(function () {
2180 var data
= $this.data('bs.tab')
2182 if (!data
) $this.data('bs.tab', (data
= new Tab(this)))
2183 if (typeof option
== 'string') data
[option
]()
2190 $.fn
.tab
.Constructor
= Tab
2196 $.fn
.tab
.noConflict = function () {
2205 var clickHandler = function (e
) {
2207 Plugin
.call($(this), 'show')
2211 .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler
)
2212 .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler
)
2216 /* ========================================================================
2217 * Bootstrap: affix.js v3.3.7
2218 * http://getbootstrap.com/javascript/#affix
2219 * ========================================================================
2220 * Copyright 2011-2016 Twitter, Inc.
2221 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2222 * ======================================================================== */
2228 // AFFIX CLASS DEFINITION
2229 // ======================
2231 var Affix = function (element
, options
) {
2232 this.options
= $.extend({}, Affix
.DEFAULTS
, options
)
2234 this.$target
= $(this.options
.target
)
2235 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition
, this))
2236 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop
, this))
2238 this.$element
= $(element
)
2241 this.pinnedOffset
= null
2243 this.checkPosition()
2246 Affix
.VERSION
= '3.3.7'
2248 Affix
.RESET
= 'affix affix-top affix-bottom'
2255 Affix
.prototype.getState = function (scrollHeight
, height
, offsetTop
, offsetBottom
) {
2256 var scrollTop
= this.$target
.scrollTop()
2257 var position
= this.$element
.offset()
2258 var targetHeight
= this.$target
.height()
2260 if (offsetTop
!= null && this.affixed
== 'top') return scrollTop
< offsetTop
? 'top' : false
2262 if (this.affixed
== 'bottom') {
2263 if (offsetTop
!= null) return (scrollTop
+ this.unpin
<= position
.top
) ? false : 'bottom'
2264 return (scrollTop
+ targetHeight
<= scrollHeight
- offsetBottom
) ? false : 'bottom'
2267 var initializing
= this.affixed
== null
2268 var colliderTop
= initializing
? scrollTop : position
.top
2269 var colliderHeight
= initializing
? targetHeight : height
2271 if (offsetTop
!= null && scrollTop
<= offsetTop
) return 'top'
2272 if (offsetBottom
!= null && (colliderTop
+ colliderHeight
>= scrollHeight
- offsetBottom
)) return 'bottom'
2277 Affix
.prototype.getPinnedOffset = function () {
2278 if (this.pinnedOffset
) return this.pinnedOffset
2279 this.$element
.removeClass(Affix
.RESET
).addClass('affix')
2280 var scrollTop
= this.$target
.scrollTop()
2281 var position
= this.$element
.offset()
2282 return (this.pinnedOffset
= position
.top
- scrollTop
)
2285 Affix
.prototype.checkPositionWithEventLoop = function () {
2286 setTimeout($.proxy(this.checkPosition
, this), 1)
2289 Affix
.prototype.checkPosition = function () {
2290 if (!this.$element
.is(':visible')) return
2292 var height
= this.$element
.height()
2293 var offset
= this.options
.offset
2294 var offsetTop
= offset
.top
2295 var offsetBottom
= offset
.bottom
2296 var scrollHeight
= Math
.max($(document
).height(), $(document
.body
).height())
2298 if (typeof offset
!= 'object') offsetBottom
= offsetTop
= offset
2299 if (typeof offsetTop
== 'function') offsetTop
= offset
.top(this.$element
)
2300 if (typeof offsetBottom
== 'function') offsetBottom
= offset
.bottom(this.$element
)
2302 var affix
= this.getState(scrollHeight
, height
, offsetTop
, offsetBottom
)
2304 if (this.affixed
!= affix
) {
2305 if (this.unpin
!= null) this.$element
.css('top', '')
2307 var affixType
= 'affix' + (affix
? '-' + affix : '')
2308 var e
= $.Event(affixType
+ '.bs.affix')
2310 this.$element
.trigger(e
)
2312 if (e
.isDefaultPrevented()) return
2314 this.affixed
= affix
2315 this.unpin
= affix
== 'bottom' ? this.getPinnedOffset() : null
2318 .removeClass(Affix
.RESET
)
2319 .addClass(affixType
)
2320 .trigger(affixType
.replace('affix', 'affixed') + '.bs.affix')
2323 if (affix
== 'bottom') {
2324 this.$element
.offset({
2325 top: scrollHeight
- height
- offsetBottom
2331 // AFFIX PLUGIN DEFINITION
2332 // =======================
2334 function Plugin(option
) {
2335 return this.each(function () {
2337 var data
= $this.data('bs.affix')
2338 var options
= typeof option
== 'object' && option
2340 if (!data
) $this.data('bs.affix', (data
= new Affix(this, options
)))
2341 if (typeof option
== 'string') data
[option
]()
2345 var old
= $.fn
.affix
2348 $.fn
.affix
.Constructor
= Affix
2351 // AFFIX NO CONFLICT
2352 // =================
2354 $.fn
.affix
.noConflict = function () {
2363 $(window
).on('load', function () {
2364 $('[data-spy="affix"]').each(function () {
2366 var data
= $spy
.data()
2368 data
.offset
= data
.offset
|| {}
2370 if (data
.offsetBottom
!= null) data
.offset
.bottom
= data
.offsetBottom
2371 if (data
.offsetTop
!= null) data
.offset
.top
= data
.offsetTop
2373 Plugin
.call($spy
, data
)