diff --git a/BForms.Docs/Scripts/BForms/Components/Bootstrap/js/bootstrap.js b/BForms.Docs/Scripts/BForms/Components/Bootstrap/js/bootstrap.js
index 253b4e2b..73a05f4b 100644
--- a/BForms.Docs/Scripts/BForms/Components/Bootstrap/js/bootstrap.js
+++ b/BForms.Docs/Scripts/BForms/Components/Bootstrap/js/bootstrap.js
@@ -1,12 +1,7 @@
 /*!
- * Bootstrap v3.3.2 (http://getbootstrap.com)
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
  * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-
-/*!
- * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=7c8d3286e41757779aed)
- * Config saved to config.json and https://gist.github.com/7c8d3286e41757779aed
+ * Licensed under the MIT license
  */
 
 /*
@@ -17,7 +12,6 @@
 
 */
 
-
 (function (factory) {
     if (typeof define === "function" && define.amd) {
         define('bootstrap', ['jquery', 'jquery-ui-core'], factory);
@@ -25,2315 +19,2359 @@
         factory();
     }
 }(function ($) {
-    if (typeof jQuery === 'undefined') {
-        throw new Error('Bootstrap\'s JavaScript requires jQuery')
-    }
-
-    +function ($) {
-        'use strict';
-        var version = $.fn.jquery.split(' ')[0].split('.')
-        if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
-            throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
-        }
-    }(jQuery);
 
-    /* ========================================================================
-     * Bootstrap: transition.js v3.3.4
-     * http://getbootstrap.com/javascript/#transitions
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+if (typeof jQuery === 'undefined') {
+    throw new Error('Bootstrap\'s JavaScript requires jQuery')
+}
 
++function ($) {
+    'use strict';
+    var version = $.fn.jquery.split(' ')[0].split('.')
+    if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
+        throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
+    }
+}(jQuery);
 
-    +function ($) {
-        'use strict';
+/* ========================================================================
+ * Bootstrap: transition.js v3.3.5
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-        // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
-        // ============================================================
 
-        function transitionEnd() {
-            var el = document.createElement('bootstrap')
++function ($) {
+    'use strict';
 
-            var transEndEventNames = {
-                WebkitTransition: 'webkitTransitionEnd',
-                MozTransition: 'transitionend',
-                OTransition: 'oTransitionEnd otransitionend',
-                transition: 'transitionend'
-            }
+    // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+    // ============================================================
 
-            for (var name in transEndEventNames) {
-                if (el.style[name] !== undefined) {
-                    return { end: transEndEventNames[name] }
-                }
-            }
+    function transitionEnd() {
+        var el = document.createElement('bootstrap')
 
-            return false // explicit for ie8 (  ._.)
+        var transEndEventNames = {
+            WebkitTransition: 'webkitTransitionEnd',
+            MozTransition: 'transitionend',
+            OTransition: 'oTransitionEnd otransitionend',
+            transition: 'transitionend'
         }
 
-        // http://blog.alexmaccaw.com/css-transitions
-        $.fn.emulateTransitionEnd = function (duration) {
-            var called = false
-            var $el = this
-            $(this).one('bsTransitionEnd', function () { called = true })
-            var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
-            setTimeout(callback, duration)
-            return this
+        for (var name in transEndEventNames) {
+            if (el.style[name] !== undefined) {
+                return { end: transEndEventNames[name] }
+            }
         }
 
-        $(function () {
-            $.support.transition = transitionEnd()
+        return false // explicit for ie8 (  ._.)
+    }
 
-            if (!$.support.transition) return
+    // http://blog.alexmaccaw.com/css-transitions
+    $.fn.emulateTransitionEnd = function (duration) {
+        var called = false
+        var $el = this
+        $(this).one('bsTransitionEnd', function () { called = true })
+        var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+        setTimeout(callback, duration)
+        return this
+    }
 
-            $.event.special.bsTransitionEnd = {
-                bindType: $.support.transition.end,
-                delegateType: $.support.transition.end,
-                handle: function (e) {
-                    if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
-                }
-            }
-        })
+    $(function () {
+        $.support.transition = transitionEnd()
 
-    }(jQuery);
+        if (!$.support.transition) return
 
-    /* ========================================================================
-     * Bootstrap: alert.js v3.3.4
-     * http://getbootstrap.com/javascript/#alerts
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+        $.event.special.bsTransitionEnd = {
+            bindType: $.support.transition.end,
+            delegateType: $.support.transition.end,
+            handle: function (e) {
+                if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
+            }
+        }
+    })
 
+}(jQuery);
 
-    +function ($) {
-        'use strict';
+/* ========================================================================
+ * Bootstrap: alert.js v3.3.5
+ * http://getbootstrap.com/javascript/#alerts
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-        // ALERT CLASS DEFINITION
-        // ======================
 
-        var dismiss = '[data-dismiss="alert"]'
-        var Alert = function (el) {
-            $(el).on('click', dismiss, this.close)
-        }
++function ($) {
+    'use strict';
 
-        Alert.VERSION = '3.3.4'
+    // ALERT CLASS DEFINITION
+    // ======================
 
-        Alert.TRANSITION_DURATION = 150
+    var dismiss = '[data-dismiss="alert"]'
+    var Alert = function (el) {
+        $(el).on('click', dismiss, this.close)
+    }
 
-        Alert.prototype.close = function (e) {
-            var $this = $(this)
-            var selector = $this.attr('data-target')
+    Alert.VERSION = '3.3.5'
 
-            if (!selector) {
-                selector = $this.attr('href')
-                selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
-            }
+    Alert.TRANSITION_DURATION = 150
 
-            var $parent = $(selector)
+    Alert.prototype.close = function (e) {
+        var $this = $(this)
+        var selector = $this.attr('data-target')
 
-            if (e) e.preventDefault()
+        if (!selector) {
+            selector = $this.attr('href')
+            selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+        }
 
-            if (!$parent.length) {
-                $parent = $this.closest('.alert')
-            }
+        var $parent = $(selector)
 
-            $parent.trigger(e = $.Event('close.bs.alert'))
+        if (e) e.preventDefault()
 
-            if (e.isDefaultPrevented()) return
+        if (!$parent.length) {
+            $parent = $this.closest('.alert')
+        }
 
-            $parent.removeClass('in')
+        $parent.trigger(e = $.Event('close.bs.alert'))
 
-            function removeElement() {
-                // detach from parent, fire event then clean up data
-                $parent.detach().trigger('closed.bs.alert').remove()
-            }
+        if (e.isDefaultPrevented()) return
 
-            $.support.transition && $parent.hasClass('fade') ?
-              $parent
-                .one('bsTransitionEnd', removeElement)
-                .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
-              removeElement()
-        }
+        $parent.removeClass('in')
 
+        function removeElement() {
+            // detach from parent, fire event then clean up data
+            $parent.detach().trigger('closed.bs.alert').remove()
+        }
 
-        // ALERT PLUGIN DEFINITION
-        // =======================
+        $.support.transition && $parent.hasClass('fade') ?
+          $parent
+            .one('bsTransitionEnd', removeElement)
+            .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
+          removeElement()
+    }
 
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.alert')
 
-                if (!data) $this.data('bs.alert', (data = new Alert(this)))
-                if (typeof option == 'string') data[option].call($this)
-            })
-        }
+    // ALERT PLUGIN DEFINITION
+    // =======================
 
-        var old = $.fn.alert
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.alert')
 
-        $.fn.alert = Plugin
-        $.fn.alert.Constructor = Alert
+            if (!data) $this.data('bs.alert', (data = new Alert(this)))
+            if (typeof option == 'string') data[option].call($this)
+        })
+    }
 
+    var old = $.fn.alert
 
-        // ALERT NO CONFLICT
-        // =================
+    $.fn.alert = Plugin
+    $.fn.alert.Constructor = Alert
 
-        $.fn.alert.noConflict = function () {
-            $.fn.alert = old
-            return this
-        }
 
+    // ALERT NO CONFLICT
+    // =================
 
-        // ALERT DATA-API
-        // ==============
+    $.fn.alert.noConflict = function () {
+        $.fn.alert = old
+        return this
+    }
 
-        $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
 
-    }(jQuery);
+    // ALERT DATA-API
+    // ==============
 
-    /* ========================================================================
-     * Bootstrap: button.js v3.3.4
-     * http://getbootstrap.com/javascript/#buttons
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+    $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
 
+}(jQuery);
 
-    +function ($) {
-        'use strict';
+/* ========================================================================
+ * Bootstrap: button.js v3.3.5
+ * http://getbootstrap.com/javascript/#buttons
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-        // BUTTON PUBLIC CLASS DEFINITION
-        // ==============================
 
-        var Button = function (element, options) {
-            this.$element = $(element)
-            this.options = $.extend({}, Button.DEFAULTS, options)
-            this.isLoading = false
-        }
++function ($) {
+    'use strict';
 
-        Button.VERSION = '3.3.4'
+    // BUTTON PUBLIC CLASS DEFINITION
+    // ==============================
 
-        Button.DEFAULTS = {
-            loadingText: 'loading...'
-        }
+    var Button = function (element, options) {
+        this.$element = $(element)
+        this.options = $.extend({}, Button.DEFAULTS, options)
+        this.isLoading = false
+    }
 
-        Button.prototype.setState = function (state) {
-            var d = 'disabled'
-            var $el = this.$element
-            var val = $el.is('input') ? 'val' : 'html'
-            var data = $el.data()
+    Button.VERSION = '3.3.5'
 
-            state = state + 'Text'
+    Button.DEFAULTS = {
+        loadingText: 'loading...'
+    }
 
-            if (data.resetText == null) $el.data('resetText', $el[val]())
+    Button.prototype.setState = function (state) {
+        var d = 'disabled'
+        var $el = this.$element
+        var val = $el.is('input') ? 'val' : 'html'
+        var data = $el.data()
 
-            // push to event loop to allow forms to submit
-            setTimeout($.proxy(function () {
-                $el[val](data[state] == null ? this.options[state] : data[state])
+        state += 'Text'
 
-                if (state == 'loadingText') {
-                    this.isLoading = true
-                    $el.addClass(d).attr(d, d)
-                } else if (this.isLoading) {
-                    this.isLoading = false
-                    $el.removeClass(d).removeAttr(d)
-                }
-            }, this), 0)
-        }
+        if (data.resetText == null) $el.data('resetText', $el[val]())
 
-        Button.prototype.toggle = function () {
-            var changed = true
-            var $parent = this.$element.closest('[data-toggle="buttons"]')
+        // push to event loop to allow forms to submit
+        setTimeout($.proxy(function () {
+            $el[val](data[state] == null ? this.options[state] : data[state])
 
-            if ($parent.length) {
-                var $input = this.$element.find('input')
-                if ($input.prop('type') == 'radio') {
-                    if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
-                    else $parent.find('.active').removeClass('active')
-                }
-                if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
-            } else {
-                this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
+            if (state == 'loadingText') {
+                this.isLoading = true
+                $el.addClass(d).attr(d, d)
+            } else if (this.isLoading) {
+                this.isLoading = false
+                $el.removeClass(d).removeAttr(d)
             }
+        }, this), 0)
+    }
 
-            if (changed) this.$element.toggleClass('active')
+    Button.prototype.toggle = function () {
+        var changed = true
+        var $parent = this.$element.closest('[data-toggle="buttons"]')
+
+        if ($parent.length) {
+            var $input = this.$element.find('input')
+            if ($input.prop('type') == 'radio') {
+                if ($input.prop('checked')) changed = false
+                $parent.find('.active').removeClass('active')
+                this.$element.addClass('active')
+            } else if ($input.prop('type') == 'checkbox') {
+                if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
+                this.$element.toggleClass('active')
+            }
+            $input.prop('checked', this.$element.hasClass('active'))
+            if (changed) $input.trigger('change')
+        } else {
+            this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
+            this.$element.toggleClass('active')
         }
+    }
 
 
-        // BUTTON PLUGIN DEFINITION
-        // ========================
-
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.button')
-                var options = typeof option == 'object' && option
+    // BUTTON PLUGIN DEFINITION
+    // ========================
 
-                if (!data) $this.data('bs.button', (data = new Button(this, options)))
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.button')
+            var options = typeof option == 'object' && option
 
-                if (option == 'toggle') data.toggle()
-                else if (option) data.setState(option)
-            })
-        }
+            if (!data) $this.data('bs.button', (data = new Button(this, options)))
 
-        var old = $.fn.button
+            if (option == 'toggle') data.toggle()
+            else if (option) data.setState(option)
+        })
+    }
 
-        $.fn.button = Plugin
-        $.fn.button.Constructor = Button
+    var old = $.fn.button
 
+    $.fn.button = Plugin
+    $.fn.button.Constructor = Button
 
-        // BUTTON NO CONFLICT
-        // ==================
 
-        $.fn.button.noConflict = function () {
-            $.fn.button = old
-            return this
-        }
+    // BUTTON NO CONFLICT
+    // ==================
 
+    $.fn.button.noConflict = function () {
+        $.fn.button = old
+        return this
+    }
 
-        // BUTTON DATA-API
-        // ===============
 
-        $(document)
-          .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
-              var $btn = $(e.target)
-              if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
-              Plugin.call($btn, 'toggle')
-              e.preventDefault()
-          })
-          .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
-              $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
-          })
+    // BUTTON DATA-API
+    // ===============
 
-    }(jQuery);
+    $(document)
+      .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+          var $btn = $(e.target)
+          if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
+          Plugin.call($btn, 'toggle')
+          if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
+      })
+      .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+          $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
+      })
 
-    /* ========================================================================
-     * Bootstrap: carousel.js v3.3.4
-     * http://getbootstrap.com/javascript/#carousel
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+}(jQuery);
 
+/* ========================================================================
+ * Bootstrap: carousel.js v3.3.5
+ * http://getbootstrap.com/javascript/#carousel
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-    +function ($) {
-        'use strict';
 
-        // CAROUSEL CLASS DEFINITION
-        // =========================
++function ($) {
+    'use strict';
 
-        var Carousel = function (element, options) {
-            this.$element = $(element)
-            this.$indicators = this.$element.find('.carousel-indicators')
-            this.options = options
-            this.paused = null
-            this.sliding = null
-            this.interval = null
-            this.$active = null
-            this.$items = null
+    // CAROUSEL CLASS DEFINITION
+    // =========================
 
-            this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
+    var Carousel = function (element, options) {
+        this.$element = $(element)
+        this.$indicators = this.$element.find('.carousel-indicators')
+        this.options = options
+        this.paused = null
+        this.sliding = null
+        this.interval = null
+        this.$active = null
+        this.$items = null
 
-            this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
-              .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
-              .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
-        }
+        this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
 
-        Carousel.VERSION = '3.3.4'
+        this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
+          .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
+          .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
+    }
 
-        Carousel.TRANSITION_DURATION = 600
+    Carousel.VERSION = '3.3.5'
 
-        Carousel.DEFAULTS = {
-            interval: 5000,
-            pause: 'hover',
-            wrap: true,
-            keyboard: true
-        }
+    Carousel.TRANSITION_DURATION = 600
 
-        Carousel.prototype.keydown = function (e) {
-            if (/input|textarea/i.test(e.target.tagName)) return
-            switch (e.which) {
-                case 37: this.prev(); break
-                case 39: this.next(); break
-                default: return
-            }
+    Carousel.DEFAULTS = {
+        interval: 5000,
+        pause: 'hover',
+        wrap: true,
+        keyboard: true
+    }
 
-            e.preventDefault()
+    Carousel.prototype.keydown = function (e) {
+        if (/input|textarea/i.test(e.target.tagName)) return
+        switch (e.which) {
+            case 37: this.prev(); break
+            case 39: this.next(); break
+            default: return
         }
 
-        Carousel.prototype.cycle = function (e) {
-            e || (this.paused = false)
-
-            this.interval && clearInterval(this.interval)
+        e.preventDefault()
+    }
 
-            this.options.interval
-              && !this.paused
-              && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+    Carousel.prototype.cycle = function (e) {
+        e || (this.paused = false)
 
-            return this
-        }
+        this.interval && clearInterval(this.interval)
 
-        Carousel.prototype.getItemIndex = function (item) {
-            this.$items = item.parent().children('.item')
-            return this.$items.index(item || this.$active)
-        }
+        this.options.interval
+          && !this.paused
+          && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
 
-        Carousel.prototype.getItemForDirection = function (direction, active) {
-            var activeIndex = this.getItemIndex(active)
-            var willWrap = (direction == 'prev' && activeIndex === 0)
-                        || (direction == 'next' && activeIndex == (this.$items.length - 1))
-            if (willWrap && !this.options.wrap) return active
-            var delta = direction == 'prev' ? -1 : 1
-            var itemIndex = (activeIndex + delta) % this.$items.length
-            return this.$items.eq(itemIndex)
-        }
+        return this
+    }
 
-        Carousel.prototype.to = function (pos) {
-            var that = this
-            var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
+    Carousel.prototype.getItemIndex = function (item) {
+        this.$items = item.parent().children('.item')
+        return this.$items.index(item || this.$active)
+    }
 
-            if (pos > (this.$items.length - 1) || pos < 0) return
+    Carousel.prototype.getItemForDirection = function (direction, active) {
+        var activeIndex = this.getItemIndex(active)
+        var willWrap = (direction == 'prev' && activeIndex === 0)
+                    || (direction == 'next' && activeIndex == (this.$items.length - 1))
+        if (willWrap && !this.options.wrap) return active
+        var delta = direction == 'prev' ? -1 : 1
+        var itemIndex = (activeIndex + delta) % this.$items.length
+        return this.$items.eq(itemIndex)
+    }
 
-            if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
-            if (activeIndex == pos) return this.pause().cycle()
+    Carousel.prototype.to = function (pos) {
+        var that = this
+        var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
 
-            return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
-        }
+        if (pos > (this.$items.length - 1) || pos < 0) return
 
-        Carousel.prototype.pause = function (e) {
-            e || (this.paused = true)
+        if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
+        if (activeIndex == pos) return this.pause().cycle()
 
-            if (this.$element.find('.next, .prev').length && $.support.transition) {
-                this.$element.trigger($.support.transition.end)
-                this.cycle(true)
-            }
+        return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
+    }
 
-            this.interval = clearInterval(this.interval)
+    Carousel.prototype.pause = function (e) {
+        e || (this.paused = true)
 
-            return this
+        if (this.$element.find('.next, .prev').length && $.support.transition) {
+            this.$element.trigger($.support.transition.end)
+            this.cycle(true)
         }
 
-        Carousel.prototype.next = function () {
-            if (this.sliding) return
-            return this.slide('next')
-        }
+        this.interval = clearInterval(this.interval)
 
-        Carousel.prototype.prev = function () {
-            if (this.sliding) return
-            return this.slide('prev')
-        }
+        return this
+    }
 
-        Carousel.prototype.slide = function (type, next) {
-            var $active = this.$element.find('.item.active')
-            var $next = next || this.getItemForDirection(type, $active)
-            var isCycling = this.interval
-            var direction = type == 'next' ? 'left' : 'right'
-            var that = this
+    Carousel.prototype.next = function () {
+        if (this.sliding) return
+        return this.slide('next')
+    }
 
-            if ($next.hasClass('active')) return (this.sliding = false)
+    Carousel.prototype.prev = function () {
+        if (this.sliding) return
+        return this.slide('prev')
+    }
 
-            var relatedTarget = $next[0]
-            var slideEvent = $.Event('slide.bs.carousel', {
-                relatedTarget: relatedTarget,
-                direction: direction
-            })
-            this.$element.trigger(slideEvent)
-            if (slideEvent.isDefaultPrevented()) return
+    Carousel.prototype.slide = function (type, next) {
+        var $active = this.$element.find('.item.active')
+        var $next = next || this.getItemForDirection(type, $active)
+        var isCycling = this.interval
+        var direction = type == 'next' ? 'left' : 'right'
+        var that = this
 
-            this.sliding = true
+        if ($next.hasClass('active')) return (this.sliding = false)
 
-            isCycling && this.pause()
+        var relatedTarget = $next[0]
+        var slideEvent = $.Event('slide.bs.carousel', {
+            relatedTarget: relatedTarget,
+            direction: direction
+        })
+        this.$element.trigger(slideEvent)
+        if (slideEvent.isDefaultPrevented()) return
+
+        this.sliding = true
+
+        isCycling && this.pause()
+
+        if (this.$indicators.length) {
+            this.$indicators.find('.active').removeClass('active')
+            var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
+            $nextIndicator && $nextIndicator.addClass('active')
+        }
+
+        var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
+        if ($.support.transition && this.$element.hasClass('slide')) {
+            $next.addClass(type)
+            $next[0].offsetWidth // force reflow
+            $active.addClass(direction)
+            $next.addClass(direction)
+            $active
+              .one('bsTransitionEnd', function () {
+                  $next.removeClass([type, direction].join(' ')).addClass('active')
+                  $active.removeClass(['active', direction].join(' '))
+                  that.sliding = false
+                  setTimeout(function () {
+                      that.$element.trigger(slidEvent)
+                  }, 0)
+              })
+              .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
+        } else {
+            $active.removeClass('active')
+            $next.addClass('active')
+            this.sliding = false
+            this.$element.trigger(slidEvent)
+        }
 
-            if (this.$indicators.length) {
-                this.$indicators.find('.active').removeClass('active')
-                var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
-                $nextIndicator && $nextIndicator.addClass('active')
-            }
+        isCycling && this.cycle()
 
-            var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
-            if ($.support.transition && this.$element.hasClass('slide')) {
-                $next.addClass(type)
-                $next[0].offsetWidth // force reflow
-                $active.addClass(direction)
-                $next.addClass(direction)
-                $active
-                  .one('bsTransitionEnd', function () {
-                      $next.removeClass([type, direction].join(' ')).addClass('active')
-                      $active.removeClass(['active', direction].join(' '))
-                      that.sliding = false
-                      setTimeout(function () {
-                          that.$element.trigger(slidEvent)
-                      }, 0)
-                  })
-                  .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
-            } else {
-                $active.removeClass('active')
-                $next.addClass('active')
-                this.sliding = false
-                this.$element.trigger(slidEvent)
-            }
+        return this
+    }
 
-            isCycling && this.cycle()
 
-            return this
-        }
+    // CAROUSEL PLUGIN DEFINITION
+    // ==========================
 
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.carousel')
+            var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
+            var action = typeof option == 'string' ? option : options.slide
+
+            if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
+            if (typeof option == 'number') data.to(option)
+            else if (action) data[action]()
+            else if (options.interval) data.pause().cycle()
+        })
+    }
 
-        // CAROUSEL PLUGIN DEFINITION
-        // ==========================
+    var old = $.fn.carousel
 
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.carousel')
-                var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
-                var action = typeof option == 'string' ? option : options.slide
+    $.fn.carousel = Plugin
+    $.fn.carousel.Constructor = Carousel
 
-                if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
-                if (typeof option == 'number') data.to(option)
-                else if (action) data[action]()
-                else if (options.interval) data.pause().cycle()
-            })
-        }
 
-        var old = $.fn.carousel
+    // CAROUSEL NO CONFLICT
+    // ====================
 
-        $.fn.carousel = Plugin
-        $.fn.carousel.Constructor = Carousel
+    $.fn.carousel.noConflict = function () {
+        $.fn.carousel = old
+        return this
+    }
 
 
-        // CAROUSEL NO CONFLICT
-        // ====================
+    // CAROUSEL DATA-API
+    // =================
 
-        $.fn.carousel.noConflict = function () {
-            $.fn.carousel = old
-            return this
-        }
+    var clickHandler = function (e) {
+        var href
+        var $this = $(this)
+        var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
+        if (!$target.hasClass('carousel')) return
+        var options = $.extend({}, $target.data(), $this.data())
+        var slideIndex = $this.attr('data-slide-to')
+        if (slideIndex) options.interval = false
 
+        Plugin.call($target, options)
 
-        // CAROUSEL DATA-API
-        // =================
+        if (slideIndex) {
+            $target.data('bs.carousel').to(slideIndex)
+        }
 
-        var clickHandler = function (e) {
-            var href
-            var $this = $(this)
-            var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
-            if (!$target.hasClass('carousel')) return
-            var options = $.extend({}, $target.data(), $this.data())
-            var slideIndex = $this.attr('data-slide-to')
-            if (slideIndex) options.interval = false
+        e.preventDefault()
+    }
 
-            Plugin.call($target, options)
+    $(document)
+      .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
+      .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
 
-            if (slideIndex) {
-                $target.data('bs.carousel').to(slideIndex)
-            }
+    $(window).on('load', function () {
+        $('[data-ride="carousel"]').each(function () {
+            var $carousel = $(this)
+            Plugin.call($carousel, $carousel.data())
+        })
+    })
 
-            e.preventDefault()
-        }
+}(jQuery);
 
-        $(document)
-          .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
-          .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
+/* ========================================================================
+ * Bootstrap: collapse.js v3.3.5
+ * http://getbootstrap.com/javascript/#collapse
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-        $(window).on('load', function () {
-            $('[data-ride="carousel"]').each(function () {
-                var $carousel = $(this)
-                Plugin.call($carousel, $carousel.data())
-            })
-        })
 
-    }(jQuery);
++function ($) {
+    'use strict';
 
-    /* ========================================================================
-     * Bootstrap: collapse.js v3.3.4
-     * http://getbootstrap.com/javascript/#collapse
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+    // COLLAPSE PUBLIC CLASS DEFINITION
+    // ================================
 
+    var Collapse = function (element, options) {
+        this.$element = $(element)
+        this.options = $.extend({}, Collapse.DEFAULTS, options)
+        this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
+                               '[data-toggle="collapse"][data-target="#' + element.id + '"]')
+        this.transitioning = null
 
-    +function ($) {
-        'use strict';
+        if (this.options.parent) {
+            this.$parent = this.getParent()
+        } else {
+            this.addAriaAndCollapsedClass(this.$element, this.$trigger)
+        }
 
-        // COLLAPSE PUBLIC CLASS DEFINITION
-        // ================================
+        if (this.options.toggle) this.toggle()
+    }
 
-        var Collapse = function (element, options) {
-            this.$element = $(element)
-            this.options = $.extend({}, Collapse.DEFAULTS, options)
-            this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
-                                   '[data-toggle="collapse"][data-target="#' + element.id + '"]')
-            this.transitioning = null
+    Collapse.VERSION = '3.3.5'
 
-            if (this.options.parent) {
-                this.$parent = this.getParent()
-            } else {
-                this.addAriaAndCollapsedClass(this.$element, this.$trigger)
-            }
+    Collapse.TRANSITION_DURATION = 350
 
-            if (this.options.toggle) this.toggle()
-        }
+    Collapse.DEFAULTS = {
+        toggle: true
+    }
 
-        Collapse.VERSION = '3.3.4'
+    Collapse.prototype.dimension = function () {
+        var hasWidth = this.$element.hasClass('width')
+        return hasWidth ? 'width' : 'height'
+    }
 
-        Collapse.TRANSITION_DURATION = 350
+    Collapse.prototype.show = function () {
+        if (this.transitioning || this.$element.hasClass('in')) return
 
-        Collapse.DEFAULTS = {
-            toggle: true
-        }
+        var activesData
+        var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
 
-        Collapse.prototype.dimension = function () {
-            var hasWidth = this.$element.hasClass('width')
-            return hasWidth ? 'width' : 'height'
+        if (actives && actives.length) {
+            activesData = actives.data('bs.collapse')
+            if (activesData && activesData.transitioning) return
         }
 
-        Collapse.prototype.show = function () {
-            if (this.transitioning || this.$element.hasClass('in')) return
+        var startEvent = $.Event('show.bs.collapse')
+        this.$element.trigger(startEvent)
+        if (startEvent.isDefaultPrevented()) return
 
-            var activesData
-            var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
+        if (actives && actives.length) {
+            Plugin.call(actives, 'hide')
+            activesData || actives.data('bs.collapse', null)
+        }
 
-            if (actives && actives.length) {
-                activesData = actives.data('bs.collapse')
-                if (activesData && activesData.transitioning) return
-            }
+        var dimension = this.dimension()
 
-            var startEvent = $.Event('show.bs.collapse')
-            this.$element.trigger(startEvent)
-            if (startEvent.isDefaultPrevented()) return
+        this.$element
+          .removeClass('collapse')
+          .addClass('collapsing')[dimension](0)
+          .attr('aria-expanded', true)
 
-            if (actives && actives.length) {
-                Plugin.call(actives, 'hide')
-                activesData || actives.data('bs.collapse', null)
-            }
+        this.$trigger
+          .removeClass('collapsed')
+          .attr('aria-expanded', true)
 
-            var dimension = this.dimension()
+        this.transitioning = 1
 
+        var complete = function () {
             this.$element
-              .removeClass('collapse')
-              .addClass('collapsing')[dimension](0)
-              .attr('aria-expanded', true)
+              .removeClass('collapsing')
+              .addClass('collapse in')[dimension]('')
+            this.transitioning = 0
+            this.$element
+              .trigger('shown.bs.collapse')
+        }
 
-            this.$trigger
-              .removeClass('collapsed')
-              .attr('aria-expanded', true)
+        if (!$.support.transition) return complete.call(this)
 
-            this.transitioning = 1
+        var scrollSize = $.camelCase(['scroll', dimension].join('-'))
 
-            var complete = function () {
-                this.$element
-                  .removeClass('collapsing')
-                  .addClass('collapse in')[dimension]('')
-                this.transitioning = 0
-                this.$element
-                  .trigger('shown.bs.collapse')
-            }
+        this.$element
+          .one('bsTransitionEnd', $.proxy(complete, this))
+          .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
+    }
 
-            if (!$.support.transition) return complete.call(this)
+    Collapse.prototype.hide = function () {
+        if (this.transitioning || !this.$element.hasClass('in')) return
 
-            var scrollSize = $.camelCase(['scroll', dimension].join('-'))
+        var startEvent = $.Event('hide.bs.collapse')
+        this.$element.trigger(startEvent)
+        if (startEvent.isDefaultPrevented()) return
 
-            this.$element
-              .one('bsTransitionEnd', $.proxy(complete, this))
-              .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
-        }
+        var dimension = this.dimension()
 
-        Collapse.prototype.hide = function () {
-            if (this.transitioning || !this.$element.hasClass('in')) return
+        this.$element[dimension](this.$element[dimension]())[0].offsetHeight
 
-            var startEvent = $.Event('hide.bs.collapse')
-            this.$element.trigger(startEvent)
-            if (startEvent.isDefaultPrevented()) return
+        this.$element
+          .addClass('collapsing')
+          .removeClass('collapse in')
+          .attr('aria-expanded', false)
 
-            var dimension = this.dimension()
+        this.$trigger
+          .addClass('collapsed')
+          .attr('aria-expanded', false)
 
-            this.$element[dimension](this.$element[dimension]())[0].offsetHeight
+        this.transitioning = 1
 
+        var complete = function () {
+            this.transitioning = 0
             this.$element
-              .addClass('collapsing')
-              .removeClass('collapse in')
-              .attr('aria-expanded', false)
+              .removeClass('collapsing')
+              .addClass('collapse')
+              .trigger('hidden.bs.collapse')
+        }
 
-            this.$trigger
-              .addClass('collapsed')
-              .attr('aria-expanded', false)
+        if (!$.support.transition) return complete.call(this)
 
-            this.transitioning = 1
+        this.$element
+          [dimension](0)
+          .one('bsTransitionEnd', $.proxy(complete, this))
+          .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
+    }
 
-            var complete = function () {
-                this.transitioning = 0
-                this.$element
-                  .removeClass('collapsing')
-                  .addClass('collapse')
-                  .trigger('hidden.bs.collapse')
-            }
+    Collapse.prototype.toggle = function () {
+        this[this.$element.hasClass('in') ? 'hide' : 'show']()
+    }
 
-            if (!$.support.transition) return complete.call(this)
+    Collapse.prototype.getParent = function () {
+        return $(this.options.parent)
+          .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
+          .each($.proxy(function (i, element) {
+              var $element = $(element)
+              this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
+          }, this))
+          .end()
+    }
 
-            this.$element
-              [dimension](0)
-              .one('bsTransitionEnd', $.proxy(complete, this))
-              .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
-        }
+    Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
+        var isOpen = $element.hasClass('in')
 
-        Collapse.prototype.toggle = function () {
-            this[this.$element.hasClass('in') ? 'hide' : 'show']()
-        }
+        $element.attr('aria-expanded', isOpen)
+        $trigger
+          .toggleClass('collapsed', !isOpen)
+          .attr('aria-expanded', isOpen)
+    }
 
-        Collapse.prototype.getParent = function () {
-            return $(this.options.parent)
-              .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
-              .each($.proxy(function (i, element) {
-                  var $element = $(element)
-                  this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
-              }, this))
-              .end()
-        }
+    function getTargetFromTrigger($trigger) {
+        var href
+        var target = $trigger.attr('data-target')
+          || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
 
-        Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
-            var isOpen = $element.hasClass('in')
+        return $(target)
+    }
 
-            $element.attr('aria-expanded', isOpen)
-            $trigger
-              .toggleClass('collapsed', !isOpen)
-              .attr('aria-expanded', isOpen)
-        }
 
-        function getTargetFromTrigger($trigger) {
-            var href
-            var target = $trigger.attr('data-target')
-              || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
+    // COLLAPSE PLUGIN DEFINITION
+    // ==========================
 
-            return $(target)
-        }
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.collapse')
+            var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
 
+            if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
+            if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
+            if (typeof option == 'string') data[option]()
+        })
+    }
 
-        // COLLAPSE PLUGIN DEFINITION
-        // ==========================
+    var old = $.fn.collapse
 
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.collapse')
-                var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
+    $.fn.collapse = Plugin
+    $.fn.collapse.Constructor = Collapse
 
-                if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
-                if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
-                if (typeof option == 'string') data[option]()
-            })
-        }
 
-        var old = $.fn.collapse
+    // COLLAPSE NO CONFLICT
+    // ====================
 
-        $.fn.collapse = Plugin
-        $.fn.collapse.Constructor = Collapse
+    $.fn.collapse.noConflict = function () {
+        $.fn.collapse = old
+        return this
+    }
 
 
-        // COLLAPSE NO CONFLICT
-        // ====================
+    // COLLAPSE DATA-API
+    // =================
 
-        $.fn.collapse.noConflict = function () {
-            $.fn.collapse = old
-            return this
-        }
+    $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
+        var $this = $(this)
 
+        if (!$this.attr('data-target')) e.preventDefault()
 
-        // COLLAPSE DATA-API
-        // =================
+        var $target = getTargetFromTrigger($this)
+        var data = $target.data('bs.collapse')
+        var option = data ? 'toggle' : $this.data()
 
-        $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
-            var $this = $(this)
+        Plugin.call($target, option)
+    })
 
-            if (!$this.attr('data-target')) e.preventDefault()
+}(jQuery);
 
-            var $target = getTargetFromTrigger($this)
-            var data = $target.data('bs.collapse')
-            var option = data ? 'toggle' : $this.data()
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.3.5
+ * http://getbootstrap.com/javascript/#dropdowns
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-            Plugin.call($target, option)
-        })
 
-    }(jQuery);
++function ($) {
+    'use strict';
 
-    /* ========================================================================
-     * Bootstrap: dropdown.js v3.3.4
-     * http://getbootstrap.com/javascript/#dropdowns
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+    // DROPDOWN CLASS DEFINITION
+    // =========================
 
+    var backdrop = '.dropdown-backdrop'
+    var toggle = '[data-toggle="dropdown"]'
+    var Dropdown = function (element) {
+        $(element).on('click.bs.dropdown', this.toggle)
+    }
 
-    +function ($) {
-        'use strict';
+    Dropdown.VERSION = '3.3.5'
 
-        // DROPDOWN CLASS DEFINITION
-        // =========================
+    function getParent($this) {
+        var selector = $this.attr('data-target')
 
-        var backdrop = '.dropdown-backdrop'
-        var toggle = '[data-toggle="dropdown"]'
-        var Dropdown = function (element) {
-            $(element).on('click.bs.dropdown', this.toggle)
+        if (!selector) {
+            selector = $this.attr('href')
+            selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
         }
 
-        Dropdown.VERSION = '3.3.4'
+        var $parent = selector && $(selector)
+
+        return $parent && $parent.length ? $parent : $this.parent()
+    }
 
-        Dropdown.prototype.toggle = function (e) {
+    function clearMenus(e) {
+        if (e && e.which === 3) return
+        $(backdrop).remove()
+        $(toggle).each(function () {
             var $this = $(this)
+            var $parent = getParent($this)
+            var relatedTarget = { relatedTarget: this }
 
-            if ($this.is('.disabled, :disabled')) return
+            if (!$parent.hasClass('open')) return
 
-            var $parent = getParent($this)
-            var isActive = $parent.hasClass('open')
+            if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
 
-            clearMenus()
+            $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
 
-            if (!isActive) {
-                if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
-                    // if mobile we use a backdrop because click events don't delegate
-                    $('<div class="dropdown-backdrop"/>').insertAfter($parent).on('click', clearMenus)
-                }
+            if (e.isDefaultPrevented()) return
+
+            $this.attr('aria-expanded', 'false')
+            $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
+        })
+    }
 
-                var relatedTarget = { relatedTarget: this }
-                $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+    Dropdown.prototype.toggle = function (e) {
+        var $this = $(this)
 
-                if (e.isDefaultPrevented()) return
+        if ($this.is('.disabled, :disabled')) return
 
-                $this
-                  .trigger('focus')
-                  .attr('aria-expanded', 'true')
+        var $parent = getParent($this)
+        var isActive = $parent.hasClass('open')
 
-                $parent
-                  .toggleClass('open')
-                  .trigger('shown.bs.dropdown', relatedTarget)
-            }
+        clearMenus()
 
-            return false
-        }
+        if (!isActive) {
+            if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+                // if mobile we use a backdrop because click events don't delegate
+                $('<div class="dropdown-backdrop"/>').insertAfter($parent).on('click', clearMenus)
+            }
 
-        Dropdown.prototype.keydown = function (e) {
-            if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
+            var relatedTarget = { relatedTarget: this }
+            $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
 
-            var $this = $(this)
+            if (e.isDefaultPrevented()) return
 
-            e.preventDefault()
-            e.stopPropagation()
+            $this
+              .trigger('focus')
+              .attr('aria-expanded', 'true')
 
-            if ($this.is('.disabled, :disabled')) return
+            $parent
+              .toggleClass('open')
+              .trigger('shown.bs.dropdown', relatedTarget)
+        }
 
-            var $parent = getParent($this)
-            var isActive = $parent.hasClass('open')
+        return false
+    }
 
-            if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
-                if (e.which == 27) $parent.find(toggle).trigger('focus')
-                return $this.trigger('click')
-            }
+    Dropdown.prototype.keydown = function (e) {
+        if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
 
-            var desc = ' li:not(.disabled):visible a'
-            var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
+        var $this = $(this)
 
-            if (!$items.length) return
+        e.preventDefault()
+        e.stopPropagation()
 
-            var index = $items.index(e.target)
+        if ($this.is('.disabled, :disabled')) return
 
-            if (e.which == 38 && index > 0) index--                        // up
-            if (e.which == 40 && index < $items.length - 1) index++                        // down
-            if (!~index) index = 0
+        var $parent = getParent($this)
+        var isActive = $parent.hasClass('open')
 
-            $items.eq(index).trigger('focus')
+        if (!isActive && e.which != 27 || isActive && e.which == 27) {
+            if (e.which == 27) $parent.find(toggle).trigger('focus')
+            return $this.trigger('click')
         }
 
-        function clearMenus(e) {
-            if (e && e.which === 3) return
-            $(backdrop).remove()
-            $(toggle).each(function () {
-                var $this = $(this)
-                var $parent = getParent($this)
-                var relatedTarget = { relatedTarget: this }
+        var desc = ' li:not(.disabled):visible a'
+        var $items = $parent.find('.dropdown-menu' + desc)
 
-                if (!$parent.hasClass('open')) return
+        if (!$items.length) return
 
-                $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+        var index = $items.index(e.target)
 
-                if (e.isDefaultPrevented()) return
+        if (e.which == 38 && index > 0) index--         // up
+        if (e.which == 40 && index < $items.length - 1) index++         // down
+        if (!~index) index = 0
 
-                $this.attr('aria-expanded', 'false')
-                $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
-            })
-        }
+        $items.eq(index).trigger('focus')
+    }
 
-        function getParent($this) {
-            var selector = $this.attr('data-target')
 
-            if (!selector) {
-                selector = $this.attr('href')
-                selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
-            }
+    // DROPDOWN PLUGIN DEFINITION
+    // ==========================
 
-            var $parent = selector && $(selector)
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.dropdown')
 
-            return $parent && $parent.length ? $parent : $this.parent()
-        }
+            if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
+            if (typeof option == 'string') data[option].call($this)
+        })
+    }
 
+    var old = $.fn.dropdown
 
-        // DROPDOWN PLUGIN DEFINITION
-        // ==========================
+    $.fn.dropdown = Plugin
+    $.fn.dropdown.Constructor = Dropdown
 
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.dropdown')
 
-                if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
-                if (typeof option == 'string') data[option].call($this)
-            })
-        }
+    // DROPDOWN NO CONFLICT
+    // ====================
 
-        var old = $.fn.dropdown
+    $.fn.dropdown.noConflict = function () {
+        $.fn.dropdown = old
+        return this
+    }
 
-        $.fn.dropdown = Plugin
-        $.fn.dropdown.Constructor = Dropdown
 
+    // APPLY TO STANDARD DROPDOWN ELEMENTS
+    // ===================================
 
-        // DROPDOWN NO CONFLICT
-        // ====================
+    $(document)
+      .on('click.bs.dropdown.data-api', clearMenus)
+      .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+      .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+      .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
+      .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
 
-        $.fn.dropdown.noConflict = function () {
-            $.fn.dropdown = old
-            return this
-        }
+}(jQuery);
 
+/* ========================================================================
+ * Bootstrap: modal.js v3.3.5
+ * http://getbootstrap.com/javascript/#modals
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-        // APPLY TO STANDARD DROPDOWN ELEMENTS
-        // ===================================
 
-        $(document)
-          .on('click.bs.dropdown.data-api', clearMenus)
-          .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
-          .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
-          .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
-          .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
-          .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
-
-    }(jQuery);
-
-    /* ========================================================================
-     * Bootstrap: modal.js v3.3.4
-     * http://getbootstrap.com/javascript/#modals
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
-
-
-    +function ($) {
-        'use strict';
-
-        // MODAL CLASS DEFINITION
-        // ======================
-
-        var Modal = function (element, options) {
-            this.options = options
-            this.$body = $(document.body)
-            this.$element = $(element)
-            this.$dialog = this.$element.find('.modal-dialog')
-            this.$backdrop = null
-            this.isShown = null
-            this.originalBodyPad = null
-            this.scrollbarWidth = 0
-            this.ignoreBackdropClick = false
-
-            if (this.options.remote) {
-                this.$element
-                  .find('.modal-content')
-                  .load(this.options.remote, $.proxy(function () {
-                      this.$element.trigger('loaded.bs.modal')
-                  }, this))
-            }
-        }
++function ($) {
+    'use strict';
 
-        Modal.VERSION = '3.3.4'
+    // MODAL CLASS DEFINITION
+    // ======================
 
-        Modal.TRANSITION_DURATION = 300
-        Modal.BACKDROP_TRANSITION_DURATION = 150
+    var Modal = function (element, options) {
+        this.options = options
+        this.$body = $(document.body)
+        this.$element = $(element)
+        this.$dialog = this.$element.find('.modal-dialog')
+        this.$backdrop = null
+        this.isShown = null
+        this.originalBodyPad = null
+        this.scrollbarWidth = 0
+        this.ignoreBackdropClick = false
 
-        Modal.DEFAULTS = {
-            backdrop: true,
-            keyboard: true,
-            show: true
+        if (this.options.remote) {
+            this.$element
+              .find('.modal-content')
+              .load(this.options.remote, $.proxy(function () {
+                  this.$element.trigger('loaded.bs.modal')
+              }, this))
         }
+    }
 
-        Modal.prototype.toggle = function (_relatedTarget) {
-            return this.isShown ? this.hide() : this.show(_relatedTarget)
-        }
+    Modal.VERSION = '3.3.5'
 
-        Modal.prototype.show = function (_relatedTarget) {
-            var that = this
-            var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+    Modal.TRANSITION_DURATION = 300
+    Modal.BACKDROP_TRANSITION_DURATION = 150
 
-            this.$element.trigger(e)
+    Modal.DEFAULTS = {
+        backdrop: true,
+        keyboard: true,
+        show: true
+    }
+
+    Modal.prototype.toggle = function (_relatedTarget) {
+        return this.isShown ? this.hide() : this.show(_relatedTarget)
+    }
 
-            if (this.isShown || e.isDefaultPrevented()) return
+    Modal.prototype.show = function (_relatedTarget) {
+        var that = this
+        var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
 
-            this.isShown = true
+        this.$element.trigger(e)
 
-            this.checkScrollbar()
-            this.setScrollbar()
-            this.$body.addClass('modal-open')
+        if (this.isShown || e.isDefaultPrevented()) return
 
-            this.escape()
-            this.resize()
+        this.isShown = true
 
-            this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+        this.checkScrollbar()
+        this.setScrollbar()
+        this.$body.addClass('modal-open')
 
-            this.$dialog.on('mousedown.dismiss.bs.modal', function () {
-                that.$element.one('mouseup.dismiss.bs.modal', function (e) {
-                    if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
-                })
+        this.escape()
+        this.resize()
+
+        this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+
+        this.$dialog.on('mousedown.dismiss.bs.modal', function () {
+            that.$element.one('mouseup.dismiss.bs.modal', function (e) {
+                if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
             })
+        })
 
-            this.backdrop(function () {
-                var transition = $.support.transition && that.$element.hasClass('fade')
+        this.backdrop(function () {
+            var transition = $.support.transition && that.$element.hasClass('fade')
 
-                if (!that.$element.parent().length) {
-                    that.$element.appendTo(that.$body) // don't move modals dom position
-                }
+            if (!that.$element.parent().length) {
+                that.$element.appendTo(that.$body) // don't move modals dom position
+            }
 
-                that.$element
-                  .show()
-                  .scrollTop(0)
+            that.$element
+              .show()
+              .scrollTop(0)
 
-                that.adjustDialog()
+            that.adjustDialog()
 
-                if (transition) {
-                    that.$element[0].offsetWidth // force reflow
-                }
+            if (transition) {
+                that.$element[0].offsetWidth // force reflow
+            }
 
-                that.$element
-                  .addClass('in')
-                  .attr('aria-hidden', false)
+            that.$element.addClass('in')
 
-                that.enforceFocus()
+            that.enforceFocus()
 
-                var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+            var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
 
-                transition ?
-                  that.$dialog // wait for modal to slide in
-                    .one('bsTransitionEnd', function () {
-                        that.$element.trigger('focus').trigger(e)
-                    })
-                    .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
-                  that.$element.trigger('focus').trigger(e)
-            })
-        }
+            transition ?
+              that.$dialog // wait for modal to slide in
+                .one('bsTransitionEnd', function () {
+                    that.$element.trigger('focus').trigger(e)
+                })
+                .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+              that.$element.trigger('focus').trigger(e)
+        })
+    }
 
-        Modal.prototype.hide = function (e) {
-            if (e) e.preventDefault()
+    Modal.prototype.hide = function (e) {
+        if (e) e.preventDefault()
 
-            e = $.Event('hide.bs.modal')
+        e = $.Event('hide.bs.modal')
 
-            this.$element.trigger(e)
+        this.$element.trigger(e)
 
-            if (!this.isShown || e.isDefaultPrevented()) return
+        if (!this.isShown || e.isDefaultPrevented()) return
 
-            this.isShown = false
+        this.isShown = false
 
-            this.escape()
-            this.resize()
+        this.escape()
+        this.resize()
 
-            $(document).off('focusin.bs.modal')
+        $(document).off('focusin.bs.modal')
 
-            this.$element
-              .removeClass('in')
-              .attr('aria-hidden', true)
-              .off('click.dismiss.bs.modal')
-              .off('mouseup.dismiss.bs.modal')
+        this.$element
+          .removeClass('in')
+          .off('click.dismiss.bs.modal')
+          .off('mouseup.dismiss.bs.modal')
 
-            this.$dialog.off('mousedown.dismiss.bs.modal')
+        this.$dialog.off('mousedown.dismiss.bs.modal')
 
-            $.support.transition && this.$element.hasClass('fade') ?
-              this.$element
-                .one('bsTransitionEnd', $.proxy(this.hideModal, this))
-                .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
-              this.hideModal()
-        }
+        $.support.transition && this.$element.hasClass('fade') ?
+          this.$element
+            .one('bsTransitionEnd', $.proxy(this.hideModal, this))
+            .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+          this.hideModal()
+    }
 
-        Modal.prototype.enforceFocus = function () {
-            $(document)
-              .off('focusin.bs.modal') // guard against infinite focus loop
-              .on('focusin.bs.modal', $.proxy(function (e) {
-                  if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
-                      this.$element.trigger('focus')
-                  }
-              }, this))
-        }
+    Modal.prototype.enforceFocus = function () {
+        $(document)
+          .off('focusin.bs.modal') // guard against infinite focus loop
+          .on('focusin.bs.modal', $.proxy(function (e) {
+              if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
+                  this.$element.trigger('focus')
+              }
+          }, this))
+    }
 
-        Modal.prototype.escape = function () {
-            if (this.isShown && this.options.keyboard) {
-                this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
-                    e.which == 27 && this.hide()
-                }, this))
-            } else if (!this.isShown) {
-                this.$element.off('keydown.dismiss.bs.modal')
-            }
+    Modal.prototype.escape = function () {
+        if (this.isShown && this.options.keyboard) {
+            this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
+                e.which == 27 && this.hide()
+            }, this))
+        } else if (!this.isShown) {
+            this.$element.off('keydown.dismiss.bs.modal')
         }
+    }
 
-        Modal.prototype.resize = function () {
-            if (this.isShown) {
-                $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
-            } else {
-                $(window).off('resize.bs.modal')
-            }
+    Modal.prototype.resize = function () {
+        if (this.isShown) {
+            $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
+        } else {
+            $(window).off('resize.bs.modal')
         }
+    }
 
-        Modal.prototype.hideModal = function () {
-            var that = this
-            this.$element.hide()
-            this.backdrop(function () {
-                that.$body.removeClass('modal-open')
-                that.resetAdjustments()
-                that.resetScrollbar()
-                that.$element.trigger('hidden.bs.modal')
-            })
-        }
+    Modal.prototype.hideModal = function () {
+        var that = this
+        this.$element.hide()
+        this.backdrop(function () {
+            that.$body.removeClass('modal-open')
+            that.resetAdjustments()
+            that.resetScrollbar()
+            that.$element.trigger('hidden.bs.modal')
+        })
+    }
 
-        Modal.prototype.removeBackdrop = function () {
-            this.$backdrop && this.$backdrop.remove()
-            this.$backdrop = null
-        }
+    Modal.prototype.removeBackdrop = function () {
+        this.$backdrop && this.$backdrop.remove()
+        this.$backdrop = null
+    }
 
-        Modal.prototype.backdrop = function (callback) {
-            var that = this
-            var animate = this.$element.hasClass('fade') ? 'fade' : ''
+    Modal.prototype.backdrop = function (callback) {
+        var that = this
+        var animate = this.$element.hasClass('fade') ? 'fade' : ''
 
-            if (this.isShown && this.options.backdrop) {
-                var doAnimate = $.support.transition && animate
+        if (this.isShown && this.options.backdrop) {
+            var doAnimate = $.support.transition && animate
 
-                this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
-                  .appendTo(this.$body)
+            this.$backdrop = $(document.createElement('div'))
+              .addClass('modal-backdrop ' + animate)
+              .appendTo(this.$body)
 
-                this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
-                    if (this.ignoreBackdropClick) {
-                        this.ignoreBackdropClick = false
-                        return
-                    }
-                    if (e.target !== e.currentTarget) return
-                    this.options.backdrop == 'static'
-                      ? this.$element[0].focus()
-                      : this.hide()
-                }, this))
+            this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
+                if (this.ignoreBackdropClick) {
+                    this.ignoreBackdropClick = false
+                    return
+                }
+                if (e.target !== e.currentTarget) return
+                this.options.backdrop == 'static'
+                  ? this.$element[0].focus()
+                  : this.hide()
+            }, this))
 
-                if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+            if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
 
-                this.$backdrop.addClass('in')
+            this.$backdrop.addClass('in')
 
-                if (!callback) return
+            if (!callback) return
 
-                doAnimate ?
-                  this.$backdrop
-                    .one('bsTransitionEnd', callback)
-                    .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
-                  callback()
+            doAnimate ?
+              this.$backdrop
+                .one('bsTransitionEnd', callback)
+                .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+              callback()
 
-            } else if (!this.isShown && this.$backdrop) {
-                this.$backdrop.removeClass('in')
+        } else if (!this.isShown && this.$backdrop) {
+            this.$backdrop.removeClass('in')
 
-                var callbackRemove = function () {
-                    that.removeBackdrop()
-                    callback && callback()
-                }
-                $.support.transition && this.$element.hasClass('fade') ?
-                  this.$backdrop
-                    .one('bsTransitionEnd', callbackRemove)
-                    .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
-                  callbackRemove()
-
-            } else if (callback) {
-                callback()
+            var callbackRemove = function () {
+                that.removeBackdrop()
+                callback && callback()
             }
-        }
-
-        // these following methods are used to handle overflowing modals
+            $.support.transition && this.$element.hasClass('fade') ?
+              this.$backdrop
+                .one('bsTransitionEnd', callbackRemove)
+                .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+              callbackRemove()
 
-        Modal.prototype.handleUpdate = function () {
-            this.adjustDialog()
+        } else if (callback) {
+            callback()
         }
+    }
 
-        Modal.prototype.adjustDialog = function () {
-            var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
+    // these following methods are used to handle overflowing modals
 
-            this.$element.css({
-                paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
-                paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
-            })
-        }
+    Modal.prototype.handleUpdate = function () {
+        this.adjustDialog()
+    }
 
-        Modal.prototype.resetAdjustments = function () {
-            this.$element.css({
-                paddingLeft: '',
-                paddingRight: ''
-            })
-        }
+    Modal.prototype.adjustDialog = function () {
+        var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
 
-        Modal.prototype.checkScrollbar = function () {
-            var fullWindowWidth = window.innerWidth
-            if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
-                var documentElementRect = document.documentElement.getBoundingClientRect()
-                fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
-            }
-            this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
-            this.scrollbarWidth = this.measureScrollbar()
-        }
+        this.$element.css({
+            paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
+            paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
+        })
+    }
 
-        Modal.prototype.setScrollbar = function () {
-            var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
-            this.originalBodyPad = document.body.style.paddingRight || ''
-            if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
-        }
+    Modal.prototype.resetAdjustments = function () {
+        this.$element.css({
+            paddingLeft: '',
+            paddingRight: ''
+        })
+    }
 
-        Modal.prototype.resetScrollbar = function () {
-            this.$body.css('padding-right', this.originalBodyPad)
+    Modal.prototype.checkScrollbar = function () {
+        var fullWindowWidth = window.innerWidth
+        if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
+            var documentElementRect = document.documentElement.getBoundingClientRect()
+            fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
         }
+        this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
+        this.scrollbarWidth = this.measureScrollbar()
+    }
 
-        Modal.prototype.measureScrollbar = function () { // thx walsh
-            var scrollDiv = document.createElement('div')
-            scrollDiv.className = 'modal-scrollbar-measure'
-            this.$body.append(scrollDiv)
-            var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
-            this.$body[0].removeChild(scrollDiv)
-            return scrollbarWidth
-        }
+    Modal.prototype.setScrollbar = function () {
+        var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
+        this.originalBodyPad = document.body.style.paddingRight || ''
+        if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
+    }
 
+    Modal.prototype.resetScrollbar = function () {
+        this.$body.css('padding-right', this.originalBodyPad)
+    }
 
-        // MODAL PLUGIN DEFINITION
-        // =======================
+    Modal.prototype.measureScrollbar = function () { // thx walsh
+        var scrollDiv = document.createElement('div')
+        scrollDiv.className = 'modal-scrollbar-measure'
+        this.$body.append(scrollDiv)
+        var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+        this.$body[0].removeChild(scrollDiv)
+        return scrollbarWidth
+    }
 
-        function Plugin(option, _relatedTarget) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.modal')
-                var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
 
-                if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
-                if (typeof option == 'string') data[option](_relatedTarget)
-                else if (options.show) data.show(_relatedTarget)
-            })
-        }
+    // MODAL PLUGIN DEFINITION
+    // =======================
+
+    function Plugin(option, _relatedTarget) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.modal')
+            var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+            if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
+            if (typeof option == 'string') data[option](_relatedTarget)
+            else if (options.show) data.show(_relatedTarget)
+        })
+    }
 
-        var old = $.fn.modal
+    var old = $.fn.modal
 
-        $.fn.modal = Plugin
-        $.fn.modal.Constructor = Modal
+    $.fn.modal = Plugin
+    $.fn.modal.Constructor = Modal
 
 
-        // MODAL NO CONFLICT
-        // =================
+    // MODAL NO CONFLICT
+    // =================
 
-        $.fn.modal.noConflict = function () {
-            $.fn.modal = old
-            return this
-        }
+    $.fn.modal.noConflict = function () {
+        $.fn.modal = old
+        return this
+    }
 
 
-        // MODAL DATA-API
-        // ==============
+    // MODAL DATA-API
+    // ==============
 
-        $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
-            var $this = $(this)
-            var href = $this.attr('href')
-            var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
-            var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
+    $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+        var $this = $(this)
+        var href = $this.attr('href')
+        var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
+        var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
 
-            if ($this.is('a')) e.preventDefault()
+        if ($this.is('a')) e.preventDefault()
 
-            $target.one('show.bs.modal', function (showEvent) {
-                if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
-                $target.one('hidden.bs.modal', function () {
-                    $this.is(':visible') && $this.trigger('focus')
-                })
+        $target.one('show.bs.modal', function (showEvent) {
+            if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
+            $target.one('hidden.bs.modal', function () {
+                $this.is(':visible') && $this.trigger('focus')
             })
-            Plugin.call($target, option, this)
         })
+        Plugin.call($target, option, this)
+    })
 
-    }(jQuery);
+}(jQuery);
 
-    /* ========================================================================
-     * Bootstrap: tooltip.js v3.3.4
-     * http://getbootstrap.com/javascript/#tooltip
-     * Inspired by the original jQuery.tipsy by Jason Frame
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+/* ========================================================================
+ * Bootstrap: tooltip.js v3.3.5
+ * http://getbootstrap.com/javascript/#tooltip
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
 
-    +function ($) {
-        'use strict';
++function ($) {
+    'use strict';
 
-        // TOOLTIP PUBLIC CLASS DEFINITION
-        // ===============================
+    // TOOLTIP PUBLIC CLASS DEFINITION
+    // ===============================
 
-        var Tooltip = function (element, options) {
-            this.type = null
-            this.options = null
-            this.enabled = null
-            this.timeout = null
-            this.hoverState = null
-            this.$element = null
+    var Tooltip = function (element, options) {
+        this.type = null
+        this.options = null
+        this.enabled = null
+        this.timeout = null
+        this.hoverState = null
+        this.$element = null
+        this.inState = null
 
-            this.init('tooltip', element, options)
-        }
+        this.init('tooltip', element, options)
+    }
 
-        Tooltip.VERSION = '3.3.4'
-
-        Tooltip.TRANSITION_DURATION = 150
-
-        Tooltip.DEFAULTS = {
-            animation: true,
-            placement: 'top',
-            selector: false,
-            template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
-            trigger: 'hover focus',
-            title: '',
-            delay: 0,
-            html: false,
-            container: false,
-            viewport: {
-                selector: 'body',
-                padding: 0
-            }
+    Tooltip.VERSION = '3.3.5'
+
+    Tooltip.TRANSITION_DURATION = 150
+
+    Tooltip.DEFAULTS = {
+        animation: true,
+        placement: 'top',
+        selector: false,
+        template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
+        trigger: 'hover focus',
+        title: '',
+        delay: 0,
+        html: false,
+        container: false,
+        viewport: {
+            selector: 'body',
+            padding: 0
         }
+    }
 
-        Tooltip.prototype.init = function (type, element, options) {
-            this.enabled = true
-            this.type = type
-            this.$element = $(element)
-            this.options = this.getOptions(options)
-            this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
+    Tooltip.prototype.init = function (type, element, options) {
+        this.enabled = true
+        this.type = type
+        this.$element = $(element)
+        this.options = this.getOptions(options)
+        this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
+        this.inState = { click: false, hover: false, focus: false }
 
-            if (this.$element[0] instanceof document.constructor && !this.options.selector) {
-                throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
-            }
+        if (this.$element[0] instanceof document.constructor && !this.options.selector) {
+            throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
+        }
 
-            var triggers = this.options.trigger.split(' ')
+        var triggers = this.options.trigger.split(' ')
 
-            for (var i = triggers.length; i--;) {
-                var trigger = triggers[i]
+        for (var i = triggers.length; i--;) {
+            var trigger = triggers[i]
 
-                if (trigger == 'click') {
-                    this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
-                } else if (trigger != 'manual') {
-                    var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
-                    var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+            if (trigger == 'click') {
+                this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+            } else if (trigger != 'manual') {
+                var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
+                var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
 
-                    this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
-                    this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
-                }
+                this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+                this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
             }
-
-            this.options.selector ?
-              (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
-              this.fixTitle()
         }
 
-        Tooltip.prototype.getDefaults = function () {
-            return Tooltip.DEFAULTS
-        }
+        this.options.selector ?
+          (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+          this.fixTitle()
+    }
 
-        Tooltip.prototype.getOptions = function (options) {
-            options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+    Tooltip.prototype.getDefaults = function () {
+        return Tooltip.DEFAULTS
+    }
 
-            if (options.delay && typeof options.delay == 'number') {
-                options.delay = {
-                    show: options.delay,
-                    hide: options.delay
-                }
-            }
+    Tooltip.prototype.getOptions = function (options) {
+        options = $.extend({}, this.getDefaults(), this.$element.data(), options)
 
-            return options
+        if (options.delay && typeof options.delay == 'number') {
+            options.delay = {
+                show: options.delay,
+                hide: options.delay
+            }
         }
 
-        Tooltip.prototype.getDelegateOptions = function () {
-            var options = {}
-            var defaults = this.getDefaults()
+        return options
+    }
 
-            this._options && $.each(this._options, function (key, value) {
-                if (defaults[key] != value) options[key] = value
-            })
+    Tooltip.prototype.getDelegateOptions = function () {
+        var options = {}
+        var defaults = this.getDefaults()
 
-            return options
-        }
+        this._options && $.each(this._options, function (key, value) {
+            if (defaults[key] != value) options[key] = value
+        })
 
-        Tooltip.prototype.enter = function (obj) {
-            var self = obj instanceof this.constructor ?
-                obj : $(obj.currentTarget).data('bs.' + this.type)
+        return options
+    }
 
-            if (self && self.$tip && self.$tip.is(':visible')) {
-                self.hoverState = 'in'
-                return
-            }
+    Tooltip.prototype.enter = function (obj) {
+        var self = obj instanceof this.constructor ?
+            obj : $(obj.currentTarget).data('bs.' + this.type)
 
-            if (!self) {
-                self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
-                $(obj.currentTarget).data('bs.' + this.type, self)
-            }
+        if (!self) {
+            self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+            $(obj.currentTarget).data('bs.' + this.type, self)
+        }
 
-            clearTimeout(self.timeout)
+        if (obj instanceof $.Event) {
+            self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
+        }
 
+        if (self.tip().hasClass('in') || self.hoverState == 'in') {
             self.hoverState = 'in'
+            return
+        }
 
-            if (!self.options.delay || !self.options.delay.show) return self.show()
+        clearTimeout(self.timeout)
 
-            self.timeout = setTimeout(function () {
-                if (self.hoverState == 'in') self.show()
-            }, self.options.delay.show)
-        }
+        self.hoverState = 'in'
 
-        Tooltip.prototype.leave = function (obj) {
-            var self = obj instanceof this.constructor ?
-                obj : $(obj.currentTarget).data('bs.' + this.type)
+        if (!self.options.delay || !self.options.delay.show) return self.show()
 
-            if (!self) {
-                self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
-                $(obj.currentTarget).data('bs.' + this.type, self)
-            }
+        self.timeout = setTimeout(function () {
+            if (self.hoverState == 'in') self.show()
+        }, self.options.delay.show)
+    }
 
-            clearTimeout(self.timeout)
+    Tooltip.prototype.isInStateTrue = function () {
+        for (var key in this.inState) {
+            if (this.inState[key]) return true
+        }
 
-            self.hoverState = 'out'
+        return false
+    }
 
-            if (!self.options.delay || !self.options.delay.hide) return self.hide()
+    Tooltip.prototype.leave = function (obj) {
+        var self = obj instanceof this.constructor ?
+            obj : $(obj.currentTarget).data('bs.' + this.type)
 
-            self.timeout = setTimeout(function () {
-                if (self.hoverState == 'out') self.hide()
-            }, self.options.delay.hide)
+        if (!self) {
+            self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+            $(obj.currentTarget).data('bs.' + this.type, self)
         }
 
-        Tooltip.prototype.show = function () {
-            var e = $.Event('show.bs.' + this.type)
+        if (obj instanceof $.Event) {
+            self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
+        }
 
-            if (this.hasContent() && this.enabled) {
-                this.$element.trigger(e)
+        if (self.isInStateTrue()) return
 
-                var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
-                if (e.isDefaultPrevented() || !inDom) return
-                var that = this
+        clearTimeout(self.timeout)
 
-                var $tip = this.tip()
+        self.hoverState = 'out'
 
-                var tipId = this.getUID(this.type)
+        if (!self.options.delay || !self.options.delay.hide) return self.hide()
 
-                this.setContent()
-                $tip.attr('id', tipId)
-                this.$element.attr('aria-describedby', tipId)
+        self.timeout = setTimeout(function () {
+            if (self.hoverState == 'out') self.hide()
+        }, self.options.delay.hide)
+    }
 
-                if (this.options.animation) $tip.addClass('fade')
+    Tooltip.prototype.show = function () {
+        var e = $.Event('show.bs.' + this.type)
 
-                var placement = typeof this.options.placement == 'function' ?
-                  this.options.placement.call(this, $tip[0], this.$element[0]) :
-                  this.options.placement
+        if (this.hasContent() && this.enabled) {
+            this.$element.trigger(e)
 
-                var autoToken = /\s?auto?\s?/i
-                var autoPlace = autoToken.test(placement)
-                if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+            var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
+            if (e.isDefaultPrevented() || !inDom) return
+            var that = this
 
-                $tip
-                  .detach()
-                  .css({ top: 0, left: 0, display: 'block' })
-                  .addClass(placement)
-                  .data('bs.' + this.type, this)
+            var $tip = this.tip()
 
-                this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+            var tipId = this.getUID(this.type)
 
-                var pos = this.getPosition()
-                var actualWidth = $tip[0].offsetWidth
-                var actualHeight = $tip[0].offsetHeight
+            this.setContent()
+            $tip.attr('id', tipId)
+            this.$element.attr('aria-describedby', tipId)
 
-                if (autoPlace) {
-                    var orgPlacement = placement
-                    var $container = this.options.container ? $(this.options.container) : this.$element.parent()
-                    var containerDim = this.getPosition($container)
+            if (this.options.animation) $tip.addClass('fade')
 
-                    placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
-                                placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
-                                placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
-                                placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
-                                placement
+            var placement = typeof this.options.placement == 'function' ?
+              this.options.placement.call(this, $tip[0], this.$element[0]) :
+              this.options.placement
 
-                    $tip
-                      .removeClass(orgPlacement)
-                      .addClass(placement)
-                }
+            var autoToken = /\s?auto?\s?/i
+            var autoPlace = autoToken.test(placement)
+            if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
 
-                var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+            $tip
+              .detach()
+              .css({ top: 0, left: 0, display: 'block' })
+              .addClass(placement)
+              .data('bs.' + this.type, this)
 
-                this.applyPlacement(calculatedOffset, placement)
+            this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+            this.$element.trigger('inserted.bs.' + this.type)
 
-                var complete = function () {
-                    var prevHoverState = that.hoverState
-                    that.$element.trigger('shown.bs.' + that.type)
-                    that.hoverState = null
+            var pos = this.getPosition()
+            var actualWidth = $tip[0].offsetWidth
+            var actualHeight = $tip[0].offsetHeight
 
-                    if (prevHoverState == 'out') that.leave(that)
-                }
+            if (autoPlace) {
+                var orgPlacement = placement
+                var viewportDim = this.getPosition(this.$viewport)
+
+                placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
+                            placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
+                            placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
+                            placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
+                            placement
 
-                $.support.transition && this.$tip.hasClass('fade') ?
-                  $tip
-                    .one('bsTransitionEnd', complete)
-                    .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
-                  complete()
+                $tip
+                  .removeClass(orgPlacement)
+                  .addClass(placement)
             }
-        }
 
-        Tooltip.prototype.applyPlacement = function (offset, placement) {
-            var $tip = this.tip()
-            var width = $tip[0].offsetWidth
-            var height = $tip[0].offsetHeight
-
-            // manually read margins because getBoundingClientRect includes difference
-            var marginTop = parseInt($tip.css('margin-top'), 10)
-            var marginLeft = parseInt($tip.css('margin-left'), 10)
-
-            // we must check for NaN for ie 8/9
-            if (isNaN(marginTop)) marginTop = 0
-            if (isNaN(marginLeft)) marginLeft = 0
-
-            offset.top = offset.top + marginTop
-            offset.left = offset.left + marginLeft
-
-            // $.fn.offset doesn't round pixel values
-            // so we use setOffset directly with our own function B-0
-            $.offset.setOffset($tip[0], $.extend({
-                using: function (props) {
-                    $tip.css({
-                        top: Math.round(props.top),
-                        left: Math.round(props.left)
-                    })
-                }
-            }, offset), 0)
+            var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
 
-            $tip.addClass('in')
+            this.applyPlacement(calculatedOffset, placement)
 
-            // check to see if placing tip in new offset caused the tip to resize itself
-            var actualWidth = $tip[0].offsetWidth
-            var actualHeight = $tip[0].offsetHeight
+            var complete = function () {
+                var prevHoverState = that.hoverState
+                that.$element.trigger('shown.bs.' + that.type)
+                that.hoverState = null
 
-            if (placement == 'top' && actualHeight != height) {
-                offset.top = offset.top + height - actualHeight
+                if (prevHoverState == 'out') that.leave(that)
             }
 
-            var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
+            $.support.transition && this.$tip.hasClass('fade') ?
+              $tip
+                .one('bsTransitionEnd', complete)
+                .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+              complete()
+        }
+    }
 
-            if (delta.left) offset.left += delta.left
-            else offset.top += delta.top
+    Tooltip.prototype.applyPlacement = function (offset, placement) {
+        var $tip = this.tip()
+        var width = $tip[0].offsetWidth
+        var height = $tip[0].offsetHeight
+
+        // manually read margins because getBoundingClientRect includes difference
+        var marginTop = parseInt($tip.css('margin-top'), 10)
+        var marginLeft = parseInt($tip.css('margin-left'), 10)
+
+        // we must check for NaN for ie 8/9
+        if (isNaN(marginTop)) marginTop = 0
+        if (isNaN(marginLeft)) marginLeft = 0
+
+        offset.top += marginTop
+        offset.left += marginLeft
+
+        // $.fn.offset doesn't round pixel values
+        // so we use setOffset directly with our own function B-0
+        $.offset.setOffset($tip[0], $.extend({
+            using: function (props) {
+                $tip.css({
+                    top: Math.round(props.top),
+                    left: Math.round(props.left)
+                })
+            }
+        }, offset), 0)
 
-            var isVertical = /top|bottom/.test(placement)
-            var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
-            var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
+        $tip.addClass('in')
 
-            $tip.offset(offset)
-            this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
-        }
+        // check to see if placing tip in new offset caused the tip to resize itself
+        var actualWidth = $tip[0].offsetWidth
+        var actualHeight = $tip[0].offsetHeight
 
-        Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
-            this.arrow()
-              .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
-              .css(isVertical ? 'top' : 'left', '')
+        if (placement == 'top' && actualHeight != height) {
+            offset.top = offset.top + height - actualHeight
         }
 
-        Tooltip.prototype.setContent = function () {
-            var $tip = this.tip()
-            var title = this.getTitle()
+        var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
 
-            $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
-            $tip.removeClass('fade in top bottom left right')
-        }
+        if (delta.left) offset.left += delta.left
+        else offset.top += delta.top
 
-        Tooltip.prototype.hide = function (callback) {
-            var that = this
-            var $tip = $(this.$tip)
-            var e = $.Event('hide.bs.' + this.type)
-
-            function complete() {
-                if (that.hoverState != 'in') $tip.detach()
-                that.$element
-                  .removeAttr('aria-describedby')
-                  .trigger('hidden.bs.' + that.type)
-                callback && callback()
-            }
+        var isVertical = /top|bottom/.test(placement)
+        var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
+        var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
 
-            this.$element.trigger(e)
+        $tip.offset(offset)
+        this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
+    }
 
-            if (e.isDefaultPrevented()) return
+    Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
+        this.arrow()
+          .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
+          .css(isVertical ? 'top' : 'left', '')
+    }
 
-            $tip.removeClass('in')
+    Tooltip.prototype.setContent = function () {
+        var $tip = this.tip()
+        var title = this.getTitle()
 
-            $.support.transition && $tip.hasClass('fade') ?
-              $tip
-                .one('bsTransitionEnd', complete)
-                .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
-              complete()
+        $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+        $tip.removeClass('fade in top bottom left right')
+    }
 
-            this.hoverState = null
+    Tooltip.prototype.hide = function (callback) {
+        var that = this
+        var $tip = $(this.$tip)
+        var e = $.Event('hide.bs.' + this.type)
 
-            return this
+        function complete() {
+            if (that.hoverState != 'in') $tip.detach()
+            that.$element
+              .removeAttr('aria-describedby')
+              .trigger('hidden.bs.' + that.type)
+            callback && callback()
         }
 
-        Tooltip.prototype.fixTitle = function () {
-            var $e = this.$element
-            if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
-                $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
-            }
-        }
+        this.$element.trigger(e)
 
-        Tooltip.prototype.hasContent = function () {
-            return this.getTitle()
-        }
+        if (e.isDefaultPrevented()) return
 
-        Tooltip.prototype.getPosition = function ($element) {
-            $element = $element || this.$element
+        $tip.removeClass('in')
 
-            var el = $element[0]
-            var isBody = el.tagName == 'BODY'
+        $.support.transition && $tip.hasClass('fade') ?
+          $tip
+            .one('bsTransitionEnd', complete)
+            .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+          complete()
 
-            var elRect = el.getBoundingClientRect()
-            if (elRect.width == null) {
-                // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
-                elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
-            }
-            var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
-            var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
-            var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+        this.hoverState = null
 
-            return $.extend({}, elRect, scroll, outerDims, elOffset)
+        return this
+    }
+
+    Tooltip.prototype.fixTitle = function () {
+        var $e = this.$element
+        if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
+            $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
         }
+    }
 
-        Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
-            return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
-                   placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
-                   placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
-                /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
+    Tooltip.prototype.hasContent = function () {
+        return this.getTitle()
+    }
+
+    Tooltip.prototype.getPosition = function ($element) {
+        $element = $element || this.$element
 
+        var el = $element[0]
+        var isBody = el.tagName == 'BODY'
+
+        var elRect = el.getBoundingClientRect()
+        if (elRect.width == null) {
+            // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
+            elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
         }
+        var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
+        var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
+        var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+
+        return $.extend({}, elRect, scroll, outerDims, elOffset)
+    }
 
-        Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
-            var delta = { top: 0, left: 0 }
-            if (!this.$viewport) return delta
+    Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+        return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+               placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+               placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
+            /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
 
-            var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
-            var viewportDimensions = this.getPosition(this.$viewport)
+    }
 
-            if (/right|left/.test(placement)) {
-                var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
-                var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
-                if (topEdgeOffset < viewportDimensions.top) { // top overflow
-                    delta.top = viewportDimensions.top - topEdgeOffset
-                } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
-                    delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
-                }
-            } else {
-                var leftEdgeOffset = pos.left - viewportPadding
-                var rightEdgeOffset = pos.left + viewportPadding + actualWidth
-                if (leftEdgeOffset < viewportDimensions.left) { // left overflow
-                    delta.left = viewportDimensions.left - leftEdgeOffset
-                } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
-                    delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
-                }
-            }
+    Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
+        var delta = { top: 0, left: 0 }
+        if (!this.$viewport) return delta
+
+        var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
+        var viewportDimensions = this.getPosition(this.$viewport)
 
-            return delta
+        if (/right|left/.test(placement)) {
+            var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
+            var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
+            if (topEdgeOffset < viewportDimensions.top) { // top overflow
+                delta.top = viewportDimensions.top - topEdgeOffset
+            } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
+                delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
+            }
+        } else {
+            var leftEdgeOffset = pos.left - viewportPadding
+            var rightEdgeOffset = pos.left + viewportPadding + actualWidth
+            if (leftEdgeOffset < viewportDimensions.left) { // left overflow
+                delta.left = viewportDimensions.left - leftEdgeOffset
+            } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
+                delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
+            }
         }
 
-        Tooltip.prototype.getTitle = function () {
-            var title
-            var $e = this.$element
-            var o = this.options
+        return delta
+    }
 
-            title = $e.attr('data-original-title')
-              || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+    Tooltip.prototype.getTitle = function () {
+        var title
+        var $e = this.$element
+        var o = this.options
 
-            return title
-        }
+        title = $e.attr('data-original-title')
+          || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
 
-        Tooltip.prototype.getUID = function (prefix) {
-            do prefix += ~~(Math.random() * 1000000)
-            while (document.getElementById(prefix))
-            return prefix
-        }
+        return title
+    }
 
-        Tooltip.prototype.tip = function () {
-            return (this.$tip = this.$tip || $(this.options.template))
-        }
+    Tooltip.prototype.getUID = function (prefix) {
+        do prefix += ~~(Math.random() * 1000000)
+        while (document.getElementById(prefix))
+        return prefix
+    }
 
-        Tooltip.prototype.arrow = function () {
-            return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+    Tooltip.prototype.tip = function () {
+        if (!this.$tip) {
+            this.$tip = $(this.options.template)
+            if (this.$tip.length != 1) {
+                throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
+            }
         }
+        return this.$tip
+    }
 
-        Tooltip.prototype.enable = function () {
-            this.enabled = true
-        }
+    Tooltip.prototype.arrow = function () {
+        return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+    }
 
-        Tooltip.prototype.disable = function () {
-            this.enabled = false
-        }
+    Tooltip.prototype.enable = function () {
+        this.enabled = true
+    }
 
-        Tooltip.prototype.toggleEnabled = function () {
-            this.enabled = !this.enabled
-        }
+    Tooltip.prototype.disable = function () {
+        this.enabled = false
+    }
 
-        Tooltip.prototype.toggle = function (e) {
-            var self = this
-            if (e) {
-                self = $(e.currentTarget).data('bs.' + this.type)
-                if (!self) {
-                    self = new this.constructor(e.currentTarget, this.getDelegateOptions())
-                    $(e.currentTarget).data('bs.' + this.type, self)
-                }
-            }
+    Tooltip.prototype.toggleEnabled = function () {
+        this.enabled = !this.enabled
+    }
 
-            self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+    Tooltip.prototype.toggle = function (e) {
+        var self = this
+        if (e) {
+            self = $(e.currentTarget).data('bs.' + this.type)
+            if (!self) {
+                self = new this.constructor(e.currentTarget, this.getDelegateOptions())
+                $(e.currentTarget).data('bs.' + this.type, self)
+            }
         }
 
-        Tooltip.prototype.destroy = function () {
-            var that = this
-            clearTimeout(this.timeout)
-            this.hide(function () {
-                that.$element.off('.' + that.type).removeData('bs.' + that.type)
-            })
+        if (e) {
+            self.inState.click = !self.inState.click
+            if (self.isInStateTrue()) self.enter(self)
+            else self.leave(self)
+        } else {
+            self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
         }
+    }
 
+    Tooltip.prototype.destroy = function () {
+        var that = this
+        clearTimeout(this.timeout)
+        this.hide(function () {
+            that.$element.off('.' + that.type).removeData('bs.' + that.type)
+            if (that.$tip) {
+                that.$tip.detach()
+            }
+            that.$tip = null
+            that.$arrow = null
+            that.$viewport = null
+        })
+    }
 
-        // TOOLTIP PLUGIN DEFINITION
-        // =========================
 
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.tooltip')
-                var options = typeof option == 'object' && option
+    // TOOLTIP PLUGIN DEFINITION
+    // =========================
 
-                if (!data && /destroy|hide/.test(option)) return
-                if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
-                if (typeof option == 'string') data[option]()
-            })
-        }
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.tooltip')
+            var options = typeof option == 'object' && option
 
-        var old = $.fn.tooltip
+            if (!data && /destroy|hide/.test(option)) return
+            if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
+            if (typeof option == 'string') data[option]()
+        })
+    }
 
-        $.fn.tooltip = Plugin
-        $.fn.tooltip.Constructor = Tooltip
+    var old = $.fn.tooltip
 
+    $.fn.tooltip = Plugin
+    $.fn.tooltip.Constructor = Tooltip
 
-        // TOOLTIP NO CONFLICT
-        // ===================
 
-        $.fn.tooltip.noConflict = function () {
-            $.fn.tooltip = old
-            return this
-        }
+    // TOOLTIP NO CONFLICT
+    // ===================
 
-    }(jQuery);
+    $.fn.tooltip.noConflict = function () {
+        $.fn.tooltip = old
+        return this
+    }
 
-    /* ========================================================================
-     * Bootstrap: popover.js v3.3.4
-     * http://getbootstrap.com/javascript/#popovers
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+}(jQuery);
 
+/* ========================================================================
+ * Bootstrap: popover.js v3.3.5
+ * http://getbootstrap.com/javascript/#popovers
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-    +function ($) {
-        'use strict';
 
-        // POPOVER PUBLIC CLASS DEFINITION
-        // ===============================
++function ($) {
+    'use strict';
 
-        var Popover = function (element, options) {
-            this.init('popover', element, options)
-        }
+    // POPOVER PUBLIC CLASS DEFINITION
+    // ===============================
 
-        if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
+    var Popover = function (element, options) {
+        this.init('popover', element, options)
+    }
 
-        Popover.VERSION = '3.3.4'
+    if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
 
-        Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
-            placement: 'right',
-            trigger: 'click',
-            content: '',
-            template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
-        })
+    Popover.VERSION = '3.3.5'
 
+    Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+        placement: 'right',
+        trigger: 'click',
+        content: '',
+        template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
+    })
 
-        // NOTE: POPOVER EXTENDS tooltip.js
-        // ================================
 
-        Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
+    // NOTE: POPOVER EXTENDS tooltip.js
+    // ================================
 
-        Popover.prototype.constructor = Popover
+    Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
 
-        Popover.prototype.getDefaults = function () {
-            return Popover.DEFAULTS
-        }
+    Popover.prototype.constructor = Popover
 
-        Popover.prototype.setContent = function () {
-            var $tip = this.tip()
-            var title = this.getTitle()
-            var content = this.getContent()
+    Popover.prototype.getDefaults = function () {
+        return Popover.DEFAULTS
+    }
 
-            $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
-            $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
-              this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
-            ](content)
+    Popover.prototype.setContent = function () {
+        var $tip = this.tip()
+        var title = this.getTitle()
+        var content = this.getContent()
 
-            $tip.removeClass('fade top bottom left right in')
+        $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+        $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
+          this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
+        ](content)
 
-            // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
-            // this manually by checking the contents.
-            if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
-        }
+        $tip.removeClass('fade top bottom left right in')
 
-        Popover.prototype.hasContent = function () {
-            return this.getTitle() || this.getContent()
-        }
+        // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
+        // this manually by checking the contents.
+        if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
+    }
 
-        Popover.prototype.getContent = function () {
-            var $e = this.$element
-            var o = this.options
+    Popover.prototype.hasContent = function () {
+        return this.getTitle() || this.getContent()
+    }
 
-            return $e.attr('data-content')
-              || (typeof o.content == 'function' ?
-                    o.content.call($e[0]) :
-                    o.content)
-        }
+    Popover.prototype.getContent = function () {
+        var $e = this.$element
+        var o = this.options
 
-        Popover.prototype.arrow = function () {
-            return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
-        }
+        return $e.attr('data-content')
+          || (typeof o.content == 'function' ?
+                o.content.call($e[0]) :
+                o.content)
+    }
 
+    Popover.prototype.arrow = function () {
+        return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
+    }
 
-        // POPOVER PLUGIN DEFINITION
-        // =========================
 
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.popover')
-                var options = typeof option == 'object' && option
+    // POPOVER PLUGIN DEFINITION
+    // =========================
 
-                if (!data && /destroy|hide/.test(option)) return
-                if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
-                if (typeof option == 'string') data[option]()
-            })
-        }
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.popover')
+            var options = typeof option == 'object' && option
 
-        var old = $.fn.popover
+            if (!data && /destroy|hide/.test(option)) return
+            if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
+            if (typeof option == 'string') data[option]()
+        })
+    }
 
-        $.fn.popover = Plugin
-        $.fn.popover.Constructor = Popover
+    var old = $.fn.popover
 
+    $.fn.popover = Plugin
+    $.fn.popover.Constructor = Popover
 
-        // POPOVER NO CONFLICT
-        // ===================
 
-        $.fn.popover.noConflict = function () {
-            $.fn.popover = old
-            return this
-        }
+    // POPOVER NO CONFLICT
+    // ===================
 
-    }(jQuery);
+    $.fn.popover.noConflict = function () {
+        $.fn.popover = old
+        return this
+    }
 
-    /* ========================================================================
-     * Bootstrap: scrollspy.js v3.3.4
-     * http://getbootstrap.com/javascript/#scrollspy
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+}(jQuery);
 
+/* ========================================================================
+ * Bootstrap: scrollspy.js v3.3.5
+ * http://getbootstrap.com/javascript/#scrollspy
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-    +function ($) {
-        'use strict';
 
-        // SCROLLSPY CLASS DEFINITION
-        // ==========================
++function ($) {
+    'use strict';
 
-        function ScrollSpy(element, options) {
-            this.$body = $(document.body)
-            this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
-            this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
-            this.selector = (this.options.target || '') + ' .nav li > a'
-            this.offsets = []
-            this.targets = []
-            this.activeTarget = null
-            this.scrollHeight = 0
+    // SCROLLSPY CLASS DEFINITION
+    // ==========================
 
-            this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
-            this.refresh()
-            this.process()
-        }
+    function ScrollSpy(element, options) {
+        this.$body = $(document.body)
+        this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
+        this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
+        this.selector = (this.options.target || '') + ' .nav li > a'
+        this.offsets = []
+        this.targets = []
+        this.activeTarget = null
+        this.scrollHeight = 0
 
-        ScrollSpy.VERSION = '3.3.4'
+        this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
+        this.refresh()
+        this.process()
+    }
 
-        ScrollSpy.DEFAULTS = {
-            offset: 10
-        }
+    ScrollSpy.VERSION = '3.3.5'
 
-        ScrollSpy.prototype.getScrollHeight = function () {
-            return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
-        }
+    ScrollSpy.DEFAULTS = {
+        offset: 10
+    }
 
-        ScrollSpy.prototype.refresh = function () {
-            var that = this
-            var offsetMethod = 'offset'
-            var offsetBase = 0
+    ScrollSpy.prototype.getScrollHeight = function () {
+        return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+    }
 
-            this.offsets = []
-            this.targets = []
-            this.scrollHeight = this.getScrollHeight()
+    ScrollSpy.prototype.refresh = function () {
+        var that = this
+        var offsetMethod = 'offset'
+        var offsetBase = 0
 
-            if (!$.isWindow(this.$scrollElement[0])) {
-                offsetMethod = 'position'
-                offsetBase = this.$scrollElement.scrollTop()
-            }
+        this.offsets = []
+        this.targets = []
+        this.scrollHeight = this.getScrollHeight()
 
-            this.$body
-              .find(this.selector)
-              .map(function () {
-                  var $el = $(this)
-                  var href = $el.data('target') || $el.attr('href')
-                  var $href = /^#./.test(href) && $(href)
-
-                  return ($href
-                    && $href.length
-                    && $href.is(':visible')
-                    && [[$href[offsetMethod]().top + offsetBase, href]]) || null
-              })
-              .sort(function (a, b) { return a[0] - b[0] })
-              .each(function () {
-                  that.offsets.push(this[0])
-                  that.targets.push(this[1])
-              })
+        if (!$.isWindow(this.$scrollElement[0])) {
+            offsetMethod = 'position'
+            offsetBase = this.$scrollElement.scrollTop()
         }
 
-        ScrollSpy.prototype.process = function () {
-            var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
-            var scrollHeight = this.getScrollHeight()
-            var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
-            var offsets = this.offsets
-            var targets = this.targets
-            var activeTarget = this.activeTarget
-            var i
-
-            if (this.scrollHeight != scrollHeight) {
-                this.refresh()
-            }
+        this.$body
+          .find(this.selector)
+          .map(function () {
+              var $el = $(this)
+              var href = $el.data('target') || $el.attr('href')
+              var $href = /^#./.test(href) && $(href)
 
-            if (scrollTop >= maxScroll) {
-                return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
-            }
+              return ($href
+                && $href.length
+                && $href.is(':visible')
+                && [[$href[offsetMethod]().top + offsetBase, href]]) || null
+          })
+          .sort(function (a, b) { return a[0] - b[0] })
+          .each(function () {
+              that.offsets.push(this[0])
+              that.targets.push(this[1])
+          })
+    }
 
-            if (activeTarget && scrollTop < offsets[0]) {
-                this.activeTarget = null
-                return this.clear()
-            }
+    ScrollSpy.prototype.process = function () {
+        var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+        var scrollHeight = this.getScrollHeight()
+        var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
+        var offsets = this.offsets
+        var targets = this.targets
+        var activeTarget = this.activeTarget
+        var i
 
-            for (i = offsets.length; i--;) {
-                activeTarget != targets[i]
-                  && scrollTop >= offsets[i]
-                  && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
-                  && this.activate(targets[i])
-            }
+        if (this.scrollHeight != scrollHeight) {
+            this.refresh()
         }
 
-        ScrollSpy.prototype.activate = function (target) {
-            this.activeTarget = target
+        if (scrollTop >= maxScroll) {
+            return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
+        }
 
-            this.clear()
+        if (activeTarget && scrollTop < offsets[0]) {
+            this.activeTarget = null
+            return this.clear()
+        }
 
-            var selector = this.selector +
-              '[data-target="' + target + '"],' +
-              this.selector + '[href="' + target + '"]'
+        for (i = offsets.length; i--;) {
+            activeTarget != targets[i]
+              && scrollTop >= offsets[i]
+              && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
+              && this.activate(targets[i])
+        }
+    }
 
-            var active = $(selector)
-              .parents('li')
-              .addClass('active')
+    ScrollSpy.prototype.activate = function (target) {
+        this.activeTarget = target
 
-            if (active.parent('.dropdown-menu').length) {
-                active = active
-                  .closest('li.dropdown')
-                  .addClass('active')
-            }
+        this.clear()
 
-            active.trigger('activate.bs.scrollspy')
-        }
+        var selector = this.selector +
+          '[data-target="' + target + '"],' +
+          this.selector + '[href="' + target + '"]'
 
-        ScrollSpy.prototype.clear = function () {
-            $(this.selector)
-              .parentsUntil(this.options.target, '.active')
-              .removeClass('active')
+        var active = $(selector)
+          .parents('li')
+          .addClass('active')
+
+        if (active.parent('.dropdown-menu').length) {
+            active = active
+              .closest('li.dropdown')
+              .addClass('active')
         }
 
+        active.trigger('activate.bs.scrollspy')
+    }
 
-        // SCROLLSPY PLUGIN DEFINITION
-        // ===========================
+    ScrollSpy.prototype.clear = function () {
+        $(this.selector)
+          .parentsUntil(this.options.target, '.active')
+          .removeClass('active')
+    }
 
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.scrollspy')
-                var options = typeof option == 'object' && option
 
-                if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
-                if (typeof option == 'string') data[option]()
-            })
-        }
+    // SCROLLSPY PLUGIN DEFINITION
+    // ===========================
 
-        var old = $.fn.scrollspy
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.scrollspy')
+            var options = typeof option == 'object' && option
 
-        $.fn.scrollspy = Plugin
-        $.fn.scrollspy.Constructor = ScrollSpy
+            if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
+            if (typeof option == 'string') data[option]()
+        })
+    }
 
+    var old = $.fn.scrollspy
 
-        // SCROLLSPY NO CONFLICT
-        // =====================
+    $.fn.scrollspy = Plugin
+    $.fn.scrollspy.Constructor = ScrollSpy
 
-        $.fn.scrollspy.noConflict = function () {
-            $.fn.scrollspy = old
-            return this
-        }
 
+    // SCROLLSPY NO CONFLICT
+    // =====================
 
-        // SCROLLSPY DATA-API
-        // ==================
+    $.fn.scrollspy.noConflict = function () {
+        $.fn.scrollspy = old
+        return this
+    }
 
-        $(window).on('load.bs.scrollspy.data-api', function () {
-            $('[data-spy="scroll"]').each(function () {
-                var $spy = $(this)
-                Plugin.call($spy, $spy.data())
-            })
+
+    // SCROLLSPY DATA-API
+    // ==================
+
+    $(window).on('load.bs.scrollspy.data-api', function () {
+        $('[data-spy="scroll"]').each(function () {
+            var $spy = $(this)
+            Plugin.call($spy, $spy.data())
         })
+    })
 
-    }(jQuery);
+}(jQuery);
 
-    /* ========================================================================
-     * Bootstrap: tab.js v3.3.4
-     * http://getbootstrap.com/javascript/#tabs
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+/* ========================================================================
+ * Bootstrap: tab.js v3.3.5
+ * http://getbootstrap.com/javascript/#tabs
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
 
-    +function ($) {
-        'use strict';
++function ($) {
+    'use strict';
 
-        // TAB CLASS DEFINITION
-        // ====================
+    // TAB CLASS DEFINITION
+    // ====================
 
-        var Tab = function (element) {
-            this.element = $(element)
+    var Tab = function (element) {
+        // jscs:disable requireDollarBeforejQueryAssignment
+        this.element = $(element)
+        // jscs:enable requireDollarBeforejQueryAssignment
+    }
+
+    Tab.VERSION = '3.3.5'
+
+    Tab.TRANSITION_DURATION = 150
+
+    Tab.prototype.show = function () {
+        var $this = this.element
+        var $ul = $this.closest('ul:not(.dropdown-menu)')
+        var selector = $this.data('target')
+
+        if (!selector) {
+            selector = $this.attr('href')
+            selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
         }
 
-        Tab.VERSION = '3.3.4'
+        if ($this.parent('li').hasClass('active')) return
 
-        Tab.TRANSITION_DURATION = 150
+        var $previous = $ul.find('.active:last a')
+        var hideEvent = $.Event('hide.bs.tab', {
+            relatedTarget: $this[0]
+        })
+        var showEvent = $.Event('show.bs.tab', {
+            relatedTarget: $previous[0]
+        })
 
-        Tab.prototype.show = function () {
-            var $this = this.element
-            var $ul = $this.closest('ul:not(.dropdown-menu)')
-            var selector = $this.data('target')
+        $previous.trigger(hideEvent)
+        $this.trigger(showEvent)
 
-            if (!selector) {
-                selector = $this.attr('href')
-                selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
-            }
+        if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
 
-            if ($this.parent('li').hasClass('active')) return
+        var $target = $(selector)
 
-            var $previous = $ul.find('.active:last a')
-            var hideEvent = $.Event('hide.bs.tab', {
+        this.activate($this.closest('li'), $ul)
+        this.activate($target, $target.parent(), function () {
+            $previous.trigger({
+                type: 'hidden.bs.tab',
                 relatedTarget: $this[0]
             })
-            var showEvent = $.Event('show.bs.tab', {
+            $this.trigger({
+                type: 'shown.bs.tab',
                 relatedTarget: $previous[0]
             })
+        })
+    }
 
-            $previous.trigger(hideEvent)
-            $this.trigger(showEvent)
-
-            if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
+    Tab.prototype.activate = function (element, container, callback) {
+        var $active = container.find('> .active')
+        var transition = callback
+          && $.support.transition
+          && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
 
-            var $target = $(selector)
+        function next() {
+            $active
+              .removeClass('active')
+              .find('> .dropdown-menu > .active')
+                .removeClass('active')
+              .end()
+              .find('[data-toggle="tab"]')
+                .attr('aria-expanded', false)
 
-            this.activate($this.closest('li'), $ul)
-            this.activate($target, $target.parent(), function () {
-                $previous.trigger({
-                    type: 'hidden.bs.tab',
-                    relatedTarget: $this[0]
-                })
-                $this.trigger({
-                    type: 'shown.bs.tab',
-                    relatedTarget: $previous[0]
-                })
-            })
-        }
+            element
+              .addClass('active')
+              .find('[data-toggle="tab"]')
+                .attr('aria-expanded', true)
 
-        Tab.prototype.activate = function (element, container, callback) {
-            var $active = container.find('> .active')
-            var transition = callback
-              && $.support.transition
-              && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
-
-            function next() {
-                $active
-                  .removeClass('active')
-                  .find('> .dropdown-menu > .active')
-                    .removeClass('active')
-                  .end()
-                  .find('[data-toggle="tab"]')
-                    .attr('aria-expanded', false)
+            if (transition) {
+                element[0].offsetWidth // reflow for transition
+                element.addClass('in')
+            } else {
+                element.removeClass('fade')
+            }
 
+            if (element.parent('.dropdown-menu').length) {
                 element
-                  .addClass('active')
+                  .closest('li.dropdown')
+                    .addClass('active')
+                  .end()
                   .find('[data-toggle="tab"]')
                     .attr('aria-expanded', true)
-
-                if (transition) {
-                    element[0].offsetWidth // reflow for transition
-                    element.addClass('in')
-                } else {
-                    element.removeClass('fade')
-                }
-
-                if (element.parent('.dropdown-menu').length) {
-                    element
-                      .closest('li.dropdown')
-                        .addClass('active')
-                      .end()
-                      .find('[data-toggle="tab"]')
-                        .attr('aria-expanded', true)
-                }
-
-                callback && callback()
             }
 
-            $active.length && transition ?
-              $active
-                .one('bsTransitionEnd', next)
-                .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
-              next()
-
-            $active.removeClass('in')
+            callback && callback()
         }
 
+        $active.length && transition ?
+          $active
+            .one('bsTransitionEnd', next)
+            .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
+          next()
 
-        // TAB PLUGIN DEFINITION
-        // =====================
-
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.tab')
-
-                if (!data) $this.data('bs.tab', (data = new Tab(this)))
-                if (typeof option == 'string') data[option]()
-            })
-        }
+        $active.removeClass('in')
+    }
 
-        var old = $.fn.tab
 
-        $.fn.tab = Plugin
-        $.fn.tab.Constructor = Tab
+    // TAB PLUGIN DEFINITION
+    // =====================
 
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.tab')
 
-        // TAB NO CONFLICT
-        // ===============
+            if (!data) $this.data('bs.tab', (data = new Tab(this)))
+            if (typeof option == 'string') data[option]()
+        })
+    }
 
-        $.fn.tab.noConflict = function () {
-            $.fn.tab = old
-            return this
-        }
+    var old = $.fn.tab
 
+    $.fn.tab = Plugin
+    $.fn.tab.Constructor = Tab
 
-        // TAB DATA-API
-        // ============
 
-        var clickHandler = function (e) {
-            e.preventDefault()
-            Plugin.call($(this), 'show')
-        }
+    // TAB NO CONFLICT
+    // ===============
 
-        $(document)
-          .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
-          .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
+    $.fn.tab.noConflict = function () {
+        $.fn.tab = old
+        return this
+    }
 
-    }(jQuery);
 
-    /* ========================================================================
-     * Bootstrap: affix.js v3.3.4
-     * http://getbootstrap.com/javascript/#affix
-     * ========================================================================
-     * Copyright 2011-2015 Twitter, Inc.
-     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
-     * ======================================================================== */
+    // TAB DATA-API
+    // ============
 
+    var clickHandler = function (e) {
+        e.preventDefault()
+        Plugin.call($(this), 'show')
+    }
 
-    +function ($) {
-        'use strict';
+    $(document)
+      .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
+      .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
 
-        // AFFIX CLASS DEFINITION
-        // ======================
+}(jQuery);
 
-        var Affix = function (element, options) {
-            this.options = $.extend({}, Affix.DEFAULTS, options)
+/* ========================================================================
+ * Bootstrap: affix.js v3.3.5
+ * http://getbootstrap.com/javascript/#affix
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
 
-            this.$target = $(this.options.target)
-              .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
-              .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
 
-            this.$element = $(element)
-            this.affixed = null
-            this.unpin = null
-            this.pinnedOffset = null
++function ($) {
+    'use strict';
 
-            this.checkPosition()
-        }
+    // AFFIX CLASS DEFINITION
+    // ======================
 
-        Affix.VERSION = '3.3.4'
+    var Affix = function (element, options) {
+        this.options = $.extend({}, Affix.DEFAULTS, options)
 
-        Affix.RESET = 'affix affix-top affix-bottom'
+        this.$target = $(this.options.target)
+          .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+          .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
 
-        Affix.DEFAULTS = {
-            offset: 0,
-            target: window
-        }
+        this.$element = $(element)
+        this.affixed = null
+        this.unpin = null
+        this.pinnedOffset = null
 
-        Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
-            var scrollTop = this.$target.scrollTop()
-            var position = this.$element.offset()
-            var targetHeight = this.$target.height()
+        this.checkPosition()
+    }
 
-            if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
+    Affix.VERSION = '3.3.5'
 
-            if (this.affixed == 'bottom') {
-                if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
-                return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
-            }
+    Affix.RESET = 'affix affix-top affix-bottom'
 
-            var initializing = this.affixed == null
-            var colliderTop = initializing ? scrollTop : position.top
-            var colliderHeight = initializing ? targetHeight : height
+    Affix.DEFAULTS = {
+        offset: 0,
+        target: window
+    }
 
-            if (offsetTop != null && scrollTop <= offsetTop) return 'top'
-            if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+    Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+        var scrollTop = this.$target.scrollTop()
+        var position = this.$element.offset()
+        var targetHeight = this.$target.height()
 
-            return false
-        }
+        if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
 
-        Affix.prototype.getPinnedOffset = function () {
-            if (this.pinnedOffset) return this.pinnedOffset
-            this.$element.removeClass(Affix.RESET).addClass('affix')
-            var scrollTop = this.$target.scrollTop()
-            var position = this.$element.offset()
-            return (this.pinnedOffset = position.top - scrollTop)
+        if (this.affixed == 'bottom') {
+            if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
+            return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
         }
 
-        Affix.prototype.checkPositionWithEventLoop = function () {
-            setTimeout($.proxy(this.checkPosition, this), 1)
-        }
+        var initializing = this.affixed == null
+        var colliderTop = initializing ? scrollTop : position.top
+        var colliderHeight = initializing ? targetHeight : height
 
-        Affix.prototype.checkPosition = function () {
-            if (!this.$element.is(':visible')) return
+        if (offsetTop != null && scrollTop <= offsetTop) return 'top'
+        if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
 
-            var height = this.$element.height()
-            var offset = this.options.offset
-            var offsetTop = offset.top
-            var offsetBottom = offset.bottom
-            var scrollHeight = $(document.body).height()
+        return false
+    }
 
-            if (typeof offset != 'object') offsetBottom = offsetTop = offset
-            if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
-            if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+    Affix.prototype.getPinnedOffset = function () {
+        if (this.pinnedOffset) return this.pinnedOffset
+        this.$element.removeClass(Affix.RESET).addClass('affix')
+        var scrollTop = this.$target.scrollTop()
+        var position = this.$element.offset()
+        return (this.pinnedOffset = position.top - scrollTop)
+    }
 
-            var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
+    Affix.prototype.checkPositionWithEventLoop = function () {
+        setTimeout($.proxy(this.checkPosition, this), 1)
+    }
 
-            if (this.affixed != affix) {
-                if (this.unpin != null) this.$element.css('top', '')
+    Affix.prototype.checkPosition = function () {
+        if (!this.$element.is(':visible')) return
 
-                var affixType = 'affix' + (affix ? '-' + affix : '')
-                var e = $.Event(affixType + '.bs.affix')
+        var height = this.$element.height()
+        var offset = this.options.offset
+        var offsetTop = offset.top
+        var offsetBottom = offset.bottom
+        var scrollHeight = Math.max($(document).height(), $(document.body).height())
 
-                this.$element.trigger(e)
+        if (typeof offset != 'object') offsetBottom = offsetTop = offset
+        if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
+        if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
 
-                if (e.isDefaultPrevented()) return
+        var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
 
-                this.affixed = affix
-                this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+        if (this.affixed != affix) {
+            if (this.unpin != null) this.$element.css('top', '')
 
-                this.$element
-                  .removeClass(Affix.RESET)
-                  .addClass(affixType)
-                  .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
-            }
+            var affixType = 'affix' + (affix ? '-' + affix : '')
+            var e = $.Event(affixType + '.bs.affix')
 
-            if (affix == 'bottom') {
-                this.$element.offset({
-                    top: scrollHeight - height - offsetBottom
-                })
-            }
-        }
+            this.$element.trigger(e)
 
+            if (e.isDefaultPrevented()) return
 
-        // AFFIX PLUGIN DEFINITION
-        // =======================
+            this.affixed = affix
+            this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
 
-        function Plugin(option) {
-            return this.each(function () {
-                var $this = $(this)
-                var data = $this.data('bs.affix')
-                var options = typeof option == 'object' && option
+            this.$element
+              .removeClass(Affix.RESET)
+              .addClass(affixType)
+              .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+        }
 
-                if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
-                if (typeof option == 'string') data[option]()
+        if (affix == 'bottom') {
+            this.$element.offset({
+                top: scrollHeight - height - offsetBottom
             })
         }
+    }
+
 
-        var old = $.fn.affix
+    // AFFIX PLUGIN DEFINITION
+    // =======================
 
-        $.fn.affix = Plugin
-        $.fn.affix.Constructor = Affix
+    function Plugin(option) {
+        return this.each(function () {
+            var $this = $(this)
+            var data = $this.data('bs.affix')
+            var options = typeof option == 'object' && option
 
+            if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
+            if (typeof option == 'string') data[option]()
+        })
+    }
 
-        // AFFIX NO CONFLICT
-        // =================
+    var old = $.fn.affix
 
-        $.fn.affix.noConflict = function () {
-            $.fn.affix = old
-            return this
-        }
+    $.fn.affix = Plugin
+    $.fn.affix.Constructor = Affix
 
 
-        // AFFIX DATA-API
-        // ==============
+    // AFFIX NO CONFLICT
+    // =================
 
-        $(window).on('load', function () {
-            $('[data-spy="affix"]').each(function () {
-                var $spy = $(this)
-                var data = $spy.data()
+    $.fn.affix.noConflict = function () {
+        $.fn.affix = old
+        return this
+    }
 
-                data.offset = data.offset || {}
 
-                if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
-                if (data.offsetTop != null) data.offset.top = data.offsetTop
+    // AFFIX DATA-API
+    // ==============
 
-                Plugin.call($spy, data)
-            })
+    $(window).on('load', function () {
+        $('[data-spy="affix"]').each(function () {
+            var $spy = $(this)
+            var data = $spy.data()
+
+            data.offset = data.offset || {}
+
+            if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
+            if (data.offsetTop != null) data.offset.top = data.offsetTop
+
+            Plugin.call($spy, data)
         })
+    })
 
-    }(jQuery);
-}));
+}(jQuery);
+}));
\ No newline at end of file
diff --git a/BForms.Docs/Scripts/BForms/Components/jQuery/jquery.js b/BForms.Docs/Scripts/BForms/Components/jQuery/jquery.js
index 4cb0e46b..4e53dc12 100644
--- a/BForms.Docs/Scripts/BForms/Components/jQuery/jquery.js
+++ b/BForms.Docs/Scripts/BForms/Components/jQuery/jquery.js
@@ -1,5 +1,5 @@
 /*!
- * jQuery JavaScript Library v1.11.2
+ * jQuery JavaScript Library v1.11.3
  * http://jquery.com/
  *
  * Includes Sizzle.js
@@ -9,7 +9,7 @@
  * Released under the MIT license
  * http://jquery.org/license
  *
- * Date: 2014-12-17T15:27Z
+ * Date: 2015-04-28T16:19Z
  */
 
 (function (global, factory) {
@@ -64,7 +64,7 @@
 
 
     var
-        version = "1.11.2",
+        version = "1.11.3",
 
         // Define a local copy of jQuery
         jQuery = function (selector, context) {
@@ -569,7 +569,12 @@
     });
 
     function isArraylike(obj) {
-        var length = obj.length,
+
+        // Support: iOS 8.2 (not reproducible in simulator)
+        // `in` check used to prevent JIT error (gh-2145)
+        // hasOwn isn't used here due to false negatives
+        // regarding Nodelist length in IE
+        var length = "length" in obj && obj.length,
             type = jQuery.type(obj);
 
         if (type === "function" || jQuery.isWindow(obj)) {
diff --git a/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/bforms.datepicker.js b/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/bforms.datepicker.js
index 0bb8aa19..3ffde508 100644
--- a/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/bforms.datepicker.js
+++ b/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/bforms.datepicker.js
@@ -47,7 +47,7 @@
                 }
             }
 
-            this.newMoment = moment().lang(this.options.language);
+            this.newMoment = moment().locale(this.options.language);
 
             switch (this.options.type) {
                 case 'datepicker':
@@ -98,7 +98,7 @@
 
         if (typeof this.options.initialValue !== "undefined" && this.options.initialValue != '') {
 
-            var initialValue = moment(this.options.initialValue).lang(this.options.language);
+            var initialValue = moment(this.options.initialValue).locale(this.options.language);
             this.currentValue = initialValue.clone();
             this._valueSet = true;
             this._updateDisplays();
@@ -113,16 +113,16 @@
             }
 
             if (valueMoment != null) {
-                valueMoment.lang(this.options.language);
+                valueMoment.locale(this.options.language);
             }
 
             if (valueMoment != null && valueMoment.isValid()) {
-                this.currentValue = valueMoment.lang(this.options.language);
+                this.currentValue = valueMoment.locale(this.options.language);
             } else {
-                this.currentValue = this._getDefaultDate().lang(this.options.language);
+                this.currentValue = this._getDefaultDate().locale(this.options.language);
             }
         } else {
-            this.currentValue = this._getDefaultDate().lang(this.options.language);
+            this.currentValue = this._getDefaultDate().locale(this.options.language);
         }
 
         if (this.options.allowDeselect !== true) {
@@ -200,13 +200,13 @@
         } else {
             switch (this._type) {
                 case this.enums.Type.DateTimepicker:
-                    this._displayFormat = moment.langData(this.options.language)._longDateFormat['L'] + ' ' + moment.langData(this.options.language)._longDateFormat['LT'];
+                    this._displayFormat = moment.localeData(this.options.language)._longDateFormat['L'] + ' ' + moment.localeData(this.options.language)._longDateFormat['LT'];
                     break;
                 case this.enums.Type.Datepicker:
-                    this._displayFormat = moment.langData(this.options.language)._longDateFormat['L'];
+                    this._displayFormat = moment.localeData(this.options.language)._longDateFormat['L'];
                     break;
                 case this.enums.Type.Timepicker:
-                    this._displayFormat = moment.langData(this.options.language)._longDateFormat['LT'];
+                    this._displayFormat = moment.localeData(this.options.language)._longDateFormat['LT'];
                     break;
                 default:
             }
@@ -299,7 +299,7 @@
             }
 
             if (initialValueMoment != null) {
-                initialValueMoment.lang(this.options.language);
+                initialValueMoment.locale(this.options.language);
             }
 
             if (initialValueMoment != null && initialValueMoment.isValid()) {
@@ -590,7 +590,7 @@
 
             this.$picker.on('mouseover', '.bs-dateValue', $.proxy(function (e) {
                 var $target = $(e.currentTarget);
-                var dateValue = moment($target.data('value')).lang(this.options.language);
+                var dateValue = moment($target.data('value')).locale(this.options.language);
 
                 this.options.onDayMouseOver(dateValue, dateValue.format(this._displayFormat), this.isValidDate(dateValue));
 
@@ -667,13 +667,13 @@
         switch (this._currentDisplay) {
             case this.enums.Display.Days:
                 if (!this._blockMonths) {
-                    this.value.subtract('month', 1);
+                    this.value.subtract(1, 'month');
                     hasChanged = true;
                 }
                 break;
             case this.enums.Display.Months:
                 if (!this._blockYears) {
-                    this.value.subtract('year', 1);
+                    this.value.subtract(1, 'year');
                     hasChanged = true;
                 }
                 break;
@@ -751,7 +751,7 @@
         this._stopEvent(e);
 
         var $target = $(e.currentTarget),
-            value = moment($target.data('value')).lang(this.options.language);
+            value = moment($target.data('value')).locale(this.options.language);
 
         if ($target.parents('.bs-notSelectable').length) return;
 
@@ -780,13 +780,13 @@
         if ($target.parents().hasClass('bs-notSelectable')) return;
 
         if (this._selectOn === this.enums.Display.Months) {
-            if (this.isValidDate(moment(value).lang(this.options.language))) {
-                this._setCurrentValue(moment(value).lang(this.options.language));
+            if (this.isValidDate(moment(value).locale(this.options.language))) {
+                this._setCurrentValue(moment(value).locale(this.options.language));
                 this.value = this.currentValue.clone();
                 this._updateDateView();
             }
         } else {
-            this.value = moment(value).lang(this.options.language);
+            this.value = moment(value).locale(this.options.language);
             this._currentDisplay = this.enums.Display.Days;
             this._updateDateView();
         }
@@ -801,14 +801,14 @@
         if ($target.parents().hasClass('bs-notSelectable')) return;
 
         if (this._selectOn === this.enums.Display.Years) {
-            if (this.isValidDate(moment(value).lang(this.options.language))) {
-                this._setCurrentValue(moment(value).lang(this.options.language));
+            if (this.isValidDate(moment(value).locale(this.options.language))) {
+                this._setCurrentValue(moment(value).locale(this.options.language));
                 this.value = this.currentValue.clone();
                 this._updateDateView();
             }
 
         } else {
-            this.value = moment(value).lang(this.options.language);
+            this.value = moment(value).locale(this.options.language);
 
             this._currentDisplay = this.enums.Display.Months;
 
@@ -819,9 +819,9 @@
     bDatepicker.prototype.dateNowClick = function (e) {
         this._stopEvent(e);
 
-        var newValue = moment().lang(this.options.language);
+        var newValue = moment().locale(this.options.language);
         if (this.isValidDate(newValue)) {
-            this._setCurrentValue(moment().lang(this.options.language));
+            this._setCurrentValue(moment().locale(this.options.language));
             this.value = this.currentValue;
 
             if (typeof this._selectOn === "undefined" || this._selectOn === this.enums.Display.Days) {
@@ -835,10 +835,10 @@
     bDatepicker.prototype.timeNowClick = function (e) {
         this._stopEvent(e);
 
-        var newValue = moment().lang(this.options.language);
+        var newValue = moment().locale(this.options.language);
 
         if (this.isValidDate(newValue)) {
-            this._setCurrentValue(moment().lang(this.options.language));
+            this._setCurrentValue(moment().locale(this.options.language));
             this.value = this.currentValue;
 
             if (typeof this._selectOn === "undefined" || this._selectOn === this.enums.Display.Days) {
@@ -1758,7 +1758,7 @@
 
         if (value != null) {
 
-            var val = moment(value).lang(this.options.language);
+            var val = moment(value).locale(this.options.language);
 
             if (this.isValidDate(val)) {
                 this._setCurrentValue(val);
@@ -1789,7 +1789,7 @@
     bDatepicker.prototype.format = function (date) {
         if (date != null) {
 
-            var fDate = moment(date).lang(this.options.language);
+            var fDate = moment(date).locale(this.options.language);
 
             if (fDate.isValid())
                 return fDate.format(this._displayFormat);
@@ -2004,8 +2004,8 @@
         var renderedDays = 0;
 
         //find start date
-        while (daysStart.day() != moment.langData(this.options.language)._week.dow) {
-            daysStart.subtract('days', 1);
+        while (daysStart.day() != moment.localeData(this.options.language)._week.dow) {
+            daysStart.subtract(1,'days');
         }
 
         //we should renderer 42 days, for uniformity with months that start on a saturday
@@ -2046,7 +2046,7 @@
     };
 
     bDatepicker.prototype.getDaysNames = function () {
-        return this.value.clone().lang()._weekdaysMin;
+        return this.value.clone().localeData()._weekdaysMin;
     };
 
     bDatepicker.prototype.getMonths = function (date) {
@@ -2081,7 +2081,7 @@
             years = [],
             it = date.clone();
 
-        it.year(startOfDecade).subtract('year', 1);
+        it.year(startOfDecade).subtract(1,'year');
 
         var prevYear = {
             year: it.format('YYYY'),
@@ -2147,7 +2147,7 @@
             hour: time.format(this.options.is12Hours ? 'h' : 'H'),
             minute: time.minute(),
             second: time.second(),
-            meridiem: time.lang().meridiem(time.clone().add('hour', 12).format('H')),
+            meridiem: time.localeData().meridiem(time.clone().add('hour', 12).format('H')),
         };
     };
 
@@ -2166,12 +2166,12 @@
             allowSame = this.options.allowSame;
 
         if (typeof this.options.maxDate !== "undefined" && this.options.maxDate !== null) {
-            maxDate = this.options.maxDate === "now" ? moment().lang(this.options.language) : moment(this.options.maxDate).lang(this.options.language);
+            maxDate = this.options.maxDate === "now" ? moment().locale(this.options.language) : moment(this.options.maxDate).locale(this.options.language);
             withMax = true;
         }
 
         if (typeof this.options.minDate !== "undefined" && this.options.minDate !== null) {
-            minDate = moment(this.options.minDate).lang(this.options.language);
+            minDate = moment(this.options.minDate).locale(this.options.language);
             withMin = true;
         }
 
diff --git a/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/i18n/lang.bundle.js b/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/i18n/lang.bundle.js
index 0403db6f..e5db5bee 100644
--- a/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/i18n/lang.bundle.js
+++ b/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/i18n/lang.bundle.js
@@ -9,7 +9,7 @@
 
 }(function (moment) {
 
-    moment.lang('es', {
+    moment.locale('es', {
         months: "enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),
         monthsShort: "ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),
         weekdays: "domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),
@@ -62,7 +62,7 @@
         }
     });
     
-    moment.lang('ro', {
+    moment.locale('ro', {
         months: "Ianuarie_Februarie_Martie_Aprilie_Mai_Iunie_Iulie_August_Septembrie_Octombrie_Noiembrie_Decembrie".split("_"),
         monthsShort: "Ian_Feb_Mar_Apr_Mai_Iun_Iul_Aug_Sep_Oct_Noi_Dec".split("_"),
         weekdays: "Luni_Marţi_Miercuri_Joi_Vineri_Sâmbătă_Duminică".split("_"),
@@ -104,7 +104,7 @@
         }
     });
 
-    moment.lang('fr', {
+    moment.locale('fr', {
         months: "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),
         monthsShort: "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),
         weekdays: "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),
@@ -149,7 +149,7 @@
         }
     });
 
-    moment.lang('en');
+    moment.locale('en');
 
 }));
 	
diff --git a/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/lib/moment.js b/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/lib/moment.js
index a6cffa84..ff1e3744 100644
--- a/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/lib/moment.js
+++ b/BForms.Docs/Scripts/BForms/Plugins/Datepicker/js/lib/moment.js
@@ -1,2750 +1,3197 @@
-// moment.js
-// version : 2.7.0
-// author : Tim Wood
-// license : MIT
-// momentjs.com
-
-(function (factory) {
+//! moment.js
+//! version : 2.10.6
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+
+(function (global, factory) {
+    global.moment = factory();
     if (typeof define === "function" && define.amd) {
         define('moment', [], factory);
     } else {
         factory();
     }
-}(function () {
+}(this, function () {
 
-    (function (undefined) {
-        /************************************
-            Constants
-        ************************************/
+    var hookCallback;
 
-        var moment,
-            VERSION = '2.7.0',
-            // the global-scope this is NOT the global object in Node.js
-            globalScope = typeof global !== 'undefined' ? global : this,
-            oldGlobalMoment,
-            round = Math.round,
-            i,
+    function utils_hooks__hooks() {
+        return hookCallback.apply(null, arguments);
+    }
 
-            YEAR = 0,
-            MONTH = 1,
-            DATE = 2,
-            HOUR = 3,
-            MINUTE = 4,
-            SECOND = 5,
-            MILLISECOND = 6,
-
-            // internal storage for language config files
-            languages = {},
-
-            // moment internal properties
-            momentProperties = {
-                _isAMomentObject: null,
-                _i: null,
-                _f: null,
-                _l: null,
-                _strict: null,
-                _tzm: null,
-                _isUTC: null,
-                _offset: null,  // optional. Combine with _isUTC
-                _pf: null,
-                _lang: null  // optional
-            },
-
-            // check for nodeJS
-            hasModule = (typeof module !== 'undefined' && module.exports),
-
-            // ASP.NET json date format regex
-            aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
-            aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
-
-            // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
-            // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
-            isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
-
-            // format tokens
-            formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,
-            localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
-
-            // parsing token regexes
-            parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
-            parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
-            parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999
-            parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
-            parseTokenDigits = /\d+/, // nonzero number of digits
-            parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
-            parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
-            parseTokenT = /T/i, // T (ISO separator)
-            parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
-            parseTokenOrdinal = /\d{1,2}/,
-
-            //strict parsing regexes
-            parseTokenOneDigit = /\d/, // 0 - 9
-            parseTokenTwoDigits = /\d\d/, // 00 - 99
-            parseTokenThreeDigits = /\d{3}/, // 000 - 999
-            parseTokenFourDigits = /\d{4}/, // 0000 - 9999
-            parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999
-            parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf
-
-            // iso 8601 regex
-            // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
-            isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
-
-            isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
-
-            isoDates = [
-                ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
-                ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
-                ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
-                ['GGGG-[W]WW', /\d{4}-W\d{2}/],
-                ['YYYY-DDD', /\d{4}-\d{3}/]
-            ],
-
-            // iso time formats and regexes
-            isoTimes = [
-                ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
-                ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
-                ['HH:mm', /(T| )\d\d:\d\d/],
-                ['HH', /(T| )\d\d/]
-            ],
-
-            // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
-            parseTimezoneChunker = /([\+\-]|\d\d)/gi,
-
-            // getter and setter names
-            proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
-            unitMillisecondFactors = {
-                'Milliseconds': 1,
-                'Seconds': 1e3,
-                'Minutes': 6e4,
-                'Hours': 36e5,
-                'Days': 864e5,
-                'Months': 2592e6,
-                'Years': 31536e6
-            },
-
-            unitAliases = {
-                ms: 'millisecond',
-                s: 'second',
-                m: 'minute',
-                h: 'hour',
-                d: 'day',
-                D: 'date',
-                w: 'week',
-                W: 'isoWeek',
-                M: 'month',
-                Q: 'quarter',
-                y: 'year',
-                DDD: 'dayOfYear',
-                e: 'weekday',
-                E: 'isoWeekday',
-                gg: 'weekYear',
-                GG: 'isoWeekYear'
-            },
-
-            camelFunctions = {
-                dayofyear: 'dayOfYear',
-                isoweekday: 'isoWeekday',
-                isoweek: 'isoWeek',
-                weekyear: 'weekYear',
-                isoweekyear: 'isoWeekYear'
-            },
-
-            // format function strings
-            formatFunctions = {},
-
-            // default relative time thresholds
-            relativeTimeThresholds = {
-                s: 45,  // seconds to minute
-                m: 45,  // minutes to hour
-                h: 22,  // hours to day
-                d: 26,  // days to month
-                M: 11   // months to year
-            },
-
-            // tokens to ordinalize and pad
-            ordinalizeTokens = 'DDD w W M D d'.split(' '),
-            paddedTokens = 'M D H h m s w W'.split(' '),
-
-            formatTokenFunctions = {
-                M: function () {
-                    return this.month() + 1;
-                },
-                MMM: function (format) {
-                    return this.lang().monthsShort(this, format);
-                },
-                MMMM: function (format) {
-                    return this.lang().months(this, format);
-                },
-                D: function () {
-                    return this.date();
-                },
-                DDD: function () {
-                    return this.dayOfYear();
-                },
-                d: function () {
-                    return this.day();
-                },
-                dd: function (format) {
-                    return this.lang().weekdaysMin(this, format);
-                },
-                ddd: function (format) {
-                    return this.lang().weekdaysShort(this, format);
-                },
-                dddd: function (format) {
-                    return this.lang().weekdays(this, format);
-                },
-                w: function () {
-                    return this.week();
-                },
-                W: function () {
-                    return this.isoWeek();
-                },
-                YY: function () {
-                    return leftZeroFill(this.year() % 100, 2);
-                },
-                YYYY: function () {
-                    return leftZeroFill(this.year(), 4);
-                },
-                YYYYY: function () {
-                    return leftZeroFill(this.year(), 5);
-                },
-                YYYYYY: function () {
-                    var y = this.year(), sign = y >= 0 ? '+' : '-';
-                    return sign + leftZeroFill(Math.abs(y), 6);
-                },
-                gg: function () {
-                    return leftZeroFill(this.weekYear() % 100, 2);
-                },
-                gggg: function () {
-                    return leftZeroFill(this.weekYear(), 4);
-                },
-                ggggg: function () {
-                    return leftZeroFill(this.weekYear(), 5);
-                },
-                GG: function () {
-                    return leftZeroFill(this.isoWeekYear() % 100, 2);
-                },
-                GGGG: function () {
-                    return leftZeroFill(this.isoWeekYear(), 4);
-                },
-                GGGGG: function () {
-                    return leftZeroFill(this.isoWeekYear(), 5);
-                },
-                e: function () {
-                    return this.weekday();
-                },
-                E: function () {
-                    return this.isoWeekday();
-                },
-                a: function () {
-                    return this.lang().meridiem(this.hours(), this.minutes(), true);
-                },
-                A: function () {
-                    return this.lang().meridiem(this.hours(), this.minutes(), false);
-                },
-                H: function () {
-                    return this.hours();
-                },
-                h: function () {
-                    return this.hours() % 12 || 12;
-                },
-                m: function () {
-                    return this.minutes();
-                },
-                s: function () {
-                    return this.seconds();
-                },
-                S: function () {
-                    return toInt(this.milliseconds() / 100);
-                },
-                SS: function () {
-                    return leftZeroFill(toInt(this.milliseconds() / 10), 2);
-                },
-                SSS: function () {
-                    return leftZeroFill(this.milliseconds(), 3);
-                },
-                SSSS: function () {
-                    return leftZeroFill(this.milliseconds(), 3);
-                },
-                Z: function () {
-                    var a = -this.zone(),
-                        b = '+';
-                    if (a < 0) {
-                        a = -a;
-                        b = '-';
-                    }
-                    return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
-                },
-                ZZ: function () {
-                    var a = -this.zone(),
-                        b = '+';
-                    if (a < 0) {
-                        a = -a;
-                        b = '-';
-                    }
-                    return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
-                },
-                z: function () {
-                    return this.zoneAbbr();
-                },
-                zz: function () {
-                    return this.zoneName();
-                },
-                X: function () {
-                    return this.unix();
-                },
-                Q: function () {
-                    return this.quarter();
-                }
-            },
+    // This is done to register the method called with moment()
+    // without creating circular dependencies.
+    function setHookCallback(callback) {
+        hookCallback = callback;
+    }
 
-            lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
+    function isArray(input) {
+        return Object.prototype.toString.call(input) === '[object Array]';
+    }
 
-        // Pick the first defined of two or three arguments. dfl comes from
-        // default.
-        function dfl(a, b, c) {
-            switch (arguments.length) {
-                case 2: return a != null ? a : b;
-                case 3: return a != null ? a : b != null ? b : c;
-                default: throw new Error('Implement me');
-            }
-        }
+    function isDate(input) {
+        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
+    }
 
-        function defaultParsingFlags() {
-            // We need to deep clone this object, and es5 standard is not very
-            // helpful.
-            return {
-                empty: false,
-                unusedTokens: [],
-                unusedInput: [],
-                overflow: -2,
-                charsLeftOver: 0,
-                nullInput: false,
-                invalidMonth: null,
-                invalidFormat: false,
-                userInvalidated: false,
-                iso: false
-            };
+    function map(arr, fn) {
+        var res = [], i;
+        for (i = 0; i < arr.length; ++i) {
+            res.push(fn(arr[i], i));
         }
+        return res;
+    }
 
-        function deprecate(msg, fn) {
-            var firstTime = true;
-            function printMsg() {
-                if (moment.suppressDeprecationWarnings === false &&
-                        typeof console !== 'undefined' && console.warn) {
-                    console.warn('Deprecation warning: ' + msg);
-                }
+    function hasOwnProp(a, b) {
+        return Object.prototype.hasOwnProperty.call(a, b);
+    }
+
+    function extend(a, b) {
+        for (var i in b) {
+            if (hasOwnProp(b, i)) {
+                a[i] = b[i];
             }
-            return extend(function () {
-                if (firstTime) {
-                    printMsg();
-                    firstTime = false;
-                }
-                return fn.apply(this, arguments);
-            }, fn);
         }
 
-        function padToken(func, count) {
-            return function (a) {
-                return leftZeroFill(func.call(this, a), count);
-            };
-        }
-        function ordinalizeToken(func, period) {
-            return function (a) {
-                return this.lang().ordinal(func.call(this, a), period);
-            };
+        if (hasOwnProp(b, 'toString')) {
+            a.toString = b.toString;
         }
 
-        while (ordinalizeTokens.length) {
-            i = ordinalizeTokens.pop();
-            formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
+        if (hasOwnProp(b, 'valueOf')) {
+            a.valueOf = b.valueOf;
         }
-        while (paddedTokens.length) {
-            i = paddedTokens.pop();
-            formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
-        }
-        formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
 
+        return a;
+    }
 
-        /************************************
-            Constructors
-        ************************************/
+    function create_utc__createUTC(input, format, locale, strict) {
+        return createLocalOrUTC(input, format, locale, strict, true).utc();
+    }
 
-        function Language() {
-        }
+    function defaultParsingFlags() {
+        // We need to deep clone this object.
+        return {
+            empty: false,
+            unusedTokens: [],
+            unusedInput: [],
+            overflow: -2,
+            charsLeftOver: 0,
+            nullInput: false,
+            invalidMonth: null,
+            invalidFormat: false,
+            userInvalidated: false,
+            iso: false
+        };
+    }
 
-        // Moment prototype object
-        function Moment(config) {
-            checkOverflow(config);
-            extend(this, config);
+    function getParsingFlags(m) {
+        if (m._pf == null) {
+            m._pf = defaultParsingFlags();
         }
+        return m._pf;
+    }
 
-        // Duration Constructor
-        function Duration(duration) {
-            var normalizedInput = normalizeObjectUnits(duration),
-                years = normalizedInput.year || 0,
-                quarters = normalizedInput.quarter || 0,
-                months = normalizedInput.month || 0,
-                weeks = normalizedInput.week || 0,
-                days = normalizedInput.day || 0,
-                hours = normalizedInput.hour || 0,
-                minutes = normalizedInput.minute || 0,
-                seconds = normalizedInput.second || 0,
-                milliseconds = normalizedInput.millisecond || 0;
+    function valid__isValid(m) {
+        if (m._isValid == null) {
+            var flags = getParsingFlags(m);
+            m._isValid = !isNaN(m._d.getTime()) &&
+                flags.overflow < 0 &&
+                !flags.empty &&
+                !flags.invalidMonth &&
+                !flags.invalidWeekday &&
+                !flags.nullInput &&
+                !flags.invalidFormat &&
+                !flags.userInvalidated;
+
+            if (m._strict) {
+                m._isValid = m._isValid &&
+                    flags.charsLeftOver === 0 &&
+                    flags.unusedTokens.length === 0 &&
+                    flags.bigHour === undefined;
+            }
+        }
+        return m._isValid;
+    }
 
-            // representation for dateAddRemove
-            this._milliseconds = +milliseconds +
-                seconds * 1e3 + // 1000
-                minutes * 6e4 + // 1000 * 60
-                hours * 36e5; // 1000 * 60 * 60
-            // Because of dateAddRemove treats 24 hours as different from a
-            // day when working around DST, we need to store them separately
-            this._days = +days +
-                weeks * 7;
-            // It is impossible translate months into days without knowing
-            // which months you are are talking about, so we have to store
-            // it separately.
-            this._months = +months +
-                quarters * 3 +
-                years * 12;
+    function valid__createInvalid(flags) {
+        var m = create_utc__createUTC(NaN);
+        if (flags != null) {
+            extend(getParsingFlags(m), flags);
+        }
+        else {
+            getParsingFlags(m).userInvalidated = true;
+        }
 
-            this._data = {};
+        return m;
+    }
 
-            this._bubble();
-        }
+    var momentProperties = utils_hooks__hooks.momentProperties = [];
 
-        /************************************
-            Helpers
-        ************************************/
+    function copyConfig(to, from) {
+        var i, prop, val;
 
+        if (typeof from._isAMomentObject !== 'undefined') {
+            to._isAMomentObject = from._isAMomentObject;
+        }
+        if (typeof from._i !== 'undefined') {
+            to._i = from._i;
+        }
+        if (typeof from._f !== 'undefined') {
+            to._f = from._f;
+        }
+        if (typeof from._l !== 'undefined') {
+            to._l = from._l;
+        }
+        if (typeof from._strict !== 'undefined') {
+            to._strict = from._strict;
+        }
+        if (typeof from._tzm !== 'undefined') {
+            to._tzm = from._tzm;
+        }
+        if (typeof from._isUTC !== 'undefined') {
+            to._isUTC = from._isUTC;
+        }
+        if (typeof from._offset !== 'undefined') {
+            to._offset = from._offset;
+        }
+        if (typeof from._pf !== 'undefined') {
+            to._pf = getParsingFlags(from);
+        }
+        if (typeof from._locale !== 'undefined') {
+            to._locale = from._locale;
+        }
 
-        function extend(a, b) {
-            for (var i in b) {
-                if (b.hasOwnProperty(i)) {
-                    a[i] = b[i];
+        if (momentProperties.length > 0) {
+            for (i in momentProperties) {
+                prop = momentProperties[i];
+                val = from[prop];
+                if (typeof val !== 'undefined') {
+                    to[prop] = val;
                 }
             }
+        }
 
-            if (b.hasOwnProperty('toString')) {
-                a.toString = b.toString;
-            }
+        return to;
+    }
 
-            if (b.hasOwnProperty('valueOf')) {
-                a.valueOf = b.valueOf;
-            }
+    var updateInProgress = false;
 
-            return a;
+    // Moment prototype object
+    function Moment(config) {
+        copyConfig(this, config);
+        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
+        // Prevent infinite loop in case updateOffset creates new moment
+        // objects.
+        if (updateInProgress === false) {
+            updateInProgress = true;
+            utils_hooks__hooks.updateOffset(this);
+            updateInProgress = false;
         }
+    }
 
-        function cloneMoment(m) {
-            var result = {}, i;
-            for (i in m) {
-                if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) {
-                    result[i] = m[i];
-                }
-            }
+    function isMoment(obj) {
+        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
+    }
 
-            return result;
+    function absFloor(number) {
+        if (number < 0) {
+            return Math.ceil(number);
+        } else {
+            return Math.floor(number);
         }
+    }
 
-        function absRound(number) {
-            if (number < 0) {
-                return Math.ceil(number);
-            } else {
-                return Math.floor(number);
-            }
+    function toInt(argumentForCoercion) {
+        var coercedNumber = +argumentForCoercion,
+            value = 0;
+
+        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
+            value = absFloor(coercedNumber);
         }
 
-        // left zero fill a number
-        // see http://jsperf.com/left-zero-filling for performance comparison
-        function leftZeroFill(number, targetLength, forceSign) {
-            var output = '' + Math.abs(number),
-                sign = number >= 0;
+        return value;
+    }
 
-            while (output.length < targetLength) {
-                output = '0' + output;
+    function compareArrays(array1, array2, dontConvert) {
+        var len = Math.min(array1.length, array2.length),
+            lengthDiff = Math.abs(array1.length - array2.length),
+            diffs = 0,
+            i;
+        for (i = 0; i < len; i++) {
+            if ((dontConvert && array1[i] !== array2[i]) ||
+                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
+                diffs++;
             }
-            return (sign ? (forceSign ? '+' : '') : '-') + output;
         }
+        return diffs + lengthDiff;
+    }
 
-        function positiveMomentsDifference(base, other) {
-            var res = { milliseconds: 0, months: 0 };
-
-            res.months = other.month() - base.month() +
-                (other.year() - base.year()) * 12;
-            if (base.clone().add(res.months, 'M').isAfter(other)) {
-                --res.months;
-            }
+    function Locale() {
+    }
 
-            res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
+    var locales = {};
+    var globalLocale;
 
-            return res;
-        }
+    function normalizeLocale(key) {
+        return key ? key.toLowerCase().replace('_', '-') : key;
+    }
 
-        function momentsDifference(base, other) {
-            var res;
-            other = makeAs(other, base);
-            if (base.isBefore(other)) {
-                res = positiveMomentsDifference(base, other);
-            } else {
-                res = positiveMomentsDifference(other, base);
-                res.milliseconds = -res.milliseconds;
-                res.months = -res.months;
+    // pick the locale from the array
+    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
+    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
+    function chooseLocale(names) {
+        var i = 0, j, next, locale, split;
+
+        while (i < names.length) {
+            split = normalizeLocale(names[i]).split('-');
+            j = split.length;
+            next = normalizeLocale(names[i + 1]);
+            next = next ? next.split('-') : null;
+            while (j > 0) {
+                locale = loadLocale(split.slice(0, j).join('-'));
+                if (locale) {
+                    return locale;
+                }
+                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
+                    //the next array item is better than a shallower substring of this one
+                    break;
+                }
+                j--;
             }
-
-            return res;
+            i++;
         }
+        return null;
+    }
 
-        // helper function for _.addTime and _.subtractTime
-        function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
-            var milliseconds = duration._milliseconds,
-                days = duration._days,
-                months = duration._months;
-            updateOffset = updateOffset == null ? true : updateOffset;
+    function loadLocale(name) {
+        var oldLocale = null;
+        // TODO: Find a better way to register and load all the locales in Node
+        if (!locales[name] && typeof module !== 'undefined' &&
+                module && module.exports) {
+            try {
+                oldLocale = globalLocale._abbr;
+                require('./locale/' + name);
+                // because defineLocale currently also sets the global locale, we
+                // want to undo that for lazy loaded locales
+                locale_locales__getSetGlobalLocale(oldLocale);
+            } catch (e) { }
+        }
+        return locales[name];
+    }
 
-            if (milliseconds) {
-                mom._d.setTime(+mom._d + milliseconds * isAdding);
+    // This function will load locale and then set the global locale.  If
+    // no arguments are passed in, it will simply return the current global
+    // locale key.
+    function locale_locales__getSetGlobalLocale(key, values) {
+        var data;
+        if (key) {
+            if (typeof values === 'undefined') {
+                data = locale_locales__getLocale(key);
             }
-            if (days) {
-                rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
-            }
-            if (months) {
-                rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
+            else {
+                data = defineLocale(key, values);
             }
-            if (updateOffset) {
-                moment.updateOffset(mom, days || months);
+
+            if (data) {
+                // moment.duration._locale = moment._locale = data;
+                globalLocale = data;
             }
         }
 
-        // check if is an array
-        function isArray(input) {
-            return Object.prototype.toString.call(input) === '[object Array]';
+        return globalLocale._abbr;
+    }
+
+    function defineLocale(name, values) {
+        if (values !== null) {
+            values.abbr = name;
+            locales[name] = locales[name] || new Locale();
+            locales[name].set(values);
+
+            // backwards compat for now: also set the locale
+            locale_locales__getSetGlobalLocale(name);
+
+            return locales[name];
+        } else {
+            // useful for testing
+            delete locales[name];
+            return null;
         }
+    }
+
+    // returns locale data
+    function locale_locales__getLocale(key) {
+        var locale;
 
-        function isDate(input) {
-            return Object.prototype.toString.call(input) === '[object Date]' ||
-                input instanceof Date;
+        if (key && key._locale && key._locale._abbr) {
+            key = key._locale._abbr;
         }
 
-        // compare two arrays, return the number of differences
-        function compareArrays(array1, array2, dontConvert) {
-            var len = Math.min(array1.length, array2.length),
-                lengthDiff = Math.abs(array1.length - array2.length),
-                diffs = 0,
-                i;
-            for (i = 0; i < len; i++) {
-                if ((dontConvert && array1[i] !== array2[i]) ||
-                    (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
-                    diffs++;
-                }
-            }
-            return diffs + lengthDiff;
+        if (!key) {
+            return globalLocale;
         }
 
-        function normalizeUnits(units) {
-            if (units) {
-                var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
-                units = unitAliases[units] || camelFunctions[lowered] || lowered;
+        if (!isArray(key)) {
+            //short-circuit everything else
+            locale = loadLocale(key);
+            if (locale) {
+                return locale;
             }
-            return units;
+            key = [key];
         }
 
-        function normalizeObjectUnits(inputObject) {
-            var normalizedInput = {},
-                normalizedProp,
-                prop;
+        return chooseLocale(key);
+    }
+
+    var aliases = {};
+
+    function addUnitAlias(unit, shorthand) {
+        var lowerCase = unit.toLowerCase();
+        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
+    }
+
+    function normalizeUnits(units) {
+        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
+    }
+
+    function normalizeObjectUnits(inputObject) {
+        var normalizedInput = {},
+            normalizedProp,
+            prop;
 
-            for (prop in inputObject) {
-                if (inputObject.hasOwnProperty(prop)) {
-                    normalizedProp = normalizeUnits(prop);
-                    if (normalizedProp) {
-                        normalizedInput[normalizedProp] = inputObject[prop];
-                    }
+        for (prop in inputObject) {
+            if (hasOwnProp(inputObject, prop)) {
+                normalizedProp = normalizeUnits(prop);
+                if (normalizedProp) {
+                    normalizedInput[normalizedProp] = inputObject[prop];
                 }
             }
-
-            return normalizedInput;
         }
 
-        function makeList(field) {
-            var count, setter;
+        return normalizedInput;
+    }
 
-            if (field.indexOf('week') === 0) {
-                count = 7;
-                setter = 'day';
+    function makeGetSet(unit, keepTime) {
+        return function (value) {
+            if (value != null) {
+                get_set__set(this, unit, value);
+                utils_hooks__hooks.updateOffset(this, keepTime);
+                return this;
+            } else {
+                return get_set__get(this, unit);
             }
-            else if (field.indexOf('month') === 0) {
-                count = 12;
-                setter = 'month';
+        };
+    }
+
+    function get_set__get(mom, unit) {
+        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
+    }
+
+    function get_set__set(mom, unit, value) {
+        return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
+    }
+
+    // MOMENTS
+
+    function getSet(units, value) {
+        var unit;
+        if (typeof units === 'object') {
+            for (unit in units) {
+                this.set(unit, units[unit]);
             }
-            else {
-                return;
+        } else {
+            units = normalizeUnits(units);
+            if (typeof this[units] === 'function') {
+                return this[units](value);
             }
+        }
+        return this;
+    }
 
-            moment[field] = function (format, index) {
-                var i, getter,
-                    method = moment.fn._lang[field],
-                    results = [];
+    function zeroFill(number, targetLength, forceSign) {
+        var absNumber = '' + Math.abs(number),
+            zerosToFill = targetLength - absNumber.length,
+            sign = number >= 0;
+        return (sign ? (forceSign ? '+' : '') : '-') +
+            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
+    }
 
-                if (typeof format === 'number') {
-                    index = format;
-                    format = undefined;
-                }
+    var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
 
-                getter = function (i) {
-                    var m = moment().utc().set(setter, i);
-                    return method.call(moment.fn._lang, m, format || '');
-                };
+    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
 
-                if (index != null) {
-                    return getter(index);
-                }
-                else {
-                    for (i = 0; i < count; i++) {
-                        results.push(getter(i));
-                    }
-                    return results;
-                }
+    var formatFunctions = {};
+
+    var formatTokenFunctions = {};
+
+    // token:    'M'
+    // padded:   ['MM', 2]
+    // ordinal:  'Mo'
+    // callback: function () { this.month() + 1 }
+    function addFormatToken(token, padded, ordinal, callback) {
+        var func = callback;
+        if (typeof callback === 'string') {
+            func = function () {
+                return this[callback]();
             };
         }
+        if (token) {
+            formatTokenFunctions[token] = func;
+        }
+        if (padded) {
+            formatTokenFunctions[padded[0]] = function () {
+                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
+            };
+        }
+        if (ordinal) {
+            formatTokenFunctions[ordinal] = function () {
+                return this.localeData().ordinal(func.apply(this, arguments), token);
+            };
+        }
+    }
+
+    function removeFormattingTokens(input) {
+        if (input.match(/\[[\s\S]/)) {
+            return input.replace(/^\[|\]$/g, '');
+        }
+        return input.replace(/\\/g, '');
+    }
 
-        function toInt(argumentForCoercion) {
-            var coercedNumber = +argumentForCoercion,
-                value = 0;
+    function makeFormatFunction(format) {
+        var array = format.match(formattingTokens), i, length;
 
-            if (coercedNumber !== 0 && isFinite(coercedNumber)) {
-                if (coercedNumber >= 0) {
-                    value = Math.floor(coercedNumber);
-                } else {
-                    value = Math.ceil(coercedNumber);
-                }
+        for (i = 0, length = array.length; i < length; i++) {
+            if (formatTokenFunctions[array[i]]) {
+                array[i] = formatTokenFunctions[array[i]];
+            } else {
+                array[i] = removeFormattingTokens(array[i]);
             }
-
-            return value;
         }
 
-        function daysInMonth(year, month) {
-            return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
-        }
+        return function (mom) {
+            var output = '';
+            for (i = 0; i < length; i++) {
+                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
+            }
+            return output;
+        };
+    }
 
-        function weeksInYear(year, dow, doy) {
-            return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;
+    // format date using native date object
+    function formatMoment(m, format) {
+        if (!m.isValid()) {
+            return m.localeData().invalidDate();
         }
 
-        function daysInYear(year) {
-            return isLeapYear(year) ? 366 : 365;
+        format = expandFormat(format, m.localeData());
+        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
+
+        return formatFunctions[format](m);
+    }
+
+    function expandFormat(format, locale) {
+        var i = 5;
+
+        function replaceLongDateFormatTokens(input) {
+            return locale.longDateFormat(input) || input;
         }
 
-        function isLeapYear(year) {
-            return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
+        localFormattingTokens.lastIndex = 0;
+        while (i >= 0 && localFormattingTokens.test(format)) {
+            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
+            localFormattingTokens.lastIndex = 0;
+            i -= 1;
         }
 
-        function checkOverflow(m) {
-            var overflow;
-            if (m._a && m._pf.overflow === -2) {
-                overflow =
-                    m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
-                    m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
-                    m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR :
-                    m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
-                    m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
-                    m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
-                    -1;
+        return format;
+    }
 
-                if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
-                    overflow = DATE;
-                }
+    var match1 = /\d/;            //       0 - 9
+    var match2 = /\d\d/;          //      00 - 99
+    var match3 = /\d{3}/;         //     000 - 999
+    var match4 = /\d{4}/;         //    0000 - 9999
+    var match6 = /[+-]?\d{6}/;    // -999999 - 999999
+    var match1to2 = /\d\d?/;         //       0 - 99
+    var match1to3 = /\d{1,3}/;       //       0 - 999
+    var match1to4 = /\d{1,4}/;       //       0 - 9999
+    var match1to6 = /[+-]?\d{1,6}/;  // -999999 - 999999
 
-                m._pf.overflow = overflow;
-            }
-        }
+    var matchUnsigned = /\d+/;           //       0 - inf
+    var matchSigned = /[+-]?\d+/;      //    -inf - inf
 
-        function isValid(m) {
-            if (m._isValid == null) {
-                m._isValid = !isNaN(m._d.getTime()) &&
-                    m._pf.overflow < 0 &&
-                    !m._pf.empty &&
-                    !m._pf.invalidMonth &&
-                    !m._pf.nullInput &&
-                    !m._pf.invalidFormat &&
-                    !m._pf.userInvalidated;
-
-                if (m._strict) {
-                    m._isValid = m._isValid &&
-                        m._pf.charsLeftOver === 0 &&
-                        m._pf.unusedTokens.length === 0;
-                }
-            }
-            return m._isValid;
+    var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
+
+    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
+
+    // any word (or two) characters or numbers including two/three word month in arabic.
+    var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
+
+    var regexes = {};
+
+    function isFunction(sth) {
+        // https://github.com/moment/moment/issues/2325
+        return typeof sth === 'function' &&
+            Object.prototype.toString.call(sth) === '[object Function]';
+    }
+
+
+    function addRegexToken(token, regex, strictRegex) {
+        regexes[token] = isFunction(regex) ? regex : function (isStrict) {
+            return (isStrict && strictRegex) ? strictRegex : regex;
+        };
+    }
+
+    function getParseRegexForToken(token, config) {
+        if (!hasOwnProp(regexes, token)) {
+            return new RegExp(unescapeFormat(token));
         }
 
-        function normalizeLanguage(key) {
-            return key ? key.toLowerCase().replace('_', '-') : key;
+        return regexes[token](config._strict, config._locale);
+    }
+
+    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
+    function unescapeFormat(s) {
+        return s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
+            return p1 || p2 || p3 || p4;
+        }).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+    }
+
+    var tokens = {};
+
+    function addParseToken(token, callback) {
+        var i, func = callback;
+        if (typeof token === 'string') {
+            token = [token];
+        }
+        if (typeof callback === 'number') {
+            func = function (input, array) {
+                array[callback] = toInt(input);
+            };
         }
+        for (i = 0; i < token.length; i++) {
+            tokens[token[i]] = func;
+        }
+    }
+
+    function addWeekParseToken(token, callback) {
+        addParseToken(token, function (input, array, config, token) {
+            config._w = config._w || {};
+            callback(input, config._w, config, token);
+        });
+    }
 
-        // Return a moment from input, that is local/utc/zone equivalent to model.
-        function makeAs(input, model) {
-            return model._isUTC ? moment(input).zone(model._offset || 0) :
-                moment(input).local();
+    function addTimeToArrayFromToken(token, input, config) {
+        if (input != null && hasOwnProp(tokens, token)) {
+            tokens[token](input, config._a, config, token);
         }
+    }
 
-        /************************************
-            Languages
-        ************************************/
+    var YEAR = 0;
+    var MONTH = 1;
+    var DATE = 2;
+    var HOUR = 3;
+    var MINUTE = 4;
+    var SECOND = 5;
+    var MILLISECOND = 6;
 
+    function daysInMonth(year, month) {
+        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
+    }
 
-        extend(Language.prototype, {
+    // FORMATTING
 
-            set: function (config) {
-                var prop, i;
-                for (i in config) {
-                    prop = config[i];
-                    if (typeof prop === 'function') {
-                        this[i] = prop;
-                    } else {
-                        this['_' + i] = prop;
-                    }
-                }
-            },
+    addFormatToken('M', ['MM', 2], 'Mo', function () {
+        return this.month() + 1;
+    });
 
-            _months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
-            months: function (m) {
-                return this._months[m.month()];
-            },
+    addFormatToken('MMM', 0, 0, function (format) {
+        return this.localeData().monthsShort(this, format);
+    });
 
-            _monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
-            monthsShort: function (m) {
-                return this._monthsShort[m.month()];
-            },
+    addFormatToken('MMMM', 0, 0, function (format) {
+        return this.localeData().months(this, format);
+    });
 
-            monthsParse: function (monthName) {
-                var i, mom, regex;
+    // ALIASES
 
-                if (!this._monthsParse) {
-                    this._monthsParse = [];
-                }
+    addUnitAlias('month', 'M');
 
-                for (i = 0; i < 12; i++) {
-                    // make the regex if we don't have it already
-                    if (!this._monthsParse[i]) {
-                        mom = moment.utc([2000, i]);
-                        regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
-                        this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
-                    }
-                    // test the regex
-                    if (this._monthsParse[i].test(monthName)) {
-                        return i;
-                    }
-                }
-            },
+    // PARSING
 
-            _weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
-            weekdays: function (m) {
-                return this._weekdays[m.day()];
-            },
+    addRegexToken('M', match1to2);
+    addRegexToken('MM', match1to2, match2);
+    addRegexToken('MMM', matchWord);
+    addRegexToken('MMMM', matchWord);
 
-            _weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
-            weekdaysShort: function (m) {
-                return this._weekdaysShort[m.day()];
-            },
+    addParseToken(['M', 'MM'], function (input, array) {
+        array[MONTH] = toInt(input) - 1;
+    });
 
-            _weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
-            weekdaysMin: function (m) {
-                return this._weekdaysMin[m.day()];
-            },
+    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
+        var month = config._locale.monthsParse(input, token, config._strict);
+        // if we didn't find a month name, mark the date as invalid.
+        if (month != null) {
+            array[MONTH] = month;
+        } else {
+            getParsingFlags(config).invalidMonth = input;
+        }
+    });
 
-            weekdaysParse: function (weekdayName) {
-                var i, mom, regex;
+    // LOCALES
 
-                if (!this._weekdaysParse) {
-                    this._weekdaysParse = [];
-                }
+    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
+    function localeMonths(m) {
+        return this._months[m.month()];
+    }
 
-                for (i = 0; i < 7; i++) {
-                    // make the regex if we don't have it already
-                    if (!this._weekdaysParse[i]) {
-                        mom = moment([2000, 1]).day(i);
-                        regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
-                        this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
-                    }
-                    // test the regex
-                    if (this._weekdaysParse[i].test(weekdayName)) {
-                        return i;
-                    }
-                }
-            },
-
-            _longDateFormat: {
-                LT: 'h:mm A',
-                L: 'MM/DD/YYYY',
-                LL: 'MMMM D YYYY',
-                LLL: 'MMMM D YYYY LT',
-                LLLL: 'dddd, MMMM D YYYY LT'
-            },
-            longDateFormat: function (key) {
-                var output = this._longDateFormat[key];
-                if (!output && this._longDateFormat[key.toUpperCase()]) {
-                    output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
-                        return val.slice(1);
-                    });
-                    this._longDateFormat[key] = output;
-                }
-                return output;
-            },
-
-            isPM: function (input) {
-                // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
-                // Using charAt should be more compatible.
-                return ((input + '').toLowerCase().charAt(0) === 'p');
-            },
-
-            _meridiemParse: /[ap]\.?m?\.?/i,
-            meridiem: function (hours, minutes, isLower) {
-                if (hours > 11) {
-                    return isLower ? 'pm' : 'PM';
-                } else {
-                    return isLower ? 'am' : 'AM';
-                }
-            },
-
-            _calendar: {
-                sameDay: '[Today at] LT',
-                nextDay: '[Tomorrow at] LT',
-                nextWeek: 'dddd [at] LT',
-                lastDay: '[Yesterday at] LT',
-                lastWeek: '[Last] dddd [at] LT',
-                sameElse: 'L'
-            },
-            calendar: function (key, mom) {
-                var output = this._calendar[key];
-                return typeof output === 'function' ? output.apply(mom) : output;
-            },
-
-            _relativeTime: {
-                future: 'in %s',
-                past: '%s ago',
-                s: 'a few seconds',
-                m: 'a minute',
-                mm: '%d minutes',
-                h: 'an hour',
-                hh: '%d hours',
-                d: 'a day',
-                dd: '%d days',
-                M: 'a month',
-                MM: '%d months',
-                y: 'a year',
-                yy: '%d years'
-            },
-
-            relativeTime: function (number, withoutSuffix, string, isFuture) {
-                var output = this._relativeTime[string];
-                return (typeof output === 'function') ?
-                    output(number, withoutSuffix, string, isFuture) :
-                    output.replace(/%d/i, number);
-            },
-
-            pastFuture: function (diff, output) {
-                var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
-                return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
-            },
-
-            ordinal: function (number) {
-                return this._ordinal.replace('%d', number);
-            },
-            _ordinal: '%d',
-
-            preparse: function (string) {
-                return string;
-            },
-
-            postformat: function (string) {
-                return string;
-            },
-
-            week: function (mom) {
-                return weekOfYear(mom, this._week.dow, this._week.doy).week;
-            },
-
-            _week: {
-                dow: 0, // Sunday is the first day of the week.
-                doy: 6  // The week that contains Jan 1st is the first week of the year.
-            },
-
-            _invalidDate: 'Invalid date',
-            invalidDate: function () {
-                return this._invalidDate;
-            }
-        });
+    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
+    function localeMonthsShort(m) {
+        return this._monthsShort[m.month()];
+    }
 
-        // Loads a language definition into the `languages` cache.  The function
-        // takes a key and optionally values.  If not in the browser and no values
-        // are provided, it will load the language file module.  As a convenience,
-        // this function also returns the language values.
-        function loadLang(key, values) {
-            values.abbr = key;
-            if (!languages[key]) {
-                languages[key] = new Language();
-            }
-            languages[key].set(values);
-            return languages[key];
-        }
-
-        // Remove a language from the `languages` cache. Mostly useful in tests.
-        function unloadLang(key) {
-            delete languages[key];
-        }
-
-        // Determines which language definition to use and returns it.
-        //
-        // With no parameters, it will return the global language.  If you
-        // pass in a language key, such as 'en', it will return the
-        // definition for 'en', so long as 'en' has already been loaded using
-        // moment.lang.
-        function getLangDefinition(key) {
-            var i = 0, j, lang, next, split,
-                get = function (k) {
-                    if (!languages[k] && hasModule) {
-                        try {
-                            require('./lang/' + k);
-                        } catch (e) { }
-                    }
-                    return languages[k];
-                };
-
-            if (!key) {
-                return moment.fn._lang;
-            }
+    function localeMonthsParse(monthName, format, strict) {
+        var i, mom, regex;
 
-            if (!isArray(key)) {
-                //short-circuit everything else
-                lang = get(key);
-                if (lang) {
-                    return lang;
-                }
-                key = [key];
-            }
+        if (!this._monthsParse) {
+            this._monthsParse = [];
+            this._longMonthsParse = [];
+            this._shortMonthsParse = [];
+        }
 
-            //pick the language from the array
-            //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
-            //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
-            while (i < key.length) {
-                split = normalizeLanguage(key[i]).split('-');
-                j = split.length;
-                next = normalizeLanguage(key[i + 1]);
-                next = next ? next.split('-') : null;
-                while (j > 0) {
-                    lang = get(split.slice(0, j).join('-'));
-                    if (lang) {
-                        return lang;
-                    }
-                    if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
-                        //the next array item is better than a shallower substring of this one
-                        break;
-                    }
-                    j--;
-                }
-                i++;
+        for (i = 0; i < 12; i++) {
+            // make the regex if we don't have it already
+            mom = create_utc__createUTC([2000, i]);
+            if (strict && !this._longMonthsParse[i]) {
+                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
+                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
+            }
+            if (!strict && !this._monthsParse[i]) {
+                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
+                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
+            }
+            // test the regex
+            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
+                return i;
+            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
+                return i;
+            } else if (!strict && this._monthsParse[i].test(monthName)) {
+                return i;
             }
-            return moment.fn._lang;
         }
+    }
 
-        /************************************
-            Formatting
-        ************************************/
+    // MOMENTS
 
+    function setMonth(mom, value) {
+        var dayOfMonth;
 
-        function removeFormattingTokens(input) {
-            if (input.match(/\[[\s\S]/)) {
-                return input.replace(/^\[|\]$/g, '');
+        // TODO: Move this out of here!
+        if (typeof value === 'string') {
+            value = mom.localeData().monthsParse(value);
+            // TODO: Another silent failure?
+            if (typeof value !== 'number') {
+                return mom;
             }
-            return input.replace(/\\/g, '');
         }
 
-        function makeFormatFunction(format) {
-            var array = format.match(formattingTokens), i, length;
-
-            for (i = 0, length = array.length; i < length; i++) {
-                if (formatTokenFunctions[array[i]]) {
-                    array[i] = formatTokenFunctions[array[i]];
-                } else {
-                    array[i] = removeFormattingTokens(array[i]);
-                }
-            }
+        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
+        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
+        return mom;
+    }
 
-            return function (mom) {
-                var output = '';
-                for (i = 0; i < length; i++) {
-                    output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
-                }
-                return output;
-            };
+    function getSetMonth(value) {
+        if (value != null) {
+            setMonth(this, value);
+            utils_hooks__hooks.updateOffset(this, true);
+            return this;
+        } else {
+            return get_set__get(this, 'Month');
         }
+    }
 
-        // format date using native date object
-        function formatMoment(m, format) {
-            if (!m.isValid()) {
-                return m.lang().invalidDate();
-            }
+    function getDaysInMonth() {
+        return daysInMonth(this.year(), this.month());
+    }
+
+    function checkOverflow(m) {
+        var overflow;
+        var a = m._a;
 
-            format = expandFormat(format, m.lang());
+        if (a && getParsingFlags(m).overflow === -2) {
+            overflow =
+                a[MONTH] < 0 || a[MONTH] > 11 ? MONTH :
+                a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
+                a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
+                a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE :
+                a[SECOND] < 0 || a[SECOND] > 59 ? SECOND :
+                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
+                -1;
 
-            if (!formatFunctions[format]) {
-                formatFunctions[format] = makeFormatFunction(format);
+            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
+                overflow = DATE;
             }
 
-            return formatFunctions[format](m);
+            getParsingFlags(m).overflow = overflow;
         }
 
-        function expandFormat(format, lang) {
-            var i = 5;
+        return m;
+    }
 
-            function replaceLongDateFormatTokens(input) {
-                return lang.longDateFormat(input) || input;
-            }
+    function warn(msg) {
+        if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
+            console.warn('Deprecation warning: ' + msg);
+        }
+    }
 
-            localFormattingTokens.lastIndex = 0;
-            while (i >= 0 && localFormattingTokens.test(format)) {
-                format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
-                localFormattingTokens.lastIndex = 0;
-                i -= 1;
+    function deprecate(msg, fn) {
+        var firstTime = true;
+
+        return extend(function () {
+            if (firstTime) {
+                warn(msg + '\n' + (new Error()).stack);
+                firstTime = false;
             }
+            return fn.apply(this, arguments);
+        }, fn);
+    }
 
-            return format;
-        }
+    var deprecations = {};
 
+    function deprecateSimple(name, msg) {
+        if (!deprecations[name]) {
+            warn(msg);
+            deprecations[name] = true;
+        }
+    }
 
-        /************************************
-            Parsing
-        ************************************/
-
-
-        // get the regex to find the next token
-        function getParseRegexForToken(token, config) {
-            var a, strict = config._strict;
-            switch (token) {
-                case 'Q':
-                    return parseTokenOneDigit;
-                case 'DDDD':
-                    return parseTokenThreeDigits;
-                case 'YYYY':
-                case 'GGGG':
-                case 'gggg':
-                    return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
-                case 'Y':
-                case 'G':
-                case 'g':
-                    return parseTokenSignedNumber;
-                case 'YYYYYY':
-                case 'YYYYY':
-                case 'GGGGG':
-                case 'ggggg':
-                    return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
-                case 'S':
-                    if (strict) {
-                        return parseTokenOneDigit;
-                    }
-                    /* falls through */
-                case 'SS':
-                    if (strict) {
-                        return parseTokenTwoDigits;
-                    }
-                    /* falls through */
-                case 'SSS':
-                    if (strict) {
-                        return parseTokenThreeDigits;
-                    }
-                    /* falls through */
-                case 'DDD':
-                    return parseTokenOneToThreeDigits;
-                case 'MMM':
-                case 'MMMM':
-                case 'dd':
-                case 'ddd':
-                case 'dddd':
-                    return parseTokenWord;
-                case 'a':
-                case 'A':
-                    return getLangDefinition(config._l)._meridiemParse;
-                case 'X':
-                    return parseTokenTimestampMs;
-                case 'Z':
-                case 'ZZ':
-                    return parseTokenTimezone;
-                case 'T':
-                    return parseTokenT;
-                case 'SSSS':
-                    return parseTokenDigits;
-                case 'MM':
-                case 'DD':
-                case 'YY':
-                case 'GG':
-                case 'gg':
-                case 'HH':
-                case 'hh':
-                case 'mm':
-                case 'ss':
-                case 'ww':
-                case 'WW':
-                    return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
-                case 'M':
-                case 'D':
-                case 'd':
-                case 'H':
-                case 'h':
-                case 'm':
-                case 's':
-                case 'w':
-                case 'W':
-                case 'e':
-                case 'E':
-                    return parseTokenOneOrTwoDigits;
-                case 'Do':
-                    return parseTokenOrdinal;
-                default:
-                    a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
-                    return a;
+    utils_hooks__hooks.suppressDeprecationWarnings = true;
+
+    var from_string__isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
+
+    var isoDates = [
+        ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
+        ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
+        ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
+        ['GGGG-[W]WW', /\d{4}-W\d{2}/],
+        ['YYYY-DDD', /\d{4}-\d{3}/]
+    ];
+
+    // iso time formats and regexes
+    var isoTimes = [
+        ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
+        ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
+        ['HH:mm', /(T| )\d\d:\d\d/],
+        ['HH', /(T| )\d\d/]
+    ];
+
+    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
+
+    // date from iso format
+    function configFromISO(config) {
+        var i, l,
+            string = config._i,
+            match = from_string__isoRegex.exec(string);
+
+        if (match) {
+            getParsingFlags(config).iso = true;
+            for (i = 0, l = isoDates.length; i < l; i++) {
+                if (isoDates[i][1].exec(string)) {
+                    config._f = isoDates[i][0];
+                    break;
+                }
+            }
+            for (i = 0, l = isoTimes.length; i < l; i++) {
+                if (isoTimes[i][1].exec(string)) {
+                    // match[6] should be 'T' or space
+                    config._f += (match[6] || ' ') + isoTimes[i][0];
+                    break;
+                }
             }
+            if (string.match(matchOffset)) {
+                config._f += 'Z';
+            }
+            configFromStringAndFormat(config);
+        } else {
+            config._isValid = false;
         }
+    }
 
-        function timezoneMinutesFromString(string) {
-            string = string || '';
-            var possibleTzMatches = (string.match(parseTokenTimezone) || []),
-                tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
-                parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
-                minutes = +(parts[1] * 60) + toInt(parts[2]);
+    // date from iso format or fallback
+    function configFromString(config) {
+        var matched = aspNetJsonRegex.exec(config._i);
 
-            return parts[0] === '+' ? -minutes : minutes;
+        if (matched !== null) {
+            config._d = new Date(+matched[1]);
+            return;
         }
 
-        // function to convert string input to date
-        function addTimeToArrayFromToken(token, input, config) {
-            var a, datePartArray = config._a;
+        configFromISO(config);
+        if (config._isValid === false) {
+            delete config._isValid;
+            utils_hooks__hooks.createFromInputFallback(config);
+        }
+    }
 
-            switch (token) {
-                // QUARTER
-                case 'Q':
-                    if (input != null) {
-                        datePartArray[MONTH] = (toInt(input) - 1) * 3;
-                    }
-                    break;
-                    // MONTH
-                case 'M': // fall through to MM
-                case 'MM':
-                    if (input != null) {
-                        datePartArray[MONTH] = toInt(input) - 1;
-                    }
-                    break;
-                case 'MMM': // fall through to MMMM
-                case 'MMMM':
-                    a = getLangDefinition(config._l).monthsParse(input);
-                    // if we didn't find a month name, mark the date as invalid.
-                    if (a != null) {
-                        datePartArray[MONTH] = a;
-                    } else {
-                        config._pf.invalidMonth = input;
-                    }
-                    break;
-                    // DAY OF MONTH
-                case 'D': // fall through to DD
-                case 'DD':
-                    if (input != null) {
-                        datePartArray[DATE] = toInt(input);
-                    }
-                    break;
-                case 'Do':
-                    if (input != null) {
-                        datePartArray[DATE] = toInt(parseInt(input, 10));
-                    }
-                    break;
-                    // DAY OF YEAR
-                case 'DDD': // fall through to DDDD
-                case 'DDDD':
-                    if (input != null) {
-                        config._dayOfYear = toInt(input);
-                    }
+    utils_hooks__hooks.createFromInputFallback = deprecate(
+        'moment construction falls back to js Date. This is ' +
+        'discouraged and will be removed in upcoming major ' +
+        'release. Please refer to ' +
+        'https://github.com/moment/moment/issues/1407 for more info.',
+        function (config) {
+            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
+        }
+    );
 
-                    break;
-                    // YEAR
-                case 'YY':
-                    datePartArray[YEAR] = moment.parseTwoDigitYear(input);
-                    break;
-                case 'YYYY':
-                case 'YYYYY':
-                case 'YYYYYY':
-                    datePartArray[YEAR] = toInt(input);
-                    break;
-                    // AM / PM
-                case 'a': // fall through to A
-                case 'A':
-                    config._isPm = getLangDefinition(config._l).isPM(input);
-                    break;
-                    // 24 HOUR
-                case 'H': // fall through to hh
-                case 'HH': // fall through to hh
-                case 'h': // fall through to hh
-                case 'hh':
-                    datePartArray[HOUR] = toInt(input);
-                    break;
-                    // MINUTE
-                case 'm': // fall through to mm
-                case 'mm':
-                    datePartArray[MINUTE] = toInt(input);
-                    break;
-                    // SECOND
-                case 's': // fall through to ss
-                case 'ss':
-                    datePartArray[SECOND] = toInt(input);
-                    break;
-                    // MILLISECOND
-                case 'S':
-                case 'SS':
-                case 'SSS':
-                case 'SSSS':
-                    datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
-                    break;
-                    // UNIX TIMESTAMP WITH MS
-                case 'X':
-                    config._d = new Date(parseFloat(input) * 1000);
-                    break;
-                    // TIMEZONE
-                case 'Z': // fall through to ZZ
-                case 'ZZ':
-                    config._useUTC = true;
-                    config._tzm = timezoneMinutesFromString(input);
-                    break;
-                    // WEEKDAY - human
-                case 'dd':
-                case 'ddd':
-                case 'dddd':
-                    a = getLangDefinition(config._l).weekdaysParse(input);
-                    // if we didn't get a weekday name, mark the date as invalid
-                    if (a != null) {
-                        config._w = config._w || {};
-                        config._w['d'] = a;
-                    } else {
-                        config._pf.invalidWeekday = input;
-                    }
-                    break;
-                    // WEEK, WEEK DAY - numeric
-                case 'w':
-                case 'ww':
-                case 'W':
-                case 'WW':
-                case 'd':
-                case 'e':
-                case 'E':
-                    token = token.substr(0, 1);
-                    /* falls through */
-                case 'gggg':
-                case 'GGGG':
-                case 'GGGGG':
-                    token = token.substr(0, 2);
-                    if (input) {
-                        config._w = config._w || {};
-                        config._w[token] = toInt(input);
-                    }
-                    break;
-                case 'gg':
-                case 'GG':
-                    config._w = config._w || {};
-                    config._w[token] = moment.parseTwoDigitYear(input);
-            }
+    function createDate(y, m, d, h, M, s, ms) {
+        //can't just apply() to create a date:
+        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
+        var date = new Date(y, m, d, h, M, s, ms);
+
+        //the date constructor doesn't accept years < 1970
+        if (y < 1970) {
+            date.setFullYear(y);
+        }
+        return date;
+    }
+
+    function createUTCDate(y) {
+        var date = new Date(Date.UTC.apply(null, arguments));
+        if (y < 1970) {
+            date.setUTCFullYear(y);
         }
+        return date;
+    }
+
+    addFormatToken(0, ['YY', 2], 0, function () {
+        return this.year() % 100;
+    });
+
+    addFormatToken(0, ['YYYY', 4], 0, 'year');
+    addFormatToken(0, ['YYYYY', 5], 0, 'year');
+    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
+
+    // ALIASES
+
+    addUnitAlias('year', 'y');
+
+    // PARSING
+
+    addRegexToken('Y', matchSigned);
+    addRegexToken('YY', match1to2, match2);
+    addRegexToken('YYYY', match1to4, match4);
+    addRegexToken('YYYYY', match1to6, match6);
+    addRegexToken('YYYYYY', match1to6, match6);
+
+    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
+    addParseToken('YYYY', function (input, array) {
+        array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
+    });
+    addParseToken('YY', function (input, array) {
+        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
+    });
+
+    // HELPERS
+
+    function daysInYear(year) {
+        return isLeapYear(year) ? 366 : 365;
+    }
+
+    function isLeapYear(year) {
+        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
+    }
+
+    // HOOKS
+
+    utils_hooks__hooks.parseTwoDigitYear = function (input) {
+        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
+    };
+
+    // MOMENTS
+
+    var getSetYear = makeGetSet('FullYear', false);
+
+    function getIsLeapYear() {
+        return isLeapYear(this.year());
+    }
+
+    addFormatToken('w', ['ww', 2], 'wo', 'week');
+    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
+
+    // ALIASES
+
+    addUnitAlias('week', 'w');
+    addUnitAlias('isoWeek', 'W');
+
+    // PARSING
+
+    addRegexToken('w', match1to2);
+    addRegexToken('ww', match1to2, match2);
+    addRegexToken('W', match1to2);
+    addRegexToken('WW', match1to2, match2);
+
+    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
+        week[token.substr(0, 1)] = toInt(input);
+    });
+
+    // HELPERS
+
+    // firstDayOfWeek       0 = sun, 6 = sat
+    //                      the day of the week that starts the week
+    //                      (usually sunday or monday)
+    // firstDayOfWeekOfYear 0 = sun, 6 = sat
+    //                      the first week is the week that contains the first
+    //                      of this day of the week
+    //                      (eg. ISO weeks use thursday (4))
+    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
+        var end = firstDayOfWeekOfYear - firstDayOfWeek,
+            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
+            adjustedMoment;
+
+
+        if (daysToDayOfWeek > end) {
+            daysToDayOfWeek -= 7;
+        }
+
+        if (daysToDayOfWeek < end - 7) {
+            daysToDayOfWeek += 7;
+        }
+
+        adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');
+        return {
+            week: Math.ceil(adjustedMoment.dayOfYear() / 7),
+            year: adjustedMoment.year()
+        };
+    }
+
+    // LOCALES
+
+    function localeWeek(mom) {
+        return weekOfYear(mom, this._week.dow, this._week.doy).week;
+    }
+
+    var defaultLocaleWeek = {
+        dow: 0, // Sunday is the first day of the week.
+        doy: 6  // The week that contains Jan 1st is the first week of the year.
+    };
+
+    function localeFirstDayOfWeek() {
+        return this._week.dow;
+    }
+
+    function localeFirstDayOfYear() {
+        return this._week.doy;
+    }
+
+    // MOMENTS
+
+    function getSetWeek(input) {
+        var week = this.localeData().week(this);
+        return input == null ? week : this.add((input - week) * 7, 'd');
+    }
+
+    function getSetISOWeek(input) {
+        var week = weekOfYear(this, 1, 4).week;
+        return input == null ? week : this.add((input - week) * 7, 'd');
+    }
+
+    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
+
+    // ALIASES
+
+    addUnitAlias('dayOfYear', 'DDD');
+
+    // PARSING
+
+    addRegexToken('DDD', match1to3);
+    addRegexToken('DDDD', match3);
+    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
+        config._dayOfYear = toInt(input);
+    });
+
+    // HELPERS
+
+    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
+    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
+        var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
+        if (d < firstDayOfWeek) {
+            d += 7;
+        }
+
+        weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
+
+        dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
+
+        return {
+            year: dayOfYear > 0 ? year : year - 1,
+            dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
+        };
+    }
+
+    // MOMENTS
+
+    function getSetDayOfYear(input) {
+        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
+        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
+    }
+
+    // Pick the first defined of two or three arguments.
+    function defaults(a, b, c) {
+        if (a != null) {
+            return a;
+        }
+        if (b != null) {
+            return b;
+        }
+        return c;
+    }
+
+    function currentDateArray(config) {
+        var now = new Date();
+        if (config._useUTC) {
+            return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];
+        }
+        return [now.getFullYear(), now.getMonth(), now.getDate()];
+    }
+
+    // convert an array to a date.
+    // the array should mirror the parameters below
+    // note: all values past the year are optional and will default to the lowest possible value.
+    // [year, month, day , hour, minute, second, millisecond]
+    function configFromArray(config) {
+        var i, date, input = [], currentDate, yearToUse;
+
+        if (config._d) {
+            return;
+        }
+
+        currentDate = currentDateArray(config);
+
+        //compute day of the year from weeks and weekdays
+        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
+            dayOfYearFromWeekInfo(config);
+        }
+
+        //if the day of the year is set, figure out what it is
+        if (config._dayOfYear) {
+            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
+
+            if (config._dayOfYear > daysInYear(yearToUse)) {
+                getParsingFlags(config)._overflowDayOfYear = true;
+            }
+
+            date = createUTCDate(yearToUse, 0, config._dayOfYear);
+            config._a[MONTH] = date.getUTCMonth();
+            config._a[DATE] = date.getUTCDate();
+        }
+
+        // Default to current date.
+        // * if no year, month, day of month are given, default to today
+        // * if day of month is given, default month and year
+        // * if month is given, default only year
+        // * if year is given, don't default anything
+        for (i = 0; i < 3 && config._a[i] == null; ++i) {
+            config._a[i] = input[i] = currentDate[i];
+        }
+
+        // Zero out whatever was not defaulted, including time
+        for (; i < 7; i++) {
+            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
+        }
+
+        // Check for 24:00:00.000
+        if (config._a[HOUR] === 24 &&
+                config._a[MINUTE] === 0 &&
+                config._a[SECOND] === 0 &&
+                config._a[MILLISECOND] === 0) {
+            config._nextDay = true;
+            config._a[HOUR] = 0;
+        }
+
+        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
+        // Apply timezone offset from input. The actual utcOffset can be changed
+        // with parseZone.
+        if (config._tzm != null) {
+            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
+        }
+
+        if (config._nextDay) {
+            config._a[HOUR] = 24;
+        }
+    }
+
+    function dayOfYearFromWeekInfo(config) {
+        var w, weekYear, week, weekday, dow, doy, temp;
+
+        w = config._w;
+        if (w.GG != null || w.W != null || w.E != null) {
+            dow = 1;
+            doy = 4;
+
+            // TODO: We need to take the current isoWeekYear, but that depends on
+            // how we interpret now (local, utc, fixed offset). So create
+            // a now version of current config (take local/utc/offset flags, and
+            // create now).
+            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);
+            week = defaults(w.W, 1);
+            weekday = defaults(w.E, 1);
+        } else {
+            dow = config._locale._week.dow;
+            doy = config._locale._week.doy;
+
+            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);
+            week = defaults(w.w, 1);
+
+            if (w.d != null) {
+                // weekday -- low day numbers are considered next week
+                weekday = w.d;
+                if (weekday < dow) {
+                    ++week;
+                }
+            } else if (w.e != null) {
+                // local weekday -- counting starts from begining of week
+                weekday = w.e + dow;
+            } else {
+                // default to begining of week
+                weekday = dow;
+            }
+        }
+        temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
+
+        config._a[YEAR] = temp.year;
+        config._dayOfYear = temp.dayOfYear;
+    }
+
+    utils_hooks__hooks.ISO_8601 = function () { };
+
+    // date from string and format string
+    function configFromStringAndFormat(config) {
+        // TODO: Move this to another part of the creation flow to prevent circular deps
+        if (config._f === utils_hooks__hooks.ISO_8601) {
+            configFromISO(config);
+            return;
+        }
+
+        config._a = [];
+        getParsingFlags(config).empty = true;
+
+        // This array is used to make a Date, either with `new Date` or `Date.UTC`
+        var string = '' + config._i,
+            i, parsedInput, tokens, token, skipped,
+            stringLength = string.length,
+            totalParsedInputLength = 0;
+
+        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
+
+        for (i = 0; i < tokens.length; i++) {
+            token = tokens[i];
+            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
+            if (parsedInput) {
+                skipped = string.substr(0, string.indexOf(parsedInput));
+                if (skipped.length > 0) {
+                    getParsingFlags(config).unusedInput.push(skipped);
+                }
+                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
+                totalParsedInputLength += parsedInput.length;
+            }
+            // don't parse if it's not a known token
+            if (formatTokenFunctions[token]) {
+                if (parsedInput) {
+                    getParsingFlags(config).empty = false;
+                }
+                else {
+                    getParsingFlags(config).unusedTokens.push(token);
+                }
+                addTimeToArrayFromToken(token, parsedInput, config);
+            }
+            else if (config._strict && !parsedInput) {
+                getParsingFlags(config).unusedTokens.push(token);
+            }
+        }
+
+        // add remaining unparsed input length to the string
+        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
+        if (string.length > 0) {
+            getParsingFlags(config).unusedInput.push(string);
+        }
+
+        // clear _12h flag if hour is <= 12
+        if (getParsingFlags(config).bigHour === true &&
+                config._a[HOUR] <= 12 &&
+                config._a[HOUR] > 0) {
+            getParsingFlags(config).bigHour = undefined;
+        }
+        // handle meridiem
+        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
+
+        configFromArray(config);
+        checkOverflow(config);
+    }
+
+
+    function meridiemFixWrap(locale, hour, meridiem) {
+        var isPm;
+
+        if (meridiem == null) {
+            // nothing to do
+            return hour;
+        }
+        if (locale.meridiemHour != null) {
+            return locale.meridiemHour(hour, meridiem);
+        } else if (locale.isPM != null) {
+            // Fallback
+            isPm = locale.isPM(meridiem);
+            if (isPm && hour < 12) {
+                hour += 12;
+            }
+            if (!isPm && hour === 12) {
+                hour = 0;
+            }
+            return hour;
+        } else {
+            // this is not supposed to happen
+            return hour;
+        }
+    }
+
+    function configFromStringAndArray(config) {
+        var tempConfig,
+            bestMoment,
+
+            scoreToBeat,
+            i,
+            currentScore;
+
+        if (config._f.length === 0) {
+            getParsingFlags(config).invalidFormat = true;
+            config._d = new Date(NaN);
+            return;
+        }
+
+        for (i = 0; i < config._f.length; i++) {
+            currentScore = 0;
+            tempConfig = copyConfig({}, config);
+            if (config._useUTC != null) {
+                tempConfig._useUTC = config._useUTC;
+            }
+            tempConfig._f = config._f[i];
+            configFromStringAndFormat(tempConfig);
+
+            if (!valid__isValid(tempConfig)) {
+                continue;
+            }
+
+            // if there is any input that was not parsed add a penalty for that format
+            currentScore += getParsingFlags(tempConfig).charsLeftOver;
+
+            //or tokens
+            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
+
+            getParsingFlags(tempConfig).score = currentScore;
+
+            if (scoreToBeat == null || currentScore < scoreToBeat) {
+                scoreToBeat = currentScore;
+                bestMoment = tempConfig;
+            }
+        }
+
+        extend(config, bestMoment || tempConfig);
+    }
+
+    function configFromObject(config) {
+        if (config._d) {
+            return;
+        }
+
+        var i = normalizeObjectUnits(config._i);
+        config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];
+
+        configFromArray(config);
+    }
+
+    function createFromConfig(config) {
+        var res = new Moment(checkOverflow(prepareConfig(config)));
+        if (res._nextDay) {
+            // Adding is smart enough around DST
+            res.add(1, 'd');
+            res._nextDay = undefined;
+        }
+
+        return res;
+    }
+
+    function prepareConfig(config) {
+        var input = config._i,
+            format = config._f;
+
+        config._locale = config._locale || locale_locales__getLocale(config._l);
+
+        if (input === null || (format === undefined && input === '')) {
+            return valid__createInvalid({ nullInput: true });
+        }
+
+        if (typeof input === 'string') {
+            config._i = input = config._locale.preparse(input);
+        }
+
+        if (isMoment(input)) {
+            return new Moment(checkOverflow(input));
+        } else if (isArray(format)) {
+            configFromStringAndArray(config);
+        } else if (format) {
+            configFromStringAndFormat(config);
+        } else if (isDate(input)) {
+            config._d = input;
+        } else {
+            configFromInput(config);
+        }
+
+        return config;
+    }
+
+    function configFromInput(config) {
+        var input = config._i;
+        if (input === undefined) {
+            config._d = new Date();
+        } else if (isDate(input)) {
+            config._d = new Date(+input);
+        } else if (typeof input === 'string') {
+            configFromString(config);
+        } else if (isArray(input)) {
+            config._a = map(input.slice(0), function (obj) {
+                return parseInt(obj, 10);
+            });
+            configFromArray(config);
+        } else if (typeof (input) === 'object') {
+            configFromObject(config);
+        } else if (typeof (input) === 'number') {
+            // from milliseconds
+            config._d = new Date(input);
+        } else {
+            utils_hooks__hooks.createFromInputFallback(config);
+        }
+    }
+
+    function createLocalOrUTC(input, format, locale, strict, isUTC) {
+        var c = {};
+
+        if (typeof (locale) === 'boolean') {
+            strict = locale;
+            locale = undefined;
+        }
+        // object construction must be done this way.
+        // https://github.com/moment/moment/issues/1423
+        c._isAMomentObject = true;
+        c._useUTC = c._isUTC = isUTC;
+        c._l = locale;
+        c._i = input;
+        c._f = format;
+        c._strict = strict;
+
+        return createFromConfig(c);
+    }
+
+    function local__createLocal(input, format, locale, strict) {
+        return createLocalOrUTC(input, format, locale, strict, false);
+    }
+
+    var prototypeMin = deprecate(
+         'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
+         function () {
+             var other = local__createLocal.apply(null, arguments);
+             return other < this ? this : other;
+         }
+     );
+
+    var prototypeMax = deprecate(
+        'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
+        function () {
+            var other = local__createLocal.apply(null, arguments);
+            return other > this ? this : other;
+        }
+    );
+
+    // Pick a moment m from moments so that m[fn](other) is true for all
+    // other. This relies on the function fn to be transitive.
+    //
+    // moments should either be an array of moment objects or an array, whose
+    // first element is an array of moment objects.
+    function pickBy(fn, moments) {
+        var res, i;
+        if (moments.length === 1 && isArray(moments[0])) {
+            moments = moments[0];
+        }
+        if (!moments.length) {
+            return local__createLocal();
+        }
+        res = moments[0];
+        for (i = 1; i < moments.length; ++i) {
+            if (!moments[i].isValid() || moments[i][fn](res)) {
+                res = moments[i];
+            }
+        }
+        return res;
+    }
+
+    // TODO: Use [].sort instead?
+    function min() {
+        var args = [].slice.call(arguments, 0);
+
+        return pickBy('isBefore', args);
+    }
+
+    function max() {
+        var args = [].slice.call(arguments, 0);
+
+        return pickBy('isAfter', args);
+    }
+
+    function Duration(duration) {
+        var normalizedInput = normalizeObjectUnits(duration),
+            years = normalizedInput.year || 0,
+            quarters = normalizedInput.quarter || 0,
+            months = normalizedInput.month || 0,
+            weeks = normalizedInput.week || 0,
+            days = normalizedInput.day || 0,
+            hours = normalizedInput.hour || 0,
+            minutes = normalizedInput.minute || 0,
+            seconds = normalizedInput.second || 0,
+            milliseconds = normalizedInput.millisecond || 0;
+
+        // representation for dateAddRemove
+        this._milliseconds = +milliseconds +
+            seconds * 1e3 + // 1000
+            minutes * 6e4 + // 1000 * 60
+            hours * 36e5; // 1000 * 60 * 60
+        // Because of dateAddRemove treats 24 hours as different from a
+        // day when working around DST, we need to store them separately
+        this._days = +days +
+            weeks * 7;
+        // It is impossible translate months into days without knowing
+        // which months you are are talking about, so we have to store
+        // it separately.
+        this._months = +months +
+            quarters * 3 +
+            years * 12;
+
+        this._data = {};
+
+        this._locale = locale_locales__getLocale();
+
+        this._bubble();
+    }
+
+    function isDuration(obj) {
+        return obj instanceof Duration;
+    }
+
+    function offset(token, separator) {
+        addFormatToken(token, 0, 0, function () {
+            var offset = this.utcOffset();
+            var sign = '+';
+            if (offset < 0) {
+                offset = -offset;
+                sign = '-';
+            }
+            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
+        });
+    }
+
+    offset('Z', ':');
+    offset('ZZ', '');
+
+    // PARSING
+
+    addRegexToken('Z', matchOffset);
+    addRegexToken('ZZ', matchOffset);
+    addParseToken(['Z', 'ZZ'], function (input, array, config) {
+        config._useUTC = true;
+        config._tzm = offsetFromString(input);
+    });
+
+    // HELPERS
+
+    // timezone chunker
+    // '+10:00' > ['10',  '00']
+    // '-1530'  > ['-15', '30']
+    var chunkOffset = /([\+\-]|\d\d)/gi;
+
+    function offsetFromString(string) {
+        var matches = ((string || '').match(matchOffset) || []);
+        var chunk = matches[matches.length - 1] || [];
+        var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
+        var minutes = +(parts[1] * 60) + toInt(parts[2]);
+
+        return parts[0] === '+' ? minutes : -minutes;
+    }
+
+    // Return a moment from input, that is local/utc/zone equivalent to model.
+    function cloneWithOffset(input, model) {
+        var res, diff;
+        if (model._isUTC) {
+            res = model.clone();
+            diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);
+            // Use low-level api, because this fn is low-level api.
+            res._d.setTime(+res._d + diff);
+            utils_hooks__hooks.updateOffset(res, false);
+            return res;
+        } else {
+            return local__createLocal(input).local();
+        }
+    }
+
+    function getDateOffset(m) {
+        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
+        // https://github.com/moment/moment/pull/1871
+        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
+    }
+
+    // HOOKS
+
+    // This function will be called whenever a moment is mutated.
+    // It is intended to keep the offset in sync with the timezone.
+    utils_hooks__hooks.updateOffset = function () { };
+
+    // MOMENTS
+
+    // keepLocalTime = true means only change the timezone, without
+    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
+    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
+    // +0200, so we adjust the time as needed, to be valid.
+    //
+    // Keeping the time actually adds/subtracts (one hour)
+    // from the actual represented time. That is why we call updateOffset
+    // a second time. In case it wants us to change the offset again
+    // _changeInProgress == true case, then we have to adjust, because
+    // there is no such time in the given timezone.
+    function getSetOffset(input, keepLocalTime) {
+        var offset = this._offset || 0,
+            localAdjust;
+        if (input != null) {
+            if (typeof input === 'string') {
+                input = offsetFromString(input);
+            }
+            if (Math.abs(input) < 16) {
+                input = input * 60;
+            }
+            if (!this._isUTC && keepLocalTime) {
+                localAdjust = getDateOffset(this);
+            }
+            this._offset = input;
+            this._isUTC = true;
+            if (localAdjust != null) {
+                this.add(localAdjust, 'm');
+            }
+            if (offset !== input) {
+                if (!keepLocalTime || this._changeInProgress) {
+                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);
+                } else if (!this._changeInProgress) {
+                    this._changeInProgress = true;
+                    utils_hooks__hooks.updateOffset(this, true);
+                    this._changeInProgress = null;
+                }
+            }
+            return this;
+        } else {
+            return this._isUTC ? offset : getDateOffset(this);
+        }
+    }
+
+    function getSetZone(input, keepLocalTime) {
+        if (input != null) {
+            if (typeof input !== 'string') {
+                input = -input;
+            }
+
+            this.utcOffset(input, keepLocalTime);
+
+            return this;
+        } else {
+            return -this.utcOffset();
+        }
+    }
+
+    function setOffsetToUTC(keepLocalTime) {
+        return this.utcOffset(0, keepLocalTime);
+    }
+
+    function setOffsetToLocal(keepLocalTime) {
+        if (this._isUTC) {
+            this.utcOffset(0, keepLocalTime);
+            this._isUTC = false;
+
+            if (keepLocalTime) {
+                this.subtract(getDateOffset(this), 'm');
+            }
+        }
+        return this;
+    }
+
+    function setOffsetToParsedOffset() {
+        if (this._tzm) {
+            this.utcOffset(this._tzm);
+        } else if (typeof this._i === 'string') {
+            this.utcOffset(offsetFromString(this._i));
+        }
+        return this;
+    }
+
+    function hasAlignedHourOffset(input) {
+        input = input ? local__createLocal(input).utcOffset() : 0;
+
+        return (this.utcOffset() - input) % 60 === 0;
+    }
+
+    function isDaylightSavingTime() {
+        return (
+            this.utcOffset() > this.clone().month(0).utcOffset() ||
+            this.utcOffset() > this.clone().month(5).utcOffset()
+        );
+    }
+
+    function isDaylightSavingTimeShifted() {
+        if (typeof this._isDSTShifted !== 'undefined') {
+            return this._isDSTShifted;
+        }
+
+        var c = {};
+
+        copyConfig(c, this);
+        c = prepareConfig(c);
+
+        if (c._a) {
+            var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
+            this._isDSTShifted = this.isValid() &&
+                compareArrays(c._a, other.toArray()) > 0;
+        } else {
+            this._isDSTShifted = false;
+        }
+
+        return this._isDSTShifted;
+    }
+
+    function isLocal() {
+        return !this._isUTC;
+    }
+
+    function isUtcOffset() {
+        return this._isUTC;
+    }
+
+    function isUtc() {
+        return this._isUTC && this._offset === 0;
+    }
+
+    var aspNetRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/;
+
+    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
+    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
+    var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;
+
+    function create__createDuration(input, key) {
+        var duration = input,
+            // matching against regexp is expensive, do it on demand
+            match = null,
+            sign,
+            ret,
+            diffRes;
+
+        if (isDuration(input)) {
+            duration = {
+                ms: input._milliseconds,
+                d: input._days,
+                M: input._months
+            };
+        } else if (typeof input === 'number') {
+            duration = {};
+            if (key) {
+                duration[key] = input;
+            } else {
+                duration.milliseconds = input;
+            }
+        } else if (!!(match = aspNetRegex.exec(input))) {
+            sign = (match[1] === '-') ? -1 : 1;
+            duration = {
+                y: 0,
+                d: toInt(match[DATE]) * sign,
+                h: toInt(match[HOUR]) * sign,
+                m: toInt(match[MINUTE]) * sign,
+                s: toInt(match[SECOND]) * sign,
+                ms: toInt(match[MILLISECOND]) * sign
+            };
+        } else if (!!(match = create__isoRegex.exec(input))) {
+            sign = (match[1] === '-') ? -1 : 1;
+            duration = {
+                y: parseIso(match[2], sign),
+                M: parseIso(match[3], sign),
+                d: parseIso(match[4], sign),
+                h: parseIso(match[5], sign),
+                m: parseIso(match[6], sign),
+                s: parseIso(match[7], sign),
+                w: parseIso(match[8], sign)
+            };
+        } else if (duration == null) {// checks for null or undefined
+            duration = {};
+        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
+            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));
+
+            duration = {};
+            duration.ms = diffRes.milliseconds;
+            duration.M = diffRes.months;
+        }
+
+        ret = new Duration(duration);
+
+        if (isDuration(input) && hasOwnProp(input, '_locale')) {
+            ret._locale = input._locale;
+        }
+
+        return ret;
+    }
+
+    create__createDuration.fn = Duration.prototype;
+
+    function parseIso(inp, sign) {
+        // We'd normally use ~~inp for this, but unfortunately it also
+        // converts floats to ints.
+        // inp may be undefined, so careful calling replace on it.
+        var res = inp && parseFloat(inp.replace(',', '.'));
+        // apply sign while we're at it
+        return (isNaN(res) ? 0 : res) * sign;
+    }
+
+    function positiveMomentsDifference(base, other) {
+        var res = { milliseconds: 0, months: 0 };
+
+        res.months = other.month() - base.month() +
+            (other.year() - base.year()) * 12;
+        if (base.clone().add(res.months, 'M').isAfter(other)) {
+            --res.months;
+        }
+
+        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
+
+        return res;
+    }
+
+    function momentsDifference(base, other) {
+        var res;
+        other = cloneWithOffset(other, base);
+        if (base.isBefore(other)) {
+            res = positiveMomentsDifference(base, other);
+        } else {
+            res = positiveMomentsDifference(other, base);
+            res.milliseconds = -res.milliseconds;
+            res.months = -res.months;
+        }
+
+        return res;
+    }
+
+    function createAdder(direction, name) {
+        return function (val, period) {
+            var dur, tmp;
+            //invert the arguments, but complain about it
+            if (period !== null && !isNaN(+period)) {
+                deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
+                tmp = val; val = period; period = tmp;
+            }
+
+            val = typeof val === 'string' ? +val : val;
+            dur = create__createDuration(val, period);
+            add_subtract__addSubtract(this, dur, direction);
+            return this;
+        };
+    }
+
+    function add_subtract__addSubtract(mom, duration, isAdding, updateOffset) {
+        var milliseconds = duration._milliseconds,
+            days = duration._days,
+            months = duration._months;
+        updateOffset = updateOffset == null ? true : updateOffset;
+
+        if (milliseconds) {
+            mom._d.setTime(+mom._d + milliseconds * isAdding);
+        }
+        if (days) {
+            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
+        }
+        if (months) {
+            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);
+        }
+        if (updateOffset) {
+            utils_hooks__hooks.updateOffset(mom, days || months);
+        }
+    }
+
+    var add_subtract__add = createAdder(1, 'add');
+    var add_subtract__subtract = createAdder(-1, 'subtract');
+
+    function moment_calendar__calendar(time, formats) {
+        // We want to compare the start of today, vs this.
+        // Getting start-of-today depends on whether we're local/utc/offset or not.
+        var now = time || local__createLocal(),
+            sod = cloneWithOffset(now, this).startOf('day'),
+            diff = this.diff(sod, 'days', true),
+            format = diff < -6 ? 'sameElse' :
+                diff < -1 ? 'lastWeek' :
+                diff < 0 ? 'lastDay' :
+                diff < 1 ? 'sameDay' :
+                diff < 2 ? 'nextDay' :
+                diff < 7 ? 'nextWeek' : 'sameElse';
+        return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));
+    }
+
+    function clone() {
+        return new Moment(this);
+    }
+
+    function isAfter(input, units) {
+        var inputMs;
+        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
+        if (units === 'millisecond') {
+            input = isMoment(input) ? input : local__createLocal(input);
+            return +this > +input;
+        } else {
+            inputMs = isMoment(input) ? +input : +local__createLocal(input);
+            return inputMs < +this.clone().startOf(units);
+        }
+    }
+
+    function isBefore(input, units) {
+        var inputMs;
+        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
+        if (units === 'millisecond') {
+            input = isMoment(input) ? input : local__createLocal(input);
+            return +this < +input;
+        } else {
+            inputMs = isMoment(input) ? +input : +local__createLocal(input);
+            return +this.clone().endOf(units) < inputMs;
+        }
+    }
+
+    function isBetween(from, to, units) {
+        return this.isAfter(from, units) && this.isBefore(to, units);
+    }
+
+    function isSame(input, units) {
+        var inputMs;
+        units = normalizeUnits(units || 'millisecond');
+        if (units === 'millisecond') {
+            input = isMoment(input) ? input : local__createLocal(input);
+            return +this === +input;
+        } else {
+            inputMs = +local__createLocal(input);
+            return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
+        }
+    }
+
+    function diff(input, units, asFloat) {
+        var that = cloneWithOffset(input, this),
+            zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,
+            delta, output;
+
+        units = normalizeUnits(units);
+
+        if (units === 'year' || units === 'month' || units === 'quarter') {
+            output = monthDiff(this, that);
+            if (units === 'quarter') {
+                output = output / 3;
+            } else if (units === 'year') {
+                output = output / 12;
+            }
+        } else {
+            delta = this - that;
+            output = units === 'second' ? delta / 1e3 : // 1000
+                units === 'minute' ? delta / 6e4 : // 1000 * 60
+                units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
+                units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
+                units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
+                delta;
+        }
+        return asFloat ? output : absFloor(output);
+    }
+
+    function monthDiff(a, b) {
+        // difference in months
+        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
+            // b is in (anchor - 1 month, anchor + 1 month)
+            anchor = a.clone().add(wholeMonthDiff, 'months'),
+            anchor2, adjust;
+
+        if (b - anchor < 0) {
+            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
+            // linear across the month
+            adjust = (b - anchor) / (anchor - anchor2);
+        } else {
+            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
+            // linear across the month
+            adjust = (b - anchor) / (anchor2 - anchor);
+        }
+
+        return -(wholeMonthDiff + adjust);
+    }
+
+    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
+
+    function toString() {
+        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
+    }
+
+    function moment_format__toISOString() {
+        var m = this.clone().utc();
+        if (0 < m.year() && m.year() <= 9999) {
+            if ('function' === typeof Date.prototype.toISOString) {
+                // native implementation is ~50x faster, use it when we can
+                return this.toDate().toISOString();
+            } else {
+                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
+            }
+        } else {
+            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
+        }
+    }
+
+    function format(inputString) {
+        var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);
+        return this.localeData().postformat(output);
+    }
+
+    function from(time, withoutSuffix) {
+        if (!this.isValid()) {
+            return this.localeData().invalidDate();
+        }
+        return create__createDuration({ to: this, from: time }).locale(this.locale()).humanize(!withoutSuffix);
+    }
+
+    function fromNow(withoutSuffix) {
+        return this.from(local__createLocal(), withoutSuffix);
+    }
+
+    function to(time, withoutSuffix) {
+        if (!this.isValid()) {
+            return this.localeData().invalidDate();
+        }
+        return create__createDuration({ from: this, to: time }).locale(this.locale()).humanize(!withoutSuffix);
+    }
+
+    function toNow(withoutSuffix) {
+        return this.to(local__createLocal(), withoutSuffix);
+    }
+
+    function locale(key) {
+        var newLocaleData;
+
+        if (key === undefined) {
+            return this._locale._abbr;
+        } else {
+            newLocaleData = locale_locales__getLocale(key);
+            if (newLocaleData != null) {
+                this._locale = newLocaleData;
+            }
+            return this;
+        }
+    }
+
+    var lang = deprecate(
+        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
+        function (key) {
+            if (key === undefined) {
+                return this.localeData();
+            } else {
+                return this.locale(key);
+            }
+        }
+    );
+
+    function localeData() {
+        return this._locale;
+    }
+
+    function startOf(units) {
+        units = normalizeUnits(units);
+        // the following switch intentionally omits break keywords
+        // to utilize falling through the cases.
+        switch (units) {
+            case 'year':
+                this.month(0);
+                /* falls through */
+            case 'quarter':
+            case 'month':
+                this.date(1);
+                /* falls through */
+            case 'week':
+            case 'isoWeek':
+            case 'day':
+                this.hours(0);
+                /* falls through */
+            case 'hour':
+                this.minutes(0);
+                /* falls through */
+            case 'minute':
+                this.seconds(0);
+                /* falls through */
+            case 'second':
+                this.milliseconds(0);
+        }
+
+        // weeks are a special case
+        if (units === 'week') {
+            this.weekday(0);
+        }
+        if (units === 'isoWeek') {
+            this.isoWeekday(1);
+        }
+
+        // quarters are also special
+        if (units === 'quarter') {
+            this.month(Math.floor(this.month() / 3) * 3);
+        }
+
+        return this;
+    }
+
+    function endOf(units) {
+        units = normalizeUnits(units);
+        if (units === undefined || units === 'millisecond') {
+            return this;
+        }
+        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
+    }
+
+    function to_type__valueOf() {
+        return +this._d - ((this._offset || 0) * 60000);
+    }
+
+    function unix() {
+        return Math.floor(+this / 1000);
+    }
+
+    function toDate() {
+        return this._offset ? new Date(+this) : this._d;
+    }
+
+    function toArray() {
+        var m = this;
+        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
+    }
+
+    function toObject() {
+        var m = this;
+        return {
+            years: m.year(),
+            months: m.month(),
+            date: m.date(),
+            hours: m.hours(),
+            minutes: m.minutes(),
+            seconds: m.seconds(),
+            milliseconds: m.milliseconds()
+        };
+    }
+
+    function moment_valid__isValid() {
+        return valid__isValid(this);
+    }
 
-        function dayOfYearFromWeekInfo(config) {
-            var w, weekYear, week, weekday, dow, doy, temp, lang;
+    function parsingFlags() {
+        return extend({}, getParsingFlags(this));
+    }
 
-            w = config._w;
-            if (w.GG != null || w.W != null || w.E != null) {
-                dow = 1;
-                doy = 4;
+    function invalidAt() {
+        return getParsingFlags(this).overflow;
+    }
 
-                // TODO: We need to take the current isoWeekYear, but that depends on
-                // how we interpret now (local, utc, fixed offset). So create
-                // a now version of current config (take local/utc/offset flags, and
-                // create now).
-                weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);
-                week = dfl(w.W, 1);
-                weekday = dfl(w.E, 1);
-            } else {
-                lang = getLangDefinition(config._l);
-                dow = lang._week.dow;
-                doy = lang._week.doy;
-
-                weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
-                week = dfl(w.w, 1);
-
-                if (w.d != null) {
-                    // weekday -- low day numbers are considered next week
-                    weekday = w.d;
-                    if (weekday < dow) {
-                        ++week;
-                    }
-                } else if (w.e != null) {
-                    // local weekday -- counting starts from begining of week
-                    weekday = w.e + dow;
-                } else {
-                    // default to begining of week
-                    weekday = dow;
-                }
-            }
-            temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
+    addFormatToken(0, ['gg', 2], 0, function () {
+        return this.weekYear() % 100;
+    });
 
-            config._a[YEAR] = temp.year;
-            config._dayOfYear = temp.dayOfYear;
-        }
+    addFormatToken(0, ['GG', 2], 0, function () {
+        return this.isoWeekYear() % 100;
+    });
 
-        // convert an array to a date.
-        // the array should mirror the parameters below
-        // note: all values past the year are optional and will default to the lowest possible value.
-        // [year, month, day , hour, minute, second, millisecond]
-        function dateFromConfig(config) {
-            var i, date, input = [], currentDate, yearToUse;
+    function addWeekYearFormatToken(token, getter) {
+        addFormatToken(0, [token, token.length], 0, getter);
+    }
 
-            if (config._d) {
-                return;
-            }
+    addWeekYearFormatToken('gggg', 'weekYear');
+    addWeekYearFormatToken('ggggg', 'weekYear');
+    addWeekYearFormatToken('GGGG', 'isoWeekYear');
+    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
 
-            currentDate = currentDateArray(config);
+    // ALIASES
 
-            //compute day of the year from weeks and weekdays
-            if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
-                dayOfYearFromWeekInfo(config);
-            }
+    addUnitAlias('weekYear', 'gg');
+    addUnitAlias('isoWeekYear', 'GG');
 
-            //if the day of the year is set, figure out what it is
-            if (config._dayOfYear) {
-                yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);
+    // PARSING
 
-                if (config._dayOfYear > daysInYear(yearToUse)) {
-                    config._pf._overflowDayOfYear = true;
-                }
+    addRegexToken('G', matchSigned);
+    addRegexToken('g', matchSigned);
+    addRegexToken('GG', match1to2, match2);
+    addRegexToken('gg', match1to2, match2);
+    addRegexToken('GGGG', match1to4, match4);
+    addRegexToken('gggg', match1to4, match4);
+    addRegexToken('GGGGG', match1to6, match6);
+    addRegexToken('ggggg', match1to6, match6);
 
-                date = makeUTCDate(yearToUse, 0, config._dayOfYear);
-                config._a[MONTH] = date.getUTCMonth();
-                config._a[DATE] = date.getUTCDate();
-            }
+    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
+        week[token.substr(0, 2)] = toInt(input);
+    });
 
-            // Default to current date.
-            // * if no year, month, day of month are given, default to today
-            // * if day of month is given, default month and year
-            // * if month is given, default only year
-            // * if year is given, don't default anything
-            for (i = 0; i < 3 && config._a[i] == null; ++i) {
-                config._a[i] = input[i] = currentDate[i];
-            }
+    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
+        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
+    });
 
-            // Zero out whatever was not defaulted, including time
-            for (; i < 7; i++) {
-                config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
-            }
+    // HELPERS
 
-            config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
-            // Apply timezone offset from input. The actual zone can be changed
-            // with parseZone.
-            if (config._tzm != null) {
-                config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm);
-            }
-        }
+    function weeksInYear(year, dow, doy) {
+        return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;
+    }
 
-        function dateFromObject(config) {
-            var normalizedInput;
+    // MOMENTS
 
-            if (config._d) {
-                return;
-            }
+    function getSetWeekYear(input) {
+        var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
+        return input == null ? year : this.add((input - year), 'y');
+    }
 
-            normalizedInput = normalizeObjectUnits(config._i);
-            config._a = [
-                normalizedInput.year,
-                normalizedInput.month,
-                normalizedInput.day,
-                normalizedInput.hour,
-                normalizedInput.minute,
-                normalizedInput.second,
-                normalizedInput.millisecond
-            ];
-
-            dateFromConfig(config);
-        }
-
-        function currentDateArray(config) {
-            var now = new Date();
-            if (config._useUTC) {
-                return [
-                    now.getUTCFullYear(),
-                    now.getUTCMonth(),
-                    now.getUTCDate()
-                ];
-            } else {
-                return [now.getFullYear(), now.getMonth(), now.getDate()];
-            }
-        }
+    function getSetISOWeekYear(input) {
+        var year = weekOfYear(this, 1, 4).year;
+        return input == null ? year : this.add((input - year), 'y');
+    }
 
-        // date from string and format string
-        function makeDateFromStringAndFormat(config) {
-            if (config._f === moment.ISO_8601) {
-                parseISO(config);
-                return;
-            }
+    function getISOWeeksInYear() {
+        return weeksInYear(this.year(), 1, 4);
+    }
 
-            config._a = [];
-            config._pf.empty = true;
+    function getWeeksInYear() {
+        var weekInfo = this.localeData()._week;
+        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
+    }
 
-            // This array is used to make a Date, either with `new Date` or `Date.UTC`
-            var lang = getLangDefinition(config._l),
-                string = '' + config._i,
-                i, parsedInput, tokens, token, skipped,
-                stringLength = string.length,
-                totalParsedInputLength = 0;
+    addFormatToken('Q', 0, 0, 'quarter');
 
-            tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
+    // ALIASES
 
-            for (i = 0; i < tokens.length; i++) {
-                token = tokens[i];
-                parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
-                if (parsedInput) {
-                    skipped = string.substr(0, string.indexOf(parsedInput));
-                    if (skipped.length > 0) {
-                        config._pf.unusedInput.push(skipped);
-                    }
-                    string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
-                    totalParsedInputLength += parsedInput.length;
-                }
-                // don't parse if it's not a known token
-                if (formatTokenFunctions[token]) {
-                    if (parsedInput) {
-                        config._pf.empty = false;
-                    }
-                    else {
-                        config._pf.unusedTokens.push(token);
-                    }
-                    addTimeToArrayFromToken(token, parsedInput, config);
-                }
-                else if (config._strict && !parsedInput) {
-                    config._pf.unusedTokens.push(token);
-                }
-            }
+    addUnitAlias('quarter', 'Q');
 
-            // add remaining unparsed input length to the string
-            config._pf.charsLeftOver = stringLength - totalParsedInputLength;
-            if (string.length > 0) {
-                config._pf.unusedInput.push(string);
-            }
+    // PARSING
 
-            // handle am pm
-            if (config._isPm && config._a[HOUR] < 12) {
-                config._a[HOUR] += 12;
-            }
-            // if is 12 am, change hours to 0
-            if (config._isPm === false && config._a[HOUR] === 12) {
-                config._a[HOUR] = 0;
-            }
+    addRegexToken('Q', match1);
+    addParseToken('Q', function (input, array) {
+        array[MONTH] = (toInt(input) - 1) * 3;
+    });
 
-            dateFromConfig(config);
-            checkOverflow(config);
-        }
+    // MOMENTS
 
-        function unescapeFormat(s) {
-            return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
-                return p1 || p2 || p3 || p4;
-            });
-        }
+    function getSetQuarter(input) {
+        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
+    }
 
-        // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
-        function regexpEscape(s) {
-            return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
-        }
+    addFormatToken('D', ['DD', 2], 'Do', 'date');
 
-        // date from string and array of format strings
-        function makeDateFromStringAndArray(config) {
-            var tempConfig,
-                bestMoment,
+    // ALIASES
 
-                scoreToBeat,
-                i,
-                currentScore;
+    addUnitAlias('date', 'D');
 
-            if (config._f.length === 0) {
-                config._pf.invalidFormat = true;
-                config._d = new Date(NaN);
-                return;
-            }
+    // PARSING
 
-            for (i = 0; i < config._f.length; i++) {
-                currentScore = 0;
-                tempConfig = extend({}, config);
-                tempConfig._pf = defaultParsingFlags();
-                tempConfig._f = config._f[i];
-                makeDateFromStringAndFormat(tempConfig);
+    addRegexToken('D', match1to2);
+    addRegexToken('DD', match1to2, match2);
+    addRegexToken('Do', function (isStrict, locale) {
+        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
+    });
 
-                if (!isValid(tempConfig)) {
-                    continue;
-                }
+    addParseToken(['D', 'DD'], DATE);
+    addParseToken('Do', function (input, array) {
+        array[DATE] = toInt(input.match(match1to2)[0], 10);
+    });
 
-                // if there is any input that was not parsed add a penalty for that format
-                currentScore += tempConfig._pf.charsLeftOver;
+    // MOMENTS
 
-                //or tokens
-                currentScore += tempConfig._pf.unusedTokens.length * 10;
+    var getSetDayOfMonth = makeGetSet('Date', true);
 
-                tempConfig._pf.score = currentScore;
+    addFormatToken('d', 0, 'do', 'day');
 
-                if (scoreToBeat == null || currentScore < scoreToBeat) {
-                    scoreToBeat = currentScore;
-                    bestMoment = tempConfig;
-                }
-            }
+    addFormatToken('dd', 0, 0, function (format) {
+        return this.localeData().weekdaysMin(this, format);
+    });
 
-            extend(config, bestMoment || tempConfig);
-        }
+    addFormatToken('ddd', 0, 0, function (format) {
+        return this.localeData().weekdaysShort(this, format);
+    });
 
-        // date from iso format
-        function parseISO(config) {
-            var i, l,
-                string = config._i,
-                match = isoRegex.exec(string);
+    addFormatToken('dddd', 0, 0, function (format) {
+        return this.localeData().weekdays(this, format);
+    });
 
-            if (match) {
-                config._pf.iso = true;
-                for (i = 0, l = isoDates.length; i < l; i++) {
-                    if (isoDates[i][1].exec(string)) {
-                        // match[5] should be "T" or undefined
-                        config._f = isoDates[i][0] + (match[6] || ' ');
-                        break;
-                    }
-                }
-                for (i = 0, l = isoTimes.length; i < l; i++) {
-                    if (isoTimes[i][1].exec(string)) {
-                        config._f += isoTimes[i][0];
-                        break;
-                    }
-                }
-                if (string.match(parseTokenTimezone)) {
-                    config._f += 'Z';
-                }
-                makeDateFromStringAndFormat(config);
-            } else {
-                config._isValid = false;
-            }
-        }
+    addFormatToken('e', 0, 0, 'weekday');
+    addFormatToken('E', 0, 0, 'isoWeekday');
 
-        // date from iso format or fallback
-        function makeDateFromString(config) {
-            parseISO(config);
-            if (config._isValid === false) {
-                delete config._isValid;
-                moment.createFromInputFallback(config);
-            }
-        }
+    // ALIASES
 
-        function makeDateFromInput(config) {
-            var input = config._i, matched;
-            if (input === undefined) {
-                config._d = new Date();
-            } else if (isDate(input)) {
-                config._d = new Date(+input);
-            } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
-                config._d = new Date(+matched[1]);
-            } else if (typeof input === 'string') {
-                makeDateFromString(config);
-            } else if (isArray(input)) {
-                config._a = input.slice(0);
-                dateFromConfig(config);
-            } else if (typeof (input) === 'object') {
-                dateFromObject(config);
-            } else if (typeof (input) === 'number') {
-                // from milliseconds
-                config._d = new Date(input);
-            } else {
-                moment.createFromInputFallback(config);
-            }
-        }
+    addUnitAlias('day', 'd');
+    addUnitAlias('weekday', 'e');
+    addUnitAlias('isoWeekday', 'E');
 
-        function makeDate(y, m, d, h, M, s, ms) {
-            //can't just apply() to create a date:
-            //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
-            var date = new Date(y, m, d, h, M, s, ms);
+    // PARSING
 
-            //the date constructor doesn't accept years < 1970
-            if (y < 1970) {
-                date.setFullYear(y);
-            }
-            return date;
-        }
+    addRegexToken('d', match1to2);
+    addRegexToken('e', match1to2);
+    addRegexToken('E', match1to2);
+    addRegexToken('dd', matchWord);
+    addRegexToken('ddd', matchWord);
+    addRegexToken('dddd', matchWord);
 
-        function makeUTCDate(y) {
-            var date = new Date(Date.UTC.apply(null, arguments));
-            if (y < 1970) {
-                date.setUTCFullYear(y);
-            }
-            return date;
+    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {
+        var weekday = config._locale.weekdaysParse(input);
+        // if we didn't get a weekday name, mark the date as invalid
+        if (weekday != null) {
+            week.d = weekday;
+        } else {
+            getParsingFlags(config).invalidWeekday = input;
         }
+    });
 
-        function parseWeekday(input, language) {
-            if (typeof input === 'string') {
-                if (!isNaN(input)) {
-                    input = parseInt(input, 10);
-                }
-                else {
-                    input = language.weekdaysParse(input);
-                    if (typeof input !== 'number') {
-                        return null;
-                    }
-                }
-            }
-            return input;
-        }
+    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
+        week[token] = toInt(input);
+    });
 
-        /************************************
-            Relative Time
-        ************************************/
+    // HELPERS
 
+    function parseWeekday(input, locale) {
+        if (typeof input !== 'string') {
+            return input;
+        }
 
-        // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
-        function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
-            return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
+        if (!isNaN(input)) {
+            return parseInt(input, 10);
         }
 
-        function relativeTime(posNegDuration, withoutSuffix, lang) {
-            var duration = moment.duration(posNegDuration).abs(),
-                seconds = round(duration.as('s')),
-                minutes = round(duration.as('m')),
-                hours = round(duration.as('h')),
-                days = round(duration.as('d')),
-                months = round(duration.as('M')),
-                years = round(duration.as('y')),
+        input = locale.weekdaysParse(input);
+        if (typeof input === 'number') {
+            return input;
+        }
 
-                args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
-                    minutes === 1 && ['m'] ||
-                    minutes < relativeTimeThresholds.m && ['mm', minutes] ||
-                    hours === 1 && ['h'] ||
-                    hours < relativeTimeThresholds.h && ['hh', hours] ||
-                    days === 1 && ['d'] ||
-                    days < relativeTimeThresholds.d && ['dd', days] ||
-                    months === 1 && ['M'] ||
-                    months < relativeTimeThresholds.M && ['MM', months] ||
-                    years === 1 && ['y'] || ['yy', years];
+        return null;
+    }
 
-            args[2] = withoutSuffix;
-            args[3] = +posNegDuration > 0;
-            args[4] = lang;
-            return substituteTimeAgo.apply({}, args);
-        }
+    // LOCALES
 
+    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
+    function localeWeekdays(m) {
+        return this._weekdays[m.day()];
+    }
 
-        /************************************
-            Week of Year
-        ************************************/
+    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
+    function localeWeekdaysShort(m) {
+        return this._weekdaysShort[m.day()];
+    }
 
+    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
+    function localeWeekdaysMin(m) {
+        return this._weekdaysMin[m.day()];
+    }
 
-        // firstDayOfWeek       0 = sun, 6 = sat
-        //                      the day of the week that starts the week
-        //                      (usually sunday or monday)
-        // firstDayOfWeekOfYear 0 = sun, 6 = sat
-        //                      the first week is the week that contains the first
-        //                      of this day of the week
-        //                      (eg. ISO weeks use thursday (4))
-        function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
-            var end = firstDayOfWeekOfYear - firstDayOfWeek,
-                daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
-                adjustedMoment;
+    function localeWeekdaysParse(weekdayName) {
+        var i, mom, regex;
 
+        this._weekdaysParse = this._weekdaysParse || [];
 
-            if (daysToDayOfWeek > end) {
-                daysToDayOfWeek -= 7;
+        for (i = 0; i < 7; i++) {
+            // make the regex if we don't have it already
+            if (!this._weekdaysParse[i]) {
+                mom = local__createLocal([2000, 1]).day(i);
+                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
+                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
             }
-
-            if (daysToDayOfWeek < end - 7) {
-                daysToDayOfWeek += 7;
+            // test the regex
+            if (this._weekdaysParse[i].test(weekdayName)) {
+                return i;
             }
-
-            adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
-            return {
-                week: Math.ceil(adjustedMoment.dayOfYear() / 7),
-                year: adjustedMoment.year()
-            };
         }
+    }
 
-        //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
-        function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
-            var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;
-
-            d = d === 0 ? 7 : d;
-            weekday = weekday != null ? weekday : firstDayOfWeek;
-            daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
-            dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
+    // MOMENTS
 
-            return {
-                year: dayOfYear > 0 ? year : year - 1,
-                dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
-            };
+    function getSetDayOfWeek(input) {
+        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
+        if (input != null) {
+            input = parseWeekday(input, this.localeData());
+            return this.add(input - day, 'd');
+        } else {
+            return day;
         }
+    }
 
-        /************************************
-            Top Level Functions
-        ************************************/
-
-        function makeMoment(config) {
-            var input = config._i,
-                format = config._f;
+    function getSetLocaleDayOfWeek(input) {
+        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
+        return input == null ? weekday : this.add(input - weekday, 'd');
+    }
 
-            if (input === null || (format === undefined && input === '')) {
-                return moment.invalid({ nullInput: true });
-            }
+    function getSetISODayOfWeek(input) {
+        // behaves the same as moment#day except
+        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
+        // as a setter, sunday should belong to the previous week.
+        return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
+    }
 
-            if (typeof input === 'string') {
-                config._i = input = getLangDefinition().preparse(input);
-            }
+    addFormatToken('H', ['HH', 2], 0, 'hour');
+    addFormatToken('h', ['hh', 2], 0, function () {
+        return this.hours() % 12 || 12;
+    });
 
-            if (moment.isMoment(input)) {
-                config = cloneMoment(input);
+    function meridiem(token, lowercase) {
+        addFormatToken(token, 0, 0, function () {
+            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
+        });
+    }
 
-                config._d = new Date(+input._d);
-            } else if (format) {
-                if (isArray(format)) {
-                    makeDateFromStringAndArray(config);
-                } else {
-                    makeDateFromStringAndFormat(config);
-                }
-            } else {
-                makeDateFromInput(config);
-            }
+    meridiem('a', true);
+    meridiem('A', false);
 
-            return new Moment(config);
-        }
+    // ALIASES
 
-        moment = function (input, format, lang, strict) {
-            var c;
+    addUnitAlias('hour', 'h');
 
-            if (typeof (lang) === 'boolean') {
-                strict = lang;
-                lang = undefined;
-            }
-            // object construction must be done this way.
-            // https://github.com/moment/moment/issues/1423
-            c = {};
-            c._isAMomentObject = true;
-            c._i = input;
-            c._f = format;
-            c._l = lang;
-            c._strict = strict;
-            c._isUTC = false;
-            c._pf = defaultParsingFlags();
-
-            return makeMoment(c);
-        };
+    // PARSING
 
-        moment.suppressDeprecationWarnings = true;
+    function matchMeridiem(isStrict, locale) {
+        return locale._meridiemParse;
+    }
 
-        moment.createFromInputFallback = deprecate(
-            'moment construction falls back to js Date. This is ' +
-            'discouraged and will be removed in upcoming major ' +
-            'release. Please refer to ' +
-            'https://github.com/moment/moment/issues/1407 for more info.',
-            function (config) {
-                config._d = new Date(config._i);
-            }
-        );
+    addRegexToken('a', matchMeridiem);
+    addRegexToken('A', matchMeridiem);
+    addRegexToken('H', match1to2);
+    addRegexToken('h', match1to2);
+    addRegexToken('HH', match1to2, match2);
+    addRegexToken('hh', match1to2, match2);
+
+    addParseToken(['H', 'HH'], HOUR);
+    addParseToken(['a', 'A'], function (input, array, config) {
+        config._isPm = config._locale.isPM(input);
+        config._meridiem = input;
+    });
+    addParseToken(['h', 'hh'], function (input, array, config) {
+        array[HOUR] = toInt(input);
+        getParsingFlags(config).bigHour = true;
+    });
+
+    // LOCALES
+
+    function localeIsPM(input) {
+        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
+        // Using charAt should be more compatible.
+        return ((input + '').toLowerCase().charAt(0) === 'p');
+    }
 
-        // Pick a moment m from moments so that m[fn](other) is true for all
-        // other. This relies on the function fn to be transitive.
-        //
-        // moments should either be an array of moment objects or an array, whose
-        // first element is an array of moment objects.
-        function pickBy(fn, moments) {
-            var res, i;
-            if (moments.length === 1 && isArray(moments[0])) {
-                moments = moments[0];
-            }
-            if (!moments.length) {
-                return moment();
-            }
-            res = moments[0];
-            for (i = 1; i < moments.length; ++i) {
-                if (moments[i][fn](res)) {
-                    res = moments[i];
-                }
-            }
-            return res;
+    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
+    function localeMeridiem(hours, minutes, isLower) {
+        if (hours > 11) {
+            return isLower ? 'pm' : 'PM';
+        } else {
+            return isLower ? 'am' : 'AM';
         }
+    }
 
-        moment.min = function () {
-            var args = [].slice.call(arguments, 0);
-
-            return pickBy('isBefore', args);
-        };
 
-        moment.max = function () {
-            var args = [].slice.call(arguments, 0);
+    // MOMENTS
 
-            return pickBy('isAfter', args);
-        };
+    // Setting the hour should keep the time, because the user explicitly
+    // specified which hour he wants. So trying to maintain the same hour (in
+    // a new timezone) makes sense. Adding/subtracting hours does not follow
+    // this rule.
+    var getSetHour = makeGetSet('Hours', true);
 
-        // creating with utc
-        moment.utc = function (input, format, lang, strict) {
-            var c;
+    addFormatToken('m', ['mm', 2], 0, 'minute');
 
-            if (typeof (lang) === 'boolean') {
-                strict = lang;
-                lang = undefined;
-            }
-            // object construction must be done this way.
-            // https://github.com/moment/moment/issues/1423
-            c = {};
-            c._isAMomentObject = true;
-            c._useUTC = true;
-            c._isUTC = true;
-            c._l = lang;
-            c._i = input;
-            c._f = format;
-            c._strict = strict;
-            c._pf = defaultParsingFlags();
-
-            return makeMoment(c).utc();
-        };
+    // ALIASES
 
-        // creating with unix timestamp (in seconds)
-        moment.unix = function (input) {
-            return moment(input * 1000);
-        };
+    addUnitAlias('minute', 'm');
 
-        // duration
-        moment.duration = function (input, key) {
-            var duration = input,
-                // matching against regexp is expensive, do it on demand
-                match = null,
-                sign,
-                ret,
-                parseIso,
-                diffRes;
-
-            if (moment.isDuration(input)) {
-                duration = {
-                    ms: input._milliseconds,
-                    d: input._days,
-                    M: input._months
-                };
-            } else if (typeof input === 'number') {
-                duration = {};
-                if (key) {
-                    duration[key] = input;
-                } else {
-                    duration.milliseconds = input;
-                }
-            } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
-                sign = (match[1] === '-') ? -1 : 1;
-                duration = {
-                    y: 0,
-                    d: toInt(match[DATE]) * sign,
-                    h: toInt(match[HOUR]) * sign,
-                    m: toInt(match[MINUTE]) * sign,
-                    s: toInt(match[SECOND]) * sign,
-                    ms: toInt(match[MILLISECOND]) * sign
-                };
-            } else if (!!(match = isoDurationRegex.exec(input))) {
-                sign = (match[1] === '-') ? -1 : 1;
-                parseIso = function (inp) {
-                    // We'd normally use ~~inp for this, but unfortunately it also
-                    // converts floats to ints.
-                    // inp may be undefined, so careful calling replace on it.
-                    var res = inp && parseFloat(inp.replace(',', '.'));
-                    // apply sign while we're at it
-                    return (isNaN(res) ? 0 : res) * sign;
-                };
-                duration = {
-                    y: parseIso(match[2]),
-                    M: parseIso(match[3]),
-                    d: parseIso(match[4]),
-                    h: parseIso(match[5]),
-                    m: parseIso(match[6]),
-                    s: parseIso(match[7]),
-                    w: parseIso(match[8])
-                };
-            } else if (typeof duration === 'object' &&
-                    ('from' in duration || 'to' in duration)) {
-                diffRes = momentsDifference(moment(duration.from), moment(duration.to));
-
-                duration = {};
-                duration.ms = diffRes.milliseconds;
-                duration.M = diffRes.months;
-            }
+    // PARSING
 
-            ret = new Duration(duration);
+    addRegexToken('m', match1to2);
+    addRegexToken('mm', match1to2, match2);
+    addParseToken(['m', 'mm'], MINUTE);
 
-            if (moment.isDuration(input) && input.hasOwnProperty('_lang')) {
-                ret._lang = input._lang;
-            }
+    // MOMENTS
 
-            return ret;
-        };
+    var getSetMinute = makeGetSet('Minutes', false);
 
-        // version number
-        moment.version = VERSION;
+    addFormatToken('s', ['ss', 2], 0, 'second');
 
-        // default format
-        moment.defaultFormat = isoFormat;
+    // ALIASES
 
-        // constant that refers to the ISO standard
-        moment.ISO_8601 = function () { };
+    addUnitAlias('second', 's');
 
-        // Plugins that add properties should also add the key here (null value),
-        // so we can properly clone ourselves.
-        moment.momentProperties = momentProperties;
+    // PARSING
 
-        // This function will be called whenever a moment is mutated.
-        // It is intended to keep the offset in sync with the timezone.
-        moment.updateOffset = function () { };
+    addRegexToken('s', match1to2);
+    addRegexToken('ss', match1to2, match2);
+    addParseToken(['s', 'ss'], SECOND);
 
-        // This function allows you to set a threshold for relative time strings
-        moment.relativeTimeThreshold = function (threshold, limit) {
-            if (relativeTimeThresholds[threshold] === undefined) {
-                return false;
-            }
-            if (limit === undefined) {
-                return relativeTimeThresholds[threshold];
-            }
-            relativeTimeThresholds[threshold] = limit;
-            return true;
-        };
+    // MOMENTS
 
-        // This function will load languages and then set the global language.  If
-        // no arguments are passed in, it will simply return the current global
-        // language key.
-        moment.lang = function (key, values) {
-            var r;
-            if (!key) {
-                return moment.fn._lang._abbr;
-            }
-            if (values) {
-                loadLang(normalizeLanguage(key), values);
-            } else if (values === null) {
-                unloadLang(key);
-                key = 'en';
-            } else if (!languages[key]) {
-                getLangDefinition(key);
-            }
-            r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
-            return r._abbr;
-        };
+    var getSetSecond = makeGetSet('Seconds', false);
 
-        // returns language data
-        moment.langData = function (key) {
-            if (key && key._lang && key._lang._abbr) {
-                key = key._lang._abbr;
-            }
-            return getLangDefinition(key);
-        };
+    addFormatToken('S', 0, 0, function () {
+        return ~~(this.millisecond() / 100);
+    });
 
-        // compare moment object
-        moment.isMoment = function (obj) {
-            return obj instanceof Moment ||
-                (obj != null && obj.hasOwnProperty('_isAMomentObject'));
-        };
+    addFormatToken(0, ['SS', 2], 0, function () {
+        return ~~(this.millisecond() / 10);
+    });
 
-        // for typechecking Duration objects
-        moment.isDuration = function (obj) {
-            return obj instanceof Duration;
-        };
+    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
+    addFormatToken(0, ['SSSS', 4], 0, function () {
+        return this.millisecond() * 10;
+    });
+    addFormatToken(0, ['SSSSS', 5], 0, function () {
+        return this.millisecond() * 100;
+    });
+    addFormatToken(0, ['SSSSSS', 6], 0, function () {
+        return this.millisecond() * 1000;
+    });
+    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
+        return this.millisecond() * 10000;
+    });
+    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
+        return this.millisecond() * 100000;
+    });
+    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
+        return this.millisecond() * 1000000;
+    });
 
-        for (i = lists.length - 1; i >= 0; --i) {
-            makeList(lists[i]);
-        }
 
-        moment.normalizeUnits = function (units) {
-            return normalizeUnits(units);
-        };
+    // ALIASES
 
-        moment.invalid = function (flags) {
-            var m = moment.utc(NaN);
-            if (flags != null) {
-                extend(m._pf, flags);
-            }
-            else {
-                m._pf.userInvalidated = true;
-            }
+    addUnitAlias('millisecond', 'ms');
 
-            return m;
-        };
+    // PARSING
 
-        moment.parseZone = function () {
-            return moment.apply(null, arguments).parseZone();
-        };
+    addRegexToken('S', match1to3, match1);
+    addRegexToken('SS', match1to3, match2);
+    addRegexToken('SSS', match1to3, match3);
 
-        moment.parseTwoDigitYear = function (input) {
-            return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
-        };
+    var token;
+    for (token = 'SSSS'; token.length <= 9; token += 'S') {
+        addRegexToken(token, matchUnsigned);
+    }
 
-        /************************************
-            Moment Prototype
-        ************************************/
+    function parseMs(input, array) {
+        array[MILLISECOND] = toInt(('0.' + input) * 1000);
+    }
 
+    for (token = 'S'; token.length <= 9; token += 'S') {
+        addParseToken(token, parseMs);
+    }
+    // MOMENTS
 
-        extend(moment.fn = Moment.prototype, {
+    var getSetMillisecond = makeGetSet('Milliseconds', false);
 
-            clone: function () {
-                return moment(this);
-            },
+    addFormatToken('z', 0, 0, 'zoneAbbr');
+    addFormatToken('zz', 0, 0, 'zoneName');
 
-            valueOf: function () {
-                return +this._d + ((this._offset || 0) * 60000);
-            },
+    // MOMENTS
 
-            unix: function () {
-                return Math.floor(+this / 1000);
-            },
+    function getZoneAbbr() {
+        return this._isUTC ? 'UTC' : '';
+    }
 
-            toString: function () {
-                return this.clone().lang('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
-            },
+    function getZoneName() {
+        return this._isUTC ? 'Coordinated Universal Time' : '';
+    }
 
-            toDate: function () {
-                return this._offset ? new Date(+this) : this._d;
-            },
+    var momentPrototype__proto = Moment.prototype;
+
+    momentPrototype__proto.add = add_subtract__add;
+    momentPrototype__proto.calendar = moment_calendar__calendar;
+    momentPrototype__proto.clone = clone;
+    momentPrototype__proto.diff = diff;
+    momentPrototype__proto.endOf = endOf;
+    momentPrototype__proto.format = format;
+    momentPrototype__proto.from = from;
+    momentPrototype__proto.fromNow = fromNow;
+    momentPrototype__proto.to = to;
+    momentPrototype__proto.toNow = toNow;
+    momentPrototype__proto.get = getSet;
+    momentPrototype__proto.invalidAt = invalidAt;
+    momentPrototype__proto.isAfter = isAfter;
+    momentPrototype__proto.isBefore = isBefore;
+    momentPrototype__proto.isBetween = isBetween;
+    momentPrototype__proto.isSame = isSame;
+    momentPrototype__proto.isValid = moment_valid__isValid;
+    momentPrototype__proto.lang = lang;
+    momentPrototype__proto.locale = locale;
+    momentPrototype__proto.localeData = localeData;
+    momentPrototype__proto.max = prototypeMax;
+    momentPrototype__proto.min = prototypeMin;
+    momentPrototype__proto.parsingFlags = parsingFlags;
+    momentPrototype__proto.set = getSet;
+    momentPrototype__proto.startOf = startOf;
+    momentPrototype__proto.subtract = add_subtract__subtract;
+    momentPrototype__proto.toArray = toArray;
+    momentPrototype__proto.toObject = toObject;
+    momentPrototype__proto.toDate = toDate;
+    momentPrototype__proto.toISOString = moment_format__toISOString;
+    momentPrototype__proto.toJSON = moment_format__toISOString;
+    momentPrototype__proto.toString = toString;
+    momentPrototype__proto.unix = unix;
+    momentPrototype__proto.valueOf = to_type__valueOf;
+
+    // Year
+    momentPrototype__proto.year = getSetYear;
+    momentPrototype__proto.isLeapYear = getIsLeapYear;
+
+    // Week Year
+    momentPrototype__proto.weekYear = getSetWeekYear;
+    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;
+
+    // Quarter
+    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;
+
+    // Month
+    momentPrototype__proto.month = getSetMonth;
+    momentPrototype__proto.daysInMonth = getDaysInMonth;
+
+    // Week
+    momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek;
+    momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek;
+    momentPrototype__proto.weeksInYear = getWeeksInYear;
+    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;
+
+    // Day
+    momentPrototype__proto.date = getSetDayOfMonth;
+    momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek;
+    momentPrototype__proto.weekday = getSetLocaleDayOfWeek;
+    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
+    momentPrototype__proto.dayOfYear = getSetDayOfYear;
+
+    // Hour
+    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;
+
+    // Minute
+    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;
+
+    // Second
+    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;
+
+    // Millisecond
+    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;
+
+    // Offset
+    momentPrototype__proto.utcOffset = getSetOffset;
+    momentPrototype__proto.utc = setOffsetToUTC;
+    momentPrototype__proto.local = setOffsetToLocal;
+    momentPrototype__proto.parseZone = setOffsetToParsedOffset;
+    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;
+    momentPrototype__proto.isDST = isDaylightSavingTime;
+    momentPrototype__proto.isDSTShifted = isDaylightSavingTimeShifted;
+    momentPrototype__proto.isLocal = isLocal;
+    momentPrototype__proto.isUtcOffset = isUtcOffset;
+    momentPrototype__proto.isUtc = isUtc;
+    momentPrototype__proto.isUTC = isUtc;
+
+    // Timezone
+    momentPrototype__proto.zoneAbbr = getZoneAbbr;
+    momentPrototype__proto.zoneName = getZoneName;
+
+    // Deprecations
+    momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
+    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
+    momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
+    momentPrototype__proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);
+
+    var momentPrototype = momentPrototype__proto;
+
+    function moment__createUnix(input) {
+        return local__createLocal(input * 1000);
+    }
 
-            toISOString: function () {
-                var m = moment(this).utc();
-                if (0 < m.year() && m.year() <= 9999) {
-                    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
-                } else {
-                    return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
-                }
-            },
-
-            toArray: function () {
-                var m = this;
-                return [
-                    m.year(),
-                    m.month(),
-                    m.date(),
-                    m.hours(),
-                    m.minutes(),
-                    m.seconds(),
-                    m.milliseconds()
-                ];
-            },
-
-            isValid: function () {
-                return isValid(this);
-            },
-
-            isDSTShifted: function () {
-                if (this._a) {
-                    return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
-                }
+    function moment__createInZone() {
+        return local__createLocal.apply(null, arguments).parseZone();
+    }
 
-                return false;
-            },
+    var defaultCalendar = {
+        sameDay: '[Today at] LT',
+        nextDay: '[Tomorrow at] LT',
+        nextWeek: 'dddd [at] LT',
+        lastDay: '[Yesterday at] LT',
+        lastWeek: '[Last] dddd [at] LT',
+        sameElse: 'L'
+    };
+
+    function locale_calendar__calendar(key, mom, now) {
+        var output = this._calendar[key];
+        return typeof output === 'function' ? output.call(mom, now) : output;
+    }
 
-            parsingFlags: function () {
-                return extend({}, this._pf);
-            },
+    var defaultLongDateFormat = {
+        LTS: 'h:mm:ss A',
+        LT: 'h:mm A',
+        L: 'MM/DD/YYYY',
+        LL: 'MMMM D, YYYY',
+        LLL: 'MMMM D, YYYY h:mm A',
+        LLLL: 'dddd, MMMM D, YYYY h:mm A'
+    };
 
-            invalidAt: function () {
-                return this._pf.overflow;
-            },
+    function longDateFormat(key) {
+        var format = this._longDateFormat[key],
+            formatUpper = this._longDateFormat[key.toUpperCase()];
 
-            utc: function (keepLocalTime) {
-                return this.zone(0, keepLocalTime);
-            },
+        if (format || !formatUpper) {
+            return format;
+        }
 
-            local: function (keepLocalTime) {
-                if (this._isUTC) {
-                    this.zone(0, keepLocalTime);
-                    this._isUTC = false;
+        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
+            return val.slice(1);
+        });
 
-                    if (keepLocalTime) {
-                        this.add(this._d.getTimezoneOffset(), 'm');
-                    }
-                }
-                return this;
-            },
-
-            format: function (inputString) {
-                var output = formatMoment(this, inputString || moment.defaultFormat);
-                return this.lang().postformat(output);
-            },
-
-            add: function (input, val) {
-                var dur;
-                // switch args to support add('s', 1) and add(1, 's')
-                if (typeof input === 'string' && typeof val === 'string') {
-                    dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
-                } else if (typeof input === 'string') {
-                    dur = moment.duration(+val, input);
-                } else {
-                    dur = moment.duration(input, val);
-                }
-                addOrSubtractDurationFromMoment(this, dur, 1);
-                return this;
-            },
-
-            subtract: function (input, val) {
-                var dur;
-                // switch args to support subtract('s', 1) and subtract(1, 's')
-                if (typeof input === 'string' && typeof val === 'string') {
-                    dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
-                } else if (typeof input === 'string') {
-                    dur = moment.duration(+val, input);
-                } else {
-                    dur = moment.duration(input, val);
-                }
-                addOrSubtractDurationFromMoment(this, dur, -1);
-                return this;
-            },
-
-            diff: function (input, units, asFloat) {
-                var that = makeAs(input, this),
-                    zoneDiff = (this.zone() - that.zone()) * 6e4,
-                    diff, output;
-
-                units = normalizeUnits(units);
-
-                if (units === 'year' || units === 'month') {
-                    // average number of days in the months in the given dates
-                    diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
-                    // difference in months
-                    output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
-                    // adjust by taking difference in days, average number of days
-                    // and dst in the given months.
-                    output += ((this - moment(this).startOf('month')) -
-                            (that - moment(that).startOf('month'))) / diff;
-                    // same as above but with zones, to negate all dst
-                    output -= ((this.zone() - moment(this).startOf('month').zone()) -
-                            (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff;
-                    if (units === 'year') {
-                        output = output / 12;
-                    }
-                } else {
-                    diff = (this - that);
-                    output = units === 'second' ? diff / 1e3 : // 1000
-                        units === 'minute' ? diff / 6e4 : // 1000 * 60
-                        units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
-                        units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
-                        units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
-                        diff;
-                }
-                return asFloat ? output : absRound(output);
-            },
-
-            from: function (time, withoutSuffix) {
-                return moment.duration({ to: this, from: time }).lang(this.lang()._abbr).humanize(!withoutSuffix);
-            },
-
-            fromNow: function (withoutSuffix) {
-                return this.from(moment(), withoutSuffix);
-            },
-
-            calendar: function (time) {
-                // We want to compare the start of today, vs this.
-                // Getting start-of-today depends on whether we're zone'd or not.
-                var now = time || moment(),
-                    sod = makeAs(now, this).startOf('day'),
-                    diff = this.diff(sod, 'days', true),
-                    format = diff < -6 ? 'sameElse' :
-                        diff < -1 ? 'lastWeek' :
-                        diff < 0 ? 'lastDay' :
-                        diff < 1 ? 'sameDay' :
-                        diff < 2 ? 'nextDay' :
-                        diff < 7 ? 'nextWeek' : 'sameElse';
-                return this.format(this.lang().calendar(format, this));
-            },
-
-            isLeapYear: function () {
-                return isLeapYear(this.year());
-            },
-
-            isDST: function () {
-                return (this.zone() < this.clone().month(0).zone() ||
-                    this.zone() < this.clone().month(5).zone());
-            },
-
-            day: function (input) {
-                var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
-                if (input != null) {
-                    input = parseWeekday(input, this.lang());
-                    return this.add(input - day, 'days');
-                } else {
-                    return day;
-                }
-            },
-
-            month: makeAccessor('Month', true),
-
-            startOf: function (units) {
-                units = normalizeUnits(units);
-                // the following switch intentionally omits break keywords
-                // to utilize falling through the cases.
-                switch (units) {
-                    case 'year':
-                        this.month(0);
-                        /* falls through */
-                    case 'quarter':
-                    case 'month':
-                        this.date(1);
-                        /* falls through */
-                    case 'week':
-                    case 'isoWeek':
-                    case 'day':
-                        this.hours(0);
-                        /* falls through */
-                    case 'hour':
-                        this.minutes(0);
-                        /* falls through */
-                    case 'minute':
-                        this.seconds(0);
-                        /* falls through */
-                    case 'second':
-                        this.milliseconds(0);
-                        /* falls through */
-                }
+        return this._longDateFormat[key];
+    }
 
-                // weeks are a special case
-                if (units === 'week') {
-                    this.weekday(0);
-                } else if (units === 'isoWeek') {
-                    this.isoWeekday(1);
-                }
+    var defaultInvalidDate = 'Invalid date';
 
-                // quarters are also special
-                if (units === 'quarter') {
-                    this.month(Math.floor(this.month() / 3) * 3);
-                }
+    function invalidDate() {
+        return this._invalidDate;
+    }
 
-                return this;
-            },
-
-            endOf: function (units) {
-                units = normalizeUnits(units);
-                return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
-            },
-
-            isAfter: function (input, units) {
-                units = typeof units !== 'undefined' ? units : 'millisecond';
-                return +this.clone().startOf(units) > +moment(input).startOf(units);
-            },
-
-            isBefore: function (input, units) {
-                units = typeof units !== 'undefined' ? units : 'millisecond';
-                return +this.clone().startOf(units) < +moment(input).startOf(units);
-            },
-
-            isSame: function (input, units) {
-                units = units || 'ms';
-                return +this.clone().startOf(units) === +makeAs(input, this).startOf(units);
-            },
-
-            min: deprecate(
-                     'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
-                     function (other) {
-                         other = moment.apply(null, arguments);
-                         return other < this ? this : other;
-                     }
-             ),
-
-            max: deprecate(
-                    'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
-                    function (other) {
-                        other = moment.apply(null, arguments);
-                        return other > this ? this : other;
-                    }
-            ),
-
-            // keepLocalTime = true means only change the timezone, without
-            // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]-->
-            // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone
-            // +0200, so we adjust the time as needed, to be valid.
-            //
-            // Keeping the time actually adds/subtracts (one hour)
-            // from the actual represented time. That is why we call updateOffset
-            // a second time. In case it wants us to change the offset again
-            // _changeInProgress == true case, then we have to adjust, because
-            // there is no such time in the given timezone.
-            zone: function (input, keepLocalTime) {
-                var offset = this._offset || 0,
-                    localAdjust;
-                if (input != null) {
-                    if (typeof input === 'string') {
-                        input = timezoneMinutesFromString(input);
-                    }
-                    if (Math.abs(input) < 16) {
-                        input = input * 60;
-                    }
-                    if (!this._isUTC && keepLocalTime) {
-                        localAdjust = this._d.getTimezoneOffset();
-                    }
-                    this._offset = input;
-                    this._isUTC = true;
-                    if (localAdjust != null) {
-                        this.subtract(localAdjust, 'm');
-                    }
-                    if (offset !== input) {
-                        if (!keepLocalTime || this._changeInProgress) {
-                            addOrSubtractDurationFromMoment(this,
-                                    moment.duration(offset - input, 'm'), 1, false);
-                        } else if (!this._changeInProgress) {
-                            this._changeInProgress = true;
-                            moment.updateOffset(this, true);
-                            this._changeInProgress = null;
-                        }
-                    }
-                } else {
-                    return this._isUTC ? offset : this._d.getTimezoneOffset();
-                }
-                return this;
-            },
+    var defaultOrdinal = '%d';
+    var defaultOrdinalParse = /\d{1,2}/;
 
-            zoneAbbr: function () {
-                return this._isUTC ? 'UTC' : '';
-            },
+    function ordinal(number) {
+        return this._ordinal.replace('%d', number);
+    }
 
-            zoneName: function () {
-                return this._isUTC ? 'Coordinated Universal Time' : '';
-            },
+    function preParsePostFormat(string) {
+        return string;
+    }
 
-            parseZone: function () {
-                if (this._tzm) {
-                    this.zone(this._tzm);
-                } else if (typeof this._i === 'string') {
-                    this.zone(this._i);
-                }
-                return this;
-            },
+    var defaultRelativeTime = {
+        future: 'in %s',
+        past: '%s ago',
+        s: 'a few seconds',
+        m: 'a minute',
+        mm: '%d minutes',
+        h: 'an hour',
+        hh: '%d hours',
+        d: 'a day',
+        dd: '%d days',
+        M: 'a month',
+        MM: '%d months',
+        y: 'a year',
+        yy: '%d years'
+    };
+
+    function relative__relativeTime(number, withoutSuffix, string, isFuture) {
+        var output = this._relativeTime[string];
+        return (typeof output === 'function') ?
+            output(number, withoutSuffix, string, isFuture) :
+            output.replace(/%d/i, number);
+    }
 
-            hasAlignedHourOffset: function (input) {
-                if (!input) {
-                    input = 0;
-                }
-                else {
-                    input = moment(input).zone();
-                }
+    function pastFuture(diff, output) {
+        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
+        return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
+    }
 
-                return (this.zone() - input) % 60 === 0;
-            },
-
-            daysInMonth: function () {
-                return daysInMonth(this.year(), this.month());
-            },
-
-            dayOfYear: function (input) {
-                var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
-                return input == null ? dayOfYear : this.add('d', (input - dayOfYear));
-            },
-
-            quarter: function (input) {
-                return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
-            },
-
-            weekYear: function (input) {
-                var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
-                return input == null ? year : this.add('y', (input - year));
-            },
-
-            isoWeekYear: function (input) {
-                var year = weekOfYear(this, 1, 4).year;
-                return input == null ? year : this.add('y', (input - year));
-            },
-
-            week: function (input) {
-                var week = this.lang().week(this);
-                return input == null ? week : this.add('d', (input - week) * 7);
-            },
-
-            isoWeek: function (input) {
-                var week = weekOfYear(this, 1, 4).week;
-                return input == null ? week : this.add('d', (input - week) * 7);
-            },
-
-            weekday: function (input) {
-                var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
-                return input == null ? weekday : this.add('d', input - weekday);
-            },
-
-            isoWeekday: function (input) {
-                // behaves the same as moment#day except
-                // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
-                // as a setter, sunday should belong to the previous week.
-                return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
-            },
-
-            isoWeeksInYear: function () {
-                return weeksInYear(this.year(), 1, 4);
-            },
-
-            weeksInYear: function () {
-                var weekInfo = this._lang._week;
-                return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
-            },
-
-            get: function (units) {
-                units = normalizeUnits(units);
-                return this[units]();
-            },
-
-            set: function (units, value) {
-                units = normalizeUnits(units);
-                if (typeof this[units] === 'function') {
-                    this[units](value);
-                }
-                return this;
-            },
-
-            // If passed a language key, it will set the language for this
-            // instance.  Otherwise, it will return the language configuration
-            // variables for this instance.
-            lang: function (key) {
-                if (key === undefined) {
-                    return this._lang;
-                } else {
-                    this._lang = getLangDefinition(key);
-                    return this;
-                }
+    function locale_set__set(config) {
+        var prop, i;
+        for (i in config) {
+            prop = config[i];
+            if (typeof prop === 'function') {
+                this[i] = prop;
+            } else {
+                this['_' + i] = prop;
             }
-        });
-
-        function rawMonthSetter(mom, value) {
-            var dayOfMonth;
+        }
+        // Lenient ordinal parsing accepts just a number in addition to
+        // number + (possibly) stuff coming from _ordinalParseLenient.
+        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source);
+    }
 
-            // TODO: Move this out of here!
-            if (typeof value === 'string') {
-                value = mom.lang().monthsParse(value);
-                // TODO: Another silent failure?
-                if (typeof value !== 'number') {
-                    return mom;
-                }
-            }
+    var prototype__proto = Locale.prototype;
+
+    prototype__proto._calendar = defaultCalendar;
+    prototype__proto.calendar = locale_calendar__calendar;
+    prototype__proto._longDateFormat = defaultLongDateFormat;
+    prototype__proto.longDateFormat = longDateFormat;
+    prototype__proto._invalidDate = defaultInvalidDate;
+    prototype__proto.invalidDate = invalidDate;
+    prototype__proto._ordinal = defaultOrdinal;
+    prototype__proto.ordinal = ordinal;
+    prototype__proto._ordinalParse = defaultOrdinalParse;
+    prototype__proto.preparse = preParsePostFormat;
+    prototype__proto.postformat = preParsePostFormat;
+    prototype__proto._relativeTime = defaultRelativeTime;
+    prototype__proto.relativeTime = relative__relativeTime;
+    prototype__proto.pastFuture = pastFuture;
+    prototype__proto.set = locale_set__set;
+
+    // Month
+    prototype__proto.months = localeMonths;
+    prototype__proto._months = defaultLocaleMonths;
+    prototype__proto.monthsShort = localeMonthsShort;
+    prototype__proto._monthsShort = defaultLocaleMonthsShort;
+    prototype__proto.monthsParse = localeMonthsParse;
+
+    // Week
+    prototype__proto.week = localeWeek;
+    prototype__proto._week = defaultLocaleWeek;
+    prototype__proto.firstDayOfYear = localeFirstDayOfYear;
+    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;
+
+    // Day of Week
+    prototype__proto.weekdays = localeWeekdays;
+    prototype__proto._weekdays = defaultLocaleWeekdays;
+    prototype__proto.weekdaysMin = localeWeekdaysMin;
+    prototype__proto._weekdaysMin = defaultLocaleWeekdaysMin;
+    prototype__proto.weekdaysShort = localeWeekdaysShort;
+    prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;
+    prototype__proto.weekdaysParse = localeWeekdaysParse;
+
+    // Hours
+    prototype__proto.isPM = localeIsPM;
+    prototype__proto._meridiemParse = defaultLocaleMeridiemParse;
+    prototype__proto.meridiem = localeMeridiem;
+
+    function lists__get(format, index, field, setter) {
+        var locale = locale_locales__getLocale();
+        var utc = create_utc__createUTC().set(setter, index);
+        return locale[field](utc, format);
+    }
 
-            dayOfMonth = Math.min(mom.date(),
-                    daysInMonth(mom.year(), value));
-            mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
-            return mom;
+    function list(format, index, field, count, setter) {
+        if (typeof format === 'number') {
+            index = format;
+            format = undefined;
         }
 
-        function rawGetter(mom, unit) {
-            return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
-        }
+        format = format || '';
 
-        function rawSetter(mom, unit, value) {
-            if (unit === 'Month') {
-                return rawMonthSetter(mom, value);
-            } else {
-                return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
-            }
+        if (index != null) {
+            return lists__get(format, index, field, setter);
         }
 
-        function makeAccessor(unit, keepTime) {
-            return function (value) {
-                if (value != null) {
-                    rawSetter(this, unit, value);
-                    moment.updateOffset(this, keepTime);
-                    return this;
-                } else {
-                    return rawGetter(this, unit);
-                }
-            };
+        var i;
+        var out = [];
+        for (i = 0; i < count; i++) {
+            out[i] = lists__get(format, i, field, setter);
         }
+        return out;
+    }
 
-        moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);
-        moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);
-        moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);
-        // Setting the hour should keep the time, because the user explicitly
-        // specified which hour he wants. So trying to maintain the same hour (in
-        // a new timezone) makes sense. Adding/subtracting hours does not follow
-        // this rule.
-        moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
-        // moment.fn.month is defined separately
-        moment.fn.date = makeAccessor('Date', true);
-        moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
-        moment.fn.year = makeAccessor('FullYear', true);
-        moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
-
-        // add plural methods
-        moment.fn.days = moment.fn.day;
-        moment.fn.months = moment.fn.month;
-        moment.fn.weeks = moment.fn.week;
-        moment.fn.isoWeeks = moment.fn.isoWeek;
-        moment.fn.quarters = moment.fn.quarter;
+    function lists__listMonths(format, index) {
+        return list(format, index, 'months', 12, 'month');
+    }
 
-        // add aliased format methods
-        moment.fn.toJSON = moment.fn.toISOString;
+    function lists__listMonthsShort(format, index) {
+        return list(format, index, 'monthsShort', 12, 'month');
+    }
 
-        /************************************
-            Duration Prototype
-        ************************************/
+    function lists__listWeekdays(format, index) {
+        return list(format, index, 'weekdays', 7, 'day');
+    }
 
+    function lists__listWeekdaysShort(format, index) {
+        return list(format, index, 'weekdaysShort', 7, 'day');
+    }
 
-        function daysToYears(days) {
-            // 400 years have 146097 days (taking into account leap year rules)
-            return days * 400 / 146097;
-        }
+    function lists__listWeekdaysMin(format, index) {
+        return list(format, index, 'weekdaysMin', 7, 'day');
+    }
 
-        function yearsToDays(years) {
-            // years * 365 + absRound(years / 4) -
-            //     absRound(years / 100) + absRound(years / 400);
-            return years * 146097 / 400;
+    locale_locales__getSetGlobalLocale('en', {
+        ordinalParse: /\d{1,2}(th|st|nd|rd)/,
+        ordinal: function (number) {
+            var b = number % 10,
+                output = (toInt(number % 100 / 10) === 1) ? 'th' :
+                (b === 1) ? 'st' :
+                (b === 2) ? 'nd' :
+                (b === 3) ? 'rd' : 'th';
+            return number + output;
         }
+    });
 
-        extend(moment.duration.fn = Duration.prototype, {
-
-            _bubble: function () {
-                var milliseconds = this._milliseconds,
-                    days = this._days,
-                    months = this._months,
-                    data = this._data,
-                    seconds, minutes, hours, years = 0;
-
-                // The following code bubbles up values, see the tests for
-                // examples of what that means.
-                data.milliseconds = milliseconds % 1000;
+    // Side effect imports
+    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
+    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);
 
-                seconds = absRound(milliseconds / 1000);
-                data.seconds = seconds % 60;
+    var mathAbs = Math.abs;
 
-                minutes = absRound(seconds / 60);
-                data.minutes = minutes % 60;
+    function duration_abs__abs() {
+        var data = this._data;
 
-                hours = absRound(minutes / 60);
-                data.hours = hours % 24;
+        this._milliseconds = mathAbs(this._milliseconds);
+        this._days = mathAbs(this._days);
+        this._months = mathAbs(this._months);
 
-                days += absRound(hours / 24);
+        data.milliseconds = mathAbs(data.milliseconds);
+        data.seconds = mathAbs(data.seconds);
+        data.minutes = mathAbs(data.minutes);
+        data.hours = mathAbs(data.hours);
+        data.months = mathAbs(data.months);
+        data.years = mathAbs(data.years);
 
-                // Accurately convert days to years, assume start from year 0.
-                years = absRound(daysToYears(days));
-                days -= absRound(yearsToDays(years));
+        return this;
+    }
 
-                // 30 days to a month
-                // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
-                months += absRound(days / 30);
-                days %= 30;
+    function duration_add_subtract__addSubtract(duration, input, value, direction) {
+        var other = create__createDuration(input, value);
 
-                // 12 months -> 1 year
-                years += absRound(months / 12);
-                months %= 12;
+        duration._milliseconds += direction * other._milliseconds;
+        duration._days += direction * other._days;
+        duration._months += direction * other._months;
 
-                data.days = days;
-                data.months = months;
-                data.years = years;
-            },
+        return duration._bubble();
+    }
 
-            abs: function () {
-                this._milliseconds = Math.abs(this._milliseconds);
-                this._days = Math.abs(this._days);
-                this._months = Math.abs(this._months);
+    // supports only 2.0-style add(1, 's') or add(duration)
+    function duration_add_subtract__add(input, value) {
+        return duration_add_subtract__addSubtract(this, input, value, 1);
+    }
 
-                this._data.milliseconds = Math.abs(this._data.milliseconds);
-                this._data.seconds = Math.abs(this._data.seconds);
-                this._data.minutes = Math.abs(this._data.minutes);
-                this._data.hours = Math.abs(this._data.hours);
-                this._data.months = Math.abs(this._data.months);
-                this._data.years = Math.abs(this._data.years);
+    // supports only 2.0-style subtract(1, 's') or subtract(duration)
+    function duration_add_subtract__subtract(input, value) {
+        return duration_add_subtract__addSubtract(this, input, value, -1);
+    }
 
-                return this;
-            },
+    function absCeil(number) {
+        if (number < 0) {
+            return Math.floor(number);
+        } else {
+            return Math.ceil(number);
+        }
+    }
 
-            weeks: function () {
-                return absRound(this.days() / 7);
-            },
+    function bubble() {
+        var milliseconds = this._milliseconds;
+        var days = this._days;
+        var months = this._months;
+        var data = this._data;
+        var seconds, minutes, hours, years, monthsFromDays;
 
-            valueOf: function () {
-                return this._milliseconds +
-                  this._days * 864e5 +
-                  (this._months % 12) * 2592e6 +
-                  toInt(this._months / 12) * 31536e6;
-            },
+        // if we have a mix of positive and negative values, bubble down first
+        // check: https://github.com/moment/moment/issues/2166
+        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
+                (milliseconds <= 0 && days <= 0 && months <= 0))) {
+            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
+            days = 0;
+            months = 0;
+        }
 
-            humanize: function (withSuffix) {
-                var output = relativeTime(this, !withSuffix, this.lang());
+        // The following code bubbles up values, see the tests for
+        // examples of what that means.
+        data.milliseconds = milliseconds % 1000;
 
-                if (withSuffix) {
-                    output = this.lang().pastFuture(+this, output);
-                }
+        seconds = absFloor(milliseconds / 1000);
+        data.seconds = seconds % 60;
 
-                return this.lang().postformat(output);
-            },
+        minutes = absFloor(seconds / 60);
+        data.minutes = minutes % 60;
 
-            add: function (input, val) {
-                // supports only 2.0-style add(1, 's') or add(moment)
-                var dur = moment.duration(input, val);
+        hours = absFloor(minutes / 60);
+        data.hours = hours % 24;
 
-                this._milliseconds += dur._milliseconds;
-                this._days += dur._days;
-                this._months += dur._months;
+        days += absFloor(hours / 24);
 
-                this._bubble();
+        // convert days to months
+        monthsFromDays = absFloor(daysToMonths(days));
+        months += monthsFromDays;
+        days -= absCeil(monthsToDays(monthsFromDays));
 
-                return this;
-            },
+        // 12 months -> 1 year
+        years = absFloor(months / 12);
+        months %= 12;
 
-            subtract: function (input, val) {
-                var dur = moment.duration(input, val);
+        data.days = days;
+        data.months = months;
+        data.years = years;
 
-                this._milliseconds -= dur._milliseconds;
-                this._days -= dur._days;
-                this._months -= dur._months;
+        return this;
+    }
 
-                this._bubble();
+    function daysToMonths(days) {
+        // 400 years have 146097 days (taking into account leap year rules)
+        // 400 years have 12 months === 4800
+        return days * 4800 / 146097;
+    }
 
-                return this;
-            },
-
-            get: function (units) {
-                units = normalizeUnits(units);
-                return this[units.toLowerCase() + 's']();
-            },
-
-            as: function (units) {
-                var days, months;
-                units = normalizeUnits(units);
-
-                days = this._days + this._milliseconds / 864e5;
-                if (units === 'month' || units === 'year') {
-                    months = this._months + daysToYears(days) * 12;
-                    return units === 'month' ? months : months / 12;
-                } else {
-                    days += yearsToDays(this._months / 12);
-                    switch (units) {
-                        case 'week': return days / 7;
-                        case 'day': return days;
-                        case 'hour': return days * 24;
-                        case 'minute': return days * 24 * 60;
-                        case 'second': return days * 24 * 60 * 60;
-                        case 'millisecond': return days * 24 * 60 * 60 * 1000;
-                        default: throw new Error('Unknown unit ' + units);
-                    }
-                }
-            },
+    function monthsToDays(months) {
+        // the reverse of daysToMonths
+        return months * 146097 / 4800;
+    }
 
-            lang: moment.fn.lang,
+    function as(units) {
+        var days;
+        var months;
+        var milliseconds = this._milliseconds;
 
-            toIsoString: deprecate(
-                "toIsoString() is deprecated. Please use toISOString() instead " +
-                "(notice the capitals)",
-                function () {
-                    return this.toISOString();
-                }
-            ),
-
-            toISOString: function () {
-                // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
-                var years = Math.abs(this.years()),
-                    months = Math.abs(this.months()),
-                    days = Math.abs(this.days()),
-                    hours = Math.abs(this.hours()),
-                    minutes = Math.abs(this.minutes()),
-                    seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);
-
-                if (!this.asSeconds()) {
-                    // this is the same as C#'s (Noda) and python (isodate)...
-                    // but not other JS (goog.date)
-                    return 'P0D';
-                }
+        units = normalizeUnits(units);
 
-                return (this.asSeconds() < 0 ? '-' : '') +
-                    'P' +
-                    (years ? years + 'Y' : '') +
-                    (months ? months + 'M' : '') +
-                    (days ? days + 'D' : '') +
-                    ((hours || minutes || seconds) ? 'T' : '') +
-                    (hours ? hours + 'H' : '') +
-                    (minutes ? minutes + 'M' : '') +
-                    (seconds ? seconds + 'S' : '');
+        if (units === 'month' || units === 'year') {
+            days = this._days + milliseconds / 864e5;
+            months = this._months + daysToMonths(days);
+            return units === 'month' ? months : months / 12;
+        } else {
+            // handle milliseconds separately because of floating point math errors (issue #1867)
+            days = this._days + Math.round(monthsToDays(this._months));
+            switch (units) {
+                case 'week': return days / 7 + milliseconds / 6048e5;
+                case 'day': return days + milliseconds / 864e5;
+                case 'hour': return days * 24 + milliseconds / 36e5;
+                case 'minute': return days * 1440 + milliseconds / 6e4;
+                case 'second': return days * 86400 + milliseconds / 1000;
+                    // Math.floor prevents floating point math errors here
+                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
+                default: throw new Error('Unknown unit ' + units);
             }
-        });
-
-        function makeDurationGetter(name) {
-            moment.duration.fn[name] = function () {
-                return this._data[name];
-            };
         }
+    }
 
-        for (i in unitMillisecondFactors) {
-            if (unitMillisecondFactors.hasOwnProperty(i)) {
-                makeDurationGetter(i.toLowerCase());
-            }
-        }
+    // TODO: Use this.as('ms')?
+    function duration_as__valueOf() {
+        return (
+            this._milliseconds +
+            this._days * 864e5 +
+            (this._months % 12) * 2592e6 +
+            toInt(this._months / 12) * 31536e6
+        );
+    }
 
-        moment.duration.fn.asMilliseconds = function () {
-            return this.as('ms');
-        };
-        moment.duration.fn.asSeconds = function () {
-            return this.as('s');
-        };
-        moment.duration.fn.asMinutes = function () {
-            return this.as('m');
-        };
-        moment.duration.fn.asHours = function () {
-            return this.as('h');
-        };
-        moment.duration.fn.asDays = function () {
-            return this.as('d');
-        };
-        moment.duration.fn.asWeeks = function () {
-            return this.as('weeks');
-        };
-        moment.duration.fn.asMonths = function () {
-            return this.as('M');
-        };
-        moment.duration.fn.asYears = function () {
-            return this.as('y');
+    function makeAs(alias) {
+        return function () {
+            return this.as(alias);
         };
+    }
 
-        /************************************
-            Default Lang
-        ************************************/
+    var asMilliseconds = makeAs('ms');
+    var asSeconds = makeAs('s');
+    var asMinutes = makeAs('m');
+    var asHours = makeAs('h');
+    var asDays = makeAs('d');
+    var asWeeks = makeAs('w');
+    var asMonths = makeAs('M');
+    var asYears = makeAs('y');
+
+    function duration_get__get(units) {
+        units = normalizeUnits(units);
+        return this[units + 's']();
+    }
 
+    function makeGetter(name) {
+        return function () {
+            return this._data[name];
+        };
+    }
 
-        // Set default language, other languages will inherit from English.
-        moment.lang('en', {
-            ordinal: function (number) {
-                var b = number % 10,
-                    output = (toInt(number % 100 / 10) === 1) ? 'th' :
-                    (b === 1) ? 'st' :
-                    (b === 2) ? 'nd' :
-                    (b === 3) ? 'rd' : 'th';
-                return number + output;
-            }
-        });
+    var milliseconds = makeGetter('milliseconds');
+    var seconds = makeGetter('seconds');
+    var minutes = makeGetter('minutes');
+    var hours = makeGetter('hours');
+    var days = makeGetter('days');
+    var months = makeGetter('months');
+    var years = makeGetter('years');
 
-        /* EMBED_LANGUAGES */
+    function weeks() {
+        return absFloor(this.days() / 7);
+    }
 
-        /************************************
-            Exposing Moment
-        ************************************/
+    var round = Math.round;
+    var thresholds = {
+        s: 45,  // seconds to minute
+        m: 45,  // minutes to hour
+        h: 22,  // hours to day
+        d: 26,  // days to month
+        M: 11   // months to year
+    };
+
+    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
+    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
+        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
+    }
 
-        function makeGlobal(shouldDeprecate) {
-            /*global ender:false */
-            if (typeof ender !== 'undefined') {
-                return;
-            }
-            oldGlobalMoment = globalScope.moment;
-            if (shouldDeprecate) {
-                globalScope.moment = deprecate(
-                        'Accessing Moment through the global scope is ' +
-                        'deprecated, and will be removed in an upcoming ' +
-                        'release.',
-                        moment);
-            } else {
-                globalScope.moment = moment;
-            }
+    function duration_humanize__relativeTime(posNegDuration, withoutSuffix, locale) {
+        var duration = create__createDuration(posNegDuration).abs();
+        var seconds = round(duration.as('s'));
+        var minutes = round(duration.as('m'));
+        var hours = round(duration.as('h'));
+        var days = round(duration.as('d'));
+        var months = round(duration.as('M'));
+        var years = round(duration.as('y'));
+
+        var a = seconds < thresholds.s && ['s', seconds] ||
+                minutes === 1 && ['m'] ||
+                minutes < thresholds.m && ['mm', minutes] ||
+                hours === 1 && ['h'] ||
+                hours < thresholds.h && ['hh', hours] ||
+                days === 1 && ['d'] ||
+                days < thresholds.d && ['dd', days] ||
+                months === 1 && ['M'] ||
+                months < thresholds.M && ['MM', months] ||
+                years === 1 && ['y'] || ['yy', years];
+
+        a[2] = withoutSuffix;
+        a[3] = +posNegDuration > 0;
+        a[4] = locale;
+        return substituteTimeAgo.apply(null, a);
+    }
+
+    // This function allows you to set a threshold for relative time strings
+    function duration_humanize__getSetRelativeTimeThreshold(threshold, limit) {
+        if (thresholds[threshold] === undefined) {
+            return false;
+        }
+        if (limit === undefined) {
+            return thresholds[threshold];
         }
+        thresholds[threshold] = limit;
+        return true;
+    }
 
-        // CommonJS module is defined
-        if (hasModule) {
-            module.exports = moment;
-        } else if (typeof define === 'function' && define.amd) {
-            define('moment', function (require, exports, module) {
-                if (module.config && module.config() && module.config().noGlobal === true) {
-                    // release the global variable
-                    globalScope.moment = oldGlobalMoment;
-                }
+    function humanize(withSuffix) {
+        var locale = this.localeData();
+        var output = duration_humanize__relativeTime(this, !withSuffix, locale);
 
-                return moment;
-            });
-            makeGlobal(true);
-        } else {
-            makeGlobal();
+        if (withSuffix) {
+            output = locale.pastFuture(+this, output);
         }
-    }).call(this);
 
-    return moment;
-}));
+        return locale.postformat(output);
+    }
+
+    var iso_string__abs = Math.abs;
+
+    function iso_string__toISOString() {
+        // for ISO strings we do not use the normal bubbling rules:
+        //  * milliseconds bubble up until they become hours
+        //  * days do not bubble at all
+        //  * months bubble up until they become years
+        // This is because there is no context-free conversion between hours and days
+        // (think of clock changes)
+        // and also not between days and months (28-31 days per month)
+        var seconds = iso_string__abs(this._milliseconds) / 1000;
+        var days = iso_string__abs(this._days);
+        var months = iso_string__abs(this._months);
+        var minutes, hours, years;
+
+        // 3600 seconds -> 60 minutes -> 1 hour
+        minutes = absFloor(seconds / 60);
+        hours = absFloor(minutes / 60);
+        seconds %= 60;
+        minutes %= 60;
+
+        // 12 months -> 1 year
+        years = absFloor(months / 12);
+        months %= 12;
+
+
+        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
+        var Y = years;
+        var M = months;
+        var D = days;
+        var h = hours;
+        var m = minutes;
+        var s = seconds;
+        var total = this.asSeconds();
+
+        if (!total) {
+            // this is the same as C#'s (Noda) and python (isodate)...
+            // but not other JS (goog.date)
+            return 'P0D';
+        }
+
+        return (total < 0 ? '-' : '') +
+            'P' +
+            (Y ? Y + 'Y' : '') +
+            (M ? M + 'M' : '') +
+            (D ? D + 'D' : '') +
+            ((h || m || s) ? 'T' : '') +
+            (h ? h + 'H' : '') +
+            (m ? m + 'M' : '') +
+            (s ? s + 'S' : '');
+    }
+
+    var duration_prototype__proto = Duration.prototype;
+
+    duration_prototype__proto.abs = duration_abs__abs;
+    duration_prototype__proto.add = duration_add_subtract__add;
+    duration_prototype__proto.subtract = duration_add_subtract__subtract;
+    duration_prototype__proto.as = as;
+    duration_prototype__proto.asMilliseconds = asMilliseconds;
+    duration_prototype__proto.asSeconds = asSeconds;
+    duration_prototype__proto.asMinutes = asMinutes;
+    duration_prototype__proto.asHours = asHours;
+    duration_prototype__proto.asDays = asDays;
+    duration_prototype__proto.asWeeks = asWeeks;
+    duration_prototype__proto.asMonths = asMonths;
+    duration_prototype__proto.asYears = asYears;
+    duration_prototype__proto.valueOf = duration_as__valueOf;
+    duration_prototype__proto._bubble = bubble;
+    duration_prototype__proto.get = duration_get__get;
+    duration_prototype__proto.milliseconds = milliseconds;
+    duration_prototype__proto.seconds = seconds;
+    duration_prototype__proto.minutes = minutes;
+    duration_prototype__proto.hours = hours;
+    duration_prototype__proto.days = days;
+    duration_prototype__proto.weeks = weeks;
+    duration_prototype__proto.months = months;
+    duration_prototype__proto.years = years;
+    duration_prototype__proto.humanize = humanize;
+    duration_prototype__proto.toISOString = iso_string__toISOString;
+    duration_prototype__proto.toString = iso_string__toISOString;
+    duration_prototype__proto.toJSON = iso_string__toISOString;
+    duration_prototype__proto.locale = locale;
+    duration_prototype__proto.localeData = localeData;
+
+    // Deprecations
+    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
+    duration_prototype__proto.lang = lang;
+
+    // Side effect imports
+
+    addFormatToken('X', 0, 0, 'unix');
+    addFormatToken('x', 0, 0, 'valueOf');
+
+    // PARSING
+
+    addRegexToken('x', matchSigned);
+    addRegexToken('X', matchTimestamp);
+    addParseToken('X', function (input, array, config) {
+        config._d = new Date(parseFloat(input, 10) * 1000);
+    });
+    addParseToken('x', function (input, array, config) {
+        config._d = new Date(toInt(input));
+    });
+
+    // Side effect imports
+
+
+    utils_hooks__hooks.version = '2.10.6';
+
+    setHookCallback(local__createLocal);
+
+    utils_hooks__hooks.fn = momentPrototype;
+    utils_hooks__hooks.min = min;
+    utils_hooks__hooks.max = max;
+    utils_hooks__hooks.utc = create_utc__createUTC;
+    utils_hooks__hooks.unix = moment__createUnix;
+    utils_hooks__hooks.months = lists__listMonths;
+    utils_hooks__hooks.isDate = isDate;
+    utils_hooks__hooks.locale = locale_locales__getSetGlobalLocale;
+    utils_hooks__hooks.invalid = valid__createInvalid;
+    utils_hooks__hooks.duration = create__createDuration;
+    utils_hooks__hooks.isMoment = isMoment;
+    utils_hooks__hooks.weekdays = lists__listWeekdays;
+    utils_hooks__hooks.parseZone = moment__createInZone;
+    utils_hooks__hooks.localeData = locale_locales__getLocale;
+    utils_hooks__hooks.isDuration = isDuration;
+    utils_hooks__hooks.monthsShort = lists__listMonthsShort;
+    utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin;
+    utils_hooks__hooks.defineLocale = defineLocale;
+    utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort;
+    utils_hooks__hooks.normalizeUnits = normalizeUnits;
+    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
+
+    var _moment = utils_hooks__hooks;
+
+    return _moment;
+}));
\ No newline at end of file
diff --git a/BForms.Docs/Scripts/BForms/Plugins/UI/bforms.initUI.js b/BForms.Docs/Scripts/BForms/Plugins/UI/bforms.initUI.js
index 4f45b329..0d644dfe 100644
--- a/BForms.Docs/Scripts/BForms/Plugins/UI/bforms.initUI.js
+++ b/BForms.Docs/Scripts/BForms/Plugins/UI/bforms.initUI.js
@@ -194,7 +194,7 @@
             var uiLocale = $('html').attr('lang') !== "undefined" ? $('html').attr('lang') : 'en';
             if (requireConfig && requireConfig.locale) {
                 var locale = requireConfig.locale;
-                if (typeof moment.langData(locale) !== "undefined") {
+                if (typeof moment.localeData(locale) !== "undefined") {
                     uiLocale = locale;
                 }
             }