PluginProbe
Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar / 2.0
Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar v2.0
2.1.21 2.1.20 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 trunk 1.1 2.0 2.0.1 2.0.10.2 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.17 2.0.18 2.0.2 2.0.20 2.0.21 2.0.22 All 55 releases
booking-manager / assets / libs / bootstrap / js / bootstrap.js

bootstrap.js in Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar 2.0, at assets/libs/bootstrap/js/bootstrap.js

2,367 lines 67.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*!
2 * Bootstrap v3.3.5 (http://getbootstrap.com)
3 * Copyright 2011-2015 Twitter, Inc.
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 */
6
7 /*!
8 * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f4b4c9cb85df757ca08c)
9 * Config saved to config.json and https://gist.github.com/f4b4c9cb85df757ca08c
10 */
11 if (typeof jQuery === 'undefined') {
12 throw new Error('Bootstrap\'s JavaScript requires jQuery')
13 }
14 +function ($) {
15 'use strict';
16 var version = $.fn.jquery.split(' ')[0].split('.')
17 if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
18 throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
19 }
20 }(jQuery);
21
22 /* ========================================================================
23 * Bootstrap: alert.js v3.3.5
24 * http://getbootstrap.com/javascript/#alerts
25 * ========================================================================
26 * Copyright 2011-2015 Twitter, Inc.
27 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
28 * ======================================================================== */
29
30
31 +function ($) {
32 'use strict';
33
34 // ALERT CLASS DEFINITION
35 // ======================
36
37 var dismiss = '[data-dismiss="alert"]'
38 var Alert = function (el) {
39 $(el).on('click', dismiss, this.close)
40 }
41
42 Alert.VERSION = '3.3.5'
43
44 Alert.TRANSITION_DURATION = 150
45
46 Alert.prototype.close = function (e) {
47 var $this = $(this)
48 var selector = $this.attr('data-target')
49
50 if (!selector) {
51 selector = $this.attr('href')
52 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
53 }
54
55 var $parent = $(selector)
56
57 if (e) e.preventDefault()
58
59 if (!$parent.length) {
60 $parent = $this.closest('.alert')
61 }
62
63 $parent.trigger(e = $.Event('close.bs.alert'))
64
65 if (e.isDefaultPrevented()) return
66
67 $parent.removeClass('in')
68
69 function removeElement() {
70 // detach from parent, fire event then clean up data
71 $parent.detach().trigger('closed.bs.alert').remove()
72 }
73
74 $.support.transition && $parent.hasClass('fade') ?
75 $parent
76 .one('bsTransitionEnd', removeElement)
77 .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
78 removeElement()
79 }
80
81
82 // ALERT PLUGIN DEFINITION
83 // =======================
84
85 function Plugin(option) {
86 return this.each(function () {
87 var $this = $(this)
88 var data = $this.data('bs.alert')
89
90 if (!data) $this.data('bs.alert', (data = new Alert(this)))
91 if (typeof option == 'string') data[option].call($this)
92 })
93 }
94
95 var old = $.fn.alert
96
97 $.fn.alert = Plugin
98 $.fn.alert.Constructor = Alert
99
100
101 // ALERT NO CONFLICT
102 // =================
103
104 $.fn.alert.noConflict = function () {
105 $.fn.alert = old
106 return this
107 }
108
109
110 // ALERT DATA-API
111 // ==============
112
113 $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
114
115 }(jQuery);
116
117 /* ========================================================================
118 * Bootstrap: button.js v3.3.5
119 * http://getbootstrap.com/javascript/#buttons
120 * ========================================================================
121 * Copyright 2011-2015 Twitter, Inc.
122 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
123 * ======================================================================== */
124
125
126 +function ($) {
127 'use strict';
128
129 // BUTTON PUBLIC CLASS DEFINITION
130 // ==============================
131
132 var Button = function (element, options) {
133 this.$element = $(element)
134 this.options = $.extend({}, Button.DEFAULTS, options)
135 this.isLoading = false
136 }
137
138 Button.VERSION = '3.3.5'
139
140 Button.DEFAULTS = {
141 loadingText: 'loading...'
142 }
143
144 Button.prototype.setState = function (state) {
145 var d = 'disabled'
146 var $el = this.$element
147 var val = $el.is('input') ? 'val' : 'html'
148 var data = $el.data()
149
150 state += 'Text'
151
152 if (data.resetText == null) $el.data('resetText', $el[val]())
153
154 // push to event loop to allow forms to submit
155 setTimeout($.proxy(function () {
156 $el[val](data[state] == null ? this.options[state] : data[state])
157
158 if (state == 'loadingText') {
159 this.isLoading = true
160 $el.addClass(d).attr(d, d)
161 } else if (this.isLoading) {
162 this.isLoading = false
163 $el.removeClass(d).removeAttr(d)
164 }
165 }, this), 0)
166 }
167
168 Button.prototype.toggle = function () {
169 var changed = true
170 var $parent = this.$element.closest('[data-toggle="buttons"]')
171
172 if ($parent.length) {
173 var $input = this.$element.find('input')
174 if ($input.prop('type') == 'radio') {
175 if ($input.prop('checked')) changed = false
176 $parent.find('.active').removeClass('active')
177 this.$element.addClass('active')
178 } else if ($input.prop('type') == 'checkbox') {
179 if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
180 this.$element.toggleClass('active')
181 }
182 $input.prop('checked', this.$element.hasClass('active'))
183 if (changed) $input.trigger('change')
184 } else {
185 this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
186 this.$element.toggleClass('active')
187 }
188 }
189
190
191 // BUTTON PLUGIN DEFINITION
192 // ========================
193
194 function Plugin(option) {
195 return this.each(function () {
196 var $this = $(this)
197 var data = $this.data('bs.button')
198 var options = typeof option == 'object' && option
199
200 if (!data) $this.data('bs.button', (data = new Button(this, options)))
201
202 if (option == 'toggle') data.toggle()
203 else if (option) data.setState(option)
204 })
205 }
206
207 var old = $.fn.button
208
209 $.fn.button = Plugin
210 $.fn.button.Constructor = Button
211
212
213 // BUTTON NO CONFLICT
214 // ==================
215
216 $.fn.button.noConflict = function () {
217 $.fn.button = old
218 return this
219 }
220
221
222 // BUTTON DATA-API
223 // ===============
224
225 $(document)
226 .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
227 var $btn = $(e.target)
228 if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
229 Plugin.call($btn, 'toggle')
230 if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
231 })
232 .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
233 $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
234 })
235
236 }(jQuery);
237
238 /* ========================================================================
239 * Bootstrap: carousel.js v3.3.5
240 * http://getbootstrap.com/javascript/#carousel
241 * ========================================================================
242 * Copyright 2011-2015 Twitter, Inc.
243 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
244 * ======================================================================== */
245
246
247 +function ($) {
248 'use strict';
249
250 // CAROUSEL CLASS DEFINITION
251 // =========================
252
253 var Carousel = function (element, options) {
254 this.$element = $(element)
255 this.$indicators = this.$element.find('.carousel-indicators')
256 this.options = options
257 this.paused = null
258 this.sliding = null
259 this.interval = null
260 this.$active = null
261 this.$items = null
262
263 this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
264
265 this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
266 .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
267 .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
268 }
269
270 Carousel.VERSION = '3.3.5'
271
272 Carousel.TRANSITION_DURATION = 600
273
274 Carousel.DEFAULTS = {
275 interval: 5000,
276 pause: 'hover',
277 wrap: true,
278 keyboard: true
279 }
280
281 Carousel.prototype.keydown = function (e) {
282 if (/input|textarea/i.test(e.target.tagName)) return
283 switch (e.which) {
284 case 37: this.prev(); break
285 case 39: this.next(); break
286 default: return
287 }
288
289 e.preventDefault()
290 }
291
292 Carousel.prototype.cycle = function (e) {
293 e || (this.paused = false)
294
295 this.interval && clearInterval(this.interval)
296
297 this.options.interval
298 && !this.paused
299 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
300
301 return this
302 }
303
304 Carousel.prototype.getItemIndex = function (item) {
305 this.$items = item.parent().children('.item')
306 return this.$items.index(item || this.$active)
307 }
308
309 Carousel.prototype.getItemForDirection = function (direction, active) {
310 var activeIndex = this.getItemIndex(active)
311 var willWrap = (direction == 'prev' && activeIndex === 0)
312 || (direction == 'next' && activeIndex == (this.$items.length - 1))
313 if (willWrap && !this.options.wrap) return active
314 var delta = direction == 'prev' ? -1 : 1
315 var itemIndex = (activeIndex + delta) % this.$items.length
316 return this.$items.eq(itemIndex)
317 }
318
319 Carousel.prototype.to = function (pos) {
320 var that = this
321 var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
322
323 if (pos > (this.$items.length - 1) || pos < 0) return
324
325 if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
326 if (activeIndex == pos) return this.pause().cycle()
327
328 return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
329 }
330
331 Carousel.prototype.pause = function (e) {
332 e || (this.paused = true)
333
334 if (this.$element.find('.next, .prev').length && $.support.transition) {
335 this.$element.trigger($.support.transition.end)
336 this.cycle(true)
337 }
338
339 this.interval = clearInterval(this.interval)
340
341 return this
342 }
343
344 Carousel.prototype.next = function () {
345 if (this.sliding) return
346 return this.slide('next')
347 }
348
349 Carousel.prototype.prev = function () {
350 if (this.sliding) return
351 return this.slide('prev')
352 }
353
354 Carousel.prototype.slide = function (type, next) {
355 var $active = this.$element.find('.item.active')
356 var $next = next || this.getItemForDirection(type, $active)
357 var isCycling = this.interval
358 var direction = type == 'next' ? 'left' : 'right'
359 var that = this
360
361 if ($next.hasClass('active')) return (this.sliding = false)
362
363 var relatedTarget = $next[0]
364 var slideEvent = $.Event('slide.bs.carousel', {
365 relatedTarget: relatedTarget,
366 direction: direction
367 })
368 this.$element.trigger(slideEvent)
369 if (slideEvent.isDefaultPrevented()) return
370
371 this.sliding = true
372
373 isCycling && this.pause()
374
375 if (this.$indicators.length) {
376 this.$indicators.find('.active').removeClass('active')
377 var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
378 $nextIndicator && $nextIndicator.addClass('active')
379 }
380
381 var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
382 if ($.support.transition && this.$element.hasClass('slide')) {
383 $next.addClass(type)
384 $next[0].offsetWidth // force reflow
385 $active.addClass(direction)
386 $next.addClass(direction)
387 $active
388 .one('bsTransitionEnd', function () {
389 $next.removeClass([type, direction].join(' ')).addClass('active')
390 $active.removeClass(['active', direction].join(' '))
391 that.sliding = false
392 setTimeout(function () {
393 that.$element.trigger(slidEvent)
394 }, 0)
395 })
396 .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
397 } else {
398 $active.removeClass('active')
399 $next.addClass('active')
400 this.sliding = false
401 this.$element.trigger(slidEvent)
402 }
403
404 isCycling && this.cycle()
405
406 return this
407 }
408
409
410 // CAROUSEL PLUGIN DEFINITION
411 // ==========================
412
413 function Plugin(option) {
414 return this.each(function () {
415 var $this = $(this)
416 var data = $this.data('bs.carousel')
417 var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
418 var action = typeof option == 'string' ? option : options.slide
419
420 if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
421 if (typeof option == 'number') data.to(option)
422 else if (action) data[action]()
423 else if (options.interval) data.pause().cycle()
424 })
425 }
426
427 var old = $.fn.carousel
428
429 $.fn.carousel = Plugin
430 $.fn.carousel.Constructor = Carousel
431
432
433 // CAROUSEL NO CONFLICT
434 // ====================
435
436 $.fn.carousel.noConflict = function () {
437 $.fn.carousel = old
438 return this
439 }
440
441
442 // CAROUSEL DATA-API
443 // =================
444
445 var clickHandler = function (e) {
446 var href
447 var $this = $(this)
448 var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
449 if (!$target.hasClass('carousel')) return
450 var options = $.extend({}, $target.data(), $this.data())
451 var slideIndex = $this.attr('data-slide-to')
452 if (slideIndex) options.interval = false
453
454 Plugin.call($target, options)
455
456 if (slideIndex) {
457 $target.data('bs.carousel').to(slideIndex)
458 }
459
460 e.preventDefault()
461 }
462
463 $(document)
464 .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
465 .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
466
467 $(window).on('load', function () {
468 $('[data-ride="carousel"]').each(function () {
469 var $carousel = $(this)
470 Plugin.call($carousel, $carousel.data())
471 })
472 })
473
474 }(jQuery);
475
476 /* ========================================================================
477 * Bootstrap: dropdown.js v3.3.5
478 * http://getbootstrap.com/javascript/#dropdowns
479 * ========================================================================
480 * Copyright 2011-2015 Twitter, Inc.
481 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
482 * ======================================================================== */
483
484
485 +function ($) {
486 'use strict';
487
488 // DROPDOWN CLASS DEFINITION
489 // =========================
490
491 var backdrop = '.dropdown-backdrop'
492 var toggle = '[data-toggle="dropdown"]'
493 var Dropdown = function (element) {
494 $(element).on('click.bs.dropdown', this.toggle)
495 }
496
497 Dropdown.VERSION = '3.3.5'
498
499 function getParent($this) {
500 var selector = $this.attr('data-target')
501
502 if (!selector) {
503 selector = $this.attr('href')
504 selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
505 }
506
507 var $parent = selector && $(selector)
508
509 return $parent && $parent.length ? $parent : $this.parent()
510 }
511
512 function clearMenus(e) {
513 if (e && e.which === 3) return
514 $(backdrop).remove()
515 $(toggle).each(function () {
516 var $this = $(this)
517 var $parent = getParent($this)
518 var relatedTarget = { relatedTarget: this }
519
520 if (!$parent.hasClass('open')) return
521
522 if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
523
524 $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
525
526 if (e.isDefaultPrevented()) return
527
528 $this.attr('aria-expanded', 'false')
529 $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
530 })
531 }
532
533 Dropdown.prototype.toggle = function (e) {
534 var $this = $(this)
535
536 if ($this.is('.disabled, :disabled')) return
537
538 var $parent = getParent($this)
539 var isActive = $parent.hasClass('open')
540
541 clearMenus()
542
543 if (!isActive) {
544 if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
545 // if mobile we use a backdrop because click events don't delegate
546 $(document.createElement('div'))
547 .addClass('dropdown-backdrop')
548 .insertAfter($(this))
549 .on('click', clearMenus)
550 }
551
552 var relatedTarget = { relatedTarget: this }
553 $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
554
555 if (e.isDefaultPrevented()) return
556
557 $this
558 .trigger('focus')
559 .attr('aria-expanded', 'true')
560
561 $parent
562 .toggleClass('open')
563 .trigger('shown.bs.dropdown', relatedTarget)
564 }
565
566 return false
567 }
568
569 Dropdown.prototype.keydown = function (e) {
570 if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
571
572 var $this = $(this)
573
574 e.preventDefault()
575 e.stopPropagation()
576
577 if ($this.is('.disabled, :disabled')) return
578
579 var $parent = getParent($this)
580 var isActive = $parent.hasClass('open')
581
582 if (!isActive && e.which != 27 || isActive && e.which == 27) {
583 if (e.which == 27) $parent.find(toggle).trigger('focus')
584 return $this.trigger('click')
585 }
586
587 var desc = ' li:not(.disabled):visible a'
588 var $items = $parent.find('.dropdown-menu' + desc)
589
590 if (!$items.length) return
591
592 var index = $items.index(e.target)
593
594 if (e.which == 38 && index > 0) index-- // up
595 if (e.which == 40 && index < $items.length - 1) index++ // down
596 if (!~index) index = 0
597
598 $items.eq(index).trigger('focus')
599 }
600
601
602 // DROPDOWN PLUGIN DEFINITION
603 // ==========================
604
605 function Plugin(option) {
606 return this.each(function () {
607 var $this = $(this)
608 var data = $this.data('bs.dropdown')
609
610 if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
611 if (typeof option == 'string') data[option].call($this)
612 })
613 }
614
615 var old = $.fn.dropdown
616
617 $.fn.dropdown = Plugin
618 $.fn.dropdown.Constructor = Dropdown
619
620
621 // DROPDOWN NO CONFLICT
622 // ====================
623
624 $.fn.dropdown.noConflict = function () {
625 $.fn.dropdown = old
626 return this
627 }
628
629
630 // APPLY TO STANDARD DROPDOWN ELEMENTS
631 // ===================================
632
633 $(document)
634 .on('click.bs.dropdown.data-api', clearMenus)
635 .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
636 .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
637 .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
638 .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
639
640 }(jQuery);
641
642 /* ========================================================================
643 * Bootstrap: modal.js v3.3.5
644 * http://getbootstrap.com/javascript/#modals
645 * ========================================================================
646 * Copyright 2011-2015 Twitter, Inc.
647 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
648 * ======================================================================== */
649
650
651 +function ($) {
652 'use strict';
653
654 // MODAL CLASS DEFINITION
655 // ======================
656
657 var Modal = function (element, options) {
658 this.options = options
659 this.$body = $(document.body)
660 this.$element = $(element)
661 this.$dialog = this.$element.find('.modal-dialog')
662 this.$backdrop = null
663 this.isShown = null
664 this.originalBodyPad = null
665 this.scrollbarWidth = 0
666 this.ignoreBackdropClick = false
667
668 if (this.options.remote) {
669 this.$element
670 .find('.modal-content')
671 .load(this.options.remote, $.proxy(function () {
672 this.$element.trigger('loaded.bs.modal')
673 }, this))
674 }
675 }
676
677 Modal.VERSION = '3.3.5'
678
679 Modal.TRANSITION_DURATION = 300
680 Modal.BACKDROP_TRANSITION_DURATION = 150
681
682 Modal.DEFAULTS = {
683 backdrop: true,
684 keyboard: true,
685 show: true
686 }
687
688 Modal.prototype.toggle = function (_relatedTarget) {
689 return this.isShown ? this.hide() : this.show(_relatedTarget)
690 }
691
692 Modal.prototype.show = function (_relatedTarget) {
693 var that = this
694 var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
695
696 this.$element.trigger(e)
697
698 if (this.isShown || e.isDefaultPrevented()) return
699
700 this.isShown = true
701
702 this.checkScrollbar()
703 this.setScrollbar()
704 this.$body.addClass('modal-open')
705
706 this.escape()
707 this.resize()
708
709 this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
710
711 this.$dialog.on('mousedown.dismiss.bs.modal', function () {
712 that.$element.one('mouseup.dismiss.bs.modal', function (e) {
713 if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
714 })
715 })
716
717 this.backdrop(function () {
718 var transition = $.support.transition && that.$element.hasClass('fade')
719
720 if (!that.$element.parent().length) {
721 that.$element.appendTo(that.$body) // don't move modals dom position
722 }
723
724 that.$element
725 .show()
726 .scrollTop(0)
727
728 that.adjustDialog()
729
730 if (transition) {
731 that.$element[0].offsetWidth // force reflow
732 }
733
734 that.$element.addClass('in')
735
736 that.enforceFocus()
737
738 var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
739
740 transition ?
741 that.$dialog // wait for modal to slide in
742 .one('bsTransitionEnd', function () {
743 that.$element.trigger('focus').trigger(e)
744 })
745 .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
746 that.$element.trigger('focus').trigger(e)
747 })
748 }
749
750 Modal.prototype.hide = function (e) {
751 if (e) e.preventDefault()
752
753 e = $.Event('hide.bs.modal')
754
755 this.$element.trigger(e)
756
757 if (!this.isShown || e.isDefaultPrevented()) return
758
759 this.isShown = false
760
761 this.escape()
762 this.resize()
763
764 $(document).off('focusin.bs.modal')
765
766 this.$element
767 .removeClass('in')
768 .off('click.dismiss.bs.modal')
769 .off('mouseup.dismiss.bs.modal')
770
771 this.$dialog.off('mousedown.dismiss.bs.modal')
772
773 $.support.transition && this.$element.hasClass('fade') ?
774 this.$element
775 .one('bsTransitionEnd', $.proxy(this.hideModal, this))
776 .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
777 this.hideModal()
778 }
779
780 Modal.prototype.enforceFocus = function () {
781 $(document)
782 .off('focusin.bs.modal') // guard against infinite focus loop
783 .on('focusin.bs.modal', $.proxy(function (e) {
784 if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
785 this.$element.trigger('focus')
786 }
787 }, this))
788 }
789
790 Modal.prototype.escape = function () {
791 if (this.isShown && this.options.keyboard) {
792 this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
793 e.which == 27 && this.hide()
794 }, this))
795 } else if (!this.isShown) {
796 this.$element.off('keydown.dismiss.bs.modal')
797 }
798 }
799
800 Modal.prototype.resize = function () {
801 if (this.isShown) {
802 $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
803 } else {
804 $(window).off('resize.bs.modal')
805 }
806 }
807
808 Modal.prototype.hideModal = function () {
809 var that = this
810 this.$element.hide()
811 this.backdrop(function () {
812 that.$body.removeClass('modal-open')
813 that.resetAdjustments()
814 that.resetScrollbar()
815 that.$element.trigger('hidden.bs.modal')
816 })
817 }
818
819 Modal.prototype.removeBackdrop = function () {
820 this.$backdrop && this.$backdrop.remove()
821 this.$backdrop = null
822 }
823
824 Modal.prototype.backdrop = function (callback) {
825 var that = this
826 var animate = this.$element.hasClass('fade') ? 'fade' : ''
827
828 if (this.isShown && this.options.backdrop) {
829 var doAnimate = $.support.transition && animate
830
831 this.$backdrop = $(document.createElement('div'))
832 .addClass('modal-backdrop ' + animate)
833 .appendTo(this.$body)
834
835 this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
836 if (this.ignoreBackdropClick) {
837 this.ignoreBackdropClick = false
838 return
839 }
840 if (e.target !== e.currentTarget) return
841 this.options.backdrop == 'static'
842 ? this.$element[0].focus()
843 : this.hide()
844 }, this))
845
846 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
847
848 this.$backdrop.addClass('in')
849
850 if (!callback) return
851
852 doAnimate ?
853 this.$backdrop
854 .one('bsTransitionEnd', callback)
855 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
856 callback()
857
858 } else if (!this.isShown && this.$backdrop) {
859 this.$backdrop.removeClass('in')
860
861 var callbackRemove = function () {
862 that.removeBackdrop()
863 callback && callback()
864 }
865 $.support.transition && this.$element.hasClass('fade') ?
866 this.$backdrop
867 .one('bsTransitionEnd', callbackRemove)
868 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
869 callbackRemove()
870
871 } else if (callback) {
872 callback()
873 }
874 }
875
876 // these following methods are used to handle overflowing modals
877
878 Modal.prototype.handleUpdate = function () {
879 this.adjustDialog()
880 }
881
882 Modal.prototype.adjustDialog = function () {
883 var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
884
885 this.$element.css({
886 paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
887 paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
888 })
889 }
890
891 Modal.prototype.resetAdjustments = function () {
892 this.$element.css({
893 paddingLeft: '',
894 paddingRight: ''
895 })
896 }
897
898 Modal.prototype.checkScrollbar = function () {
899 var fullWindowWidth = window.innerWidth
900 if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
901 var documentElementRect = document.documentElement.getBoundingClientRect()
902 fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
903 }
904 this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
905 this.scrollbarWidth = this.measureScrollbar()
906 }
907
908 Modal.prototype.setScrollbar = function () {
909 var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
910 this.originalBodyPad = document.body.style.paddingRight || ''
911 if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
912 }
913
914 Modal.prototype.resetScrollbar = function () {
915 this.$body.css('padding-right', this.originalBodyPad)
916 }
917
918 Modal.prototype.measureScrollbar = function () { // thx walsh
919 var scrollDiv = document.createElement('div')
920 scrollDiv.className = 'modal-scrollbar-measure'
921 this.$body.append(scrollDiv)
922 var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
923 this.$body[0].removeChild(scrollDiv)
924 return scrollbarWidth
925 }
926
927
928 // MODAL PLUGIN DEFINITION
929 // =======================
930
931 function Plugin(option, _relatedTarget) {
932 return this.each(function () {
933 var $this = $(this)
934 var data = $this.data('bs.modal')
935 var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
936
937 if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
938 if (typeof option == 'string') data[option](_relatedTarget)
939 else if (options.show) data.show(_relatedTarget)
940 })
941 }
942
943 var old = $.fn.modal
944
945 $.fn.modal = Plugin
946 $.fn.modal.Constructor = Modal
947
948
949 // MODAL NO CONFLICT
950 // =================
951
952 $.fn.modal.noConflict = function () {
953 $.fn.modal = old
954 return this
955 }
956
957
958 // MODAL DATA-API
959 // ==============
960
961 $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
962 var $this = $(this)
963 var href = $this.attr('href')
964 var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
965 var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
966
967 if ($this.is('a')) e.preventDefault()
968
969 $target.one('show.bs.modal', function (showEvent) {
970 if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
971 $target.one('hidden.bs.modal', function () {
972 $this.is(':visible') && $this.trigger('focus')
973 })
974 })
975 Plugin.call($target, option, this)
976 })
977
978 }(jQuery);
979
980 /* ========================================================================
981 * Bootstrap: tooltip.js v3.3.5
982 * http://getbootstrap.com/javascript/#tooltip
983 * Inspired by the original jQuery.tipsy by Jason Frame
984 * ========================================================================
985 * Copyright 2011-2015 Twitter, Inc.
986 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
987 * ======================================================================== */
988
989
990 +function ($) {
991 'use strict';
992
993 // TOOLTIP PUBLIC CLASS DEFINITION
994 // ===============================
995
996 var Tooltip = function (element, options) {
997 this.type = null
998 this.options = null
999 this.enabled = null
1000 this.timeout = null
1001 this.hoverState = null
1002 this.$element = null
1003 this.inState = null
1004
1005 this.init('tooltip', element, options)
1006 }
1007
1008 Tooltip.VERSION = '3.3.5'
1009
1010 Tooltip.TRANSITION_DURATION = 150
1011
1012 Tooltip.DEFAULTS = {
1013 animation: true,
1014 placement: 'top',
1015 selector: false,
1016 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
1017 trigger: 'hover focus',
1018 title: '',
1019 delay: 0,
1020 html: false,
1021 container: false,
1022 viewport: {
1023 selector: 'body',
1024 padding: 0
1025 }
1026 }
1027
1028 Tooltip.prototype.init = function (type, element, options) {
1029 this.enabled = true
1030 this.type = type
1031 this.$element = $(element)
1032 this.options = this.getOptions(options)
1033 this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
1034 this.inState = { click: false, hover: false, focus: false }
1035
1036 if (this.$element[0] instanceof document.constructor && !this.options.selector) {
1037 throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
1038 }
1039
1040 var triggers = this.options.trigger.split(' ')
1041
1042 for (var i = triggers.length; i--;) {
1043 var trigger = triggers[i]
1044
1045 if (trigger == 'click') {
1046 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
1047 } else if (trigger != 'manual') {
1048 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
1049 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
1050
1051 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
1052 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
1053 }
1054 }
1055
1056 this.options.selector ?
1057 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
1058 this.fixTitle()
1059 }
1060
1061 Tooltip.prototype.getDefaults = function () {
1062 return Tooltip.DEFAULTS
1063 }
1064
1065 Tooltip.prototype.getOptions = function (options) {
1066 options = $.extend({}, this.getDefaults(), this.$element.data(), options)
1067
1068 if (options.delay && typeof options.delay == 'number') {
1069 options.delay = {
1070 show: options.delay,
1071 hide: options.delay
1072 }
1073 }
1074
1075 return options
1076 }
1077
1078 Tooltip.prototype.getDelegateOptions = function () {
1079 var options = {}
1080 var defaults = this.getDefaults()
1081
1082 this._options && $.each(this._options, function (key, value) {
1083 if (defaults[key] != value) options[key] = value
1084 })
1085
1086 return options
1087 }
1088
1089 Tooltip.prototype.enter = function (obj) {
1090 var self = obj instanceof this.constructor ?
1091 obj : $(obj.currentTarget).data('bs.' + this.type)
1092
1093 if (!self) {
1094 self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1095 $(obj.currentTarget).data('bs.' + this.type, self)
1096 }
1097
1098 if (obj instanceof $.Event) {
1099 self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
1100 }
1101
1102 if (self.tip().hasClass('in') || self.hoverState == 'in') {
1103 self.hoverState = 'in'
1104 return
1105 }
1106
1107 clearTimeout(self.timeout)
1108
1109 self.hoverState = 'in'
1110
1111 if (!self.options.delay || !self.options.delay.show) return self.show()
1112
1113 self.timeout = setTimeout(function () {
1114 if (self.hoverState == 'in') self.show()
1115 }, self.options.delay.show)
1116 }
1117
1118 Tooltip.prototype.isInStateTrue = function () {
1119 for (var key in this.inState) {
1120 if (this.inState[key]) return true
1121 }
1122
1123 return false
1124 }
1125
1126 Tooltip.prototype.leave = function (obj) {
1127 var self = obj instanceof this.constructor ?
1128 obj : $(obj.currentTarget).data('bs.' + this.type)
1129
1130 if (!self) {
1131 self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1132 $(obj.currentTarget).data('bs.' + this.type, self)
1133 }
1134
1135 if (obj instanceof $.Event) {
1136 self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
1137 }
1138
1139 if (self.isInStateTrue()) return
1140
1141 clearTimeout(self.timeout)
1142
1143 self.hoverState = 'out'
1144
1145 if (!self.options.delay || !self.options.delay.hide) return self.hide()
1146
1147 self.timeout = setTimeout(function () {
1148 if (self.hoverState == 'out') self.hide()
1149 }, self.options.delay.hide)
1150 }
1151
1152 Tooltip.prototype.show = function () {
1153 var e = $.Event('show.bs.' + this.type)
1154
1155 if (this.hasContent() && this.enabled) {
1156 this.$element.trigger(e)
1157
1158 var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
1159 if (e.isDefaultPrevented() || !inDom) return
1160 var that = this
1161
1162 var $tip = this.tip()
1163
1164 var tipId = this.getUID(this.type)
1165
1166 this.setContent()
1167 $tip.attr('id', tipId)
1168 this.$element.attr('aria-describedby', tipId)
1169
1170 if (this.options.animation) $tip.addClass('fade')
1171
1172 var placement = typeof this.options.placement == 'function' ?
1173 this.options.placement.call(this, $tip[0], this.$element[0]) :
1174 this.options.placement
1175
1176 var autoToken = /\s?auto?\s?/i
1177 var autoPlace = autoToken.test(placement)
1178 if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
1179
1180 $tip
1181 .detach()
1182 .css({ top: 0, left: 0, display: 'block' })
1183 .addClass(placement)
1184 .data('bs.' + this.type, this)
1185
1186 this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
1187 this.$element.trigger('inserted.bs.' + this.type)
1188
1189 var pos = this.getPosition()
1190 var actualWidth = $tip[0].offsetWidth
1191 var actualHeight = $tip[0].offsetHeight
1192
1193 if (autoPlace) {
1194 var orgPlacement = placement
1195 var viewportDim = this.getPosition(this.$viewport)
1196
1197 placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
1198 placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
1199 placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
1200 placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
1201 placement
1202
1203 $tip
1204 .removeClass(orgPlacement)
1205 .addClass(placement)
1206 }
1207
1208 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
1209
1210 this.applyPlacement(calculatedOffset, placement)
1211
1212 var complete = function () {
1213 var prevHoverState = that.hoverState
1214 that.$element.trigger('shown.bs.' + that.type)
1215 that.hoverState = null
1216
1217 if (prevHoverState == 'out') that.leave(that)
1218 }
1219
1220 $.support.transition && this.$tip.hasClass('fade') ?
1221 $tip
1222 .one('bsTransitionEnd', complete)
1223 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
1224 complete()
1225 }
1226 }
1227
1228 Tooltip.prototype.applyPlacement = function (offset, placement) {
1229 var $tip = this.tip()
1230 var width = $tip[0].offsetWidth
1231 var height = $tip[0].offsetHeight
1232
1233 // manually read margins because getBoundingClientRect includes difference
1234 var marginTop = parseInt($tip.css('margin-top'), 10)
1235 var marginLeft = parseInt($tip.css('margin-left'), 10)
1236
1237 // we must check for NaN for ie 8/9
1238 if (isNaN(marginTop)) marginTop = 0
1239 if (isNaN(marginLeft)) marginLeft = 0
1240
1241 offset.top += marginTop
1242 offset.left += marginLeft
1243
1244 // $.fn.offset doesn't round pixel values
1245 // so we use setOffset directly with our own function B-0
1246 $.offset.setOffset($tip[0], $.extend({
1247 using: function (props) {
1248 $tip.css({
1249 top: Math.round(props.top),
1250 left: Math.round(props.left)
1251 })
1252 }
1253 }, offset), 0)
1254
1255 $tip.addClass('in')
1256
1257 // check to see if placing tip in new offset caused the tip to resize itself
1258 var actualWidth = $tip[0].offsetWidth
1259 var actualHeight = $tip[0].offsetHeight
1260
1261 if (placement == 'top' && actualHeight != height) {
1262 offset.top = offset.top + height - actualHeight
1263 }
1264
1265 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
1266
1267 if (delta.left) offset.left += delta.left
1268 else offset.top += delta.top
1269
1270 var isVertical = /top|bottom/.test(placement)
1271 var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
1272 var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
1273
1274 $tip.offset(offset)
1275 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
1276 }
1277
1278 Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
1279 this.arrow()
1280 .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
1281 .css(isVertical ? 'top' : 'left', '')
1282 }
1283
1284 Tooltip.prototype.setContent = function () {
1285 var $tip = this.tip()
1286 var title = this.getTitle()
1287
1288 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1289 $tip.removeClass('fade in top bottom left right')
1290 }
1291
1292 Tooltip.prototype.hide = function (callback) {
1293 var that = this
1294 var $tip = $(this.$tip)
1295 var e = $.Event('hide.bs.' + this.type)
1296
1297 function complete() {
1298 if (that.hoverState != 'in') $tip.detach()
1299 that.$element
1300 .removeAttr('aria-describedby')
1301 .trigger('hidden.bs.' + that.type)
1302 callback && callback()
1303 }
1304
1305 this.$element.trigger(e)
1306
1307 if (e.isDefaultPrevented()) return
1308
1309 $tip.removeClass('in')
1310
1311 $.support.transition && $tip.hasClass('fade') ?
1312 $tip
1313 .one('bsTransitionEnd', complete)
1314 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
1315 complete()
1316
1317 this.hoverState = null
1318
1319 return this
1320 }
1321
1322 Tooltip.prototype.fixTitle = function () {
1323 var $e = this.$element
1324 if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
1325 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1326 }
1327 }
1328
1329 Tooltip.prototype.hasContent = function () {
1330 return this.getTitle()
1331 }
1332
1333 Tooltip.prototype.getPosition = function ($element) {
1334 $element = $element || this.$element
1335
1336 var el = $element[0]
1337 var isBody = el.tagName == 'BODY'
1338
1339 var elRect = el.getBoundingClientRect()
1340 if (elRect.width == null) {
1341 // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
1342 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
1343 }
1344 var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
1345 var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
1346 var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
1347
1348 return $.extend({}, elRect, scroll, outerDims, elOffset)
1349 }
1350
1351 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
1352 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1353 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1354 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
1355 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
1356
1357 }
1358
1359 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
1360 var delta = { top: 0, left: 0 }
1361 if (!this.$viewport) return delta
1362
1363 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
1364 var viewportDimensions = this.getPosition(this.$viewport)
1365
1366 if (/right|left/.test(placement)) {
1367 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
1368 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
1369 if (topEdgeOffset < viewportDimensions.top) { // top overflow
1370 delta.top = viewportDimensions.top - topEdgeOffset
1371 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
1372 delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
1373 }
1374 } else {
1375 var leftEdgeOffset = pos.left - viewportPadding
1376 var rightEdgeOffset = pos.left + viewportPadding + actualWidth
1377 if (leftEdgeOffset < viewportDimensions.left) { // left overflow
1378 delta.left = viewportDimensions.left - leftEdgeOffset
1379 } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
1380 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
1381 }
1382 }
1383
1384 return delta
1385 }
1386
1387 Tooltip.prototype.getTitle = function () {
1388 var title
1389 var $e = this.$element
1390 var o = this.options
1391
1392 title = $e.attr('data-original-title')
1393 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
1394
1395 return title
1396 }
1397
1398 Tooltip.prototype.getUID = function (prefix) {
1399 do prefix += ~~(Math.random() * 1000000)
1400 while (document.getElementById(prefix))
1401 return prefix
1402 }
1403
1404 Tooltip.prototype.tip = function () {
1405 if (!this.$tip) {
1406 this.$tip = $(this.options.template)
1407 if (this.$tip.length != 1) {
1408 throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
1409 }
1410 }
1411 return this.$tip
1412 }
1413
1414 Tooltip.prototype.arrow = function () {
1415 return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
1416 }
1417
1418 Tooltip.prototype.enable = function () {
1419 this.enabled = true
1420 }
1421
1422 Tooltip.prototype.disable = function () {
1423 this.enabled = false
1424 }
1425
1426 Tooltip.prototype.toggleEnabled = function () {
1427 this.enabled = !this.enabled
1428 }
1429
1430 Tooltip.prototype.toggle = function (e) {
1431 var self = this
1432 if (e) {
1433 self = $(e.currentTarget).data('bs.' + this.type)
1434 if (!self) {
1435 self = new this.constructor(e.currentTarget, this.getDelegateOptions())
1436 $(e.currentTarget).data('bs.' + this.type, self)
1437 }
1438 }
1439
1440 if (e) {
1441 self.inState.click = !self.inState.click
1442 if (self.isInStateTrue()) self.enter(self)
1443 else self.leave(self)
1444 } else {
1445 self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
1446 }
1447 }
1448
1449 Tooltip.prototype.destroy = function () {
1450 var that = this
1451 clearTimeout(this.timeout)
1452 this.hide(function () {
1453 that.$element.off('.' + that.type).removeData('bs.' + that.type)
1454 if (that.$tip) {
1455 that.$tip.detach()
1456 }
1457 that.$tip = null
1458 that.$arrow = null
1459 that.$viewport = null
1460 })
1461 }
1462
1463
1464 // TOOLTIP PLUGIN DEFINITION
1465 // =========================
1466
1467 function Plugin(option) {
1468 return this.each(function () {
1469 var $this = $(this)
1470 var data = $this.data('bs.tooltip')
1471 var options = typeof option == 'object' && option
1472
1473 if (!data && /destroy|hide/.test(option)) return
1474 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
1475 if (typeof option == 'string') data[option]()
1476 })
1477 }
1478
1479 var old = $.fn.tooltip
1480
1481 $.fn.tooltip = Plugin
1482 $.fn.tooltip.Constructor = Tooltip
1483
1484
1485 // TOOLTIP NO CONFLICT
1486 // ===================
1487
1488 $.fn.tooltip.noConflict = function () {
1489 $.fn.tooltip = old
1490 return this
1491 }
1492
1493 }(jQuery);
1494
1495 /* ========================================================================
1496 * Bootstrap: popover.js v3.3.5
1497 * http://getbootstrap.com/javascript/#popovers
1498 * ========================================================================
1499 * Copyright 2011-2015 Twitter, Inc.
1500 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1501 * ======================================================================== */
1502
1503
1504 +function ($) {
1505 'use strict';
1506
1507 // POPOVER PUBLIC CLASS DEFINITION
1508 // ===============================
1509
1510 var Popover = function (element, options) {
1511 this.init('popover', element, options)
1512 }
1513
1514 if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1515
1516 Popover.VERSION = '3.3.5'
1517
1518 Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
1519 placement: 'right',
1520 trigger: 'click',
1521 content: '',
1522 template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1523 })
1524
1525
1526 // NOTE: POPOVER EXTENDS tooltip.js
1527 // ================================
1528
1529 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
1530
1531 Popover.prototype.constructor = Popover
1532
1533 Popover.prototype.getDefaults = function () {
1534 return Popover.DEFAULTS
1535 }
1536
1537 Popover.prototype.setContent = function () {
1538 var $tip = this.tip()
1539 var title = this.getTitle()
1540 var content = this.getContent()
1541
1542 $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1543 $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
1544 this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
1545 ](content)
1546
1547 $tip.removeClass('fade top bottom left right in')
1548
1549 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
1550 // this manually by checking the contents.
1551 if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
1552 }
1553
1554 Popover.prototype.hasContent = function () {
1555 return this.getTitle() || this.getContent()
1556 }
1557
1558 Popover.prototype.getContent = function () {
1559 var $e = this.$element
1560 var o = this.options
1561
1562 return $e.attr('data-content')
1563 || (typeof o.content == 'function' ?
1564 o.content.call($e[0]) :
1565 o.content)
1566 }
1567
1568 Popover.prototype.arrow = function () {
1569 return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
1570 }
1571
1572
1573 // POPOVER PLUGIN DEFINITION
1574 // =========================
1575
1576 function Plugin(option) {
1577 return this.each(function () {
1578 var $this = $(this)
1579 var data = $this.data('bs.popover')
1580 var options = typeof option == 'object' && option
1581
1582 if (!data && /destroy|hide/.test(option)) return
1583 if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
1584 if (typeof option == 'string') data[option]()
1585 })
1586 }
1587
1588 var old = $.fn.popover
1589
1590 $.fn.popover = Plugin
1591 $.fn.popover.Constructor = Popover
1592
1593
1594 // POPOVER NO CONFLICT
1595 // ===================
1596
1597 $.fn.popover.noConflict = function () {
1598 $.fn.popover = old
1599 return this
1600 }
1601
1602 }(jQuery);
1603
1604 /* ========================================================================
1605 * Bootstrap: tab.js v3.3.5
1606 * http://getbootstrap.com/javascript/#tabs
1607 * ========================================================================
1608 * Copyright 2011-2015 Twitter, Inc.
1609 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1610 * ======================================================================== */
1611
1612
1613 +function ($) {
1614 'use strict';
1615
1616 // TAB CLASS DEFINITION
1617 // ====================
1618
1619 var Tab = function (element) {
1620 // jscs:disable requireDollarBeforejQueryAssignment
1621 this.element = $(element)
1622 // jscs:enable requireDollarBeforejQueryAssignment
1623 }
1624
1625 Tab.VERSION = '3.3.5'
1626
1627 Tab.TRANSITION_DURATION = 150
1628
1629 Tab.prototype.show = function () {
1630 var $this = this.element
1631 var $ul = $this.closest('ul:not(.dropdown-menu)')
1632 var selector = $this.data('target')
1633
1634 if (!selector) {
1635 selector = $this.attr('href')
1636 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
1637 }
1638
1639 if ($this.parent('li').hasClass('active')) return
1640
1641 var $previous = $ul.find('.active:last a')
1642 var hideEvent = $.Event('hide.bs.tab', {
1643 relatedTarget: $this[0]
1644 })
1645 var showEvent = $.Event('show.bs.tab', {
1646 relatedTarget: $previous[0]
1647 })
1648
1649 $previous.trigger(hideEvent)
1650 $this.trigger(showEvent)
1651
1652 if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
1653
1654 var $target = $(selector)
1655
1656 this.activate($this.closest('li'), $ul)
1657 this.activate($target, $target.parent(), function () {
1658 $previous.trigger({
1659 type: 'hidden.bs.tab',
1660 relatedTarget: $this[0]
1661 })
1662 $this.trigger({
1663 type: 'shown.bs.tab',
1664 relatedTarget: $previous[0]
1665 })
1666 })
1667 }
1668
1669 Tab.prototype.activate = function (element, container, callback) {
1670 var $active = container.find('> .active')
1671 var transition = callback
1672 && $.support.transition
1673 && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
1674
1675 function next() {
1676 $active
1677 .removeClass('active')
1678 .find('> .dropdown-menu > .active')
1679 .removeClass('active')
1680 .end()
1681 .find('[data-toggle="tab"]')
1682 .attr('aria-expanded', false)
1683
1684 element
1685 .addClass('active')
1686 .find('[data-toggle="tab"]')
1687 .attr('aria-expanded', true)
1688
1689 if (transition) {
1690 element[0].offsetWidth // reflow for transition
1691 element.addClass('in')
1692 } else {
1693 element.removeClass('fade')
1694 }
1695
1696 if (element.parent('.dropdown-menu').length) {
1697 element
1698 .closest('li.dropdown')
1699 .addClass('active')
1700 .end()
1701 .find('[data-toggle="tab"]')
1702 .attr('aria-expanded', true)
1703 }
1704
1705 callback && callback()
1706 }
1707
1708 $active.length && transition ?
1709 $active
1710 .one('bsTransitionEnd', next)
1711 .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
1712 next()
1713
1714 $active.removeClass('in')
1715 }
1716
1717
1718 // TAB PLUGIN DEFINITION
1719 // =====================
1720
1721 function Plugin(option) {
1722 return this.each(function () {
1723 var $this = $(this)
1724 var data = $this.data('bs.tab')
1725
1726 if (!data) $this.data('bs.tab', (data = new Tab(this)))
1727 if (typeof option == 'string') data[option]()
1728 })
1729 }
1730
1731 var old = $.fn.tab
1732
1733 $.fn.tab = Plugin
1734 $.fn.tab.Constructor = Tab
1735
1736
1737 // TAB NO CONFLICT
1738 // ===============
1739
1740 $.fn.tab.noConflict = function () {
1741 $.fn.tab = old
1742 return this
1743 }
1744
1745
1746 // TAB DATA-API
1747 // ============
1748
1749 var clickHandler = function (e) {
1750 e.preventDefault()
1751 Plugin.call($(this), 'show')
1752 }
1753
1754 $(document)
1755 .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
1756 .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
1757
1758 }(jQuery);
1759
1760 /* ========================================================================
1761 * Bootstrap: affix.js v3.3.5
1762 * http://getbootstrap.com/javascript/#affix
1763 * ========================================================================
1764 * Copyright 2011-2015 Twitter, Inc.
1765 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1766 * ======================================================================== */
1767
1768
1769 +function ($) {
1770 'use strict';
1771
1772 // AFFIX CLASS DEFINITION
1773 // ======================
1774
1775 var Affix = function (element, options) {
1776 this.options = $.extend({}, Affix.DEFAULTS, options)
1777
1778 this.$target = $(this.options.target)
1779 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
1780 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
1781
1782 this.$element = $(element)
1783 this.affixed = null
1784 this.unpin = null
1785 this.pinnedOffset = null
1786
1787 this.checkPosition()
1788 }
1789
1790 Affix.VERSION = '3.3.5'
1791
1792 Affix.RESET = 'affix affix-top affix-bottom'
1793
1794 Affix.DEFAULTS = {
1795 offset: 0,
1796 target: window
1797 }
1798
1799 Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
1800 var scrollTop = this.$target.scrollTop()
1801 var position = this.$element.offset()
1802 var targetHeight = this.$target.height()
1803
1804 if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
1805
1806 if (this.affixed == 'bottom') {
1807 if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
1808 return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
1809 }
1810
1811 var initializing = this.affixed == null
1812 var colliderTop = initializing ? scrollTop : position.top
1813 var colliderHeight = initializing ? targetHeight : height
1814
1815 if (offsetTop != null && scrollTop <= offsetTop) return 'top'
1816 if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
1817
1818 return false
1819 }
1820
1821 Affix.prototype.getPinnedOffset = function () {
1822 if (this.pinnedOffset) return this.pinnedOffset
1823 this.$element.removeClass(Affix.RESET).addClass('affix')
1824 var scrollTop = this.$target.scrollTop()
1825 var position = this.$element.offset()
1826 return (this.pinnedOffset = position.top - scrollTop)
1827 }
1828
1829 Affix.prototype.checkPositionWithEventLoop = function () {
1830 setTimeout($.proxy(this.checkPosition, this), 1)
1831 }
1832
1833 Affix.prototype.checkPosition = function () {
1834 if (!this.$element.is(':visible')) return
1835
1836 var height = this.$element.height()
1837 var offset = this.options.offset
1838 var offsetTop = offset.top
1839 var offsetBottom = offset.bottom
1840 var scrollHeight = Math.max($(document).height(), $(document.body).height())
1841
1842 if (typeof offset != 'object') offsetBottom = offsetTop = offset
1843 if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
1844 if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
1845
1846 var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
1847
1848 if (this.affixed != affix) {
1849 if (this.unpin != null) this.$element.css('top', '')
1850
1851 var affixType = 'affix' + (affix ? '-' + affix : '')
1852 var e = $.Event(affixType + '.bs.affix')
1853
1854 this.$element.trigger(e)
1855
1856 if (e.isDefaultPrevented()) return
1857
1858 this.affixed = affix
1859 this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
1860
1861 this.$element
1862 .removeClass(Affix.RESET)
1863 .addClass(affixType)
1864 .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
1865 }
1866
1867 if (affix == 'bottom') {
1868 this.$element.offset({
1869 top: scrollHeight - height - offsetBottom
1870 })
1871 }
1872 }
1873
1874
1875 // AFFIX PLUGIN DEFINITION
1876 // =======================
1877
1878 function Plugin(option) {
1879 return this.each(function () {
1880 var $this = $(this)
1881 var data = $this.data('bs.affix')
1882 var options = typeof option == 'object' && option
1883
1884 if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
1885 if (typeof option == 'string') data[option]()
1886 })
1887 }
1888
1889 var old = $.fn.affix
1890
1891 $.fn.affix = Plugin
1892 $.fn.affix.Constructor = Affix
1893
1894
1895 // AFFIX NO CONFLICT
1896 // =================
1897
1898 $.fn.affix.noConflict = function () {
1899 $.fn.affix = old
1900 return this
1901 }
1902
1903
1904 // AFFIX DATA-API
1905 // ==============
1906
1907 $(window).on('load', function () {
1908 $('[data-spy="affix"]').each(function () {
1909 var $spy = $(this)
1910 var data = $spy.data()
1911
1912 data.offset = data.offset || {}
1913
1914 if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
1915 if (data.offsetTop != null) data.offset.top = data.offsetTop
1916
1917 Plugin.call($spy, data)
1918 })
1919 })
1920
1921 }(jQuery);
1922
1923 /* ========================================================================
1924 * Bootstrap: collapse.js v3.3.5
1925 * http://getbootstrap.com/javascript/#collapse
1926 * ========================================================================
1927 * Copyright 2011-2015 Twitter, Inc.
1928 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1929 * ======================================================================== */
1930
1931
1932 +function ($) {
1933 'use strict';
1934
1935 // COLLAPSE PUBLIC CLASS DEFINITION
1936 // ================================
1937
1938 var Collapse = function (element, options) {
1939 this.$element = $(element)
1940 this.options = $.extend({}, Collapse.DEFAULTS, options)
1941 this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
1942 '[data-toggle="collapse"][data-target="#' + element.id + '"]')
1943 this.transitioning = null
1944
1945 if (this.options.parent) {
1946 this.$parent = this.getParent()
1947 } else {
1948 this.addAriaAndCollapsedClass(this.$element, this.$trigger)
1949 }
1950
1951 if (this.options.toggle) this.toggle()
1952 }
1953
1954 Collapse.VERSION = '3.3.5'
1955
1956 Collapse.TRANSITION_DURATION = 350
1957
1958 Collapse.DEFAULTS = {
1959 toggle: true
1960 }
1961
1962 Collapse.prototype.dimension = function () {
1963 var hasWidth = this.$element.hasClass('width')
1964 return hasWidth ? 'width' : 'height'
1965 }
1966
1967 Collapse.prototype.show = function () {
1968 if (this.transitioning || this.$element.hasClass('in')) return
1969
1970 var activesData
1971 var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
1972
1973 if (actives && actives.length) {
1974 activesData = actives.data('bs.collapse')
1975 if (activesData && activesData.transitioning) return
1976 }
1977
1978 var startEvent = $.Event('show.bs.collapse')
1979 this.$element.trigger(startEvent)
1980 if (startEvent.isDefaultPrevented()) return
1981
1982 if (actives && actives.length) {
1983 Plugin.call(actives, 'hide')
1984 activesData || actives.data('bs.collapse', null)
1985 }
1986
1987 var dimension = this.dimension()
1988
1989 this.$element
1990 .removeClass('collapse')
1991 .addClass('collapsing')[dimension](0)
1992 .attr('aria-expanded', true)
1993
1994 this.$trigger
1995 .removeClass('collapsed')
1996 .attr('aria-expanded', true)
1997
1998 this.transitioning = 1
1999
2000 var complete = function () {
2001 this.$element
2002 .removeClass('collapsing')
2003 .addClass('collapse in')[dimension]('')
2004 this.transitioning = 0
2005 this.$element
2006 .trigger('shown.bs.collapse')
2007 }
2008
2009 if (!$.support.transition) return complete.call(this)
2010
2011 var scrollSize = $.camelCase(['scroll', dimension].join('-'))
2012
2013 this.$element
2014 .one('bsTransitionEnd', $.proxy(complete, this))
2015 .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
2016 }
2017
2018 Collapse.prototype.hide = function () {
2019 if (this.transitioning || !this.$element.hasClass('in')) return
2020
2021 var startEvent = $.Event('hide.bs.collapse')
2022 this.$element.trigger(startEvent)
2023 if (startEvent.isDefaultPrevented()) return
2024
2025 var dimension = this.dimension()
2026
2027 this.$element[dimension](this.$element[dimension]())[0].offsetHeight
2028
2029 this.$element
2030 .addClass('collapsing')
2031 .removeClass('collapse in')
2032 .attr('aria-expanded', false)
2033
2034 this.$trigger
2035 .addClass('collapsed')
2036 .attr('aria-expanded', false)
2037
2038 this.transitioning = 1
2039
2040 var complete = function () {
2041 this.transitioning = 0
2042 this.$element
2043 .removeClass('collapsing')
2044 .addClass('collapse')
2045 .trigger('hidden.bs.collapse')
2046 }
2047
2048 if (!$.support.transition) return complete.call(this)
2049
2050 this.$element
2051 [dimension](0)
2052 .one('bsTransitionEnd', $.proxy(complete, this))
2053 .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
2054 }
2055
2056 Collapse.prototype.toggle = function () {
2057 this[this.$element.hasClass('in') ? 'hide' : 'show']()
2058 }
2059
2060 Collapse.prototype.getParent = function () {
2061 return $(this.options.parent)
2062 .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
2063 .each($.proxy(function (i, element) {
2064 var $element = $(element)
2065 this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
2066 }, this))
2067 .end()
2068 }
2069
2070 Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
2071 var isOpen = $element.hasClass('in')
2072
2073 $element.attr('aria-expanded', isOpen)
2074 $trigger
2075 .toggleClass('collapsed', !isOpen)
2076 .attr('aria-expanded', isOpen)
2077 }
2078
2079 function getTargetFromTrigger($trigger) {
2080 var href
2081 var target = $trigger.attr('data-target')
2082 || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
2083
2084 return $(target)
2085 }
2086
2087
2088 // COLLAPSE PLUGIN DEFINITION
2089 // ==========================
2090
2091 function Plugin(option) {
2092 return this.each(function () {
2093 var $this = $(this)
2094 var data = $this.data('bs.collapse')
2095 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
2096
2097 if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
2098 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
2099 if (typeof option == 'string') data[option]()
2100 })
2101 }
2102
2103 var old = $.fn.collapse
2104
2105 $.fn.collapse = Plugin
2106 $.fn.collapse.Constructor = Collapse
2107
2108
2109 // COLLAPSE NO CONFLICT
2110 // ====================
2111
2112 $.fn.collapse.noConflict = function () {
2113 $.fn.collapse = old
2114 return this
2115 }
2116
2117
2118 // COLLAPSE DATA-API
2119 // =================
2120
2121 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
2122 var $this = $(this)
2123
2124 if (!$this.attr('data-target')) e.preventDefault()
2125
2126 var $target = getTargetFromTrigger($this)
2127 var data = $target.data('bs.collapse')
2128 var option = data ? 'toggle' : $this.data()
2129
2130 Plugin.call($target, option)
2131 })
2132
2133 }(jQuery);
2134
2135 /* ========================================================================
2136 * Bootstrap: scrollspy.js v3.3.5
2137 * http://getbootstrap.com/javascript/#scrollspy
2138 * ========================================================================
2139 * Copyright 2011-2015 Twitter, Inc.
2140 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2141 * ======================================================================== */
2142
2143
2144 +function ($) {
2145 'use strict';
2146
2147 // SCROLLSPY CLASS DEFINITION
2148 // ==========================
2149
2150 function ScrollSpy(element, options) {
2151 this.$body = $(document.body)
2152 this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
2153 this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
2154 this.selector = (this.options.target || '') + ' .nav li > a'
2155 this.offsets = []
2156 this.targets = []
2157 this.activeTarget = null
2158 this.scrollHeight = 0
2159
2160 this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
2161 this.refresh()
2162 this.process()
2163 }
2164
2165 ScrollSpy.VERSION = '3.3.5'
2166
2167 ScrollSpy.DEFAULTS = {
2168 offset: 10
2169 }
2170
2171 ScrollSpy.prototype.getScrollHeight = function () {
2172 return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
2173 }
2174
2175 ScrollSpy.prototype.refresh = function () {
2176 var that = this
2177 var offsetMethod = 'offset'
2178 var offsetBase = 0
2179
2180 this.offsets = []
2181 this.targets = []
2182 this.scrollHeight = this.getScrollHeight()
2183
2184 if (!$.isWindow(this.$scrollElement[0])) {
2185 offsetMethod = 'position'
2186 offsetBase = this.$scrollElement.scrollTop()
2187 }
2188
2189 this.$body
2190 .find(this.selector)
2191 .map(function () {
2192 var $el = $(this)
2193 var href = $el.data('target') || $el.attr('href')
2194 var $href = /^#./.test(href) && $(href)
2195
2196 return ($href
2197 && $href.length
2198 && $href.is(':visible')
2199 && [[$href[offsetMethod]().top + offsetBase, href]]) || null
2200 })
2201 .sort(function (a, b) { return a[0] - b[0] })
2202 .each(function () {
2203 that.offsets.push(this[0])
2204 that.targets.push(this[1])
2205 })
2206 }
2207
2208 ScrollSpy.prototype.process = function () {
2209 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
2210 var scrollHeight = this.getScrollHeight()
2211 var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
2212 var offsets = this.offsets
2213 var targets = this.targets
2214 var activeTarget = this.activeTarget
2215 var i
2216
2217 if (this.scrollHeight != scrollHeight) {
2218 this.refresh()
2219 }
2220
2221 if (scrollTop >= maxScroll) {
2222 return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
2223 }
2224
2225 if (activeTarget && scrollTop < offsets[0]) {
2226 this.activeTarget = null
2227 return this.clear()
2228 }
2229
2230 for (i = offsets.length; i--;) {
2231 activeTarget != targets[i]
2232 && scrollTop >= offsets[i]
2233 && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
2234 && this.activate(targets[i])
2235 }
2236 }
2237
2238 ScrollSpy.prototype.activate = function (target) {
2239 this.activeTarget = target
2240
2241 this.clear()
2242
2243 var selector = this.selector +
2244 '[data-target="' + target + '"],' +
2245 this.selector + '[href="' + target + '"]'
2246
2247 var active = $(selector)
2248 .parents('li')
2249 .addClass('active')
2250
2251 if (active.parent('.dropdown-menu').length) {
2252 active = active
2253 .closest('li.dropdown')
2254 .addClass('active')
2255 }
2256
2257 active.trigger('activate.bs.scrollspy')
2258 }
2259
2260 ScrollSpy.prototype.clear = function () {
2261 $(this.selector)
2262 .parentsUntil(this.options.target, '.active')
2263 .removeClass('active')
2264 }
2265
2266
2267 // SCROLLSPY PLUGIN DEFINITION
2268 // ===========================
2269
2270 function Plugin(option) {
2271 return this.each(function () {
2272 var $this = $(this)
2273 var data = $this.data('bs.scrollspy')
2274 var options = typeof option == 'object' && option
2275
2276 if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
2277 if (typeof option == 'string') data[option]()
2278 })
2279 }
2280
2281 var old = $.fn.scrollspy
2282
2283 $.fn.scrollspy = Plugin
2284 $.fn.scrollspy.Constructor = ScrollSpy
2285
2286
2287 // SCROLLSPY NO CONFLICT
2288 // =====================
2289
2290 $.fn.scrollspy.noConflict = function () {
2291 $.fn.scrollspy = old
2292 return this
2293 }
2294
2295
2296 // SCROLLSPY DATA-API
2297 // ==================
2298
2299 $(window).on('load.bs.scrollspy.data-api', function () {
2300 $('[data-spy="scroll"]').each(function () {
2301 var $spy = $(this)
2302 Plugin.call($spy, $spy.data())
2303 })
2304 })
2305
2306 }(jQuery);
2307
2308 /* ========================================================================
2309 * Bootstrap: transition.js v3.3.5
2310 * http://getbootstrap.com/javascript/#transitions
2311 * ========================================================================
2312 * Copyright 2011-2015 Twitter, Inc.
2313 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2314 * ======================================================================== */
2315
2316
2317 +function ($) {
2318 'use strict';
2319
2320 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
2321 // ============================================================
2322
2323 function transitionEnd() {
2324 var el = document.createElement('bootstrap')
2325
2326 var transEndEventNames = {
2327 WebkitTransition : 'webkitTransitionEnd',
2328 MozTransition : 'transitionend',
2329 OTransition : 'oTransitionEnd otransitionend',
2330 transition : 'transitionend'
2331 }
2332
2333 for (var name in transEndEventNames) {
2334 if (el.style[name] !== undefined) {
2335 return { end: transEndEventNames[name] }
2336 }
2337 }
2338
2339 return false // explicit for ie8 ( ._.)
2340 }
2341
2342 // http://blog.alexmaccaw.com/css-transitions
2343 $.fn.emulateTransitionEnd = function (duration) {
2344 var called = false
2345 var $el = this
2346 $(this).one('bsTransitionEnd', function () { called = true })
2347 var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
2348 setTimeout(callback, duration)
2349 return this
2350 }
2351
2352 $(function () {
2353 $.support.transition = transitionEnd()
2354
2355 if (!$.support.transition) return
2356
2357 $.event.special.bsTransitionEnd = {
2358 bindType: $.support.transition.end,
2359 delegateType: $.support.transition.end,
2360 handle: function (e) {
2361 if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
2362 }
2363 }
2364 })
2365
2366 }(jQuery);
2367