bootstrap.js 60 KB
Newer Older
1
/*!
Mark Otto's avatar
Mark Otto committed
2
 * Bootstrap v3.2.0 (http://getbootstrap.com)
3
 * Copyright 2011-2014 Twitter, Inc.
Mark Otto's avatar
Mark Otto committed
4
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
Chris Rebert's avatar
Chris Rebert committed
5
 */
6

7
if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') }
8

9
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
10
 * Bootstrap: transition.js v3.2.0
Mark Otto's avatar
Mark Otto committed
11
 * http://getbootstrap.com/javascript/#transitions
12
 * ========================================================================
13
 * Copyright 2011-2014 Twitter, Inc.
14
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15
 * ======================================================================== */
16
17


XhmikosR's avatar
XhmikosR committed
18
19
+function ($) {
  'use strict';
Mark Otto's avatar
grunt    
Mark Otto committed
20

XhmikosR's avatar
XhmikosR committed
21
22
  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  // ============================================================
23

XhmikosR's avatar
XhmikosR committed
24
25
  function transitionEnd() {
    var el = document.createElement('bootstrap')
26

XhmikosR's avatar
XhmikosR committed
27
28
29
30
31
32
    var transEndEventNames = {
      WebkitTransition : 'webkitTransitionEnd',
      MozTransition    : 'transitionend',
      OTransition      : 'oTransitionEnd otransitionend',
      transition       : 'transitionend'
    }
33

XhmikosR's avatar
XhmikosR committed
34
35
36
    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return { end: transEndEventNames[name] }
37
      }
Chris Rebert's avatar
Chris Rebert committed
38
39
    }

XhmikosR's avatar
XhmikosR committed
40
41
    return false // explicit for ie8 (  ._.)
  }
42

XhmikosR's avatar
XhmikosR committed
43
44
45
46
47
48
49
50
51
  // http://blog.alexmaccaw.com/css-transitions
  $.fn.emulateTransitionEnd = function (duration) {
    var called = false
    var $el = this
    $(this).one('bsTransitionEnd', function () { called = true })
    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
    setTimeout(callback, duration)
    return this
  }
52

XhmikosR's avatar
XhmikosR committed
53
54
  $(function () {
    $.support.transition = transitionEnd()
Chris Rebert's avatar
Chris Rebert committed
55

XhmikosR's avatar
XhmikosR committed
56
    if (!$.support.transition) return
57

XhmikosR's avatar
XhmikosR committed
58
59
60
61
62
63
64
    $.event.special.bsTransitionEnd = {
      bindType: $.support.transition.end,
      delegateType: $.support.transition.end,
      handle: function (e) {
        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
      }
    }
fat's avatar
fat committed
65
  })
66

XhmikosR's avatar
XhmikosR committed
67
}(jQuery);
68

69
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
70
 * Bootstrap: alert.js v3.2.0
Mark Otto's avatar
Mark Otto committed
71
 * http://getbootstrap.com/javascript/#alerts
72
 * ========================================================================
73
 * Copyright 2011-2014 Twitter, Inc.
74
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
75
 * ======================================================================== */
76
77


XhmikosR's avatar
XhmikosR committed
78
79
+function ($) {
  'use strict';
80

XhmikosR's avatar
XhmikosR committed
81
82
  // ALERT CLASS DEFINITION
  // ======================
83

XhmikosR's avatar
XhmikosR committed
84
85
86
87
  var dismiss = '[data-dismiss="alert"]'
  var Alert   = function (el) {
    $(el).on('click', dismiss, this.close)
  }
Mark Otto's avatar
grunt    
Mark Otto committed
88

Mark Otto's avatar
Mark Otto committed
89
  Alert.VERSION = '3.2.0'
90

XhmikosR's avatar
XhmikosR committed
91
92
93
  Alert.prototype.close = function (e) {
    var $this    = $(this)
    var selector = $this.attr('data-target')
94

XhmikosR's avatar
XhmikosR committed
95
96
97
98
    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }
99

XhmikosR's avatar
XhmikosR committed
100
    var $parent = $(selector)
101

XhmikosR's avatar
XhmikosR committed
102
    if (e) e.preventDefault()
103

XhmikosR's avatar
XhmikosR committed
104
105
106
    if (!$parent.length) {
      $parent = $this.hasClass('alert') ? $this : $this.parent()
    }
107

XhmikosR's avatar
XhmikosR committed
108
    $parent.trigger(e = $.Event('close.bs.alert'))
Chris Rebert's avatar
Chris Rebert committed
109

XhmikosR's avatar
XhmikosR committed
110
    if (e.isDefaultPrevented()) return
111

XhmikosR's avatar
XhmikosR committed
112
    $parent.removeClass('in')
113

XhmikosR's avatar
XhmikosR committed
114
115
116
    function removeElement() {
      // detach from parent, fire event then clean up data
      $parent.detach().trigger('closed.bs.alert').remove()
117
118
    }

XhmikosR's avatar
XhmikosR committed
119
120
121
122
123
124
    $.support.transition && $parent.hasClass('fade') ?
      $parent
        .one('bsTransitionEnd', removeElement)
        .emulateTransitionEnd(150) :
      removeElement()
  }
125
126


XhmikosR's avatar
XhmikosR committed
127
128
  // ALERT PLUGIN DEFINITION
  // =======================
129

XhmikosR's avatar
XhmikosR committed
130
131
132
133
  function Plugin(option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.alert')
fat's avatar
fat committed
134

XhmikosR's avatar
XhmikosR committed
135
136
137
138
      if (!data) $this.data('bs.alert', (data = new Alert(this)))
      if (typeof option == 'string') data[option].call($this)
    })
  }
139

XhmikosR's avatar
XhmikosR committed
140
  var old = $.fn.alert
Mark Otto's avatar
Mark Otto committed
141

XhmikosR's avatar
XhmikosR committed
142
143
  $.fn.alert             = Plugin
  $.fn.alert.Constructor = Alert
144
145


XhmikosR's avatar
XhmikosR committed
146
147
  // ALERT NO CONFLICT
  // =================
148

XhmikosR's avatar
XhmikosR committed
149
150
151
152
  $.fn.alert.noConflict = function () {
    $.fn.alert = old
    return this
  }
153
154


XhmikosR's avatar
XhmikosR committed
155
156
  // ALERT DATA-API
  // ==============
157

XhmikosR's avatar
XhmikosR committed
158
  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
159

XhmikosR's avatar
XhmikosR committed
160
}(jQuery);
161

162
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
163
 * Bootstrap: button.js v3.2.0
Mark Otto's avatar
Mark Otto committed
164
 * http://getbootstrap.com/javascript/#buttons
165
 * ========================================================================
166
 * Copyright 2011-2014 Twitter, Inc.
167
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
168
 * ======================================================================== */
169
170


XhmikosR's avatar
XhmikosR committed
171
172
+function ($) {
  'use strict';
fat's avatar
fat committed
173

XhmikosR's avatar
XhmikosR committed
174
175
  // BUTTON PUBLIC CLASS DEFINITION
  // ==============================
Mark Otto's avatar
grunt    
Mark Otto committed
176

XhmikosR's avatar
XhmikosR committed
177
178
179
180
181
  var Button = function (element, options) {
    this.$element  = $(element)
    this.options   = $.extend({}, Button.DEFAULTS, options)
    this.isLoading = false
  }
182

Mark Otto's avatar
Mark Otto committed
183
  Button.VERSION  = '3.2.0'
184

XhmikosR's avatar
XhmikosR committed
185
186
187
  Button.DEFAULTS = {
    loadingText: 'loading...'
  }
fat's avatar
fat committed
188

XhmikosR's avatar
XhmikosR committed
189
190
191
192
193
  Button.prototype.setState = function (state) {
    var d    = 'disabled'
    var $el  = this.$element
    var val  = $el.is('input') ? 'val' : 'html'
    var data = $el.data()
194

XhmikosR's avatar
XhmikosR committed
195
    state = state + 'Text'
196

XhmikosR's avatar
XhmikosR committed
197
    if (data.resetText == null) $el.data('resetText', $el[val]())
Chris Rebert's avatar
Chris Rebert committed
198

XhmikosR's avatar
XhmikosR committed
199
    $el[val](data[state] == null ? this.options[state] : data[state])
Chris Rebert's avatar
Chris Rebert committed
200

XhmikosR's avatar
XhmikosR committed
201
202
203
204
205
206
207
208
    // push to event loop to allow forms to submit
    setTimeout($.proxy(function () {
      if (state == 'loadingText') {
        this.isLoading = true
        $el.addClass(d).attr(d, d)
      } else if (this.isLoading) {
        this.isLoading = false
        $el.removeClass(d).removeAttr(d)
209
      }
XhmikosR's avatar
XhmikosR committed
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    }, this), 0)
  }

  Button.prototype.toggle = function () {
    var changed = true
    var $parent = this.$element.closest('[data-toggle="buttons"]')

    if ($parent.length) {
      var $input = this.$element.find('input')
      if ($input.prop('type') == 'radio') {
        if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
        else $parent.find('.active').removeClass('active')
      }
      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
fat's avatar
fat committed
224
    }
225

XhmikosR's avatar
XhmikosR committed
226
227
    if (changed) this.$element.toggleClass('active')
  }
228
229


XhmikosR's avatar
XhmikosR committed
230
231
  // BUTTON PLUGIN DEFINITION
  // ========================
232

XhmikosR's avatar
XhmikosR committed
233
234
235
236
237
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.button')
      var options = typeof option == 'object' && option
fat's avatar
fat committed
238

XhmikosR's avatar
XhmikosR committed
239
      if (!data) $this.data('bs.button', (data = new Button(this, options)))
fat's avatar
fat committed
240

XhmikosR's avatar
XhmikosR committed
241
242
243
244
      if (option == 'toggle') data.toggle()
      else if (option) data.setState(option)
    })
  }
245

XhmikosR's avatar
XhmikosR committed
246
  var old = $.fn.button
Mark Otto's avatar
Mark Otto committed
247

XhmikosR's avatar
XhmikosR committed
248
249
  $.fn.button             = Plugin
  $.fn.button.Constructor = Button
250
251


XhmikosR's avatar
XhmikosR committed
252
253
  // BUTTON NO CONFLICT
  // ==================
254

XhmikosR's avatar
XhmikosR committed
255
256
257
258
  $.fn.button.noConflict = function () {
    $.fn.button = old
    return this
  }
259
260


Mark Otto's avatar
grunt    
Mark Otto committed
261
262
263
264
265
266
267
268
269
  // FOCUS SHIM (FOR BUTTON GROUPS)
  // ==============================

  function getBtnTarget(target) {
    var $target = $(target)
    return $target.hasClass('btn') ? $target : $target.parent('.btn')
  }


XhmikosR's avatar
XhmikosR committed
270
271
  // BUTTON DATA-API
  // ===============
272

Mark Otto's avatar
grunt    
Mark Otto committed
273
274
275
276
277
278
279
280
281
282
283
284
285
  $(document)
    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
      var $btn = $(e.target)
      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
      Plugin.call($btn, 'toggle')
      e.preventDefault()
    })
    .on('focus.bs.button.data-api', '[data-toggle^="button"]', function (e) {
      getBtnTarget(e.target).addClass('focus')
    })
    .on('blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
      getBtnTarget(e.target).removeClass('focus')
    })
286

XhmikosR's avatar
XhmikosR committed
287
}(jQuery);
288

289
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
290
 * Bootstrap: carousel.js v3.2.0
Mark Otto's avatar
Mark Otto committed
291
 * http://getbootstrap.com/javascript/#carousel
292
 * ========================================================================
293
 * Copyright 2011-2014 Twitter, Inc.
294
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
295
 * ======================================================================== */
296
297


XhmikosR's avatar
XhmikosR committed
298
299
+function ($) {
  'use strict';
300

XhmikosR's avatar
XhmikosR committed
301
302
  // CAROUSEL CLASS DEFINITION
  // =========================
303

XhmikosR's avatar
XhmikosR committed
304
305
306
307
308
309
310
311
312
  var Carousel = function (element, options) {
    this.$element    = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
    this.$indicators = this.$element.find('.carousel-indicators')
    this.options     = options
    this.paused      =
    this.sliding     =
    this.interval    =
    this.$active     =
    this.$items      = null
fat's avatar
fat committed
313

XhmikosR's avatar
XhmikosR committed
314
315
316
317
    this.options.pause == 'hover' && this.$element
      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
  }
318

Mark Otto's avatar
Mark Otto committed
319
  Carousel.VERSION  = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
320

XhmikosR's avatar
XhmikosR committed
321
322
323
324
325
  Carousel.DEFAULTS = {
    interval: 5000,
    pause: 'hover',
    wrap: true
  }
326

XhmikosR's avatar
XhmikosR committed
327
328
329
330
331
  Carousel.prototype.keydown = function (e) {
    switch (e.which) {
      case 37: this.prev(); break
      case 39: this.next(); break
      default: return
Mark Otto's avatar
Mark Otto committed
332
333
    }

XhmikosR's avatar
XhmikosR committed
334
335
    e.preventDefault()
  }
336

XhmikosR's avatar
XhmikosR committed
337
338
  Carousel.prototype.cycle = function (e) {
    e || (this.paused = false)
fat's avatar
fat committed
339

XhmikosR's avatar
XhmikosR committed
340
    this.interval && clearInterval(this.interval)
341

XhmikosR's avatar
XhmikosR committed
342
343
344
    this.options.interval
      && !this.paused
      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
345

XhmikosR's avatar
XhmikosR committed
346
347
    return this
  }
348

XhmikosR's avatar
XhmikosR committed
349
350
351
352
  Carousel.prototype.getItemIndex = function (item) {
    this.$items = item.parent().children('.item')
    return this.$items.index(item || this.$active)
  }
353

XhmikosR's avatar
XhmikosR committed
354
355
356
  Carousel.prototype.to = function (pos) {
    var that        = this
    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
357

XhmikosR's avatar
XhmikosR committed
358
    if (pos > (this.$items.length - 1) || pos < 0) return
fat's avatar
fat committed
359

XhmikosR's avatar
XhmikosR committed
360
361
    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
    if (activeIndex == pos) return this.pause().cycle()
362

XhmikosR's avatar
XhmikosR committed
363
364
    return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
  }
fat's avatar
fat committed
365

XhmikosR's avatar
XhmikosR committed
366
367
368
369
370
371
  Carousel.prototype.pause = function (e) {
    e || (this.paused = true)

    if (this.$element.find('.next, .prev').length && $.support.transition) {
      this.$element.trigger($.support.transition.end)
      this.cycle(true)
372
373
    }

XhmikosR's avatar
XhmikosR committed
374
    this.interval = clearInterval(this.interval)
375

XhmikosR's avatar
XhmikosR committed
376
377
    return this
  }
378

XhmikosR's avatar
XhmikosR committed
379
380
381
382
  Carousel.prototype.next = function () {
    if (this.sliding) return
    return this.slide('next')
  }
383

XhmikosR's avatar
XhmikosR committed
384
385
386
387
  Carousel.prototype.prev = function () {
    if (this.sliding) return
    return this.slide('prev')
  }
388

XhmikosR's avatar
XhmikosR committed
389
390
391
392
393
394
395
  Carousel.prototype.slide = function (type, next) {
    var $active   = this.$element.find('.item.active')
    var $next     = next || $active[type]()
    var isCycling = this.interval
    var direction = type == 'next' ? 'left' : 'right'
    var fallback  = type == 'next' ? 'first' : 'last'
    var that      = this
Jacob Thornton's avatar
Jacob Thornton committed
396

XhmikosR's avatar
XhmikosR committed
397
398
399
    if (!$next.length) {
      if (!this.options.wrap) return
      $next = this.$element.find('.item')[fallback]()
Jacob Thornton's avatar
Jacob Thornton committed
400
401
    }

XhmikosR's avatar
XhmikosR committed
402
    if ($next.hasClass('active')) return (this.sliding = false)
403

XhmikosR's avatar
XhmikosR committed
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
    var relatedTarget = $next[0]
    var slideEvent = $.Event('slide.bs.carousel', {
      relatedTarget: relatedTarget,
      direction: direction
    })
    this.$element.trigger(slideEvent)
    if (slideEvent.isDefaultPrevented()) return

    this.sliding = true

    isCycling && this.pause()

    if (this.$indicators.length) {
      this.$indicators.find('.active').removeClass('active')
      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
      $nextIndicator && $nextIndicator.addClass('active')
    }

    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
    if ($.support.transition && this.$element.hasClass('slide')) {
      $next.addClass(type)
      $next[0].offsetWidth // force reflow
      $active.addClass(direction)
      $next.addClass(direction)
      $active
        .one('bsTransitionEnd', function () {
          $next.removeClass([type, direction].join(' ')).addClass('active')
          $active.removeClass(['active', direction].join(' '))
          that.sliding = false
          setTimeout(function () {
            that.$element.trigger(slidEvent)
          }, 0)
        })
        .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
    } else {
      $active.removeClass('active')
      $next.addClass('active')
      this.sliding = false
      this.$element.trigger(slidEvent)
    }
fat's avatar
fat committed
444

XhmikosR's avatar
XhmikosR committed
445
    isCycling && this.cycle()
446

XhmikosR's avatar
XhmikosR committed
447
448
    return this
  }
449
450


XhmikosR's avatar
XhmikosR committed
451
452
  // CAROUSEL PLUGIN DEFINITION
  // ==========================
Chris Rebert's avatar
Chris Rebert committed
453

XhmikosR's avatar
XhmikosR committed
454
455
456
457
458
459
460
461
462
463
464
465
466
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.carousel')
      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
      var action  = typeof option == 'string' ? option : options.slide

      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
      if (typeof option == 'number') data.to(option)
      else if (action) data[action]()
      else if (options.interval) data.pause().cycle()
    })
  }
467

XhmikosR's avatar
XhmikosR committed
468
  var old = $.fn.carousel
Mark Otto's avatar
Mark Otto committed
469

XhmikosR's avatar
XhmikosR committed
470
471
  $.fn.carousel             = Plugin
  $.fn.carousel.Constructor = Carousel
472
473


XhmikosR's avatar
XhmikosR committed
474
475
  // CAROUSEL NO CONFLICT
  // ====================
476

XhmikosR's avatar
XhmikosR committed
477
478
479
480
  $.fn.carousel.noConflict = function () {
    $.fn.carousel = old
    return this
  }
481

fat's avatar
fat committed
482

XhmikosR's avatar
XhmikosR committed
483
484
  // CAROUSEL DATA-API
  // =================
485

XhmikosR's avatar
XhmikosR committed
486
487
488
489
490
491
492
493
  $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
    var href
    var $this   = $(this)
    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
    if (!$target.hasClass('carousel')) return
    var options = $.extend({}, $target.data(), $this.data())
    var slideIndex = $this.attr('data-slide-to')
    if (slideIndex) options.interval = false
494

XhmikosR's avatar
XhmikosR committed
495
    Plugin.call($target, options)
496

XhmikosR's avatar
XhmikosR committed
497
498
    if (slideIndex) {
      $target.data('bs.carousel').to(slideIndex)
499
500
    }

XhmikosR's avatar
XhmikosR committed
501
502
    e.preventDefault()
  })
503

XhmikosR's avatar
XhmikosR committed
504
505
506
507
  $(window).on('load', function () {
    $('[data-ride="carousel"]').each(function () {
      var $carousel = $(this)
      Plugin.call($carousel, $carousel.data())
fat's avatar
fat committed
508
509
510
    })
  })

XhmikosR's avatar
XhmikosR committed
511
}(jQuery);
512

513
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
514
 * Bootstrap: collapse.js v3.2.0
Mark Otto's avatar
Mark Otto committed
515
 * http://getbootstrap.com/javascript/#collapse
516
 * ========================================================================
517
 * Copyright 2011-2014 Twitter, Inc.
518
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
519
 * ======================================================================== */
520
521


XhmikosR's avatar
XhmikosR committed
522
523
+function ($) {
  'use strict';
524

XhmikosR's avatar
XhmikosR committed
525
526
  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================
Mark Otto's avatar
grunt    
Mark Otto committed
527

XhmikosR's avatar
XhmikosR committed
528
529
530
531
  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.transitioning = null
532

XhmikosR's avatar
XhmikosR committed
533
534
535
    if (this.options.parent) this.$parent = $(this.options.parent)
    if (this.options.toggle) this.toggle()
  }
536

Mark Otto's avatar
Mark Otto committed
537
  Collapse.VERSION  = '3.2.0'
538

XhmikosR's avatar
XhmikosR committed
539
540
541
  Collapse.DEFAULTS = {
    toggle: true
  }
fat's avatar
fat committed
542

XhmikosR's avatar
XhmikosR committed
543
544
545
546
  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }
547

XhmikosR's avatar
XhmikosR committed
548
549
  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return
550

XhmikosR's avatar
XhmikosR committed
551
552
553
    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return
554

XhmikosR's avatar
XhmikosR committed
555
    var actives = this.$parent && this.$parent.find('> .panel > .in')
556

XhmikosR's avatar
XhmikosR committed
557
558
559
560
561
562
    if (actives && actives.length) {
      var hasData = actives.data('bs.collapse')
      if (hasData && hasData.transitioning) return
      Plugin.call(actives, 'hide')
      hasData || actives.data('bs.collapse', null)
    }
563

XhmikosR's avatar
XhmikosR committed
564
    var dimension = this.dimension()
565

XhmikosR's avatar
XhmikosR committed
566
567
568
    this.$element
      .removeClass('collapse')
      .addClass('collapsing')[dimension](0)
569

XhmikosR's avatar
XhmikosR committed
570
    this.transitioning = 1
571

XhmikosR's avatar
XhmikosR committed
572
573
574
575
576
    var complete = function () {
      this.$element
        .removeClass('collapsing')
        .addClass('collapse in')[dimension]('')
      this.transitioning = 0
Chris Rebert's avatar
Chris Rebert committed
577
      this.$element
XhmikosR's avatar
XhmikosR committed
578
        .trigger('shown.bs.collapse')
Chris Rebert's avatar
Chris Rebert committed
579
    }
580

XhmikosR's avatar
XhmikosR committed
581
    if (!$.support.transition) return complete.call(this)
fat's avatar
fat committed
582

XhmikosR's avatar
XhmikosR committed
583
    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
fat's avatar
fat committed
584

XhmikosR's avatar
XhmikosR committed
585
586
587
588
    this.$element
      .one('bsTransitionEnd', $.proxy(complete, this))
      .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
  }
589

XhmikosR's avatar
XhmikosR committed
590
591
  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return
592

XhmikosR's avatar
XhmikosR committed
593
594
595
    var startEvent = $.Event('hide.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return
596

XhmikosR's avatar
XhmikosR committed
597
    var dimension = this.dimension()
598

XhmikosR's avatar
XhmikosR committed
599
600
601
602
    this.$element[dimension](this.$element[dimension]())[0].offsetHeight

    this.$element
      .addClass('collapsing')
Mark Otto's avatar
grunt    
Mark Otto committed
603
      .removeClass('collapse in')
604

XhmikosR's avatar
XhmikosR committed
605
    this.transitioning = 1
606

XhmikosR's avatar
XhmikosR committed
607
608
    var complete = function () {
      this.transitioning = 0
Chris Rebert's avatar
Chris Rebert committed
609
      this.$element
XhmikosR's avatar
XhmikosR committed
610
611
612
        .trigger('hidden.bs.collapse')
        .removeClass('collapsing')
        .addClass('collapse')
Chris Rebert's avatar
Chris Rebert committed
613
    }
614

XhmikosR's avatar
XhmikosR committed
615
    if (!$.support.transition) return complete.call(this)
616

XhmikosR's avatar
XhmikosR committed
617
618
619
620
621
    this.$element
      [dimension](0)
      .one('bsTransitionEnd', $.proxy(complete, this))
      .emulateTransitionEnd(350)
  }
622

XhmikosR's avatar
XhmikosR committed
623
624
625
  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }
626

627

XhmikosR's avatar
XhmikosR committed
628
629
  // COLLAPSE PLUGIN DEFINITION
  // ==========================
630

XhmikosR's avatar
XhmikosR committed
631
632
633
634
635
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
Mark Otto's avatar
Mark Otto committed
636

XhmikosR's avatar
XhmikosR committed
637
638
639
640
641
      if (!data && options.toggle && option == 'show') option = !option
      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
642

XhmikosR's avatar
XhmikosR committed
643
  var old = $.fn.collapse
644

XhmikosR's avatar
XhmikosR committed
645
646
  $.fn.collapse             = Plugin
  $.fn.collapse.Constructor = Collapse
647

648

XhmikosR's avatar
XhmikosR committed
649
650
  // COLLAPSE NO CONFLICT
  // ====================
651

XhmikosR's avatar
XhmikosR committed
652
653
654
655
  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }
656

657

XhmikosR's avatar
XhmikosR committed
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
    var href
    var $this   = $(this)
    var target  = $this.attr('data-target')
        || e.preventDefault()
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
    var $target = $(target)
    var data    = $target.data('bs.collapse')
    var option  = data ? 'toggle' : $this.data()
    var parent  = $this.attr('data-parent')
    var $parent = parent && $(parent)

    if (!data || !data.transitioning) {
      if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
Mark Otto's avatar
grunt    
Mark Otto committed
675
      $this.toggleClass('collapsed', $target.hasClass('in'))
XhmikosR's avatar
XhmikosR committed
676
    }
fat's avatar
fat committed
677

XhmikosR's avatar
XhmikosR committed
678
    Plugin.call($target, option)
679
680
  })

XhmikosR's avatar
XhmikosR committed
681
}(jQuery);
682

683
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
684
 * Bootstrap: dropdown.js v3.2.0
Mark Otto's avatar
Mark Otto committed
685
 * http://getbootstrap.com/javascript/#dropdowns
686
 * ========================================================================
687
 * Copyright 2011-2014 Twitter, Inc.
688
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
689
 * ======================================================================== */
690
691


XhmikosR's avatar
XhmikosR committed
692
693
+function ($) {
  'use strict';
Chris Rebert's avatar
Chris Rebert committed
694

XhmikosR's avatar
XhmikosR committed
695
696
  // DROPDOWN CLASS DEFINITION
  // =========================
Mark Otto's avatar
grunt    
Mark Otto committed
697

XhmikosR's avatar
XhmikosR committed
698
699
700
701
702
  var backdrop = '.dropdown-backdrop'
  var toggle   = '[data-toggle="dropdown"]'
  var Dropdown = function (element) {
    $(element).on('click.bs.dropdown', this.toggle)
  }
703

Mark Otto's avatar
Mark Otto committed
704
  Dropdown.VERSION = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
705

XhmikosR's avatar
XhmikosR committed
706
707
  Dropdown.prototype.toggle = function (e) {
    var $this = $(this)
708

XhmikosR's avatar
XhmikosR committed
709
    if ($this.is('.disabled, :disabled')) return
710

XhmikosR's avatar
XhmikosR committed
711
712
    var $parent  = getParent($this)
    var isActive = $parent.hasClass('open')
713

XhmikosR's avatar
XhmikosR committed
714
    clearMenus()
fat's avatar
fat committed
715

XhmikosR's avatar
XhmikosR committed
716
717
718
719
720
    if (!isActive) {
      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
        // if mobile we use a backdrop because click events don't delegate
        $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
      }
721

XhmikosR's avatar
XhmikosR committed
722
723
      var relatedTarget = { relatedTarget: this }
      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
724

XhmikosR's avatar
XhmikosR committed
725
      if (e.isDefaultPrevented()) return
726

XhmikosR's avatar
XhmikosR committed
727
      $this.trigger('focus')
Mark Otto's avatar
Mark Otto committed
728

XhmikosR's avatar
XhmikosR committed
729
730
731
      $parent
        .toggleClass('open')
        .trigger('shown.bs.dropdown', relatedTarget)
fat's avatar
rebuild    
fat committed
732
    }
733

XhmikosR's avatar
XhmikosR committed
734
735
    return false
  }
736

XhmikosR's avatar
XhmikosR committed
737
738
  Dropdown.prototype.keydown = function (e) {
    if (!/(38|40|27)/.test(e.keyCode)) return
739

XhmikosR's avatar
XhmikosR committed
740
    var $this = $(this)
741

XhmikosR's avatar
XhmikosR committed
742
743
    e.preventDefault()
    e.stopPropagation()
744

XhmikosR's avatar
XhmikosR committed
745
    if ($this.is('.disabled, :disabled')) return
746

XhmikosR's avatar
XhmikosR committed
747
748
    var $parent  = getParent($this)
    var isActive = $parent.hasClass('open')
749

XhmikosR's avatar
XhmikosR committed
750
751
752
753
    if (!isActive || (isActive && e.keyCode == 27)) {
      if (e.which == 27) $parent.find(toggle).trigger('focus')
      return $this.trigger('click')
    }
754

XhmikosR's avatar
XhmikosR committed
755
756
    var desc = ' li:not(.divider):visible a'
    var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
757

XhmikosR's avatar
XhmikosR committed
758
    if (!$items.length) return
759

XhmikosR's avatar
XhmikosR committed
760
    var index = $items.index($items.filter(':focus'))
761

XhmikosR's avatar
XhmikosR committed
762
763
764
    if (e.keyCode == 38 && index > 0)                 index--                        // up
    if (e.keyCode == 40 && index < $items.length - 1) index++                        // down
    if (!~index)                                      index = 0
765

XhmikosR's avatar
XhmikosR committed
766
767
    $items.eq(index).trigger('focus')
  }
Chris Rebert's avatar
Chris Rebert committed
768

XhmikosR's avatar
XhmikosR committed
769
770
771
772
773
774
775
776
777
778
779
780
  function clearMenus(e) {
    if (e && e.which === 3) return
    $(backdrop).remove()
    $(toggle).each(function () {
      var $parent = getParent($(this))
      var relatedTarget = { relatedTarget: this }
      if (!$parent.hasClass('open')) return
      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
      if (e.isDefaultPrevented()) return
      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
    })
  }
781

XhmikosR's avatar
XhmikosR committed
782
783
  function getParent($this) {
    var selector = $this.attr('data-target')
784

XhmikosR's avatar
XhmikosR committed
785
786
787
    if (!selector) {
      selector = $this.attr('href')
      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
788
789
    }

XhmikosR's avatar
XhmikosR committed
790
    var $parent = selector && $(selector)
791

XhmikosR's avatar
XhmikosR committed
792
793
    return $parent && $parent.length ? $parent : $this.parent()
  }
794
795


XhmikosR's avatar
XhmikosR committed
796
797
  // DROPDOWN PLUGIN DEFINITION
  // ==========================
798

XhmikosR's avatar
XhmikosR committed
799
800
801
802
  function Plugin(option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.dropdown')
803

XhmikosR's avatar
XhmikosR committed
804
805
806
807
      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
      if (typeof option == 'string') data[option].call($this)
    })
  }
Mark Otto's avatar
Mark Otto committed
808

XhmikosR's avatar
XhmikosR committed
809
  var old = $.fn.dropdown
810

XhmikosR's avatar
XhmikosR committed
811
812
  $.fn.dropdown             = Plugin
  $.fn.dropdown.Constructor = Dropdown
813

814

XhmikosR's avatar
XhmikosR committed
815
816
  // DROPDOWN NO CONFLICT
  // ====================
817

XhmikosR's avatar
XhmikosR committed
818
819
820
821
  $.fn.dropdown.noConflict = function () {
    $.fn.dropdown = old
    return this
  }
822

823

XhmikosR's avatar
XhmikosR committed
824
825
826
827
828
829
830
831
  // APPLY TO STANDARD DROPDOWN ELEMENTS
  // ===================================

  $(document)
    .on('click.bs.dropdown.data-api', clearMenus)
    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
    .on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
832

XhmikosR's avatar
XhmikosR committed
833
}(jQuery);
834

835
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
836
 * Bootstrap: modal.js v3.2.0
Mark Otto's avatar
Mark Otto committed
837
 * http://getbootstrap.com/javascript/#modals
838
 * ========================================================================
839
 * Copyright 2011-2014 Twitter, Inc.
840
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
841
 * ======================================================================== */
842
843


XhmikosR's avatar
XhmikosR committed
844
845
+function ($) {
  'use strict';
846

XhmikosR's avatar
XhmikosR committed
847
848
  // MODAL CLASS DEFINITION
  // ======================
849

XhmikosR's avatar
XhmikosR committed
850
851
852
853
854
855
856
  var Modal = function (element, options) {
    this.options        = options
    this.$body          = $(document.body)
    this.$element       = $(element)
    this.$backdrop      =
    this.isShown        = null
    this.scrollbarWidth = 0
857

XhmikosR's avatar
XhmikosR committed
858
859
860
861
862
863
    if (this.options.remote) {
      this.$element
        .find('.modal-content')
        .load(this.options.remote, $.proxy(function () {
          this.$element.trigger('loaded.bs.modal')
        }, this))
864
    }
XhmikosR's avatar
XhmikosR committed
865
  }
866

Mark Otto's avatar
Mark Otto committed
867
  Modal.VERSION  = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
868

XhmikosR's avatar
XhmikosR committed
869
870
871
872
873
  Modal.DEFAULTS = {
    backdrop: true,
    keyboard: true,
    show: true
  }
874

XhmikosR's avatar
XhmikosR committed
875
876
877
  Modal.prototype.toggle = function (_relatedTarget) {
    return this.isShown ? this.hide() : this.show(_relatedTarget)
  }
878

XhmikosR's avatar
XhmikosR committed
879
880
881
  Modal.prototype.show = function (_relatedTarget) {
    var that = this
    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
882

XhmikosR's avatar
XhmikosR committed
883
    this.$element.trigger(e)
884

XhmikosR's avatar
XhmikosR committed
885
    if (this.isShown || e.isDefaultPrevented()) return
886

XhmikosR's avatar
XhmikosR committed
887
    this.isShown = true
fat's avatar
build    
fat committed
888

XhmikosR's avatar
XhmikosR committed
889
890
    this.checkScrollbar()
    this.$body.addClass('modal-open')
891

XhmikosR's avatar
XhmikosR committed
892
893
    this.setScrollbar()
    this.escape()
fat's avatar
rebuild    
fat committed
894

XhmikosR's avatar
XhmikosR committed
895
    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
896

XhmikosR's avatar
XhmikosR committed
897
898
    this.backdrop(function () {
      var transition = $.support.transition && that.$element.hasClass('fade')
899

XhmikosR's avatar
XhmikosR committed
900
901
902
      if (!that.$element.parent().length) {
        that.$element.appendTo(that.$body) // don't move modals dom position
      }
903

XhmikosR's avatar
XhmikosR committed
904
905
906
      that.$element
        .show()
        .scrollTop(0)
Jacob Thornton's avatar
Jacob Thornton committed
907

XhmikosR's avatar
XhmikosR committed
908
909
910
      if (transition) {
        that.$element[0].offsetWidth // force reflow
      }
911

XhmikosR's avatar
XhmikosR committed
912
913
914
      that.$element
        .addClass('in')
        .attr('aria-hidden', false)
915

XhmikosR's avatar
XhmikosR committed
916
      that.enforceFocus()
917

XhmikosR's avatar
XhmikosR committed
918
      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
919

XhmikosR's avatar
XhmikosR committed
920
921
922
923
924
925
926
927
928
      transition ?
        that.$element.find('.modal-dialog') // wait for modal to slide in
          .one('bsTransitionEnd', function () {
            that.$element.trigger('focus').trigger(e)
          })
          .emulateTransitionEnd(300) :
        that.$element.trigger('focus').trigger(e)
    })
  }
929

XhmikosR's avatar
XhmikosR committed
930
931
  Modal.prototype.hide = function (e) {
    if (e) e.preventDefault()
932

XhmikosR's avatar
XhmikosR committed
933
    e = $.Event('hide.bs.modal')
fat's avatar
build    
fat committed
934

XhmikosR's avatar
XhmikosR committed
935
    this.$element.trigger(e)
936

XhmikosR's avatar
XhmikosR committed
937
    if (!this.isShown || e.isDefaultPrevented()) return
938

XhmikosR's avatar
XhmikosR committed
939
    this.isShown = false
940

XhmikosR's avatar
XhmikosR committed
941
    this.$body.removeClass('modal-open')
942

XhmikosR's avatar
XhmikosR committed
943
944
    this.resetScrollbar()
    this.escape()
Chris Rebert's avatar
Chris Rebert committed
945

XhmikosR's avatar
XhmikosR committed
946
    $(document).off('focusin.bs.modal')
Chris Rebert's avatar
Chris Rebert committed
947

XhmikosR's avatar
XhmikosR committed
948
949
950
951
    this.$element
      .removeClass('in')
      .attr('aria-hidden', true)
      .off('click.dismiss.bs.modal')
952

XhmikosR's avatar
XhmikosR committed
953
954
955
956
957
958
    $.support.transition && this.$element.hasClass('fade') ?
      this.$element
        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
        .emulateTransitionEnd(300) :
      this.hideModal()
  }
959

XhmikosR's avatar
XhmikosR committed
960
961
962
963
964
965
966
967
968
969
970
971
  Modal.prototype.enforceFocus = function () {
    $(document)
      .off('focusin.bs.modal') // guard against infinite focus loop
      .on('focusin.bs.modal', $.proxy(function (e) {
        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
          this.$element.trigger('focus')
        }
      }, this))
  }

  Modal.prototype.escape = function () {
    if (this.isShown && this.options.keyboard) {
Mark Otto's avatar
grunt    
Mark Otto committed
972
      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
XhmikosR's avatar
XhmikosR committed
973
974
975
        e.which == 27 && this.hide()
      }, this))
    } else if (!this.isShown) {
Mark Otto's avatar
grunt    
Mark Otto committed
976
      this.$element.off('keydown.dismiss.bs.modal')
XhmikosR's avatar
XhmikosR committed
977
978
979
980
981
982
983
984
985
986
    }
  }

  Modal.prototype.hideModal = function () {
    var that = this
    this.$element.hide()
    this.backdrop(function () {
      that.$element.trigger('hidden.bs.modal')
    })
  }
987

XhmikosR's avatar
XhmikosR committed
988
989
990
991
  Modal.prototype.removeBackdrop = function () {
    this.$backdrop && this.$backdrop.remove()
    this.$backdrop = null
  }
992

XhmikosR's avatar
XhmikosR committed
993
994
995
  Modal.prototype.backdrop = function (callback) {
    var that = this
    var animate = this.$element.hasClass('fade') ? 'fade' : ''
996

XhmikosR's avatar
XhmikosR committed
997
998
    if (this.isShown && this.options.backdrop) {
      var doAnimate = $.support.transition && animate
999

XhmikosR's avatar
XhmikosR committed
1000
1001
      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
        .appendTo(this.$body)
1002

Mark Otto's avatar
grunt    
Mark Otto committed
1003
      this.$element.on('mousedown.dismiss.bs.modal', $.proxy(function (e) {
XhmikosR's avatar
XhmikosR committed
1004
1005
1006
1007
1008
        if (e.target !== e.currentTarget) return
        this.options.backdrop == 'static'
          ? this.$element[0].focus.call(this.$element[0])
          : this.hide.call(this)
      }, this))
1009

XhmikosR's avatar
XhmikosR committed
1010
      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
1011

XhmikosR's avatar
XhmikosR committed
1012
      this.$backdrop.addClass('in')
1013

XhmikosR's avatar
XhmikosR committed
1014
      if (!callback) return
1015

XhmikosR's avatar
XhmikosR committed
1016
1017
1018
1019
1020
      doAnimate ?
        this.$backdrop
          .one('bsTransitionEnd', callback)
          .emulateTransitionEnd(150) :
        callback()
1021

XhmikosR's avatar
XhmikosR committed
1022
1023
    } else if (!this.isShown && this.$backdrop) {
      this.$backdrop.removeClass('in')
Chris Rebert's avatar
Chris Rebert committed
1024

XhmikosR's avatar
XhmikosR committed
1025
1026
1027
      var callbackRemove = function () {
        that.removeBackdrop()
        callback && callback()
Chris Rebert's avatar
Chris Rebert committed
1028
      }
XhmikosR's avatar
XhmikosR committed
1029
1030
1031
1032
1033
      $.support.transition && this.$element.hasClass('fade') ?
        this.$backdrop
          .one('bsTransitionEnd', callbackRemove)
          .emulateTransitionEnd(150) :
        callbackRemove()
1034

XhmikosR's avatar
XhmikosR committed
1035
1036
    } else if (callback) {
      callback()
Chris Rebert's avatar
Chris Rebert committed
1037
    }
XhmikosR's avatar
XhmikosR committed
1038
  }
1039

XhmikosR's avatar
XhmikosR committed
1040
1041
1042
1043
  Modal.prototype.checkScrollbar = function () {
    if (document.body.clientWidth >= window.innerWidth) return
    this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
  }
fat's avatar
build    
fat committed
1044

XhmikosR's avatar
XhmikosR committed
1045
1046
1047
1048
  Modal.prototype.setScrollbar = function () {
    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
    if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
  }
fat's avatar
build    
fat committed
1049

XhmikosR's avatar
XhmikosR committed
1050
1051
1052
  Modal.prototype.resetScrollbar = function () {
    this.$body.css('padding-right', '')
  }
fat's avatar
build    
fat committed
1053

XhmikosR's avatar
XhmikosR committed
1054
1055
1056
1057
1058
1059
1060
1061
  Modal.prototype.measureScrollbar = function () { // thx walsh
    var scrollDiv = document.createElement('div')
    scrollDiv.className = 'modal-scrollbar-measure'
    this.$body.append(scrollDiv)
    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
    this.$body[0].removeChild(scrollDiv)
    return scrollbarWidth
  }
1062
1063


XhmikosR's avatar
XhmikosR committed
1064
1065
  // MODAL PLUGIN DEFINITION
  // =======================
fat's avatar
fat committed
1066

XhmikosR's avatar
XhmikosR committed
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
  function Plugin(option, _relatedTarget) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.modal')
      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
      if (typeof option == 'string') data[option](_relatedTarget)
      else if (options.show) data.show(_relatedTarget)
    })
  }
1078

XhmikosR's avatar
XhmikosR committed
1079
  var old = $.fn.modal
Mark Otto's avatar
Mark Otto committed
1080

XhmikosR's avatar
XhmikosR committed
1081
1082
  $.fn.modal             = Plugin
  $.fn.modal.Constructor = Modal
1083
1084


XhmikosR's avatar
XhmikosR committed
1085
1086
  // MODAL NO CONFLICT
  // =================
1087

XhmikosR's avatar
XhmikosR committed
1088
1089
1090
1091
  $.fn.modal.noConflict = function () {
    $.fn.modal = old
    return this
  }
1092
1093


XhmikosR's avatar
XhmikosR committed
1094
1095
  // MODAL DATA-API
  // ==============
1096

XhmikosR's avatar
XhmikosR committed
1097
1098
1099
1100
1101
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
    var $this   = $(this)
    var href    = $this.attr('href')
    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
1102

XhmikosR's avatar
XhmikosR committed
1103
    if ($this.is('a')) e.preventDefault()
1104

XhmikosR's avatar
XhmikosR committed
1105
1106
1107
1108
    $target.one('show.bs.modal', function (showEvent) {
      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
      $target.one('hidden.bs.modal', function () {
        $this.is(':visible') && $this.trigger('focus')
Mark Otto's avatar
grunt    
Mark Otto committed
1109
      })
Mark Otto's avatar
Mark Otto committed
1110
    })
XhmikosR's avatar
XhmikosR committed
1111
    Plugin.call($target, option, this)
Jacob Thornton's avatar
Jacob Thornton committed
1112
  })
1113

XhmikosR's avatar
XhmikosR committed
1114
}(jQuery);
1115

1116
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1117
 * Bootstrap: tooltip.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1118
 * http://getbootstrap.com/javascript/#tooltip
1119
 * Inspired by the original jQuery.tipsy by Jason Frame
1120
 * ========================================================================
1121
 * Copyright 2011-2014 Twitter, Inc.
1122
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1123
 * ======================================================================== */
1124
1125


XhmikosR's avatar
XhmikosR committed
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
+function ($) {
  'use strict';

  // TOOLTIP PUBLIC CLASS DEFINITION
  // ===============================

  var Tooltip = function (element, options) {
    this.type       =
    this.options    =
    this.enabled    =
    this.timeout    =
    this.hoverState =
    this.$element   = null

    this.init('tooltip', element, options)
  }

Mark Otto's avatar
Mark Otto committed
1143
  Tooltip.VERSION  = '3.2.0'
XhmikosR's avatar
XhmikosR committed
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182

  Tooltip.DEFAULTS = {
    animation: true,
    placement: 'top',
    selector: false,
    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
    trigger: 'hover focus',
    title: '',
    delay: 0,
    html: false,
    container: false,
    viewport: {
      selector: 'body',
      padding: 0
    }
  }

  Tooltip.prototype.init = function (type, element, options) {
    this.enabled   = true
    this.type      = type
    this.$element  = $(element)
    this.options   = this.getOptions(options)
    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)

    var triggers = this.options.trigger.split(' ')

    for (var i = triggers.length; i--;) {
      var trigger = triggers[i]

      if (trigger == 'click') {
        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
      } else if (trigger != 'manual') {
        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'

        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
      }
    }
1183

XhmikosR's avatar
XhmikosR committed
1184
1185
1186
1187
    this.options.selector ?
      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
      this.fixTitle()
  }
1188

XhmikosR's avatar
XhmikosR committed
1189
1190
1191
  Tooltip.prototype.getDefaults = function () {
    return Tooltip.DEFAULTS
  }
1192

XhmikosR's avatar
XhmikosR committed
1193
1194
  Tooltip.prototype.getOptions = function (options) {
    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
1195

XhmikosR's avatar
XhmikosR committed
1196
1197
1198
1199
    if (options.delay && typeof options.delay == 'number') {
      options.delay = {
        show: options.delay,
        hide: options.delay
1200
1201
      }
    }
1202

XhmikosR's avatar
XhmikosR committed
1203
1204
    return options
  }
Jacob Thornton's avatar
Jacob Thornton committed
1205

XhmikosR's avatar
XhmikosR committed
1206
1207
1208
  Tooltip.prototype.getDelegateOptions = function () {
    var options  = {}
    var defaults = this.getDefaults()
1209

XhmikosR's avatar
XhmikosR committed
1210
1211
1212
    this._options && $.each(this._options, function (key, value) {
      if (defaults[key] != value) options[key] = value
    })
fat's avatar
rebuild    
fat committed
1213

XhmikosR's avatar
XhmikosR committed
1214
1215
    return options
  }
Jacob Thornton's avatar
Jacob Thornton committed
1216

XhmikosR's avatar
XhmikosR committed
1217
1218
1219
  Tooltip.prototype.enter = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget).data('bs.' + this.type)
Mark Otto's avatar
Mark Otto committed
1220

XhmikosR's avatar
XhmikosR committed
1221
1222
1223
    if (!self) {
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
      $(obj.currentTarget).data('bs.' + this.type, self)
Mark Otto's avatar
Mark Otto committed
1224
    }
1225

XhmikosR's avatar
XhmikosR committed
1226
    clearTimeout(self.timeout)
1227

XhmikosR's avatar
XhmikosR committed
1228
    self.hoverState = 'in'
1229

XhmikosR's avatar
XhmikosR committed
1230
    if (!self.options.delay || !self.options.delay.show) return self.show()
1231

XhmikosR's avatar
XhmikosR committed
1232
1233
1234
1235
    self.timeout = setTimeout(function () {
      if (self.hoverState == 'in') self.show()
    }, self.options.delay.show)
  }
1236

XhmikosR's avatar
XhmikosR committed
1237
1238
1239
  Tooltip.prototype.leave = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget).data('bs.' + this.type)
Mark Otto's avatar
Mark Otto committed
1240

XhmikosR's avatar
XhmikosR committed
1241
1242
1243
    if (!self) {
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
      $(obj.currentTarget).data('bs.' + this.type, self)
Mark Otto's avatar
Mark Otto committed
1244
    }
1245

XhmikosR's avatar
XhmikosR committed
1246
    clearTimeout(self.timeout)
fat's avatar
fat committed
1247

XhmikosR's avatar
XhmikosR committed
1248
    self.hoverState = 'out'
1249

XhmikosR's avatar
XhmikosR committed
1250
    if (!self.options.delay || !self.options.delay.hide) return self.hide()
1251

XhmikosR's avatar
XhmikosR committed
1252
1253
1254
1255
    self.timeout = setTimeout(function () {
      if (self.hoverState == 'out') self.hide()
    }, self.options.delay.hide)
  }
1256

XhmikosR's avatar
XhmikosR committed
1257
1258
  Tooltip.prototype.show = function () {
    var e = $.Event('show.bs.' + this.type)
Chris Rebert's avatar
Chris Rebert committed
1259

XhmikosR's avatar
XhmikosR committed
1260
1261
    if (this.hasContent() && this.enabled) {
      this.$element.trigger(e)
fat's avatar
fat committed
1262

XhmikosR's avatar
XhmikosR committed
1263
1264
1265
      var inDom = $.contains(document.documentElement, this.$element[0])
      if (e.isDefaultPrevented() || !inDom) return
      var that = this
1266

XhmikosR's avatar
XhmikosR committed
1267
      var $tip = this.tip()
fat's avatar
fat committed
1268

XhmikosR's avatar
XhmikosR committed
1269
      var tipId = this.getUID(this.type)
fat's avatar
fat committed
1270

XhmikosR's avatar
XhmikosR committed
1271
1272
1273
      this.setContent()
      $tip.attr('id', tipId)
      this.$element.attr('aria-describedby', tipId)
1274

XhmikosR's avatar
XhmikosR committed
1275
      if (this.options.animation) $tip.addClass('fade')
1276

XhmikosR's avatar
XhmikosR committed
1277
1278
1279
      var placement = typeof this.options.placement == 'function' ?
        this.options.placement.call(this, $tip[0], this.$element[0]) :
        this.options.placement
1280

XhmikosR's avatar
XhmikosR committed
1281
1282
1283
      var autoToken = /\s?auto?\s?/i
      var autoPlace = autoToken.test(placement)
      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
1284

XhmikosR's avatar
XhmikosR committed
1285
1286
1287
1288
1289
      $tip
        .detach()
        .css({ top: 0, left: 0, display: 'block' })
        .addClass(placement)
        .data('bs.' + this.type, this)
fat's avatar
fat committed
1290

XhmikosR's avatar
XhmikosR committed
1291
      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
1292

XhmikosR's avatar
XhmikosR committed
1293
1294
1295
      var pos          = this.getPosition()
      var actualWidth  = $tip[0].offsetWidth
      var actualHeight = $tip[0].offsetHeight
Chris Rebert's avatar
Chris Rebert committed
1296

XhmikosR's avatar
XhmikosR committed
1297
1298
1299
1300
      if (autoPlace) {
        var orgPlacement = placement
        var $parent      = this.$element.parent()
        var parentDim    = this.getPosition($parent)
Chris Rebert's avatar
Chris Rebert committed
1301

XhmikosR's avatar
XhmikosR committed
1302
1303
1304
1305
1306
        placement = placement == 'bottom' && pos.top   + pos.height       + actualHeight - parentDim.scroll > parentDim.height ? 'top'    :
                    placement == 'top'    && pos.top   - parentDim.scroll - actualHeight < 0                                   ? 'bottom' :
                    placement == 'right'  && pos.right + actualWidth      > parentDim.width                                    ? 'left'   :
                    placement == 'left'   && pos.left  - actualWidth      < parentDim.left                                     ? 'right'  :
                    placement
fat's avatar
fat committed
1307

1308
        $tip
XhmikosR's avatar
XhmikosR committed
1309
          .removeClass(orgPlacement)
1310
          .addClass(placement)
XhmikosR's avatar
XhmikosR committed
1311
      }
1312

XhmikosR's avatar
XhmikosR committed
1313
      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
1314

XhmikosR's avatar
XhmikosR committed
1315
      this.applyPlacement(calculatedOffset, placement)
fat's avatar
fat committed
1316

XhmikosR's avatar
XhmikosR committed
1317
1318
1319
1320
      var complete = function () {
        that.$element.trigger('shown.bs.' + that.type)
        that.hoverState = null
      }
fat's avatar
fat committed
1321

XhmikosR's avatar
XhmikosR committed
1322
1323
1324
1325
1326
1327
1328
      $.support.transition && this.$tip.hasClass('fade') ?
        $tip
          .one('bsTransitionEnd', complete)
          .emulateTransitionEnd(150) :
        complete()
    }
  }
fat's avatar
fat committed
1329

XhmikosR's avatar
XhmikosR committed
1330
1331
1332
1333
  Tooltip.prototype.applyPlacement = function (offset, placement) {
    var $tip   = this.tip()
    var width  = $tip[0].offsetWidth
    var height = $tip[0].offsetHeight
fat's avatar
fat committed
1334

XhmikosR's avatar
XhmikosR committed
1335
1336
1337
    // manually read margins because getBoundingClientRect includes difference
    var marginTop = parseInt($tip.css('margin-top'), 10)
    var marginLeft = parseInt($tip.css('margin-left'), 10)
fat's avatar
fat committed
1338

XhmikosR's avatar
XhmikosR committed
1339
1340
1341
    // we must check for NaN for ie 8/9
    if (isNaN(marginTop))  marginTop  = 0
    if (isNaN(marginLeft)) marginLeft = 0
fat's avatar
fat committed
1342

XhmikosR's avatar
XhmikosR committed
1343
1344
    offset.top  = offset.top  + marginTop
    offset.left = offset.left + marginLeft
fat's avatar
fat committed
1345

XhmikosR's avatar
XhmikosR committed
1346
1347
1348
1349
1350
1351
1352
1353
    // $.fn.offset doesn't round pixel values
    // so we use setOffset directly with our own function B-0
    $.offset.setOffset($tip[0], $.extend({
      using: function (props) {
        $tip.css({
          top: Math.round(props.top),
          left: Math.round(props.left)
        })
1354
      }
XhmikosR's avatar
XhmikosR committed
1355
    }, offset), 0)
1356

XhmikosR's avatar
XhmikosR committed
1357
    $tip.addClass('in')
fat's avatar
fat committed
1358

XhmikosR's avatar
XhmikosR committed
1359
1360
1361
    // check to see if placing tip in new offset caused the tip to resize itself
    var actualWidth  = $tip[0].offsetWidth
    var actualHeight = $tip[0].offsetHeight
fat's avatar
fat committed
1362

XhmikosR's avatar
XhmikosR committed
1363
1364
1365
    if (placement == 'top' && actualHeight != height) {
      offset.top = offset.top + height - actualHeight
    }
fat's avatar
fat committed
1366

XhmikosR's avatar
XhmikosR committed
1367
    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
fat's avatar
fat committed
1368

XhmikosR's avatar
XhmikosR committed
1369
1370
    if (delta.left) offset.left += delta.left
    else offset.top += delta.top
1371

XhmikosR's avatar
XhmikosR committed
1372
1373
1374
    var arrowDelta          = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
    var arrowPosition       = delta.left ? 'left'        : 'top'
    var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
1375

XhmikosR's avatar
XhmikosR committed
1376
1377
1378
    $tip.offset(offset)
    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
  }
1379

XhmikosR's avatar
XhmikosR committed
1380
1381
1382
  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
  }
1383

XhmikosR's avatar
XhmikosR committed
1384
1385
1386
  Tooltip.prototype.setContent = function () {
    var $tip  = this.tip()
    var title = this.getTitle()
1387

XhmikosR's avatar
XhmikosR committed
1388
1389
1390
    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
    $tip.removeClass('fade in top bottom left right')
  }
1391

XhmikosR's avatar
XhmikosR committed
1392
1393
1394
1395
  Tooltip.prototype.hide = function () {
    var that = this
    var $tip = this.tip()
    var e    = $.Event('hide.bs.' + this.type)
1396

XhmikosR's avatar
XhmikosR committed
1397
    this.$element.removeAttr('aria-describedby')
1398

XhmikosR's avatar
XhmikosR committed
1399
1400
1401
1402
    function complete() {
      if (that.hoverState != 'in') $tip.detach()
      that.$element.trigger('hidden.bs.' + that.type)
    }
Jacob Thornton's avatar
Jacob Thornton committed
1403

XhmikosR's avatar
XhmikosR committed
1404
    this.$element.trigger(e)
1405

XhmikosR's avatar
XhmikosR committed
1406
    if (e.isDefaultPrevented()) return
1407

XhmikosR's avatar
XhmikosR committed
1408
    $tip.removeClass('in')
1409

XhmikosR's avatar
XhmikosR committed
1410
1411
1412
1413
1414
    $.support.transition && this.$tip.hasClass('fade') ?
      $tip
        .one('bsTransitionEnd', complete)
        .emulateTransitionEnd(150) :
      complete()
1415

XhmikosR's avatar
XhmikosR committed
1416
    this.hoverState = null
1417

XhmikosR's avatar
XhmikosR committed
1418
1419
    return this
  }
1420

XhmikosR's avatar
XhmikosR committed
1421
1422
1423
1424
  Tooltip.prototype.fixTitle = function () {
    var $e = this.$element
    if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1425
    }
XhmikosR's avatar
XhmikosR committed
1426
  }
1427

XhmikosR's avatar
XhmikosR committed
1428
1429
1430
  Tooltip.prototype.hasContent = function () {
    return this.getTitle()
  }
1431

XhmikosR's avatar
XhmikosR committed
1432
1433
  Tooltip.prototype.getPosition = function ($element) {
    $element   = $element || this.$element
Mark Otto's avatar
grunt    
Mark Otto committed
1434

XhmikosR's avatar
XhmikosR committed
1435
1436
    var el     = $element[0]
    var isBody = el.tagName == 'BODY'
Mark Otto's avatar
grunt    
Mark Otto committed
1437
1438
1439
1440
1441
    var isSvg  = window.SVGElement && el instanceof window.SVGElement

    var elRect    = typeof el.getBoundingClientRect == 'function' ? el.getBoundingClientRect() : null
    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
Chris Rebert's avatar
Chris Rebert committed
1442
    var outerDims = isSvg ? {} : {
XhmikosR's avatar
XhmikosR committed
1443
1444
      width:  isBody ? $(window).width()  : $element.outerWidth(),
      height: isBody ? $(window).height() : $element.outerHeight()
Chris Rebert's avatar
Chris Rebert committed
1445
    }
Mark Otto's avatar
grunt    
Mark Otto committed
1446
1447

    return $.extend({}, elRect, scroll, outerDims, elOffset)
XhmikosR's avatar
XhmikosR committed
1448
  }
1449

XhmikosR's avatar
XhmikosR committed
1450
1451
1452
1453
1454
  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
1455

XhmikosR's avatar
XhmikosR committed
1456
  }
1457

XhmikosR's avatar
XhmikosR committed
1458
1459
1460
  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
    var delta = { top: 0, left: 0 }
    if (!this.$viewport) return delta
1461

XhmikosR's avatar
XhmikosR committed
1462
1463
    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
    var viewportDimensions = this.getPosition(this.$viewport)
1464

XhmikosR's avatar
XhmikosR committed
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
    if (/right|left/.test(placement)) {
      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
      if (topEdgeOffset < viewportDimensions.top) { // top overflow
        delta.top = viewportDimensions.top - topEdgeOffset
      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
      }
    } else {
      var leftEdgeOffset  = pos.left - viewportPadding
      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
        delta.left = viewportDimensions.left - leftEdgeOffset
      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
1480
      }
Chris Rebert's avatar
Chris Rebert committed
1481
    }
fat's avatar
fat committed
1482

XhmikosR's avatar
XhmikosR committed
1483
1484
    return delta
  }
1485

XhmikosR's avatar
XhmikosR committed
1486
1487
1488
1489
  Tooltip.prototype.getTitle = function () {
    var title
    var $e = this.$element
    var o  = this.options
1490

XhmikosR's avatar
XhmikosR committed
1491
1492
    title = $e.attr('data-original-title')
      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
1493

XhmikosR's avatar
XhmikosR committed
1494
1495
    return title
  }
1496

XhmikosR's avatar
XhmikosR committed
1497
1498
1499
1500
1501
  Tooltip.prototype.getUID = function (prefix) {
    do prefix += ~~(Math.random() * 1000000)
    while (document.getElementById(prefix))
    return prefix
  }
1502

XhmikosR's avatar
XhmikosR committed
1503
1504
1505
  Tooltip.prototype.tip = function () {
    return (this.$tip = this.$tip || $(this.options.template))
  }
1506

XhmikosR's avatar
XhmikosR committed
1507
1508
1509
  Tooltip.prototype.arrow = function () {
    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
  }
1510

XhmikosR's avatar
XhmikosR committed
1511
1512
1513
1514
1515
  Tooltip.prototype.validate = function () {
    if (!this.$element[0].parentNode) {
      this.hide()
      this.$element = null
      this.options  = null
Chris Rebert's avatar
Chris Rebert committed
1516
    }
XhmikosR's avatar
XhmikosR committed
1517
  }
1518

XhmikosR's avatar
XhmikosR committed
1519
1520
1521
  Tooltip.prototype.enable = function () {
    this.enabled = true
  }
1522

XhmikosR's avatar
XhmikosR committed
1523
1524
1525
  Tooltip.prototype.disable = function () {
    this.enabled = false
  }
Mark Otto's avatar
Mark Otto committed
1526

XhmikosR's avatar
XhmikosR committed
1527
1528
1529
  Tooltip.prototype.toggleEnabled = function () {
    this.enabled = !this.enabled
  }
Chris Rebert's avatar
Chris Rebert committed
1530

XhmikosR's avatar
XhmikosR committed
1531
1532
1533
1534
1535
1536
1537
1538
  Tooltip.prototype.toggle = function (e) {
    var self = this
    if (e) {
      self = $(e.currentTarget).data('bs.' + this.type)
      if (!self) {
        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
        $(e.currentTarget).data('bs.' + this.type, self)
      }
Mark Otto's avatar
Mark Otto committed
1539
1540
    }

XhmikosR's avatar
XhmikosR committed
1541
1542
    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  }
1543

XhmikosR's avatar
XhmikosR committed
1544
1545
1546
1547
  Tooltip.prototype.destroy = function () {
    clearTimeout(this.timeout)
    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
  }
1548
1549


XhmikosR's avatar
XhmikosR committed
1550
1551
  // TOOLTIP PLUGIN DEFINITION
  // =========================
1552

XhmikosR's avatar
XhmikosR committed
1553
1554
1555
1556
1557
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.tooltip')
      var options = typeof option == 'object' && option
fat's avatar
fat committed
1558

XhmikosR's avatar
XhmikosR committed
1559
1560
1561
1562
1563
      if (!data && option == 'destroy') return
      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1564

XhmikosR's avatar
XhmikosR committed
1565
  var old = $.fn.tooltip
Mark Otto's avatar
Mark Otto committed
1566

XhmikosR's avatar
XhmikosR committed
1567
1568
  $.fn.tooltip             = Plugin
  $.fn.tooltip.Constructor = Tooltip
1569

1570

XhmikosR's avatar
XhmikosR committed
1571
1572
  // TOOLTIP NO CONFLICT
  // ===================
1573

XhmikosR's avatar
XhmikosR committed
1574
1575
1576
1577
  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }
1578

XhmikosR's avatar
XhmikosR committed
1579
}(jQuery);
1580

1581
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1582
 * Bootstrap: popover.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1583
 * http://getbootstrap.com/javascript/#popovers
1584
 * ========================================================================
1585
 * Copyright 2011-2014 Twitter, Inc.
1586
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1587
 * ======================================================================== */
1588
1589


XhmikosR's avatar
XhmikosR committed
1590
1591
+function ($) {
  'use strict';
Mark Otto's avatar
grunt    
Mark Otto committed
1592

XhmikosR's avatar
XhmikosR committed
1593
1594
  // POPOVER PUBLIC CLASS DEFINITION
  // ===============================
1595

XhmikosR's avatar
XhmikosR committed
1596
1597
1598
  var Popover = function (element, options) {
    this.init('popover', element, options)
  }
fat's avatar
fat committed
1599

XhmikosR's avatar
XhmikosR committed
1600
  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1601

Mark Otto's avatar
Mark Otto committed
1602
  Popover.VERSION  = '3.2.0'
1603

XhmikosR's avatar
XhmikosR committed
1604
1605
1606
1607
1608
1609
  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
    placement: 'right',
    trigger: 'click',
    content: '',
    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  })
fat's avatar
fat committed
1610
1611


XhmikosR's avatar
XhmikosR committed
1612
1613
  // NOTE: POPOVER EXTENDS tooltip.js
  // ================================
1614

XhmikosR's avatar
XhmikosR committed
1615
  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
fat's avatar
fat committed
1616

XhmikosR's avatar
XhmikosR committed
1617
  Popover.prototype.constructor = Popover
1618

XhmikosR's avatar
XhmikosR committed
1619
1620
1621
  Popover.prototype.getDefaults = function () {
    return Popover.DEFAULTS
  }
1622

XhmikosR's avatar
XhmikosR committed
1623
1624
1625
1626
  Popover.prototype.setContent = function () {
    var $tip    = this.tip()
    var title   = this.getTitle()
    var content = this.getContent()
1627

XhmikosR's avatar
XhmikosR committed
1628
1629
1630
1631
    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
    $tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
    ](content)
1632

XhmikosR's avatar
XhmikosR committed
1633
    $tip.removeClass('fade top bottom left right in')
1634

XhmikosR's avatar
XhmikosR committed
1635
1636
1637
1638
    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
    // this manually by checking the contents.
    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
  }
1639

XhmikosR's avatar
XhmikosR committed
1640
1641
1642
  Popover.prototype.hasContent = function () {
    return this.getTitle() || this.getContent()
  }
1643

XhmikosR's avatar
XhmikosR committed
1644
1645
1646
  Popover.prototype.getContent = function () {
    var $e = this.$element
    var o  = this.options
1647

XhmikosR's avatar
XhmikosR committed
1648
1649
1650
1651
1652
    return $e.attr('data-content')
      || (typeof o.content == 'function' ?
            o.content.call($e[0]) :
            o.content)
  }
fat's avatar
fat committed
1653

XhmikosR's avatar
XhmikosR committed
1654
1655
1656
  Popover.prototype.arrow = function () {
    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
  }
1657

XhmikosR's avatar
XhmikosR committed
1658
1659
1660
1661
  Popover.prototype.tip = function () {
    if (!this.$tip) this.$tip = $(this.options.template)
    return this.$tip
  }
1662

1663

XhmikosR's avatar
XhmikosR committed
1664
1665
  // POPOVER PLUGIN DEFINITION
  // =========================
1666

XhmikosR's avatar
XhmikosR committed
1667
1668
1669
1670
1671
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.popover')
      var options = typeof option == 'object' && option
Chris Rebert's avatar
Chris Rebert committed
1672

XhmikosR's avatar
XhmikosR committed
1673
1674
1675
1676
1677
      if (!data && option == 'destroy') return
      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1678

XhmikosR's avatar
XhmikosR committed
1679
  var old = $.fn.popover
Mark Otto's avatar
Mark Otto committed
1680

XhmikosR's avatar
XhmikosR committed
1681
1682
  $.fn.popover             = Plugin
  $.fn.popover.Constructor = Popover
fat's avatar
fat committed
1683

1684

XhmikosR's avatar
XhmikosR committed
1685
1686
  // POPOVER NO CONFLICT
  // ===================
1687

XhmikosR's avatar
XhmikosR committed
1688
1689
1690
1691
  $.fn.popover.noConflict = function () {
    $.fn.popover = old
    return this
  }
1692

XhmikosR's avatar
XhmikosR committed
1693
}(jQuery);
1694

1695
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1696
 * Bootstrap: scrollspy.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1697
 * http://getbootstrap.com/javascript/#scrollspy
1698
 * ========================================================================
1699
 * Copyright 2011-2014 Twitter, Inc.
1700
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1701
 * ======================================================================== */
1702
1703


XhmikosR's avatar
XhmikosR committed
1704
1705
+function ($) {
  'use strict';
1706

XhmikosR's avatar
XhmikosR committed
1707
1708
  // SCROLLSPY CLASS DEFINITION
  // ==========================
1709

XhmikosR's avatar
XhmikosR committed
1710
1711
  function ScrollSpy(element, options) {
    var process  = $.proxy(this.process, this)
1712

XhmikosR's avatar
XhmikosR committed
1713
1714
1715
1716
1717
1718
1719
1720
    this.$body          = $('body')
    this.$scrollElement = $(element).is('body') ? $(window) : $(element)
    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
    this.selector       = (this.options.target || '') + ' .nav li > a'
    this.offsets        = []
    this.targets        = []
    this.activeTarget   = null
    this.scrollHeight   = 0
1721

XhmikosR's avatar
XhmikosR committed
1722
1723
1724
1725
    this.$scrollElement.on('scroll.bs.scrollspy', process)
    this.refresh()
    this.process()
  }
1726

Mark Otto's avatar
Mark Otto committed
1727
  ScrollSpy.VERSION  = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
1728

XhmikosR's avatar
XhmikosR committed
1729
1730
1731
  ScrollSpy.DEFAULTS = {
    offset: 10
  }
1732

XhmikosR's avatar
XhmikosR committed
1733
1734
1735
  ScrollSpy.prototype.getScrollHeight = function () {
    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
  }
Mark Otto's avatar
grunt    
Mark Otto committed
1736

XhmikosR's avatar
XhmikosR committed
1737
1738
1739
  ScrollSpy.prototype.refresh = function () {
    var offsetMethod = 'offset'
    var offsetBase   = 0
Mark Otto's avatar
grunt    
Mark Otto committed
1740

XhmikosR's avatar
XhmikosR committed
1741
1742
1743
1744
    if (!$.isWindow(this.$scrollElement[0])) {
      offsetMethod = 'position'
      offsetBase   = this.$scrollElement.scrollTop()
    }
Mark Otto's avatar
grunt    
Mark Otto committed
1745

XhmikosR's avatar
XhmikosR committed
1746
1747
1748
    this.offsets = []
    this.targets = []
    this.scrollHeight = this.getScrollHeight()
fat's avatar
fat committed
1749

XhmikosR's avatar
XhmikosR committed
1750
    var self     = this
XhmikosR's avatar
XhmikosR committed
1751

XhmikosR's avatar
XhmikosR committed
1752
1753
1754
1755
1756
1757
    this.$body
      .find(this.selector)
      .map(function () {
        var $el   = $(this)
        var href  = $el.data('target') || $el.attr('href')
        var $href = /^#./.test(href) && $(href)
1758

XhmikosR's avatar
XhmikosR committed
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
        return ($href
          && $href.length
          && $href.is(':visible')
          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
      })
      .sort(function (a, b) { return a[0] - b[0] })
      .each(function () {
        self.offsets.push(this[0])
        self.targets.push(this[1])
      })
  }

  ScrollSpy.prototype.process = function () {
    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
    var scrollHeight = this.getScrollHeight()
    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
    var offsets      = this.offsets
    var targets      = this.targets
    var activeTarget = this.activeTarget
    var i

    if (this.scrollHeight != scrollHeight) {
      this.refresh()
Mark Otto's avatar
grunt    
Mark Otto committed
1782
1783
    }

XhmikosR's avatar
XhmikosR committed
1784
1785
1786
    if (scrollTop >= maxScroll) {
      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
    }
1787

XhmikosR's avatar
XhmikosR committed
1788
1789
    if (activeTarget && scrollTop <= offsets[0]) {
      return activeTarget != (i = targets[0]) && this.activate(i)
Chris Rebert's avatar
Chris Rebert committed
1790
    }
1791

XhmikosR's avatar
XhmikosR committed
1792
1793
1794
1795
1796
1797
1798
    for (i = offsets.length; i--;) {
      activeTarget != targets[i]
        && scrollTop >= offsets[i]
        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
        && this.activate(targets[i])
    }
  }
1799

XhmikosR's avatar
XhmikosR committed
1800
1801
  ScrollSpy.prototype.activate = function (target) {
    this.activeTarget = target
1802

XhmikosR's avatar
XhmikosR committed
1803
1804
1805
    $(this.selector)
      .parentsUntil(this.options.target, '.active')
      .removeClass('active')
1806

XhmikosR's avatar
XhmikosR committed
1807
1808
1809
    var selector = this.selector +
        '[data-target="' + target + '"],' +
        this.selector + '[href="' + target + '"]'
1810

XhmikosR's avatar
XhmikosR committed
1811
1812
1813
    var active = $(selector)
      .parents('li')
      .addClass('active')
1814

XhmikosR's avatar
XhmikosR committed
1815
1816
1817
1818
    if (active.parent('.dropdown-menu').length) {
      active = active
        .closest('li.dropdown')
        .addClass('active')
Chris Rebert's avatar
Chris Rebert committed
1819
    }
1820

XhmikosR's avatar
XhmikosR committed
1821
1822
    active.trigger('activate.bs.scrollspy')
  }
1823
1824


XhmikosR's avatar
XhmikosR committed
1825
1826
  // SCROLLSPY PLUGIN DEFINITION
  // ===========================
1827

XhmikosR's avatar
XhmikosR committed
1828
1829
1830
1831
1832
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.scrollspy')
      var options = typeof option == 'object' && option
Mark Otto's avatar
Mark Otto committed
1833

XhmikosR's avatar
XhmikosR committed
1834
1835
1836
1837
      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
1838

XhmikosR's avatar
XhmikosR committed
1839
  var old = $.fn.scrollspy
1840

XhmikosR's avatar
XhmikosR committed
1841
1842
  $.fn.scrollspy             = Plugin
  $.fn.scrollspy.Constructor = ScrollSpy
1843

1844

XhmikosR's avatar
XhmikosR committed
1845
1846
  // SCROLLSPY NO CONFLICT
  // =====================
1847

XhmikosR's avatar
XhmikosR committed
1848
1849
1850
1851
  $.fn.scrollspy.noConflict = function () {
    $.fn.scrollspy = old
    return this
  }
1852

Chris Rebert's avatar
Chris Rebert committed
1853

XhmikosR's avatar
XhmikosR committed
1854
1855
  // SCROLLSPY DATA-API
  // ==================
Chris Rebert's avatar
Chris Rebert committed
1856

XhmikosR's avatar
XhmikosR committed
1857
1858
1859
1860
1861
  $(window).on('load.bs.scrollspy.data-api', function () {
    $('[data-spy="scroll"]').each(function () {
      var $spy = $(this)
      Plugin.call($spy, $spy.data())
    })
1862
  })
1863

XhmikosR's avatar
XhmikosR committed
1864
}(jQuery);
1865

1866
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1867
 * Bootstrap: tab.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1868
 * http://getbootstrap.com/javascript/#tabs
1869
 * ========================================================================
1870
 * Copyright 2011-2014 Twitter, Inc.
1871
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1872
 * ======================================================================== */
1873

1874

XhmikosR's avatar
XhmikosR committed
1875
1876
+function ($) {
  'use strict';
Mark Otto's avatar
grunt    
Mark Otto committed
1877

XhmikosR's avatar
XhmikosR committed
1878
1879
  // TAB CLASS DEFINITION
  // ====================
1880

XhmikosR's avatar
XhmikosR committed
1881
1882
1883
  var Tab = function (element) {
    this.element = $(element)
  }
1884

Mark Otto's avatar
Mark Otto committed
1885
  Tab.VERSION = '3.2.0'
Mark Otto's avatar
grunt    
Mark Otto committed
1886

XhmikosR's avatar
XhmikosR committed
1887
1888
1889
1890
  Tab.prototype.show = function () {
    var $this    = this.element
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.data('target')
1891

XhmikosR's avatar
XhmikosR committed
1892
1893
1894
1895
    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }
1896

XhmikosR's avatar
XhmikosR committed
1897
    if ($this.parent('li').hasClass('active')) return
1898

XhmikosR's avatar
XhmikosR committed
1899
1900
1901
1902
    var previous = $ul.find('.active:last a')[0]
    var e        = $.Event('show.bs.tab', {
      relatedTarget: previous
    })
1903

XhmikosR's avatar
XhmikosR committed
1904
    $this.trigger(e)
1905

XhmikosR's avatar
XhmikosR committed
1906
    if (e.isDefaultPrevented()) return
1907

XhmikosR's avatar
XhmikosR committed
1908
    var $target = $(selector)
1909

XhmikosR's avatar
XhmikosR committed
1910
1911
1912
1913
1914
    this.activate($this.closest('li'), $ul)
    this.activate($target, $target.parent(), function () {
      $this.trigger({
        type: 'shown.bs.tab',
        relatedTarget: previous
1915
      })
XhmikosR's avatar
XhmikosR committed
1916
1917
    })
  }
1918

XhmikosR's avatar
XhmikosR committed
1919
1920
1921
1922
  Tab.prototype.activate = function (element, container, callback) {
    var $active    = container.find('> .active')
    var transition = callback
      && $.support.transition
Mark Otto's avatar
grunt    
Mark Otto committed
1923
      && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
1924

XhmikosR's avatar
XhmikosR committed
1925
1926
1927
1928
1929
    function next() {
      $active
        .removeClass('active')
        .find('> .dropdown-menu > .active')
        .removeClass('active')
1930

XhmikosR's avatar
XhmikosR committed
1931
1932
1933
1934
1935
1936
1937
      element.addClass('active')

      if (transition) {
        element[0].offsetWidth // reflow for transition
        element.addClass('in')
      } else {
        element.removeClass('fade')
1938
      }
1939

XhmikosR's avatar
XhmikosR committed
1940
1941
1942
      if (element.parent('.dropdown-menu')) {
        element.closest('li.dropdown').addClass('active')
      }
fat's avatar
fat committed
1943

XhmikosR's avatar
XhmikosR committed
1944
      callback && callback()
1945
    }
fat's avatar
fat committed
1946

Mark Otto's avatar
grunt    
Mark Otto committed
1947
    $active.length && transition ?
XhmikosR's avatar
XhmikosR committed
1948
1949
1950
1951
      $active
        .one('bsTransitionEnd', next)
        .emulateTransitionEnd(150) :
      next()
1952

XhmikosR's avatar
XhmikosR committed
1953
1954
    $active.removeClass('in')
  }
1955
1956


XhmikosR's avatar
XhmikosR committed
1957
1958
  // TAB PLUGIN DEFINITION
  // =====================
fat's avatar
fat committed
1959

XhmikosR's avatar
XhmikosR committed
1960
1961
1962
1963
  function Plugin(option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.tab')
1964

XhmikosR's avatar
XhmikosR committed
1965
1966
1967
1968
      if (!data) $this.data('bs.tab', (data = new Tab(this)))
      if (typeof option == 'string') data[option]()
    })
  }
Mark Otto's avatar
Mark Otto committed
1969

XhmikosR's avatar
XhmikosR committed
1970
  var old = $.fn.tab
1971

XhmikosR's avatar
XhmikosR committed
1972
1973
  $.fn.tab             = Plugin
  $.fn.tab.Constructor = Tab
1974

1975

XhmikosR's avatar
XhmikosR committed
1976
1977
  // TAB NO CONFLICT
  // ===============
1978

XhmikosR's avatar
XhmikosR committed
1979
1980
1981
1982
  $.fn.tab.noConflict = function () {
    $.fn.tab = old
    return this
  }
1983
1984


XhmikosR's avatar
XhmikosR committed
1985
1986
1987
1988
1989
1990
  // TAB DATA-API
  // ============

  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
    e.preventDefault()
    Plugin.call($(this), 'show')
1991
1992
  })

XhmikosR's avatar
XhmikosR committed
1993
}(jQuery);
1994

1995
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
1996
 * Bootstrap: affix.js v3.2.0
Mark Otto's avatar
Mark Otto committed
1997
 * http://getbootstrap.com/javascript/#affix
1998
 * ========================================================================
1999
 * Copyright 2011-2014 Twitter, Inc.
2000
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2001
 * ======================================================================== */
Mark Otto's avatar
Mark Otto committed
2002
2003


XhmikosR's avatar
XhmikosR committed
2004
2005
+function ($) {
  'use strict';
Mark Otto's avatar
grunt    
Mark Otto committed
2006

XhmikosR's avatar
XhmikosR committed
2007
2008
  // AFFIX CLASS DEFINITION
  // ======================
Mark Otto's avatar
Mark Otto committed
2009

XhmikosR's avatar
XhmikosR committed
2010
2011
  var Affix = function (element, options) {
    this.options = $.extend({}, Affix.DEFAULTS, options)
Mark Otto's avatar
Mark Otto committed
2012

XhmikosR's avatar
XhmikosR committed
2013
2014
2015
    this.$target = $(this.options.target)
      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
Chris Rebert's avatar
Chris Rebert committed
2016

XhmikosR's avatar
XhmikosR committed
2017
2018
2019
2020
    this.$element     = $(element)
    this.affixed      =
    this.unpin        =
    this.pinnedOffset = null
fat's avatar
fat committed
2021

XhmikosR's avatar
XhmikosR committed
2022
2023
    this.checkPosition()
  }
fat's avatar
fat committed
2024

Mark Otto's avatar
Mark Otto committed
2025
  Affix.VERSION  = '3.2.0'
2026

XhmikosR's avatar
XhmikosR committed
2027
  Affix.RESET    = 'affix affix-top affix-bottom'
Mark Otto's avatar
grunt    
Mark Otto committed
2028

XhmikosR's avatar
XhmikosR committed
2029
2030
2031
2032
  Affix.DEFAULTS = {
    offset: 0,
    target: window
  }
2033

XhmikosR's avatar
XhmikosR committed
2034
2035
2036
2037
2038
2039
2040
  Affix.prototype.getPinnedOffset = function () {
    if (this.pinnedOffset) return this.pinnedOffset
    this.$element.removeClass(Affix.RESET).addClass('affix')
    var scrollTop = this.$target.scrollTop()
    var position  = this.$element.offset()
    return (this.pinnedOffset = position.top - scrollTop)
  }
2041

XhmikosR's avatar
XhmikosR committed
2042
2043
2044
  Affix.prototype.checkPositionWithEventLoop = function () {
    setTimeout($.proxy(this.checkPosition, this), 1)
  }
fat's avatar
fat committed
2045

XhmikosR's avatar
XhmikosR committed
2046
2047
  Affix.prototype.checkPosition = function () {
    if (!this.$element.is(':visible')) return
2048

XhmikosR's avatar
XhmikosR committed
2049
2050
2051
2052
2053
2054
    var scrollHeight = $(document).height()
    var scrollTop    = this.$target.scrollTop()
    var position     = this.$element.offset()
    var offset       = this.options.offset
    var offsetTop    = offset.top
    var offsetBottom = offset.bottom
2055

XhmikosR's avatar
XhmikosR committed
2056
2057
2058
    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
2059

XhmikosR's avatar
XhmikosR committed
2060
2061
2062
    var affix = this.unpin   != null && (scrollTop + this.unpin <= position.top) ? false :
                offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
                offsetTop    != null && (scrollTop <= offsetTop) ? 'top' : false
2063

XhmikosR's avatar
XhmikosR committed
2064
2065
    if (this.affixed === affix) return
    if (this.unpin != null) this.$element.css('top', '')
2066

XhmikosR's avatar
XhmikosR committed
2067
2068
    var affixType = 'affix' + (affix ? '-' + affix : '')
    var e         = $.Event(affixType + '.bs.affix')
2069

XhmikosR's avatar
XhmikosR committed
2070
    this.$element.trigger(e)
2071

XhmikosR's avatar
XhmikosR committed
2072
    if (e.isDefaultPrevented()) return
2073

XhmikosR's avatar
XhmikosR committed
2074
2075
    this.affixed = affix
    this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
2076

XhmikosR's avatar
XhmikosR committed
2077
2078
2079
    this.$element
      .removeClass(Affix.RESET)
      .addClass(affixType)
Mark Otto's avatar
grunt    
Mark Otto committed
2080
      .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
2081

XhmikosR's avatar
XhmikosR committed
2082
2083
2084
2085
    if (affix == 'bottom') {
      this.$element.offset({
        top: scrollHeight - this.$element.height() - offsetBottom
      })
2086
    }
XhmikosR's avatar
XhmikosR committed
2087
  }
Mark Otto's avatar
Mark Otto committed
2088

2089

XhmikosR's avatar
XhmikosR committed
2090
2091
  // AFFIX PLUGIN DEFINITION
  // =======================
2092

XhmikosR's avatar
XhmikosR committed
2093
2094
2095
2096
2097
  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.affix')
      var options = typeof option == 'object' && option
2098

XhmikosR's avatar
XhmikosR committed
2099
2100
2101
2102
      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }
2103

XhmikosR's avatar
XhmikosR committed
2104
  var old = $.fn.affix
Mark Otto's avatar
Mark Otto committed
2105

XhmikosR's avatar
XhmikosR committed
2106
2107
  $.fn.affix             = Plugin
  $.fn.affix.Constructor = Affix
2108
2109


XhmikosR's avatar
XhmikosR committed
2110
2111
  // AFFIX NO CONFLICT
  // =================
2112

XhmikosR's avatar
XhmikosR committed
2113
2114
2115
2116
  $.fn.affix.noConflict = function () {
    $.fn.affix = old
    return this
  }
2117
2118


XhmikosR's avatar
XhmikosR committed
2119
2120
  // AFFIX DATA-API
  // ==============
2121

XhmikosR's avatar
XhmikosR committed
2122
2123
2124
2125
  $(window).on('load', function () {
    $('[data-spy="affix"]').each(function () {
      var $spy = $(this)
      var data = $spy.data()
2126

XhmikosR's avatar
XhmikosR committed
2127
      data.offset = data.offset || {}
2128

XhmikosR's avatar
XhmikosR committed
2129
2130
      if (data.offsetBottom) data.offset.bottom = data.offsetBottom
      if (data.offsetTop)    data.offset.top    = data.offsetTop
2131

XhmikosR's avatar
XhmikosR committed
2132
      Plugin.call($spy, data)
2133
    })
Mark Otto's avatar
Mark Otto committed
2134
2135
  })

XhmikosR's avatar
XhmikosR committed
2136
}(jQuery);