mailbuilder-preview 0.1.3 → 0.1.4

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