bootstrap-sass 3.3.4.1 → 3.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +8 -12
  4. data/CHANGELOG.md +26 -0
  5. data/Gemfile +1 -4
  6. data/LICENSE +2 -1
  7. data/README.md +80 -74
  8. data/Rakefile +46 -11
  9. data/assets/javascripts/bootstrap.js +441 -178
  10. data/assets/javascripts/bootstrap.min.js +4 -5
  11. data/assets/javascripts/bootstrap/affix.js +8 -6
  12. data/assets/javascripts/bootstrap/alert.js +6 -5
  13. data/assets/javascripts/bootstrap/button.js +24 -15
  14. data/assets/javascripts/bootstrap/carousel.js +16 -7
  15. data/assets/javascripts/bootstrap/collapse.js +7 -6
  16. data/assets/javascripts/bootstrap/dropdown.js +49 -45
  17. data/assets/javascripts/bootstrap/modal.js +47 -28
  18. data/assets/javascripts/bootstrap/popover.js +25 -10
  19. data/assets/javascripts/bootstrap/scrollspy.js +4 -4
  20. data/assets/javascripts/bootstrap/tab.js +13 -11
  21. data/assets/javascripts/bootstrap/tooltip.js +232 -31
  22. data/assets/javascripts/bootstrap/transition.js +5 -5
  23. data/assets/stylesheets/_bootstrap-mincer.scss +2 -2
  24. data/assets/stylesheets/_bootstrap.scss +6 -0
  25. data/assets/stylesheets/bootstrap/_alerts.scss +3 -3
  26. data/assets/stylesheets/bootstrap/_badges.scss +3 -3
  27. data/assets/stylesheets/bootstrap/_breadcrumbs.scss +3 -1
  28. data/assets/stylesheets/bootstrap/_button-groups.scss +9 -8
  29. data/assets/stylesheets/bootstrap/_buttons.scss +17 -9
  30. data/assets/stylesheets/bootstrap/_carousel.scss +34 -32
  31. data/assets/stylesheets/bootstrap/_close.scss +1 -0
  32. data/assets/stylesheets/bootstrap/_code.scss +3 -3
  33. data/assets/stylesheets/bootstrap/_component-animations.scss +1 -0
  34. data/assets/stylesheets/bootstrap/_dropdowns.scss +22 -23
  35. data/assets/stylesheets/bootstrap/_forms.scss +101 -72
  36. data/assets/stylesheets/bootstrap/_glyphicons.scss +15 -13
  37. data/assets/stylesheets/bootstrap/_grid.scss +10 -0
  38. data/assets/stylesheets/bootstrap/_input-groups.scss +10 -5
  39. data/assets/stylesheets/bootstrap/_jumbotron.scss +8 -4
  40. data/assets/stylesheets/bootstrap/_labels.scss +1 -1
  41. data/assets/stylesheets/bootstrap/_list-group.scss +30 -26
  42. data/assets/stylesheets/bootstrap/_media.scss +6 -1
  43. data/assets/stylesheets/bootstrap/_mixins.scss +1 -0
  44. data/assets/stylesheets/bootstrap/_modals.scss +8 -8
  45. data/assets/stylesheets/bootstrap/_navbar.scss +75 -81
  46. data/assets/stylesheets/bootstrap/_navs.scss +4 -4
  47. data/assets/stylesheets/bootstrap/_normalize.scss +13 -13
  48. data/assets/stylesheets/bootstrap/_pager.scss +2 -2
  49. data/assets/stylesheets/bootstrap/_pagination.scss +15 -17
  50. data/assets/stylesheets/bootstrap/_panels.scss +11 -5
  51. data/assets/stylesheets/bootstrap/_popovers.scss +50 -59
  52. data/assets/stylesheets/bootstrap/_print.scss +90 -98
  53. data/assets/stylesheets/bootstrap/_progress-bars.scss +3 -3
  54. data/assets/stylesheets/bootstrap/_responsive-embed.scss +2 -2
  55. data/assets/stylesheets/bootstrap/_responsive-utilities.scss +7 -5
  56. data/assets/stylesheets/bootstrap/_scaffolding.scss +8 -9
  57. data/assets/stylesheets/bootstrap/_tables.scss +23 -23
  58. data/assets/stylesheets/bootstrap/_theme.scss +42 -20
  59. data/assets/stylesheets/bootstrap/_thumbnails.scss +1 -1
  60. data/assets/stylesheets/bootstrap/_tooltip.scss +42 -32
  61. data/assets/stylesheets/bootstrap/_type.scss +11 -11
  62. data/assets/stylesheets/bootstrap/_variables.scss +16 -8
  63. data/assets/stylesheets/bootstrap/_wells.scss +2 -2
  64. data/assets/stylesheets/bootstrap/mixins/_alerts.scss +2 -1
  65. data/assets/stylesheets/bootstrap/mixins/_background-variant.scss +2 -1
  66. data/assets/stylesheets/bootstrap/mixins/_border-radius.scss +4 -4
  67. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +20 -11
  68. data/assets/stylesheets/bootstrap/mixins/_center-block.scss +1 -1
  69. data/assets/stylesheets/bootstrap/mixins/_clearfix.scss +1 -1
  70. data/assets/stylesheets/bootstrap/mixins/_forms.scss +4 -4
  71. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +6 -8
  72. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +2 -2
  73. data/assets/stylesheets/bootstrap/mixins/_grid.scss +8 -8
  74. data/assets/stylesheets/bootstrap/mixins/_hide-text.scss +2 -2
  75. data/assets/stylesheets/bootstrap/mixins/_image.scss +5 -10
  76. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +3 -2
  77. data/assets/stylesheets/bootstrap/mixins/_opacity.scss +2 -3
  78. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +2 -1
  79. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +18 -0
  80. data/assets/stylesheets/bootstrap/mixins/_resize.scss +1 -1
  81. data/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +1 -5
  82. data/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +3 -3
  83. data/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +2 -1
  84. data/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +3 -3
  85. data/bootstrap-sass.gemspec +10 -9
  86. data/bower.json +5 -9
  87. data/composer.json +2 -2
  88. data/eyeglass-exports.js +7 -0
  89. data/lib/bootstrap-sass.rb +18 -11
  90. data/lib/bootstrap-sass/engine.rb +6 -1
  91. data/lib/bootstrap-sass/version.rb +2 -2
  92. data/package-lock.json +1611 -0
  93. data/package.json +20 -6
  94. data/sache.json +1 -1
  95. data/tasks/converter/less_conversion.rb +20 -9
  96. data/tasks/converter/network.rb +2 -2
  97. data/templates/project/_bootstrap-variables.sass +17 -9
  98. data/test/compilation_test.rb +24 -12
  99. data/test/dummy_rails/config/application.rb +2 -1
  100. data/test/dummy_rails/config/boot.rb +1 -1
  101. data/test/dummy_sass_only/Gemfile +1 -1
  102. data/test/dummy_sass_only/compile.rb +14 -7
  103. data/test/dummy_sass_only/import_all.scss +2 -0
  104. data/test/gemfiles/default.gemfile +3 -0
  105. data/test/node_mincer_test.rb +2 -3
  106. data/test/node_sass_compile_test.sh +4 -3
  107. data/test/sass_test.rb +10 -7
  108. data/test/sprockets_rails_test.rb +12 -8
  109. data/test/support/dummy_rails_integration.rb +1 -1
  110. data/test/support/reporting.rb +10 -0
  111. data/test/test_helper.rb +3 -2
  112. metadata +38 -29
  113. data/test/compass_test.rb +0 -9
  114. data/test/dummy_sass_only/import_all.sass +0 -2
  115. data/test/gemfiles/sass_3_2.gemfile +0 -6
  116. data/test/gemfiles/sass_3_3.gemfile +0 -6
  117. data/test/gemfiles/sass_3_4.gemfile +0 -7
  118. data/test/gemfiles/sass_head.gemfile +0 -6
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * Bootstrap v3.3.4 (http://getbootstrap.com)
3
- * Copyright 2011-2015 Twitter, Inc.
4
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2
+ * Bootstrap v3.4.1 (https://getbootstrap.com/)
3
+ * Copyright 2011-2019 Twitter, Inc.
4
+ * Licensed under the MIT license
5
5
  */
6
6
 
7
7
  if (typeof jQuery === 'undefined') {
@@ -11,16 +11,16 @@ if (typeof jQuery === 'undefined') {
11
11
  +function ($) {
12
12
  'use strict';
13
13
  var version = $.fn.jquery.split(' ')[0].split('.')
14
- if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
15
- throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
14
+ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
15
+ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
16
16
  }
17
17
  }(jQuery);
18
18
 
19
19
  /* ========================================================================
20
- * Bootstrap: transition.js v3.3.4
21
- * http://getbootstrap.com/javascript/#transitions
20
+ * Bootstrap: transition.js v3.4.1
21
+ * https://getbootstrap.com/docs/3.4/javascript/#transitions
22
22
  * ========================================================================
23
- * Copyright 2011-2015 Twitter, Inc.
23
+ * Copyright 2011-2019 Twitter, Inc.
24
24
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
25
25
  * ======================================================================== */
26
26
 
@@ -28,7 +28,7 @@ if (typeof jQuery === 'undefined') {
28
28
  +function ($) {
29
29
  'use strict';
30
30
 
31
- // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
31
+ // CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/)
32
32
  // ============================================================
33
33
 
34
34
  function transitionEnd() {
@@ -50,7 +50,7 @@ if (typeof jQuery === 'undefined') {
50
50
  return false // explicit for ie8 ( ._.)
51
51
  }
52
52
 
53
- // http://blog.alexmaccaw.com/css-transitions
53
+ // https://blog.alexmaccaw.com/css-transitions
54
54
  $.fn.emulateTransitionEnd = function (duration) {
55
55
  var called = false
56
56
  var $el = this
@@ -77,10 +77,10 @@ if (typeof jQuery === 'undefined') {
77
77
  }(jQuery);
78
78
 
79
79
  /* ========================================================================
80
- * Bootstrap: alert.js v3.3.4
81
- * http://getbootstrap.com/javascript/#alerts
80
+ * Bootstrap: alert.js v3.4.1
81
+ * https://getbootstrap.com/docs/3.4/javascript/#alerts
82
82
  * ========================================================================
83
- * Copyright 2011-2015 Twitter, Inc.
83
+ * Copyright 2011-2019 Twitter, Inc.
84
84
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
85
85
  * ======================================================================== */
86
86
 
@@ -96,7 +96,7 @@ if (typeof jQuery === 'undefined') {
96
96
  $(el).on('click', dismiss, this.close)
97
97
  }
98
98
 
99
- Alert.VERSION = '3.3.4'
99
+ Alert.VERSION = '3.4.1'
100
100
 
101
101
  Alert.TRANSITION_DURATION = 150
102
102
 
@@ -109,7 +109,8 @@ if (typeof jQuery === 'undefined') {
109
109
  selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
110
110
  }
111
111
 
112
- var $parent = $(selector)
112
+ selector = selector === '#' ? [] : selector
113
+ var $parent = $(document).find(selector)
113
114
 
114
115
  if (e) e.preventDefault()
115
116
 
@@ -172,10 +173,10 @@ if (typeof jQuery === 'undefined') {
172
173
  }(jQuery);
173
174
 
174
175
  /* ========================================================================
175
- * Bootstrap: button.js v3.3.4
176
- * http://getbootstrap.com/javascript/#buttons
176
+ * Bootstrap: button.js v3.4.1
177
+ * https://getbootstrap.com/docs/3.4/javascript/#buttons
177
178
  * ========================================================================
178
- * Copyright 2011-2015 Twitter, Inc.
179
+ * Copyright 2011-2019 Twitter, Inc.
179
180
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
180
181
  * ======================================================================== */
181
182
 
@@ -192,7 +193,7 @@ if (typeof jQuery === 'undefined') {
192
193
  this.isLoading = false
193
194
  }
194
195
 
195
- Button.VERSION = '3.3.4'
196
+ Button.VERSION = '3.4.1'
196
197
 
197
198
  Button.DEFAULTS = {
198
199
  loadingText: 'loading...'
@@ -204,7 +205,7 @@ if (typeof jQuery === 'undefined') {
204
205
  var val = $el.is('input') ? 'val' : 'html'
205
206
  var data = $el.data()
206
207
 
207
- state = state + 'Text'
208
+ state += 'Text'
208
209
 
209
210
  if (data.resetText == null) $el.data('resetText', $el[val]())
210
211
 
@@ -214,10 +215,10 @@ if (typeof jQuery === 'undefined') {
214
215
 
215
216
  if (state == 'loadingText') {
216
217
  this.isLoading = true
217
- $el.addClass(d).attr(d, d)
218
+ $el.addClass(d).attr(d, d).prop(d, true)
218
219
  } else if (this.isLoading) {
219
220
  this.isLoading = false
220
- $el.removeClass(d).removeAttr(d)
221
+ $el.removeClass(d).removeAttr(d).prop(d, false)
221
222
  }
222
223
  }, this), 0)
223
224
  }
@@ -229,15 +230,19 @@ if (typeof jQuery === 'undefined') {
229
230
  if ($parent.length) {
230
231
  var $input = this.$element.find('input')
231
232
  if ($input.prop('type') == 'radio') {
232
- if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
233
- else $parent.find('.active').removeClass('active')
233
+ if ($input.prop('checked')) changed = false
234
+ $parent.find('.active').removeClass('active')
235
+ this.$element.addClass('active')
236
+ } else if ($input.prop('type') == 'checkbox') {
237
+ if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
238
+ this.$element.toggleClass('active')
234
239
  }
235
- if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
240
+ $input.prop('checked', this.$element.hasClass('active'))
241
+ if (changed) $input.trigger('change')
236
242
  } else {
237
243
  this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
244
+ this.$element.toggleClass('active')
238
245
  }
239
-
240
- if (changed) this.$element.toggleClass('active')
241
246
  }
242
247
 
243
248
 
@@ -277,10 +282,15 @@ if (typeof jQuery === 'undefined') {
277
282
 
278
283
  $(document)
279
284
  .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
280
- var $btn = $(e.target)
281
- if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
285
+ var $btn = $(e.target).closest('.btn')
282
286
  Plugin.call($btn, 'toggle')
283
- e.preventDefault()
287
+ if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
288
+ // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
289
+ e.preventDefault()
290
+ // The target component still receive the focus
291
+ if ($btn.is('input,button')) $btn.trigger('focus')
292
+ else $btn.find('input:visible,button:visible').first().trigger('focus')
293
+ }
284
294
  })
285
295
  .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
286
296
  $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
@@ -289,10 +299,10 @@ if (typeof jQuery === 'undefined') {
289
299
  }(jQuery);
290
300
 
291
301
  /* ========================================================================
292
- * Bootstrap: carousel.js v3.3.4
293
- * http://getbootstrap.com/javascript/#carousel
302
+ * Bootstrap: carousel.js v3.4.1
303
+ * https://getbootstrap.com/docs/3.4/javascript/#carousel
294
304
  * ========================================================================
295
- * Copyright 2011-2015 Twitter, Inc.
305
+ * Copyright 2011-2019 Twitter, Inc.
296
306
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
297
307
  * ======================================================================== */
298
308
 
@@ -320,7 +330,7 @@ if (typeof jQuery === 'undefined') {
320
330
  .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
321
331
  }
322
332
 
323
- Carousel.VERSION = '3.3.4'
333
+ Carousel.VERSION = '3.4.1'
324
334
 
325
335
  Carousel.TRANSITION_DURATION = 600
326
336
 
@@ -434,7 +444,9 @@ if (typeof jQuery === 'undefined') {
434
444
  var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
435
445
  if ($.support.transition && this.$element.hasClass('slide')) {
436
446
  $next.addClass(type)
437
- $next[0].offsetWidth // force reflow
447
+ if (typeof $next === 'object' && $next.length) {
448
+ $next[0].offsetWidth // force reflow
449
+ }
438
450
  $active.addClass(direction)
439
451
  $next.addClass(direction)
440
452
  $active
@@ -496,10 +508,17 @@ if (typeof jQuery === 'undefined') {
496
508
  // =================
497
509
 
498
510
  var clickHandler = function (e) {
499
- var href
500
511
  var $this = $(this)
501
- var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
512
+ var href = $this.attr('href')
513
+ if (href) {
514
+ href = href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
515
+ }
516
+
517
+ var target = $this.attr('data-target') || href
518
+ var $target = $(document).find(target)
519
+
502
520
  if (!$target.hasClass('carousel')) return
521
+
503
522
  var options = $.extend({}, $target.data(), $this.data())
504
523
  var slideIndex = $this.attr('data-slide-to')
505
524
  if (slideIndex) options.interval = false
@@ -527,13 +546,14 @@ if (typeof jQuery === 'undefined') {
527
546
  }(jQuery);
528
547
 
529
548
  /* ========================================================================
530
- * Bootstrap: collapse.js v3.3.4
531
- * http://getbootstrap.com/javascript/#collapse
549
+ * Bootstrap: collapse.js v3.4.1
550
+ * https://getbootstrap.com/docs/3.4/javascript/#collapse
532
551
  * ========================================================================
533
- * Copyright 2011-2015 Twitter, Inc.
552
+ * Copyright 2011-2019 Twitter, Inc.
534
553
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
535
554
  * ======================================================================== */
536
555
 
556
+ /* jshint latedef: false */
537
557
 
538
558
  +function ($) {
539
559
  'use strict';
@@ -557,7 +577,7 @@ if (typeof jQuery === 'undefined') {
557
577
  if (this.options.toggle) this.toggle()
558
578
  }
559
579
 
560
- Collapse.VERSION = '3.3.4'
580
+ Collapse.VERSION = '3.4.1'
561
581
 
562
582
  Collapse.TRANSITION_DURATION = 350
563
583
 
@@ -664,7 +684,7 @@ if (typeof jQuery === 'undefined') {
664
684
  }
665
685
 
666
686
  Collapse.prototype.getParent = function () {
667
- return $(this.options.parent)
687
+ return $(document).find(this.options.parent)
668
688
  .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
669
689
  .each($.proxy(function (i, element) {
670
690
  var $element = $(element)
@@ -687,7 +707,7 @@ if (typeof jQuery === 'undefined') {
687
707
  var target = $trigger.attr('data-target')
688
708
  || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
689
709
 
690
- return $(target)
710
+ return $(document).find(target)
691
711
  }
692
712
 
693
713
 
@@ -739,10 +759,10 @@ if (typeof jQuery === 'undefined') {
739
759
  }(jQuery);
740
760
 
741
761
  /* ========================================================================
742
- * Bootstrap: dropdown.js v3.3.4
743
- * http://getbootstrap.com/javascript/#dropdowns
762
+ * Bootstrap: dropdown.js v3.4.1
763
+ * https://getbootstrap.com/docs/3.4/javascript/#dropdowns
744
764
  * ========================================================================
745
- * Copyright 2011-2015 Twitter, Inc.
765
+ * Copyright 2011-2019 Twitter, Inc.
746
766
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
747
767
  * ======================================================================== */
748
768
 
@@ -759,7 +779,41 @@ if (typeof jQuery === 'undefined') {
759
779
  $(element).on('click.bs.dropdown', this.toggle)
760
780
  }
761
781
 
762
- Dropdown.VERSION = '3.3.4'
782
+ Dropdown.VERSION = '3.4.1'
783
+
784
+ function getParent($this) {
785
+ var selector = $this.attr('data-target')
786
+
787
+ if (!selector) {
788
+ selector = $this.attr('href')
789
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
790
+ }
791
+
792
+ var $parent = selector !== '#' ? $(document).find(selector) : null
793
+
794
+ return $parent && $parent.length ? $parent : $this.parent()
795
+ }
796
+
797
+ function clearMenus(e) {
798
+ if (e && e.which === 3) return
799
+ $(backdrop).remove()
800
+ $(toggle).each(function () {
801
+ var $this = $(this)
802
+ var $parent = getParent($this)
803
+ var relatedTarget = { relatedTarget: this }
804
+
805
+ if (!$parent.hasClass('open')) return
806
+
807
+ if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
808
+
809
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
810
+
811
+ if (e.isDefaultPrevented()) return
812
+
813
+ $this.attr('aria-expanded', 'false')
814
+ $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
815
+ })
816
+ }
763
817
 
764
818
  Dropdown.prototype.toggle = function (e) {
765
819
  var $this = $(this)
@@ -774,7 +828,10 @@ if (typeof jQuery === 'undefined') {
774
828
  if (!isActive) {
775
829
  if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
776
830
  // if mobile we use a backdrop because click events don't delegate
777
- $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
831
+ $(document.createElement('div'))
832
+ .addClass('dropdown-backdrop')
833
+ .insertAfter($(this))
834
+ .on('click', clearMenus)
778
835
  }
779
836
 
780
837
  var relatedTarget = { relatedTarget: this }
@@ -788,7 +845,7 @@ if (typeof jQuery === 'undefined') {
788
845
 
789
846
  $parent
790
847
  .toggleClass('open')
791
- .trigger('shown.bs.dropdown', relatedTarget)
848
+ .trigger($.Event('shown.bs.dropdown', relatedTarget))
792
849
  }
793
850
 
794
851
  return false
@@ -807,57 +864,25 @@ if (typeof jQuery === 'undefined') {
807
864
  var $parent = getParent($this)
808
865
  var isActive = $parent.hasClass('open')
809
866
 
810
- if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
867
+ if (!isActive && e.which != 27 || isActive && e.which == 27) {
811
868
  if (e.which == 27) $parent.find(toggle).trigger('focus')
812
869
  return $this.trigger('click')
813
870
  }
814
871
 
815
872
  var desc = ' li:not(.disabled):visible a'
816
- var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
873
+ var $items = $parent.find('.dropdown-menu' + desc)
817
874
 
818
875
  if (!$items.length) return
819
876
 
820
877
  var index = $items.index(e.target)
821
878
 
822
- if (e.which == 38 && index > 0) index-- // up
823
- if (e.which == 40 && index < $items.length - 1) index++ // down
824
- if (!~index) index = 0
879
+ if (e.which == 38 && index > 0) index-- // up
880
+ if (e.which == 40 && index < $items.length - 1) index++ // down
881
+ if (!~index) index = 0
825
882
 
826
883
  $items.eq(index).trigger('focus')
827
884
  }
828
885
 
829
- function clearMenus(e) {
830
- if (e && e.which === 3) return
831
- $(backdrop).remove()
832
- $(toggle).each(function () {
833
- var $this = $(this)
834
- var $parent = getParent($this)
835
- var relatedTarget = { relatedTarget: this }
836
-
837
- if (!$parent.hasClass('open')) return
838
-
839
- $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
840
-
841
- if (e.isDefaultPrevented()) return
842
-
843
- $this.attr('aria-expanded', 'false')
844
- $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
845
- })
846
- }
847
-
848
- function getParent($this) {
849
- var selector = $this.attr('data-target')
850
-
851
- if (!selector) {
852
- selector = $this.attr('href')
853
- selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
854
- }
855
-
856
- var $parent = selector && $(selector)
857
-
858
- return $parent && $parent.length ? $parent : $this.parent()
859
- }
860
-
861
886
 
862
887
  // DROPDOWN PLUGIN DEFINITION
863
888
  // ==========================
@@ -895,16 +920,15 @@ if (typeof jQuery === 'undefined') {
895
920
  .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
896
921
  .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
897
922
  .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
898
- .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
899
- .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
923
+ .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
900
924
 
901
925
  }(jQuery);
902
926
 
903
927
  /* ========================================================================
904
- * Bootstrap: modal.js v3.3.4
905
- * http://getbootstrap.com/javascript/#modals
928
+ * Bootstrap: modal.js v3.4.1
929
+ * https://getbootstrap.com/docs/3.4/javascript/#modals
906
930
  * ========================================================================
907
- * Copyright 2011-2015 Twitter, Inc.
931
+ * Copyright 2011-2019 Twitter, Inc.
908
932
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
909
933
  * ======================================================================== */
910
934
 
@@ -916,15 +940,16 @@ if (typeof jQuery === 'undefined') {
916
940
  // ======================
917
941
 
918
942
  var Modal = function (element, options) {
919
- this.options = options
920
- this.$body = $(document.body)
921
- this.$element = $(element)
922
- this.$dialog = this.$element.find('.modal-dialog')
923
- this.$backdrop = null
924
- this.isShown = null
925
- this.originalBodyPad = null
926
- this.scrollbarWidth = 0
943
+ this.options = options
944
+ this.$body = $(document.body)
945
+ this.$element = $(element)
946
+ this.$dialog = this.$element.find('.modal-dialog')
947
+ this.$backdrop = null
948
+ this.isShown = null
949
+ this.originalBodyPad = null
950
+ this.scrollbarWidth = 0
927
951
  this.ignoreBackdropClick = false
952
+ this.fixedContent = '.navbar-fixed-top, .navbar-fixed-bottom'
928
953
 
929
954
  if (this.options.remote) {
930
955
  this.$element
@@ -935,7 +960,7 @@ if (typeof jQuery === 'undefined') {
935
960
  }
936
961
  }
937
962
 
938
- Modal.VERSION = '3.3.4'
963
+ Modal.VERSION = '3.4.1'
939
964
 
940
965
  Modal.TRANSITION_DURATION = 300
941
966
  Modal.BACKDROP_TRANSITION_DURATION = 150
@@ -952,7 +977,7 @@ if (typeof jQuery === 'undefined') {
952
977
 
953
978
  Modal.prototype.show = function (_relatedTarget) {
954
979
  var that = this
955
- var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
980
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
956
981
 
957
982
  this.$element.trigger(e)
958
983
 
@@ -992,9 +1017,7 @@ if (typeof jQuery === 'undefined') {
992
1017
  that.$element[0].offsetWidth // force reflow
993
1018
  }
994
1019
 
995
- that.$element
996
- .addClass('in')
997
- .attr('aria-hidden', false)
1020
+ that.$element.addClass('in')
998
1021
 
999
1022
  that.enforceFocus()
1000
1023
 
@@ -1028,7 +1051,6 @@ if (typeof jQuery === 'undefined') {
1028
1051
 
1029
1052
  this.$element
1030
1053
  .removeClass('in')
1031
- .attr('aria-hidden', true)
1032
1054
  .off('click.dismiss.bs.modal')
1033
1055
  .off('mouseup.dismiss.bs.modal')
1034
1056
 
@@ -1045,7 +1067,9 @@ if (typeof jQuery === 'undefined') {
1045
1067
  $(document)
1046
1068
  .off('focusin.bs.modal') // guard against infinite focus loop
1047
1069
  .on('focusin.bs.modal', $.proxy(function (e) {
1048
- if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
1070
+ if (document !== e.target &&
1071
+ this.$element[0] !== e.target &&
1072
+ !this.$element.has(e.target).length) {
1049
1073
  this.$element.trigger('focus')
1050
1074
  }
1051
1075
  }, this))
@@ -1092,7 +1116,8 @@ if (typeof jQuery === 'undefined') {
1092
1116
  if (this.isShown && this.options.backdrop) {
1093
1117
  var doAnimate = $.support.transition && animate
1094
1118
 
1095
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
1119
+ this.$backdrop = $(document.createElement('div'))
1120
+ .addClass('modal-backdrop ' + animate)
1096
1121
  .appendTo(this.$body)
1097
1122
 
1098
1123
  this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
@@ -1146,7 +1171,7 @@ if (typeof jQuery === 'undefined') {
1146
1171
  var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
1147
1172
 
1148
1173
  this.$element.css({
1149
- paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
1174
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
1150
1175
  paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
1151
1176
  })
1152
1177
  }
@@ -1171,11 +1196,26 @@ if (typeof jQuery === 'undefined') {
1171
1196
  Modal.prototype.setScrollbar = function () {
1172
1197
  var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
1173
1198
  this.originalBodyPad = document.body.style.paddingRight || ''
1174
- if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
1199
+ var scrollbarWidth = this.scrollbarWidth
1200
+ if (this.bodyIsOverflowing) {
1201
+ this.$body.css('padding-right', bodyPad + scrollbarWidth)
1202
+ $(this.fixedContent).each(function (index, element) {
1203
+ var actualPadding = element.style.paddingRight
1204
+ var calculatedPadding = $(element).css('padding-right')
1205
+ $(element)
1206
+ .data('padding-right', actualPadding)
1207
+ .css('padding-right', parseFloat(calculatedPadding) + scrollbarWidth + 'px')
1208
+ })
1209
+ }
1175
1210
  }
1176
1211
 
1177
1212
  Modal.prototype.resetScrollbar = function () {
1178
1213
  this.$body.css('padding-right', this.originalBodyPad)
1214
+ $(this.fixedContent).each(function (index, element) {
1215
+ var padding = $(element).data('padding-right')
1216
+ $(element).removeData('padding-right')
1217
+ element.style.paddingRight = padding ? padding : ''
1218
+ })
1179
1219
  }
1180
1220
 
1181
1221
  Modal.prototype.measureScrollbar = function () { // thx walsh
@@ -1193,8 +1233,8 @@ if (typeof jQuery === 'undefined') {
1193
1233
 
1194
1234
  function Plugin(option, _relatedTarget) {
1195
1235
  return this.each(function () {
1196
- var $this = $(this)
1197
- var data = $this.data('bs.modal')
1236
+ var $this = $(this)
1237
+ var data = $this.data('bs.modal')
1198
1238
  var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
1199
1239
 
1200
1240
  if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
@@ -1205,7 +1245,7 @@ if (typeof jQuery === 'undefined') {
1205
1245
 
1206
1246
  var old = $.fn.modal
1207
1247
 
1208
- $.fn.modal = Plugin
1248
+ $.fn.modal = Plugin
1209
1249
  $.fn.modal.Constructor = Modal
1210
1250
 
1211
1251
 
@@ -1222,10 +1262,13 @@ if (typeof jQuery === 'undefined') {
1222
1262
  // ==============
1223
1263
 
1224
1264
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
1225
- var $this = $(this)
1226
- var href = $this.attr('href')
1227
- var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
1228
- var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
1265
+ var $this = $(this)
1266
+ var href = $this.attr('href')
1267
+ var target = $this.attr('data-target') ||
1268
+ (href && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
1269
+
1270
+ var $target = $(document).find(target)
1271
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
1229
1272
 
1230
1273
  if ($this.is('a')) e.preventDefault()
1231
1274
 
@@ -1241,18 +1284,148 @@ if (typeof jQuery === 'undefined') {
1241
1284
  }(jQuery);
1242
1285
 
1243
1286
  /* ========================================================================
1244
- * Bootstrap: tooltip.js v3.3.4
1245
- * http://getbootstrap.com/javascript/#tooltip
1287
+ * Bootstrap: tooltip.js v3.4.1
1288
+ * https://getbootstrap.com/docs/3.4/javascript/#tooltip
1246
1289
  * Inspired by the original jQuery.tipsy by Jason Frame
1247
1290
  * ========================================================================
1248
- * Copyright 2011-2015 Twitter, Inc.
1291
+ * Copyright 2011-2019 Twitter, Inc.
1249
1292
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1250
1293
  * ======================================================================== */
1251
1294
 
1252
-
1253
1295
  +function ($) {
1254
1296
  'use strict';
1255
1297
 
1298
+ var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']
1299
+
1300
+ var uriAttrs = [
1301
+ 'background',
1302
+ 'cite',
1303
+ 'href',
1304
+ 'itemtype',
1305
+ 'longdesc',
1306
+ 'poster',
1307
+ 'src',
1308
+ 'xlink:href'
1309
+ ]
1310
+
1311
+ var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
1312
+
1313
+ var DefaultWhitelist = {
1314
+ // Global attributes allowed on any supplied element below.
1315
+ '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
1316
+ a: ['target', 'href', 'title', 'rel'],
1317
+ area: [],
1318
+ b: [],
1319
+ br: [],
1320
+ col: [],
1321
+ code: [],
1322
+ div: [],
1323
+ em: [],
1324
+ hr: [],
1325
+ h1: [],
1326
+ h2: [],
1327
+ h3: [],
1328
+ h4: [],
1329
+ h5: [],
1330
+ h6: [],
1331
+ i: [],
1332
+ img: ['src', 'alt', 'title', 'width', 'height'],
1333
+ li: [],
1334
+ ol: [],
1335
+ p: [],
1336
+ pre: [],
1337
+ s: [],
1338
+ small: [],
1339
+ span: [],
1340
+ sub: [],
1341
+ sup: [],
1342
+ strong: [],
1343
+ u: [],
1344
+ ul: []
1345
+ }
1346
+
1347
+ /**
1348
+ * A pattern that recognizes a commonly useful subset of URLs that are safe.
1349
+ *
1350
+ * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
1351
+ */
1352
+ var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi
1353
+
1354
+ /**
1355
+ * A pattern that matches safe data URLs. Only matches image, video and audio types.
1356
+ *
1357
+ * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
1358
+ */
1359
+ var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i
1360
+
1361
+ function allowedAttribute(attr, allowedAttributeList) {
1362
+ var attrName = attr.nodeName.toLowerCase()
1363
+
1364
+ if ($.inArray(attrName, allowedAttributeList) !== -1) {
1365
+ if ($.inArray(attrName, uriAttrs) !== -1) {
1366
+ return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))
1367
+ }
1368
+
1369
+ return true
1370
+ }
1371
+
1372
+ var regExp = $(allowedAttributeList).filter(function (index, value) {
1373
+ return value instanceof RegExp
1374
+ })
1375
+
1376
+ // Check if a regular expression validates the attribute.
1377
+ for (var i = 0, l = regExp.length; i < l; i++) {
1378
+ if (attrName.match(regExp[i])) {
1379
+ return true
1380
+ }
1381
+ }
1382
+
1383
+ return false
1384
+ }
1385
+
1386
+ function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
1387
+ if (unsafeHtml.length === 0) {
1388
+ return unsafeHtml
1389
+ }
1390
+
1391
+ if (sanitizeFn && typeof sanitizeFn === 'function') {
1392
+ return sanitizeFn(unsafeHtml)
1393
+ }
1394
+
1395
+ // IE 8 and below don't support createHTMLDocument
1396
+ if (!document.implementation || !document.implementation.createHTMLDocument) {
1397
+ return unsafeHtml
1398
+ }
1399
+
1400
+ var createdDocument = document.implementation.createHTMLDocument('sanitization')
1401
+ createdDocument.body.innerHTML = unsafeHtml
1402
+
1403
+ var whitelistKeys = $.map(whiteList, function (el, i) { return i })
1404
+ var elements = $(createdDocument.body).find('*')
1405
+
1406
+ for (var i = 0, len = elements.length; i < len; i++) {
1407
+ var el = elements[i]
1408
+ var elName = el.nodeName.toLowerCase()
1409
+
1410
+ if ($.inArray(elName, whitelistKeys) === -1) {
1411
+ el.parentNode.removeChild(el)
1412
+
1413
+ continue
1414
+ }
1415
+
1416
+ var attributeList = $.map(el.attributes, function (el) { return el })
1417
+ var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])
1418
+
1419
+ for (var j = 0, len2 = attributeList.length; j < len2; j++) {
1420
+ if (!allowedAttribute(attributeList[j], whitelistedAttributes)) {
1421
+ el.removeAttribute(attributeList[j].nodeName)
1422
+ }
1423
+ }
1424
+ }
1425
+
1426
+ return createdDocument.body.innerHTML
1427
+ }
1428
+
1256
1429
  // TOOLTIP PUBLIC CLASS DEFINITION
1257
1430
  // ===============================
1258
1431
 
@@ -1263,11 +1436,12 @@ if (typeof jQuery === 'undefined') {
1263
1436
  this.timeout = null
1264
1437
  this.hoverState = null
1265
1438
  this.$element = null
1439
+ this.inState = null
1266
1440
 
1267
1441
  this.init('tooltip', element, options)
1268
1442
  }
1269
1443
 
1270
- Tooltip.VERSION = '3.3.4'
1444
+ Tooltip.VERSION = '3.4.1'
1271
1445
 
1272
1446
  Tooltip.TRANSITION_DURATION = 150
1273
1447
 
@@ -1284,7 +1458,10 @@ if (typeof jQuery === 'undefined') {
1284
1458
  viewport: {
1285
1459
  selector: 'body',
1286
1460
  padding: 0
1287
- }
1461
+ },
1462
+ sanitize : true,
1463
+ sanitizeFn : null,
1464
+ whiteList : DefaultWhitelist
1288
1465
  }
1289
1466
 
1290
1467
  Tooltip.prototype.init = function (type, element, options) {
@@ -1292,7 +1469,8 @@ if (typeof jQuery === 'undefined') {
1292
1469
  this.type = type
1293
1470
  this.$element = $(element)
1294
1471
  this.options = this.getOptions(options)
1295
- this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
1472
+ this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
1473
+ this.inState = { click: false, hover: false, focus: false }
1296
1474
 
1297
1475
  if (this.$element[0] instanceof document.constructor && !this.options.selector) {
1298
1476
  throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
@@ -1324,7 +1502,15 @@ if (typeof jQuery === 'undefined') {
1324
1502
  }
1325
1503
 
1326
1504
  Tooltip.prototype.getOptions = function (options) {
1327
- options = $.extend({}, this.getDefaults(), this.$element.data(), options)
1505
+ var dataAttributes = this.$element.data()
1506
+
1507
+ for (var dataAttr in dataAttributes) {
1508
+ if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) {
1509
+ delete dataAttributes[dataAttr]
1510
+ }
1511
+ }
1512
+
1513
+ options = $.extend({}, this.getDefaults(), dataAttributes, options)
1328
1514
 
1329
1515
  if (options.delay && typeof options.delay == 'number') {
1330
1516
  options.delay = {
@@ -1333,6 +1519,10 @@ if (typeof jQuery === 'undefined') {
1333
1519
  }
1334
1520
  }
1335
1521
 
1522
+ if (options.sanitize) {
1523
+ options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn)
1524
+ }
1525
+
1336
1526
  return options
1337
1527
  }
1338
1528
 
@@ -1351,16 +1541,20 @@ if (typeof jQuery === 'undefined') {
1351
1541
  var self = obj instanceof this.constructor ?
1352
1542
  obj : $(obj.currentTarget).data('bs.' + this.type)
1353
1543
 
1354
- if (self && self.$tip && self.$tip.is(':visible')) {
1355
- self.hoverState = 'in'
1356
- return
1357
- }
1358
-
1359
1544
  if (!self) {
1360
1545
  self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1361
1546
  $(obj.currentTarget).data('bs.' + this.type, self)
1362
1547
  }
1363
1548
 
1549
+ if (obj instanceof $.Event) {
1550
+ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
1551
+ }
1552
+
1553
+ if (self.tip().hasClass('in') || self.hoverState == 'in') {
1554
+ self.hoverState = 'in'
1555
+ return
1556
+ }
1557
+
1364
1558
  clearTimeout(self.timeout)
1365
1559
 
1366
1560
  self.hoverState = 'in'
@@ -1372,6 +1566,14 @@ if (typeof jQuery === 'undefined') {
1372
1566
  }, self.options.delay.show)
1373
1567
  }
1374
1568
 
1569
+ Tooltip.prototype.isInStateTrue = function () {
1570
+ for (var key in this.inState) {
1571
+ if (this.inState[key]) return true
1572
+ }
1573
+
1574
+ return false
1575
+ }
1576
+
1375
1577
  Tooltip.prototype.leave = function (obj) {
1376
1578
  var self = obj instanceof this.constructor ?
1377
1579
  obj : $(obj.currentTarget).data('bs.' + this.type)
@@ -1381,6 +1583,12 @@ if (typeof jQuery === 'undefined') {
1381
1583
  $(obj.currentTarget).data('bs.' + this.type, self)
1382
1584
  }
1383
1585
 
1586
+ if (obj instanceof $.Event) {
1587
+ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
1588
+ }
1589
+
1590
+ if (self.isInStateTrue()) return
1591
+
1384
1592
  clearTimeout(self.timeout)
1385
1593
 
1386
1594
  self.hoverState = 'out'
@@ -1426,7 +1634,8 @@ if (typeof jQuery === 'undefined') {
1426
1634
  .addClass(placement)
1427
1635
  .data('bs.' + this.type, this)
1428
1636
 
1429
- this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
1637
+ this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)
1638
+ this.$element.trigger('inserted.bs.' + this.type)
1430
1639
 
1431
1640
  var pos = this.getPosition()
1432
1641
  var actualWidth = $tip[0].offsetWidth
@@ -1434,13 +1643,12 @@ if (typeof jQuery === 'undefined') {
1434
1643
 
1435
1644
  if (autoPlace) {
1436
1645
  var orgPlacement = placement
1437
- var $container = this.options.container ? $(this.options.container) : this.$element.parent()
1438
- var containerDim = this.getPosition($container)
1646
+ var viewportDim = this.getPosition(this.$viewport)
1439
1647
 
1440
- placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
1441
- placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
1442
- placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
1443
- placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
1648
+ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
1649
+ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
1650
+ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
1651
+ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
1444
1652
  placement
1445
1653
 
1446
1654
  $tip
@@ -1481,8 +1689,8 @@ if (typeof jQuery === 'undefined') {
1481
1689
  if (isNaN(marginTop)) marginTop = 0
1482
1690
  if (isNaN(marginLeft)) marginLeft = 0
1483
1691
 
1484
- offset.top = offset.top + marginTop
1485
- offset.left = offset.left + marginLeft
1692
+ offset.top += marginTop
1693
+ offset.left += marginLeft
1486
1694
 
1487
1695
  // $.fn.offset doesn't round pixel values
1488
1696
  // so we use setOffset directly with our own function B-0
@@ -1528,7 +1736,16 @@ if (typeof jQuery === 'undefined') {
1528
1736
  var $tip = this.tip()
1529
1737
  var title = this.getTitle()
1530
1738
 
1531
- $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1739
+ if (this.options.html) {
1740
+ if (this.options.sanitize) {
1741
+ title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn)
1742
+ }
1743
+
1744
+ $tip.find('.tooltip-inner').html(title)
1745
+ } else {
1746
+ $tip.find('.tooltip-inner').text(title)
1747
+ }
1748
+
1532
1749
  $tip.removeClass('fade in top bottom left right')
1533
1750
  }
1534
1751
 
@@ -1539,9 +1756,11 @@ if (typeof jQuery === 'undefined') {
1539
1756
 
1540
1757
  function complete() {
1541
1758
  if (that.hoverState != 'in') $tip.detach()
1542
- that.$element
1543
- .removeAttr('aria-describedby')
1544
- .trigger('hidden.bs.' + that.type)
1759
+ if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
1760
+ that.$element
1761
+ .removeAttr('aria-describedby')
1762
+ .trigger('hidden.bs.' + that.type)
1763
+ }
1545
1764
  callback && callback()
1546
1765
  }
1547
1766
 
@@ -1564,7 +1783,7 @@ if (typeof jQuery === 'undefined') {
1564
1783
 
1565
1784
  Tooltip.prototype.fixTitle = function () {
1566
1785
  var $e = this.$element
1567
- if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
1786
+ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
1568
1787
  $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1569
1788
  }
1570
1789
  }
@@ -1584,7 +1803,10 @@ if (typeof jQuery === 'undefined') {
1584
1803
  // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
1585
1804
  elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
1586
1805
  }
1587
- var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
1806
+ var isSvg = window.SVGElement && el instanceof window.SVGElement
1807
+ // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
1808
+ // See https://github.com/twbs/bootstrap/issues/20280
1809
+ var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
1588
1810
  var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
1589
1811
  var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
1590
1812
 
@@ -1619,7 +1841,7 @@ if (typeof jQuery === 'undefined') {
1619
1841
  var rightEdgeOffset = pos.left + viewportPadding + actualWidth
1620
1842
  if (leftEdgeOffset < viewportDimensions.left) { // left overflow
1621
1843
  delta.left = viewportDimensions.left - leftEdgeOffset
1622
- } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
1844
+ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
1623
1845
  delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
1624
1846
  }
1625
1847
  }
@@ -1645,7 +1867,13 @@ if (typeof jQuery === 'undefined') {
1645
1867
  }
1646
1868
 
1647
1869
  Tooltip.prototype.tip = function () {
1648
- return (this.$tip = this.$tip || $(this.options.template))
1870
+ if (!this.$tip) {
1871
+ this.$tip = $(this.options.template)
1872
+ if (this.$tip.length != 1) {
1873
+ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
1874
+ }
1875
+ }
1876
+ return this.$tip
1649
1877
  }
1650
1878
 
1651
1879
  Tooltip.prototype.arrow = function () {
@@ -1674,7 +1902,13 @@ if (typeof jQuery === 'undefined') {
1674
1902
  }
1675
1903
  }
1676
1904
 
1677
- self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
1905
+ if (e) {
1906
+ self.inState.click = !self.inState.click
1907
+ if (self.isInStateTrue()) self.enter(self)
1908
+ else self.leave(self)
1909
+ } else {
1910
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
1911
+ }
1678
1912
  }
1679
1913
 
1680
1914
  Tooltip.prototype.destroy = function () {
@@ -1682,9 +1916,19 @@ if (typeof jQuery === 'undefined') {
1682
1916
  clearTimeout(this.timeout)
1683
1917
  this.hide(function () {
1684
1918
  that.$element.off('.' + that.type).removeData('bs.' + that.type)
1919
+ if (that.$tip) {
1920
+ that.$tip.detach()
1921
+ }
1922
+ that.$tip = null
1923
+ that.$arrow = null
1924
+ that.$viewport = null
1925
+ that.$element = null
1685
1926
  })
1686
1927
  }
1687
1928
 
1929
+ Tooltip.prototype.sanitizeHtml = function (unsafeHtml) {
1930
+ return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn)
1931
+ }
1688
1932
 
1689
1933
  // TOOLTIP PLUGIN DEFINITION
1690
1934
  // =========================
@@ -1718,10 +1962,10 @@ if (typeof jQuery === 'undefined') {
1718
1962
  }(jQuery);
1719
1963
 
1720
1964
  /* ========================================================================
1721
- * Bootstrap: popover.js v3.3.4
1722
- * http://getbootstrap.com/javascript/#popovers
1965
+ * Bootstrap: popover.js v3.4.1
1966
+ * https://getbootstrap.com/docs/3.4/javascript/#popovers
1723
1967
  * ========================================================================
1724
- * Copyright 2011-2015 Twitter, Inc.
1968
+ * Copyright 2011-2019 Twitter, Inc.
1725
1969
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1726
1970
  * ======================================================================== */
1727
1971
 
@@ -1738,7 +1982,7 @@ if (typeof jQuery === 'undefined') {
1738
1982
 
1739
1983
  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1740
1984
 
1741
- Popover.VERSION = '3.3.4'
1985
+ Popover.VERSION = '3.4.1'
1742
1986
 
1743
1987
  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
1744
1988
  placement: 'right',
@@ -1764,10 +2008,25 @@ if (typeof jQuery === 'undefined') {
1764
2008
  var title = this.getTitle()
1765
2009
  var content = this.getContent()
1766
2010
 
1767
- $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1768
- $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
1769
- this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
1770
- ](content)
2011
+ if (this.options.html) {
2012
+ var typeContent = typeof content
2013
+
2014
+ if (this.options.sanitize) {
2015
+ title = this.sanitizeHtml(title)
2016
+
2017
+ if (typeContent === 'string') {
2018
+ content = this.sanitizeHtml(content)
2019
+ }
2020
+ }
2021
+
2022
+ $tip.find('.popover-title').html(title)
2023
+ $tip.find('.popover-content').children().detach().end()[
2024
+ typeContent === 'string' ? 'html' : 'append'
2025
+ ](content)
2026
+ } else {
2027
+ $tip.find('.popover-title').text(title)
2028
+ $tip.find('.popover-content').children().detach().end().text(content)
2029
+ }
1771
2030
 
1772
2031
  $tip.removeClass('fade top bottom left right in')
1773
2032
 
@@ -1786,8 +2045,8 @@ if (typeof jQuery === 'undefined') {
1786
2045
 
1787
2046
  return $e.attr('data-content')
1788
2047
  || (typeof o.content == 'function' ?
1789
- o.content.call($e[0]) :
1790
- o.content)
2048
+ o.content.call($e[0]) :
2049
+ o.content)
1791
2050
  }
1792
2051
 
1793
2052
  Popover.prototype.arrow = function () {
@@ -1827,10 +2086,10 @@ if (typeof jQuery === 'undefined') {
1827
2086
  }(jQuery);
1828
2087
 
1829
2088
  /* ========================================================================
1830
- * Bootstrap: scrollspy.js v3.3.4
1831
- * http://getbootstrap.com/javascript/#scrollspy
2089
+ * Bootstrap: scrollspy.js v3.4.1
2090
+ * https://getbootstrap.com/docs/3.4/javascript/#scrollspy
1832
2091
  * ========================================================================
1833
- * Copyright 2011-2015 Twitter, Inc.
2092
+ * Copyright 2011-2019 Twitter, Inc.
1834
2093
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1835
2094
  * ======================================================================== */
1836
2095
 
@@ -1856,7 +2115,7 @@ if (typeof jQuery === 'undefined') {
1856
2115
  this.process()
1857
2116
  }
1858
2117
 
1859
- ScrollSpy.VERSION = '3.3.4'
2118
+ ScrollSpy.VERSION = '3.4.1'
1860
2119
 
1861
2120
  ScrollSpy.DEFAULTS = {
1862
2121
  offset: 10
@@ -2000,10 +2259,10 @@ if (typeof jQuery === 'undefined') {
2000
2259
  }(jQuery);
2001
2260
 
2002
2261
  /* ========================================================================
2003
- * Bootstrap: tab.js v3.3.4
2004
- * http://getbootstrap.com/javascript/#tabs
2262
+ * Bootstrap: tab.js v3.4.1
2263
+ * https://getbootstrap.com/docs/3.4/javascript/#tabs
2005
2264
  * ========================================================================
2006
- * Copyright 2011-2015 Twitter, Inc.
2265
+ * Copyright 2011-2019 Twitter, Inc.
2007
2266
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2008
2267
  * ======================================================================== */
2009
2268
 
@@ -2015,10 +2274,12 @@ if (typeof jQuery === 'undefined') {
2015
2274
  // ====================
2016
2275
 
2017
2276
  var Tab = function (element) {
2277
+ // jscs:disable requireDollarBeforejQueryAssignment
2018
2278
  this.element = $(element)
2279
+ // jscs:enable requireDollarBeforejQueryAssignment
2019
2280
  }
2020
2281
 
2021
- Tab.VERSION = '3.3.4'
2282
+ Tab.VERSION = '3.4.1'
2022
2283
 
2023
2284
  Tab.TRANSITION_DURATION = 150
2024
2285
 
@@ -2047,7 +2308,7 @@ if (typeof jQuery === 'undefined') {
2047
2308
 
2048
2309
  if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
2049
2310
 
2050
- var $target = $(selector)
2311
+ var $target = $(document).find(selector)
2051
2312
 
2052
2313
  this.activate($this.closest('li'), $ul)
2053
2314
  this.activate($target, $target.parent(), function () {
@@ -2066,21 +2327,21 @@ if (typeof jQuery === 'undefined') {
2066
2327
  var $active = container.find('> .active')
2067
2328
  var transition = callback
2068
2329
  && $.support.transition
2069
- && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
2330
+ && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
2070
2331
 
2071
2332
  function next() {
2072
2333
  $active
2073
2334
  .removeClass('active')
2074
2335
  .find('> .dropdown-menu > .active')
2075
- .removeClass('active')
2336
+ .removeClass('active')
2076
2337
  .end()
2077
2338
  .find('[data-toggle="tab"]')
2078
- .attr('aria-expanded', false)
2339
+ .attr('aria-expanded', false)
2079
2340
 
2080
2341
  element
2081
2342
  .addClass('active')
2082
2343
  .find('[data-toggle="tab"]')
2083
- .attr('aria-expanded', true)
2344
+ .attr('aria-expanded', true)
2084
2345
 
2085
2346
  if (transition) {
2086
2347
  element[0].offsetWidth // reflow for transition
@@ -2092,10 +2353,10 @@ if (typeof jQuery === 'undefined') {
2092
2353
  if (element.parent('.dropdown-menu').length) {
2093
2354
  element
2094
2355
  .closest('li.dropdown')
2095
- .addClass('active')
2356
+ .addClass('active')
2096
2357
  .end()
2097
2358
  .find('[data-toggle="tab"]')
2098
- .attr('aria-expanded', true)
2359
+ .attr('aria-expanded', true)
2099
2360
  }
2100
2361
 
2101
2362
  callback && callback()
@@ -2154,10 +2415,10 @@ if (typeof jQuery === 'undefined') {
2154
2415
  }(jQuery);
2155
2416
 
2156
2417
  /* ========================================================================
2157
- * Bootstrap: affix.js v3.3.4
2158
- * http://getbootstrap.com/javascript/#affix
2418
+ * Bootstrap: affix.js v3.4.1
2419
+ * https://getbootstrap.com/docs/3.4/javascript/#affix
2159
2420
  * ========================================================================
2160
- * Copyright 2011-2015 Twitter, Inc.
2421
+ * Copyright 2011-2019 Twitter, Inc.
2161
2422
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2162
2423
  * ======================================================================== */
2163
2424
 
@@ -2171,7 +2432,9 @@ if (typeof jQuery === 'undefined') {
2171
2432
  var Affix = function (element, options) {
2172
2433
  this.options = $.extend({}, Affix.DEFAULTS, options)
2173
2434
 
2174
- this.$target = $(this.options.target)
2435
+ var target = this.options.target === Affix.DEFAULTS.target ? $(this.options.target) : $(document).find(this.options.target)
2436
+
2437
+ this.$target = target
2175
2438
  .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
2176
2439
  .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
2177
2440
 
@@ -2183,7 +2446,7 @@ if (typeof jQuery === 'undefined') {
2183
2446
  this.checkPosition()
2184
2447
  }
2185
2448
 
2186
- Affix.VERSION = '3.3.4'
2449
+ Affix.VERSION = '3.4.1'
2187
2450
 
2188
2451
  Affix.RESET = 'affix affix-top affix-bottom'
2189
2452
 
@@ -2233,7 +2496,7 @@ if (typeof jQuery === 'undefined') {
2233
2496
  var offset = this.options.offset
2234
2497
  var offsetTop = offset.top
2235
2498
  var offsetBottom = offset.bottom
2236
- var scrollHeight = $(document.body).height()
2499
+ var scrollHeight = Math.max($(document).height(), $(document.body).height())
2237
2500
 
2238
2501
  if (typeof offset != 'object') offsetBottom = offsetTop = offset
2239
2502
  if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)