PageSourceSearch

https://www.pep.com.cn/images/bootstrap.js

js pep.com.cn collected 2026-10-02 03:56:20 UTC 76,929 bytes, 2,520 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.