weeler 1.0.2 → 1.0.3

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