volt-bootstrap 0.0.6 → 0.0.7

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