shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

bootstrap.js (71253B)


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