Jelajahi Sumber

创建虚拟机开始实现表单校验功能

James Iter 8 tahun lalu
induk
melakukan
f7c4a3b0e1
63 mengubah file dengan 31094 tambahan dan 46 penghapusan
  1. TEMPAT SAMPAH
      static/formvalidation/.DS_Store
  2. 299 0
      static/formvalidation/css/formValidation.css
  3. 8 0
      static/formvalidation/css/formValidation.min.css
  4. TEMPAT SAMPAH
      static/formvalidation/js/.DS_Store
  5. 9620 0
      static/formvalidation/js/formValidation.js
  6. 9 0
      static/formvalidation/js/formValidation.min.js
  7. 4768 0
      static/formvalidation/js/formValidation.popular.js
  8. 34 0
      static/formvalidation/js/formValidation.popular.min.js
  9. 276 0
      static/formvalidation/js/framework/bootstrap.js
  10. 9 0
      static/formvalidation/js/framework/bootstrap.min.js
  11. 215 0
      static/formvalidation/js/framework/bootstrap4.js
  12. 9 0
      static/formvalidation/js/framework/bootstrap4.min.js
  13. 149 0
      static/formvalidation/js/framework/foundation.js
  14. 10 0
      static/formvalidation/js/framework/foundation.min.js
  15. 161 0
      static/formvalidation/js/framework/foundation5.js
  16. 10 0
      static/formvalidation/js/framework/foundation5.min.js
  17. 65 0
      static/formvalidation/js/framework/pure.js
  18. 10 0
      static/formvalidation/js/framework/pure.min.js
  19. 163 0
      static/formvalidation/js/framework/semantic.js
  20. 10 0
      static/formvalidation/js/framework/semantic.min.js
  21. 165 0
      static/formvalidation/js/framework/uikit.js
  22. 10 0
      static/formvalidation/js/framework/uikit.min.js
  23. 385 0
      static/formvalidation/js/language/ar_MA.js
  24. 385 0
      static/formvalidation/js/language/bg_BG.js
  25. 385 0
      static/formvalidation/js/language/ca_ES.js
  26. 385 0
      static/formvalidation/js/language/cs_CZ.js
  27. 385 0
      static/formvalidation/js/language/da_DK.js
  28. 385 0
      static/formvalidation/js/language/de_DE.js
  29. 385 0
      static/formvalidation/js/language/el_GR.js
  30. 385 0
      static/formvalidation/js/language/en_US.js
  31. 385 0
      static/formvalidation/js/language/es_CL.js
  32. 385 0
      static/formvalidation/js/language/es_ES.js
  33. 385 0
      static/formvalidation/js/language/eu_ES.js
  34. 385 0
      static/formvalidation/js/language/fa_IR.js
  35. 385 0
      static/formvalidation/js/language/fi_FI.js
  36. 385 0
      static/formvalidation/js/language/fr_BE.js
  37. 385 0
      static/formvalidation/js/language/fr_FR.js
  38. 385 0
      static/formvalidation/js/language/he_IL.js
  39. 385 0
      static/formvalidation/js/language/hi_IN.js
  40. 385 0
      static/formvalidation/js/language/hu_HU.js
  41. 385 0
      static/formvalidation/js/language/id_ID.js
  42. 385 0
      static/formvalidation/js/language/it_IT.js
  43. 385 0
      static/formvalidation/js/language/ja_JP.js
  44. 385 0
      static/formvalidation/js/language/nl_BE.js
  45. 385 0
      static/formvalidation/js/language/nl_NL.js
  46. 385 0
      static/formvalidation/js/language/no_NO.js
  47. 385 0
      static/formvalidation/js/language/pl_PL.js
  48. 385 0
      static/formvalidation/js/language/pt_BR.js
  49. 385 0
      static/formvalidation/js/language/pt_PT.js
  50. 385 0
      static/formvalidation/js/language/ro_RO.js
  51. 385 0
      static/formvalidation/js/language/ru_RU.js
  52. 385 0
      static/formvalidation/js/language/sk_SK.js
  53. 385 0
      static/formvalidation/js/language/sq_AL.js
  54. 385 0
      static/formvalidation/js/language/sr_RS.js
  55. 385 0
      static/formvalidation/js/language/sv_SE.js
  56. 385 0
      static/formvalidation/js/language/th_TH.js
  57. 385 0
      static/formvalidation/js/language/tr_TR.js
  58. 385 0
      static/formvalidation/js/language/ua_UA.js
  59. 385 0
      static/formvalidation/js/language/vi_VN.js
  60. 385 0
      static/formvalidation/js/language/zh_CN.js
  61. 385 0
      static/formvalidation/js/language/zh_TW.js
  62. 71 46
      templates/guest_create.html
  63. 8 0
      templates/layout.html

TEMPAT SAMPAH
static/formvalidation/.DS_Store


+ 299 - 0
static/formvalidation/css/formValidation.css

@@ -0,0 +1,299 @@
+/*!
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @version     v0.8.1, built on 2016-07-29 1:10:54 AM
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+.fv-has-feedback {
+    position: relative;
+}
+
+.fv-control-feedback {
+    position: absolute;
+    top: 0;
+    right: 0;
+    z-index: 3;
+    display: block;
+    text-align: center;
+}
+
+.fv-help-block {
+    display: block;
+}
+
+/* Hide the clear icon for field using placeholder attribute on IE10/11 */
+.fv-form [placeholder]::-ms-clear {
+    display: none;
+}
+
+/* -------------------
+ * Support Bootstrap 3
+ * ------------------- */
+
+.fv-form-bootstrap .help-block {
+    margin-bottom: 0;
+}
+
+.fv-form-bootstrap .tooltip-inner {
+    text-align: left;
+}
+
+.fv-form-bootstrap .fv-bootstrap-icon-input-group {
+    z-index: 100;
+}
+
+/* Inline form */
+.form-inline.fv-form-bootstrap .form-group {
+    vertical-align: top;
+}
+
+/* -------------------------
+ * Support Bootstrap 4 alpha
+ * ------------------------- */
+
+.fv-form-bootstrap4 .fv-control-feedback {
+    width: 38px;
+    height: 38px;
+    line-height: 38px;
+}
+
+/* For horizontal form */
+.fv-form-bootstrap4 .form-group.row .fv-control-feedback {
+    right: 15px;
+}
+.fv-form-bootstrap4 .form-group.row .form-check~.fv-control-feedback {
+    top: -7px; /* labelHeight/2 - iconHeight/2 */
+}
+/* Inline form */
+.fv-form-bootstrap4.form-inline .form-group {
+    vertical-align: top;
+}
+/* Stacked form */
+.fv-form-bootstrap4:not(.form-inline) label~.fv-control-feedback {
+    top: 32px;
+}
+/* Without label */
+.fv-form-bootstrap4:not(.form-inline) label.sr-only~.fv-control-feedback {
+    top: -7px; /* labelHeight/2 - iconHeight/2 */
+}
+.fv-form-bootstrap4:not(.form-inline) .form-check~.fv-control-feedback {
+    top: 25px; /* labelHeight + checkboxHeight/2 - iconHeight/2 */
+}
+
+.fv-form-bootstrap4 .has-success label,
+.fv-form-bootstrap4 .has-success .fv-control-feedback {
+    color: #5cb85c;
+}
+
+.fv-form-bootstrap4 .has-warning label,
+.fv-form-bootstrap4 .has-warning .fv-control-feedback {
+    color: #f0ad4e;
+}
+
+/* --------------------
+ * Support Foundation 5
+ * -------------------- */
+
+/* Icon position */
+.fv-form-foundation5 .fv-control-feedback {
+    right: 15px;    /* The padding-right of .columns */
+    width: 37px;    /* Same as height of input */
+    height: 37px;
+    line-height: 37px;
+}
+
+.fv-form-foundation5 .row .row:not(.collapse) .fv-control-feedback {
+    right: 8px;     /* Multiple fields in the same row, same as padding-right of .row .row .column(s) */
+}
+
+.fv-form-foundation5 .row .collapse .fv-control-feedback {
+    right: 0;
+}
+
+.fv-form-foundation5.fv-form-horizontal [type="checkbox"]~.fv-control-feedback,
+.fv-form-foundation5.fv-form-horizontal [type="radio"]~.fv-control-feedback {
+    top: -8px;      /* labelHeight/2 - iconHeight/2 */
+}
+
+/* Stacked form */
+.fv-form-foundation5 label .fv-control-feedback {
+    top: 21px;      /* Same as height of label */
+}
+
+.fv-form-foundation5 [type="checkbox"]~.fv-control-feedback,
+.fv-form-foundation5 [type="radio"]~.fv-control-feedback {
+    top: 15px;
+}
+
+/* Color */
+.fv-form-foundation5 .error .fv-control-feedback {
+    color: #f04124; /* Same as $alert-color, .error */
+}
+
+.fv-form-foundation5 .fv-has-success label,
+.fv-form-foundation5 .fv-has-success .fv-control-feedback {
+    color: #43AC6A; /* Same as $success-color */
+}
+
+/* --------------------
+ * Support Foundation 6
+ * -------------------- */
+
+/* Icon position */
+.fv-form-foundation .fv-control-feedback {
+    right: 15px;    /* The padding-right of .columns */
+    width: 39px;    /* Same as height of input */
+    height: 39px;
+    line-height: 39px;
+}
+
+.fv-form-foundation [type="checkbox"]~.fv-control-feedback,
+.fv-form-foundation [type="radio"]~.fv-control-feedback {
+    top: -7px;      /* labelHeight/2 - iconHeight/2 */
+}
+
+.fv-form-foundation .form-error {
+    display: block;
+}
+
+/* Stacked form */
+.fv-form-foundation label .fv-control-feedback,
+.fv-form-foundation fieldset [type="checkbox"]~.fv-control-feedback,
+.fv-form-foundation fieldset [type="radio"]~.fv-control-feedback {
+    top: 25px;      /* Same as height of label */
+}
+
+/* Color */
+.fv-form-foundation .fv-has-error label,
+.fv-form-foundation .fv-has-error fieldset legend,
+.fv-form-foundation .fv-has-error .fv-control-feedback {
+    color: #ec5840; /* Same as .alert */
+}
+
+.fv-form-foundation .fv-has-success label,
+.fv-form-foundation .fv-has-success fieldset legend,
+.fv-form-foundation .fv-has-success .fv-control-feedback {
+    color: #3adb76; /* Same as .success */
+}
+
+/* Tooltip */
+.fv-foundation-tooltip:before {
+    border-color: transparent transparent #0a0a0a;
+}
+
+/* ------------
+ * Support Pure
+ * ------------ */
+
+.fv-form-pure .fv-control-feedback {
+    width: 36px;    /* Height of Pure input */
+    height: 36px;
+    line-height: 36px;
+}
+
+/* Horizontal form */
+.fv-form-pure.pure-form-aligned [type="checkbox"]~.fv-control-feedback,
+.fv-form-pure.pure-form-aligned [type="radio"]~.fv-control-feedback {
+    top: -9px;      /* labelHeight/2 - iconHeight/2 */
+}
+
+.fv-form-pure.pure-form-aligned .fv-help-block {
+    margin-top: 5px;
+    margin-left: 180px;
+}
+
+/* Stacked form */
+.fv-form-pure.pure-form-stacked .pure-control-group {
+    margin-bottom: 8px;
+}
+
+.fv-form-pure.pure-form-stacked .fv-control-feedback {
+    top: 22px;      /* Same as height of label */
+}
+
+.fv-form-pure.pure-form-stacked .pure-radio~.fv-control-feedback {
+    top: 20px;
+}
+
+.fv-form-pure.pure-form-stacked .fv-sr-only~.fv-control-feedback {
+    top: -9px;
+}
+
+.fv-form-pure .fv-has-error label,
+.fv-form-pure .fv-has-error .fv-help-block,
+.fv-form-pure .fv-has-error .fv-control-feedback {
+    color: #CA3C3C; /* Same as .button-error */
+}
+
+.fv-form-pure .fv-has-success label,
+.fv-form-pure .fv-has-success .fv-help-block,
+.fv-form-pure .fv-has-success .fv-control-feedback {
+    color: #1CB841; /* Same as .button-success */
+}
+
+/* -------------------
+ * Support Semantic UI
+ * ------------------- */
+
+.fv-form-semantic.ui.form .fields.error label {
+    color: #9f3a38; /* Same as .ui.form .field.error .input */
+}
+
+.fv-form-semantic .fv-control-feedback {
+    right: 7px;
+}
+
+.fv-form-semantic .error .icon {
+    color: #9f3a38;
+}
+
+/* --------------
+ * Support UI Kit
+ * -------------- */
+
+.fv-form-uikit .fv-control-feedback {
+    top: 25px;      /* Height of UIKit label */
+    width: 30px;    /* Height of UIKit input */
+    height: 30px;
+    line-height: 30px;
+}
+
+.fv-form-uikit .uk-text-danger {
+    display: block;
+}
+
+/* UIKit horizontal form */
+.fv-form-uikit.uk-form-horizontal .fv-control-feedback {
+    top: 0;
+}
+
+.fv-form-uikit.uk-form-horizontal [type="checkbox"]~.fv-control-feedback,
+.fv-form-uikit.uk-form-horizontal [type="radio"]~.fv-control-feedback {
+    top: -7px;
+}
+
+/* Without labels */
+.fv-form-uikit label.fv-sr-only~.fv-control-feedback {
+    top: -7px !important;
+}
+
+/* Stacked form */
+.fv-form-uikit.uk-form-stacked [type="checkbox"]~.fv-control-feedback,
+.fv-form-uikit.uk-form-stacked [type="radio"]~.fv-control-feedback {
+    top: 20px;
+}
+
+.fv-form-uikit .fv-has-error label,
+.fv-form-uikit .fv-has-error .uk-form-label,
+.fv-form-uikit .fv-has-error .fv-control-feedback {
+    color: #D85030;     /* Same as .uk-form-danger */
+}
+
+.fv-form-uikit .fv-has-success label,
+.fv-form-uikit .fv-has-success .uk-form-label,
+.fv-form-uikit .fv-has-success .fv-control-feedback {
+    color: #659F13;     /* Same as .uk-form-success */
+}

File diff ditekan karena terlalu besar
+ 8 - 0
static/formvalidation/css/formValidation.min.css


TEMPAT SAMPAH
static/formvalidation/js/.DS_Store


+ 9620 - 0
static/formvalidation/js/formValidation.js

@@ -0,0 +1,9620 @@
+/*!
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @version     v0.8.1, built on 2016-07-29 1:10:54 AM
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+// Register the namespace
+window.FormValidation = {
+    AddOn:     {},  // Add-ons
+    Framework: {},  // Supported frameworks
+    I18n:      {},  // i18n
+    Validator: {}   // Available validators
+};
+
+if (typeof jQuery === 'undefined') {
+    throw new Error('FormValidation requires jQuery');
+}
+
+(function($) {
+    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('FormValidation requires jQuery version 1.9.1 or higher');
+    }
+}(jQuery));
+
+(function($) {
+    // TODO: Remove backward compatibility
+    /**
+     * Constructor
+     *
+     * @param {jQuery|String} form The form element or selector
+     * @param {Object} options The options
+     * @param {String} [namespace] The optional namespace which is used for data-{namespace}-xxx attributes and internal data.
+     * Currently, it's used to support backward version
+     * @constructor
+     */
+    FormValidation.Base = function(form, options, namespace) {
+        this.$form      = $(form);
+        this.options    = $.extend({}, $.fn.formValidation.DEFAULT_OPTIONS, options);
+        this._namespace = namespace || 'fv';
+
+        this.$invalidFields = $([]);    // Array of invalid fields
+        this.$submitButton  = null;     // The submit button which is clicked to submit form
+        this.$hiddenButton  = null;
+
+        // Validating status
+        this.STATUS_NOT_VALIDATED = 'NOT_VALIDATED';
+        this.STATUS_VALIDATING    = 'VALIDATING';
+        this.STATUS_INVALID       = 'INVALID';
+        this.STATUS_VALID         = 'VALID';
+        this.STATUS_IGNORED       = 'IGNORED';
+
+        // Default message
+        this.DEFAULT_MESSAGE      = $.fn.formValidation.DEFAULT_MESSAGE;
+
+        // Determine the event that is fired when user change the field value
+        // Most modern browsers supports input event except IE 7, 8.
+        // IE 9 supports input event but the event is still not fired if I press the backspace key.
+        // Get IE version
+        // https://gist.github.com/padolsey/527683/#comment-7595
+        this._ieVersion = (function() {
+            var v = 3, div = document.createElement('div'), a = div.all || [];
+            while (div.innerHTML = '<!--[if gt IE '+(++v)+']><br><![endif]-->', a[0]) {}
+            return v > 4 ? v : document.documentMode;
+        }());
+
+        var el = document.createElement('div');
+        this._changeEvent = (this._ieVersion === 9 || !('oninput' in el)) ? 'keyup' : 'input';
+
+        // The flag to indicate that the form is ready to submit when a remote/callback validator returns
+        this._submitIfValid = null;
+
+        // Field elements
+        this._cacheFields = {};
+
+        this._init();
+    };
+
+    FormValidation.Base.prototype = {
+        constructor: FormValidation.Base,
+
+        /**
+         * Check if the number of characters of field value exceed the threshold or not
+         *
+         * @param {jQuery} $field The field element
+         * @returns {Boolean}
+         */
+        _exceedThreshold: function($field) {
+            var ns        = this._namespace,
+                field     = $field.attr('data-' + ns + '-field'),
+                threshold = this.options.fields[field].threshold || this.options.threshold;
+            if (!threshold) {
+                return true;
+            }
+            var cannotType = $.inArray($field.attr('type'), ['button', 'checkbox', 'file', 'hidden', 'image', 'radio', 'reset', 'submit']) !== -1;
+            return (cannotType || $field.val().length >= threshold);
+        },
+
+        /**
+         * Init form
+         */
+        _init: function() {
+            var that    = this,
+                ns      = this._namespace,
+                options = {
+                    addOns:         {},
+                    autoFocus:      this.$form.attr('data-' + ns + '-autofocus'),
+                    button: {
+                        selector: this.$form.attr('data-' + ns + '-button-selector') || this.$form.attr('data-' + ns + '-submitbuttons'), // Support backward
+                        disabled: this.$form.attr('data-' + ns + '-button-disabled')
+                    },
+                    control: {
+                        valid:   this.$form.attr('data-' + ns + '-control-valid'),
+                        invalid: this.$form.attr('data-' + ns + '-control-invalid')
+                    },
+                    err: {
+                        clazz:     this.$form.attr('data-' + ns + '-err-clazz'),
+                        container: this.$form.attr('data-' + ns + '-err-container') || this.$form.attr('data-' + ns + '-container'), // Support backward
+                        parent:    this.$form.attr('data-' + ns + '-err-parent')
+                    },
+                    events: {
+                        formInit:         this.$form.attr('data-' + ns + '-events-form-init'),
+                        formPreValidate:  this.$form.attr('data-' + ns + '-events-form-prevalidate'),
+                        formError:        this.$form.attr('data-' + ns + '-events-form-error'),
+                        formReset:        this.$form.attr('data-' + ns + '-events-form-reset'),
+                        formSuccess:      this.$form.attr('data-' + ns + '-events-form-success'),
+                        fieldAdded:       this.$form.attr('data-' + ns + '-events-field-added'),
+                        fieldRemoved:     this.$form.attr('data-' + ns + '-events-field-removed'),
+                        fieldInit:        this.$form.attr('data-' + ns + '-events-field-init'),
+                        fieldError:       this.$form.attr('data-' + ns + '-events-field-error'),
+                        fieldReset:       this.$form.attr('data-' + ns + '-events-field-reset'),
+                        fieldSuccess:     this.$form.attr('data-' + ns + '-events-field-success'),
+                        fieldStatus:      this.$form.attr('data-' + ns + '-events-field-status'),
+                        localeChanged:    this.$form.attr('data-' + ns + '-events-locale-changed'),
+                        validatorError:   this.$form.attr('data-' + ns + '-events-validator-error'),
+                        validatorSuccess: this.$form.attr('data-' + ns + '-events-validator-success'),
+                        validatorIgnored: this.$form.attr('data-' + ns + '-events-validator-ignored')
+                    },
+                    excluded:      this.$form.attr('data-' + ns + '-excluded'),
+                    icon: {
+                        valid:      this.$form.attr('data-' + ns + '-icon-valid')      || this.$form.attr('data-' + ns + '-feedbackicons-valid'),      // Support backward
+                        invalid:    this.$form.attr('data-' + ns + '-icon-invalid')    || this.$form.attr('data-' + ns + '-feedbackicons-invalid'),    // Support backward
+                        validating: this.$form.attr('data-' + ns + '-icon-validating') || this.$form.attr('data-' + ns + '-feedbackicons-validating'), // Support backward
+                        feedback:   this.$form.attr('data-' + ns + '-icon-feedback')
+                    },
+                    live:          this.$form.attr('data-' + ns + '-live'),
+                    locale:        this.$form.attr('data-' + ns + '-locale'),
+                    message:       this.$form.attr('data-' + ns + '-message'),
+                    onPreValidate: this.$form.attr('data-' + ns + '-onprevalidate'),
+                    onError:       this.$form.attr('data-' + ns + '-onerror'),
+                    onReset:       this.$form.attr('data-' + ns + '-onreset'),
+                    onSuccess:     this.$form.attr('data-' + ns + '-onsuccess'),
+                    row: {
+                        selector: this.$form.attr('data-' + ns + '-row-selector') || this.$form.attr('data-' + ns + '-group'), // Support backward
+                        valid:    this.$form.attr('data-' + ns + '-row-valid'),
+                        invalid:  this.$form.attr('data-' + ns + '-row-invalid'),
+                        feedback: this.$form.attr('data-' + ns + '-row-feedback')
+                    },
+                    threshold:     this.$form.attr('data-' + ns + '-threshold'),
+                    trigger:       this.$form.attr('data-' + ns + '-trigger'),
+                    verbose:       this.$form.attr('data-' + ns + '-verbose'),
+                    fields:        {}
+                };
+
+            this.$form
+                // Disable client side validation in HTML 5
+                .attr('novalidate', 'novalidate')
+                .addClass(this.options.elementClass)
+                // Disable the default submission first
+                .on('submit.' + ns, function(e) {
+                    e.preventDefault();
+                    that.validate();
+                })
+                .on('click.' + ns, this.options.button.selector, function() {
+                    that.$submitButton  = $(this);
+                    // The user just click the submit button
+                    that._submitIfValid = true;
+                });
+
+            if (this.options.declarative === true || this.options.declarative === 'true') {
+                // Find all fields which have either "name" or "data-{namespace}-field" attribute
+                this.$form
+                    .find('[name], [data-' + ns + '-field]')
+                    .each(function() {
+                        var $field = $(this),
+                            field  = $field.attr('name') || $field.attr('data-' + ns + '-field'),
+                            opts   = that._parseOptions($field);
+                        if (opts) {
+                            $field.attr('data-' + ns + '-field', field);
+                            options.fields[field] = $.extend({}, opts, options.fields[field]);
+                        }
+                    });
+            }
+
+            this.options = $.extend(true, this.options, options);
+
+            // Normalize the err.parent option
+            if ('string' === typeof this.options.err.parent) {
+                this.options.err.parent = new RegExp(this.options.err.parent);
+            }
+
+            // Support backward
+            if (this.options.container) {
+                this.options.err.container = this.options.container;
+                delete this.options.container;
+            }
+            if (this.options.feedbackIcons) {
+                this.options.icon = $.extend(true, this.options.icon, this.options.feedbackIcons);
+                delete this.options.feedbackIcons;
+            }
+            if (this.options.group) {
+                this.options.row.selector = this.options.group;
+                delete this.options.group;
+            }
+            if (this.options.submitButtons) {
+                this.options.button.selector = this.options.submitButtons;
+                delete this.options.submitButtons;
+            }
+
+            // If the locale is not found, reset it to default one
+            if (!FormValidation.I18n[this.options.locale]) {
+                this.options.locale = $.fn.formValidation.DEFAULT_OPTIONS.locale;
+            }
+
+            // Parse the add-on options from HTML attributes
+            if (this.options.declarative === true || this.options.declarative === 'true') {
+                this.options = $.extend(true, this.options, { addOns: this._parseAddOnOptions() });
+            }
+
+            // When pressing Enter on any field in the form, the first submit button will do its job.
+            // The form then will be submitted.
+            // I create a first hidden submit button
+            this.$hiddenButton = $('<button/>')
+                                    .attr('type', 'submit')
+                                    .prependTo(this.$form)
+                                    .addClass('fv-hidden-submit')
+                                    .css({ display: 'none', width: 0, height: 0 });
+
+            this.$form
+                .on('click.' +  this._namespace, '[type="submit"]', function(e) {
+                    // #746: Check if the button click handler returns false
+                    if (!e.isDefaultPrevented()) {
+                        var $target = $(e.target),
+                            // The button might contain HTML tag
+                            $button = $target.is('[type="submit"]') ? $target.eq(0) : $target.parent('[type="submit"]').eq(0);
+
+                        // Don't perform validation when clicking on the submit button/input which
+                        // aren't defined by the 'button.selector' option
+                        if (that.options.button.selector && !$button.is(that.options.button.selector) && !$button.is(that.$hiddenButton)) {
+                            that.$form.off('submit.' + that._namespace).submit();
+                            // Fix the issue where 'formnovalidate' causes IE to send two postbacks to server
+                            return false;
+                        }
+                    }
+                });
+
+            for (var field in this.options.fields) {
+                this._initField(field);
+            }
+
+            // Init the add-ons
+            for (var addOn in this.options.addOns) {
+                if ('function' === typeof FormValidation.AddOn[addOn].init) {
+                    FormValidation.AddOn[addOn].init(this, this.options.addOns[addOn]);
+                }
+            }
+
+            this.$form.trigger($.Event(this.options.events.formInit), {
+                bv: this,   // Support backward
+                fv: this,
+                options: this.options
+            });
+
+            // Prepare the events
+            if (this.options.onPreValidate) {
+                this.$form.on(this.options.events.formPreValidate, function(e) {
+                    FormValidation.Helper.call(that.options.onPreValidate, [e]);
+                });
+            }
+            if (this.options.onSuccess) {
+                this.$form.on(this.options.events.formSuccess, function(e) {
+                    FormValidation.Helper.call(that.options.onSuccess, [e]);
+                });
+            }
+            if (this.options.onError) {
+                this.$form.on(this.options.events.formError, function(e) {
+                    FormValidation.Helper.call(that.options.onError, [e]);
+                });
+            }
+            if (this.options.onReset) {
+                this.$form.on(this.options.events.formReset, function(e) {
+                    FormValidation.Helper.call(that.options.onReset, [e]);
+                });
+            }
+        },
+
+        /**
+         * Init field
+         *
+         * @param {String|jQuery} field The field name or field element
+         */
+        _initField: function(field) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    fields.attr('data-' + ns + '-field', field);
+                    break;
+                default:
+                    break;
+            }
+
+            // We don't need to validate non-existing fields
+            if (fields.length === 0) {
+                return;
+            }
+
+            if (this.options.fields[field] === null || this.options.fields[field].validators === null) {
+                return;
+            }
+
+            var validators = this.options.fields[field].validators,
+                validatorName,
+                alias;
+            for (validatorName in validators) {
+                alias = validators[validatorName].alias || validatorName;
+                if (!FormValidation.Validator[alias]) {
+                    delete this.options.fields[field].validators[validatorName];
+                }
+            }
+            if (this.options.fields[field].enabled === null) {
+                this.options.fields[field].enabled = true;
+            }
+
+            var that      = this,
+                total     = fields.length,
+                type      = fields.attr('type'),
+                updateAll = (total === 1) || ('radio' === type) || ('checkbox' === type),
+                trigger   = this._getFieldTrigger(fields.eq(0)),
+                clazz     = this.options.err.clazz.split(' ').join('.'),
+                events    = $.map(trigger, function(item) {
+                    return item + '.update.' + ns;
+                }).join(' ');
+
+            for (var i = 0; i < total; i++) {
+                var $field    = fields.eq(i),
+                    row       = this.options.fields[field].row || this.options.row.selector,
+                    $parent   = $field.closest(row),
+                    // Allow user to indicate where the error messages are shown
+                    // Support backward
+                    container = ('function' === typeof (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container))
+                                ? (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container).call(this, $field, this)
+                                : (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container),
+                    $message  = (container && container !== 'tooltip' && container !== 'popover') ? $(container) : this._getMessageContainer($field, row);
+
+                if (container && container !== 'tooltip' && container !== 'popover') {
+                    $message.addClass(this.options.err.clazz);
+                }
+
+                // Remove all error messages and feedback icons
+                $message.find('.' + clazz + '[data-' + ns + '-validator][data-' + ns + '-for="' + field + '"]').remove();
+                $parent.find('i[data-' + ns + '-icon-for="' + field + '"]').remove();
+
+                // Whenever the user change the field value, mark it as not validated yet
+                $field.off(events).on(events, function() {
+                    that.updateStatus($(this), that.STATUS_NOT_VALIDATED);
+                });
+
+                // Create help block elements for showing the error messages
+                $field.data(ns + '.messages', $message);
+                for (validatorName in validators) {
+                    $field.data(ns + '.result.' + validatorName, this.STATUS_NOT_VALIDATED);
+
+                    if (!updateAll || i === total - 1) {
+                        $('<small/>')
+                            .css('display', 'none')
+                            .addClass(this.options.err.clazz)
+                            .attr('data-' + ns + '-validator', validatorName)
+                            .attr('data-' + ns + '-for', field)
+                            .attr('data-' + ns + '-result', this.STATUS_NOT_VALIDATED)
+                            .html(this._getMessage(field, validatorName))
+                            .appendTo($message);
+                    }
+
+                    // Init the validator
+                    alias = validators[validatorName].alias || validatorName;
+                    if ('function' === typeof FormValidation.Validator[alias].init) {
+                        FormValidation.Validator[alias].init(this, $field, this.options.fields[field].validators[validatorName], validatorName);
+                    }
+                }
+
+                // Prepare the feedback icons
+                if (this.options.fields[field].icon !== false && this.options.fields[field].icon !== 'false'
+                    && this.options.icon
+                    && this.options.icon.valid && this.options.icon.invalid && this.options.icon.validating
+                    && (!updateAll || i === total - 1))
+                {
+                    // $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid).addClass(this.options.row.feedback);
+                    // Keep error messages which are populated from back-end
+                    $parent.addClass(this.options.row.feedback);
+                    var $icon = $('<i/>')
+                                    .css('display', 'none')
+                                    .addClass(this.options.icon.feedback)
+                                    .attr('data-' + ns + '-icon-for', field)
+                                    .insertAfter($field);
+
+                    // Store the icon as a data of field element
+                    (!updateAll ? $field : fields).data(ns + '.icon', $icon);
+
+                    if ('tooltip' === container || 'popover' === container) {
+                        (!updateAll ? $field : fields)
+                            .on(this.options.events.fieldError, function() {
+                                $parent.addClass('fv-has-tooltip');
+                            })
+                            .on(this.options.events.fieldSuccess, function() {
+                                $parent.removeClass('fv-has-tooltip');
+                            });
+
+                        $field
+                            // Show tooltip/popover message when field gets focus
+                            .off('focus.container.' + ns)
+                            .on('focus.container.' + ns, function() {
+                                that._showTooltip($(this), container);
+                            })
+                            // and hide them when losing focus
+                            .off('blur.container.' + ns)
+                            .on('blur.container.' + ns, function() {
+                                that._hideTooltip($(this), container);
+                            });
+                    }
+
+                    if ('string' === typeof this.options.fields[field].icon && this.options.fields[field].icon !== 'true') {
+                        $icon.appendTo($(this.options.fields[field].icon));
+                    } else {
+                        this._fixIcon($field, $icon);
+                    }
+                }
+            }
+
+            // Sort the validators by priority
+            var sortedByPriority = [];
+            for (validatorName in validators) {
+                alias = validators[validatorName].alias || validatorName;
+
+                // Determine the priority
+                validators[validatorName].priority = parseInt(validators[validatorName].priority
+                                                            || FormValidation.Validator[alias].priority
+                                                            || 1, 10);
+                sortedByPriority.push({
+                    validator: validatorName,
+                    priority: validators[validatorName].priority
+                });
+            }
+            sortedByPriority = sortedByPriority.sort(function(a, b) {
+                return a.priority - b.priority;
+            });
+
+            // Prepare the events
+            fields
+                .data(ns + '.validators', sortedByPriority)
+                .on(this.options.events.fieldSuccess, function(e, data) {
+                    var onSuccess = that.getOptions(data.field, null, 'onSuccess');
+                    if (onSuccess) {
+                        FormValidation.Helper.call(onSuccess, [e, data]);
+                    }
+                })
+                .on(this.options.events.fieldError, function(e, data) {
+                    var onError = that.getOptions(data.field, null, 'onError');
+                    if (onError) {
+                        FormValidation.Helper.call(onError, [e, data]);
+                    }
+                })
+                .on(this.options.events.fieldReset, function(e, data) {
+                    var onReset = that.getOptions(data.field, null, 'onReset');
+                    if (onReset) {
+                        FormValidation.Helper.call(onReset, [e, data]);
+                    }
+                })
+                .on(this.options.events.fieldStatus, function(e, data) {
+                    var onStatus = that.getOptions(data.field, null, 'onStatus');
+                    if (onStatus) {
+                        FormValidation.Helper.call(onStatus, [e, data]);
+                    }
+                })
+                .on(this.options.events.validatorError, function(e, data) {
+                    var onError = that.getOptions(data.field, data.validator, 'onError');
+                    if (onError) {
+                        FormValidation.Helper.call(onError, [e, data]);
+                    }
+                })
+                .on(this.options.events.validatorIgnored, function(e, data) {
+                    var onIgnored = that.getOptions(data.field, data.validator, 'onIgnored');
+                    if (onIgnored) {
+                        FormValidation.Helper.call(onIgnored, [e, data]);
+                    }
+                })
+                .on(this.options.events.validatorSuccess, function(e, data) {
+                    var onSuccess = that.getOptions(data.field, data.validator, 'onSuccess');
+                    if (onSuccess) {
+                        FormValidation.Helper.call(onSuccess, [e, data]);
+                    }
+                });
+
+            // Set live mode
+            this.onLiveChange(fields, 'live', function() {
+                if (that._exceedThreshold($(this))) {
+                    that.validateField($(this));
+                }
+            });
+
+            fields.trigger($.Event(this.options.events.fieldInit), {
+                bv: this,   // Support backward
+                fv: this,
+                field: field,
+                element: fields
+            });
+        },
+
+        /**
+         * Check if the field is excluded.
+         * Returning true means that the field will not be validated
+         *
+         * @param {jQuery} $field The field element
+         * @returns {Boolean}
+         */
+        _isExcluded: function($field) {
+            var ns           = this._namespace,
+                excludedAttr = $field.attr('data-' + ns + '-excluded'),
+                // I still need to check the 'name' attribute while initializing the field
+                field        = $field.attr('data-' + ns + '-field') || $field.attr('name');
+
+            switch (true) {
+                case (!!field && this.options.fields && this.options.fields[field] && (this.options.fields[field].excluded === 'true' || this.options.fields[field].excluded === true)):
+                case (excludedAttr === 'true'):
+                case (excludedAttr === ''):
+                    return true;
+
+                case (!!field && this.options.fields && this.options.fields[field] && (this.options.fields[field].excluded === 'false' || this.options.fields[field].excluded === false)):
+                case (excludedAttr === 'false'):
+                    return false;
+
+                case (!!field && this.options.fields && this.options.fields[field] && 'function' === typeof this.options.fields[field].excluded):
+                    return this.options.fields[field].excluded.call(this, $field, this);
+
+                case (!!field && this.options.fields && this.options.fields[field] && 'string' === typeof this.options.fields[field].excluded):
+                case (excludedAttr):
+                    return FormValidation.Helper.call(this.options.fields[field].excluded, [$field, this]);
+
+                default:
+                    if (this.options.excluded) {
+                        // Convert to array first
+                        if ('string' === typeof this.options.excluded) {
+                            this.options.excluded = $.map(this.options.excluded.split(','), function(item) {
+                                // Trim the spaces
+                                return $.trim(item);
+                            });
+                        }
+
+                        var length = this.options.excluded.length;
+                        for (var i = 0; i < length; i++) {
+                            if (('string' === typeof this.options.excluded[i] && $field.is(this.options.excluded[i]))
+                                || ('function' === typeof this.options.excluded[i] && this.options.excluded[i].call(this, $field, this) === true))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                    return false;
+            }
+        },
+
+        /**
+         * Get a field changed trigger event
+         *
+         * @param {jQuery} $field The field element
+         * @returns {String[]} The event names triggered on field change
+         */
+        _getFieldTrigger: function($field) {
+            var ns      = this._namespace,
+                trigger = $field.data(ns + '.trigger');
+            if (trigger) {
+                return trigger;
+            }
+
+            // IE10/11 auto fires input event of elements using the placeholder attribute
+            // https://connect.microsoft.com/IE/feedback/details/856700/
+            var type  = $field.attr('type'),
+                name  = $field.attr('data-' + ns + '-field'),
+                event = ('radio' === type || 'checkbox' === type || 'file' === type || 'SELECT' === $field.get(0).tagName)
+                        ? 'change'
+                        : (this._ieVersion >= 10 && $field.attr('placeholder') ? 'keyup' : this._changeEvent);
+            trigger   = ((this.options.fields[name] ? this.options.fields[name].trigger : null) || this.options.trigger || event).split(' ');
+
+            // Since the trigger data is used many times, I need to cache it to use later
+            $field.data(ns + '.trigger', trigger);
+
+            return trigger;
+        },
+
+        /**
+         * Get the error message for given field and validator
+         *
+         * @param {String} field The field name
+         * @param {String} validatorName The validator name
+         * @returns {String}
+         */
+        _getMessage: function(field, validatorName) {
+            if (!this.options.fields[field] || !this.options.fields[field].validators) {
+                return '';
+            }
+            var validators = this.options.fields[field].validators,
+                alias      = (validators[validatorName] && validators[validatorName].alias) ? validators[validatorName].alias : validatorName;
+            if (!FormValidation.Validator[alias]) {
+                return '';
+            }
+
+            switch (true) {
+                case !!validators[validatorName].message:
+                    return validators[validatorName].message;
+                case !!this.options.fields[field].message:
+                    return this.options.fields[field].message;
+                case !!this.options.message:
+                    return this.options.message;
+                case (!!FormValidation.I18n[this.options.locale] && !!FormValidation.I18n[this.options.locale][alias] && !!FormValidation.I18n[this.options.locale][alias]['default']):
+                    return FormValidation.I18n[this.options.locale][alias]['default'];
+                default:
+                    return this.DEFAULT_MESSAGE;
+            }
+        },
+
+        /**
+         * Get the element to place the error messages
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} row
+         * @returns {jQuery}
+         */
+        _getMessageContainer: function($field, row) {
+            if (!this.options.err.parent) {
+                throw new Error('The err.parent option is not defined');
+            }
+
+            var $parent = $field.parent();
+            if ($parent.is(row)) {
+                return $parent;
+            }
+
+            var cssClasses = $parent.attr('class');
+            if (!cssClasses) {
+                return this._getMessageContainer($parent, row);
+            }
+
+            if (this.options.err.parent.test(cssClasses)) {
+                return $parent;
+            }
+
+            return this._getMessageContainer($parent, row);
+        },
+
+        /**
+         * Parse the add-on options from HTML attributes
+         *
+         * @returns {Object}
+         */
+        _parseAddOnOptions: function() {
+            var ns     = this._namespace,
+                names  = this.$form.attr('data-' + ns + '-addons'),
+                addOns = this.options.addOns || {};
+
+            if (names) {
+                names = names.replace(/\s/g, '').split(',');
+                for (var i = 0; i < names.length; i++) {
+                    if (!addOns[names[i]]) {
+                        addOns[names[i]] = {};
+                    }
+                }
+            }
+
+            // Try to parse each add-on options
+            var addOn, attrMap, attr, option;
+            for (addOn in addOns) {
+                if (!FormValidation.AddOn[addOn]) {
+                    // Add-on is not found
+                    delete addOns[addOn];
+                    continue;
+                }
+
+                attrMap = FormValidation.AddOn[addOn].html5Attributes;
+                if (attrMap) {
+                    for (attr in attrMap) {
+                        option = this.$form.attr('data-' + ns + '-addons-' + addOn.toLowerCase() + '-' + attr.toLowerCase());
+                        if (option) {
+                            addOns[addOn][attrMap[attr]] = option;
+                        }
+                    }
+                }
+            }
+
+            return addOns;
+        },
+
+        /**
+         * Parse the validator options from HTML attributes
+         *
+         * @param {jQuery} $field The field element
+         * @returns {Object}
+         */
+        _parseOptions: function($field) {
+            var ns           = this._namespace,
+                field        = $field.attr('name') || $field.attr('data-' + ns + '-field'),
+                validators   = {},
+                aliasAttr    = new RegExp('^data-' + ns + '-([a-z]+)-alias$'),
+                validatorSet = $.extend({}, FormValidation.Validator),
+                validator,
+                v,          // Validator name
+                attrName,
+                enabled,
+                optionName,
+                optionAttrName,
+                optionValue,
+                html5AttrName,
+                html5AttrMap;
+
+            // Determine whether the alias validator is used by checking the data-fv-validator-alias attribute
+            $.each($field.get(0).attributes, function(i, attribute) {
+                if (attribute.value && aliasAttr.test(attribute.name)) {
+                    v = attribute.name.split('-')[2];
+                    if (validatorSet[attribute.value]) {
+                        validatorSet[v]       = validatorSet[attribute.value];
+                        validatorSet[v].alias = attribute.value;
+                    }
+                }
+            });
+
+            for (v in validatorSet) {
+                validator    = validatorSet[v];
+                attrName     = 'data-' + ns + '-' + v.toLowerCase(),
+                enabled      = $field.attr(attrName) + '';
+                html5AttrMap = ('function' === typeof validator.enableByHtml5) ? validator.enableByHtml5($field) : null;
+
+                if ((html5AttrMap && enabled !== 'false')
+                    || (html5AttrMap !== true && ('' === enabled || 'true' === enabled || attrName === enabled.toLowerCase())))
+                {
+                    // Try to parse the options via attributes
+                    validator.html5Attributes = $.extend({}, {
+                                                    message: 'message',
+                                                    onerror: 'onError',
+                                                    onreset: 'onReset',
+                                                    onsuccess: 'onSuccess',
+                                                    priority: 'priority',
+                                                    transformer: 'transformer'
+                                                }, validator.html5Attributes);
+                    validators[v] = $.extend({}, html5AttrMap === true ? {} : html5AttrMap, validators[v]);
+                    if (validator.alias) {
+                        validators[v].alias = validator.alias;
+                    }
+
+                    for (html5AttrName in validator.html5Attributes) {
+                        optionName     = validator.html5Attributes[html5AttrName];
+                        optionAttrName = 'data-' + ns + '-' + v.toLowerCase() + '-' + html5AttrName;
+                        optionValue    = $field.attr(optionAttrName);
+                        if (optionValue) {
+                            if ('true' === optionValue || optionAttrName === optionValue.toLowerCase()) {
+                                optionValue = true;
+                            } else if ('false' === optionValue) {
+                                optionValue = false;
+                            }
+                            validators[v][optionName] = optionValue;
+                        }
+                    }
+                }
+            }
+
+            var opts = {
+                    autoFocus:   $field.attr('data-' + ns + '-autofocus'),
+                    err:         $field.attr('data-' + ns + '-err-container') || $field.attr('data-' + ns + '-container'), // Support backward
+                    enabled:     $field.attr('data-' + ns + '-enabled'),
+                    excluded:    $field.attr('data-' + ns + '-excluded'),
+                    icon:        $field.attr('data-' + ns + '-icon') || $field.attr('data-' + ns + '-feedbackicons') || (this.options.fields && this.options.fields[field] ? this.options.fields[field].feedbackIcons : null), // Support backward
+                    message:     $field.attr('data-' + ns + '-message'),
+                    onError:     $field.attr('data-' + ns + '-onerror'),
+                    onReset:     $field.attr('data-' + ns + '-onreset'),
+                    onStatus:    $field.attr('data-' + ns + '-onstatus'),
+                    onSuccess:   $field.attr('data-' + ns + '-onsuccess'),
+                    row:         $field.attr('data-' + ns + '-row') || $field.attr('data-' + ns + '-group') || (this.options.fields && this.options.fields[field] ? this.options.fields[field].group : null), // Support backward
+                    selector:    $field.attr('data-' + ns + '-selector'),
+                    threshold:   $field.attr('data-' + ns + '-threshold'),
+                    transformer: $field.attr('data-' + ns + '-transformer'),
+                    trigger:     $field.attr('data-' + ns + '-trigger'),
+                    verbose:     $field.attr('data-' + ns + '-verbose'),
+                    validators:  validators
+                },
+                emptyOptions    = $.isEmptyObject(opts),        // Check if the field options are set using HTML attributes
+                emptyValidators = $.isEmptyObject(validators);  // Check if the field validators are set using HTML attributes
+
+            if (!emptyValidators || (!emptyOptions && this.options.fields && this.options.fields[field])) {
+                //opts.validators = validators;
+                return opts;
+            } else {
+                return null;
+            }
+        },
+
+        /**
+         * Called when all validations are completed
+         */
+        _submit: function() {
+            var isValid = this.isValid();
+            if (isValid === null) {
+                return;
+            }
+
+            var eventType = isValid ? this.options.events.formSuccess : this.options.events.formError,
+                e         = $.Event(eventType);
+
+            this.$form.trigger(e);
+
+            // Call default handler
+            // Check if whether the submit button is clicked
+            if (this.$submitButton) {
+                isValid ? this._onSuccess(e) : this._onError(e);
+            }
+        },
+
+        // ~~~~~~
+        // Events
+        // ~~~~~~
+
+        /**
+         * The default handler of error.form.fv event.
+         * It will be called when there is a invalid field
+         *
+         * @param {jQuery.Event} e The jQuery event object
+         */
+        _onError: function(e) {
+            if (e.isDefaultPrevented()) {
+                return;
+            }
+
+            if ('submitted' === this.options.live) {
+                // Enable live mode
+                this.options.live = 'enabled';
+
+                var that = this;
+                for (var field in this.options.fields) {
+                    (function(f) {
+                        var fields  = that.getFieldElements(f);
+                        if (fields.length) {
+                            that.onLiveChange(fields, 'live', function() {
+                                if (that._exceedThreshold($(this))) {
+                                    that.validateField($(this));
+                                }
+                            });
+                        }
+                    })(field);
+                }
+            }
+
+            // Determined the first invalid field which will be focused on automatically
+            var ns = this._namespace;
+            for (var i = 0; i < this.$invalidFields.length; i++) {
+                var $field    = this.$invalidFields.eq(i),
+                    autoFocus = this.isOptionEnabled($field.attr('data-' + ns + '-field'), 'autoFocus');
+                if (autoFocus) {
+                    // Focus the field
+                    $field.focus();
+                    break;
+                }
+            }
+        },
+
+        /**
+         * Called after validating a field element
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} [validatorName] The validator name
+         */
+        _onFieldValidated: function($field, validatorName) {
+            var ns            = this._namespace,
+                field         = $field.attr('data-' + ns + '-field'),
+                validators    = this.options.fields[field].validators,
+                counter       = {},
+                numValidators = 0,
+                data          = {
+                    bv: this,   // Support backward
+                    fv: this,
+                    field: field,
+                    element: $field,
+                    validator: validatorName,
+                    result: $field.data(ns + '.response.' + validatorName)
+                };
+
+            // Trigger an event after given validator completes
+            if (validatorName) {
+                switch ($field.data(ns + '.result.' + validatorName)) {
+                    case this.STATUS_INVALID:
+                        $field.trigger($.Event(this.options.events.validatorError), data);
+                        break;
+                    case this.STATUS_VALID:
+                        $field.trigger($.Event(this.options.events.validatorSuccess), data);
+                        break;
+                    case this.STATUS_IGNORED:
+                        $field.trigger($.Event(this.options.events.validatorIgnored), data);
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            counter[this.STATUS_NOT_VALIDATED] = 0;
+            counter[this.STATUS_VALIDATING]    = 0;
+            counter[this.STATUS_INVALID]       = 0;
+            counter[this.STATUS_VALID]         = 0;
+            counter[this.STATUS_IGNORED]       = 0;
+
+            for (var v in validators) {
+                if (validators[v].enabled === false) {
+                    continue;
+                }
+
+                numValidators++;
+                var result = $field.data(ns + '.result.' + v);
+                if (result) {
+                    counter[result]++;
+                }
+            }
+
+            // The sum of valid fields now also include ignored fields
+            if (counter[this.STATUS_VALID] + counter[this.STATUS_IGNORED] === numValidators) {
+                // Remove from the list of invalid fields
+                this.$invalidFields = this.$invalidFields.not($field);
+
+                $field.trigger($.Event(this.options.events.fieldSuccess), data);
+            }
+            // If all validators are completed and there is at least one validator which doesn't pass
+            else if ((counter[this.STATUS_NOT_VALIDATED] === 0 || !this.isOptionEnabled(field, 'verbose')) && counter[this.STATUS_VALIDATING] === 0 && counter[this.STATUS_INVALID] > 0) {
+                // Add to the list of invalid fields
+                this.$invalidFields = this.$invalidFields.add($field);
+
+                $field.trigger($.Event(this.options.events.fieldError), data);
+            }
+        },
+
+        /**
+         * The default handler of success.form.fv event.
+         * It will be called when all the fields are valid
+         *
+         * @param {jQuery.Event} e The jQuery event object
+         */
+        _onSuccess: function(e) {
+            if (e.isDefaultPrevented()) {
+                return;
+            }
+
+            // Submit the form
+            this.disableSubmitButtons(true).defaultSubmit();
+        },
+
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        // Abstract methods
+        // Need to be implemented by sub-class that supports specific framework
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+        },
+
+        /**
+         * Create a tooltip or popover
+         * It will be shown when focusing on the field
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} message The message
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _createTooltip: function($field, message, type) {
+        },
+
+        /**
+         * Destroy the tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _destroyTooltip: function($field, type) {
+        },
+
+        /**
+         * Hide a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _hideTooltip: function($field, type) {
+        },
+
+        /**
+         * Show a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _showTooltip: function($field, type) {
+        },
+
+        // ~~~~~~~~~~~~~~
+        // Public methods
+        // ~~~~~~~~~~~~~~
+
+        /**
+         * Submit the form using default submission.
+         * It also does not perform any validations when submitting the form
+         */
+        defaultSubmit: function() {
+            var ns = this._namespace;
+            if (this.$submitButton) {
+                // Create hidden input to send the submit buttons
+                $('<input/>')
+                    .attr({
+                        'type': 'hidden',
+                        name: this.$submitButton.attr('name')
+                    })
+                    .attr('data-' + ns + '-submit-hidden', '')
+                    .val(this.$submitButton.val())
+                    .appendTo(this.$form);
+            }
+
+            // Submit form
+            this.$form.off('submit.' + ns).submit();
+        },
+
+        /**
+         * Disable/enable submit buttons
+         *
+         * @param {Boolean} disabled Can be true or false
+         * @returns {FormValidation.Base}
+         */
+        disableSubmitButtons: function(disabled) {
+            if (!disabled) {
+                this.$form
+                    .find(this.options.button.selector)
+                        .removeAttr('disabled')
+                        .removeClass(this.options.button.disabled);
+            } else if (this.options.live !== 'disabled') {
+                // Don't disable if the live validating mode is disabled
+                this.$form
+                    .find(this.options.button.selector)
+                        .attr('disabled', 'disabled')
+                        .addClass(this.options.button.disabled);
+            }
+
+            return this;
+        },
+
+        /**
+         * Retrieve the field elements by given name
+         *
+         * @param {String} field The field name
+         * @returns {null|jQuery[]}
+         */
+        getFieldElements: function(field) {
+            if (!this._cacheFields[field]) {
+                if (this.options.fields[field] && this.options.fields[field].selector) {
+                    // Look for the field inside the form first
+                    var f = this.$form.find(this.options.fields[field].selector);
+                    // If not found, search in entire document
+                    this._cacheFields[field] = f.length ? f : $(this.options.fields[field].selector);
+                } else {
+                    this._cacheFields[field] = this.$form.find('[name="' + field + '"]');
+                }
+            }
+
+            return this._cacheFields[field];
+        },
+
+        /**
+         * Get the field value after applying transformer
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} validatorName The validator name
+         * @returns {String}
+         */
+        getFieldValue: function(field, validatorName) {
+            var $field, ns = this._namespace;
+            if ('string' === typeof field) {
+                $field = this.getFieldElements(field);
+                if ($field.length === 0) {
+                    return null;
+                }
+            } else {
+                $field = field;
+                field  = $field.attr('data-' + ns + '-field');
+            }
+
+            if (!field || !this.options.fields[field]) {
+                return $field.val();
+            }
+
+            var transformer = (this.options.fields[field].validators && this.options.fields[field].validators[validatorName]
+                                ? this.options.fields[field].validators[validatorName].transformer : null)
+                                || this.options.fields[field].transformer;
+            return transformer ? FormValidation.Helper.call(transformer, [$field, validatorName, this]) : $field.val();
+        },
+
+        /**
+         * Get the namespace
+         *
+         * @returns {String}
+         */
+        getNamespace: function() {
+            return this._namespace;
+        },
+
+        /**
+         * Get the field options
+         *
+         * @param {String|jQuery} [field] The field name or field element. If it is not set, the method returns the form options
+         * @param {String} [validator] The name of validator. It null, the method returns form options
+         * @param {String} [option] The option name
+         * @return {String|Object}
+         */
+        getOptions: function(field, validator, option) {
+            var ns = this._namespace;
+            if (!field) {
+                return option ? this.options[option] : this.options;
+            }
+            if ('object' === typeof field) {
+                field = field.attr('data-' + ns + '-field');
+            }
+            if (!this.options.fields[field]) {
+                return null;
+            }
+
+            var options = this.options.fields[field];
+            if (!validator) {
+                return option ? options[option] : options;
+            }
+            if (!options.validators || !options.validators[validator]) {
+                return null;
+            }
+
+            return option ? options.validators[validator][option] : options.validators[validator];
+        },
+
+        /**
+         * Get the validating result of field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} validatorName The validator name
+         * @returns {String} The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID', 'VALID' or 'IGNORED'
+         */
+        getStatus: function(field, validatorName) {
+            var ns = this._namespace;
+            switch (typeof field) {
+                case 'object':
+                    return field.data(ns + '.result.' + validatorName);
+                case 'string':
+                /* falls through */
+                default:
+                    return this.getFieldElements(field).eq(0).data(ns + '.result.' + validatorName);
+            }
+        },
+
+        /**
+         * Check whether or not a field option is enabled
+         *
+         * @param {String} field The field name
+         * @param {String} option The option name, "verbose", "autoFocus", for example
+         * @returns {Boolean}
+         */
+        isOptionEnabled: function(field, option) {
+            if (this.options.fields[field] && (this.options.fields[field][option] === 'true' || this.options.fields[field][option] === true)) {
+                return true;
+            }
+            if (this.options.fields[field] && (this.options.fields[field][option] === 'false' || this.options.fields[field][option] === false)) {
+                return false;
+            }
+            return this.options[option] === 'true' || this.options[option] === true;
+        },
+
+        /**
+         * Check the form validity
+         *
+         * @returns {Boolean|null} Returns one of three values
+         * - true, if all fields are valid
+         * - false, if there is one invalid field
+         * - null, if there is at least one field which is not validated yet or being validated
+         */
+        isValid: function() {
+            for (var field in this.options.fields) {
+                var isValidField = this.isValidField(field);
+                if (isValidField === null) {
+                    return null;
+                }
+                if (isValidField === false) {
+                    return false;
+                }
+            }
+
+            return true;
+        },
+
+        /**
+         * Check if all fields inside a given container are valid.
+         * It's useful when working with a wizard-like such as tab, collapse
+         *
+         * @param {String|jQuery} container The container selector or element
+         * @returns {Boolean|null} Returns one of three values
+         * - true, if all fields inside the container are valid
+         * - false, if there is one invalid field inside the container
+         * - null, if the container consists of at least one field which is not validated yet or being validated
+         */
+        isValidContainer: function(container) {
+            var that       = this,
+                ns         = this._namespace,
+                fields     = [],
+                $container = ('string' === typeof container) ? $(container) : container;
+            if ($container.length === 0) {
+                return true;
+            }
+
+            $container.find('[data-' + ns + '-field]').each(function() {
+                var $field = $(this);
+                if (!that._isExcluded($field)) {
+                    fields.push($field);
+                }
+            });
+
+            var total = fields.length,
+                clazz = this.options.err.clazz.split(' ').join('.');
+            for (var i = 0; i < total; i++) {
+                var $f      = fields[i],
+                    field   = $f.attr('data-' + ns + '-field'),
+                    $errors = $f.data(ns + '.messages')
+                                .find('.' + clazz + '[data-' + ns + '-validator][data-' + ns + '-for="' + field + '"]');
+
+                if (this.options.fields && this.options.fields[field]
+                    && (this.options.fields[field].enabled === 'false' || this.options.fields[field].enabled === false))
+                {
+                    continue;
+                }
+
+                if ($errors.filter('[data-' + ns + '-result="' + this.STATUS_INVALID + '"]').length > 0) {
+                    return false;
+                }
+
+                // If the field is not validated
+                if ($errors.filter('[data-' + ns + '-result="' + this.STATUS_NOT_VALIDATED + '"]').length > 0
+                    || $errors.filter('[data-' + ns + '-result="' + this.STATUS_VALIDATING + '"]').length > 0)
+                {
+                    return null;
+                }
+            }
+
+            return true;
+        },
+
+        /**
+         * Check if the field is valid or not
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @returns {Boolean|null} Returns one of three values
+         * - true, if the field passes all validators
+         * - false, if the field doesn't pass any validator
+         * - null, if there is at least one validator which isn't validated yet or being validated
+         */
+        isValidField: function(field) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+            if (fields.length === 0 || !this.options.fields[field]
+                || this.options.fields[field].enabled === 'false' || this.options.fields[field].enabled === false)
+            {
+                return true;
+            }
+
+            var type  = fields.attr('type'),
+                total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length,
+                $field, validatorName, status;
+            for (var i = 0; i < total; i++) {
+                $field = fields.eq(i);
+                if (this._isExcluded($field)) {
+                    continue;
+                }
+
+                for (validatorName in this.options.fields[field].validators) {
+                    if (this.options.fields[field].validators[validatorName].enabled === false) {
+                        continue;
+                    }
+
+                    status = $field.data(ns + '.result.' + validatorName);
+                    if (status === this.STATUS_VALIDATING || status === this.STATUS_NOT_VALIDATED) {
+                        return null;
+                    } else if (status === this.STATUS_INVALID) {
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        },
+
+        /**
+         * Detach a handler function for a field live change event
+         *
+         * @param {jQuery[]} $fields The field elements
+         * @param {String} namespace The event namespace
+         * @returns {FormValidation.Base}
+         */
+        offLiveChange: function($fields, namespace) {
+            if ($fields === null || $fields.length === 0) {
+                return this;
+            }
+
+            var ns      = this._namespace,
+                trigger = this._getFieldTrigger($fields.eq(0)),
+                events  = $.map(trigger, function(item) {
+                    return item + '.' + namespace + '.' + ns;
+                }).join(' ');
+
+            $fields.off(events);
+            return this;
+        },
+
+        /**
+         * Attach a handler function for a field live change event
+         *
+         * @param {jQuery[]} $fields The field elements
+         * @param {String} namespace The event namespace
+         * @param {Function} handler The handler function
+         * @returns {FormValidation.Base}
+         */
+        onLiveChange: function($fields, namespace, handler) {
+            if ($fields === null || $fields.length === 0) {
+                return this;
+            }
+
+            var ns      = this._namespace,
+                trigger = this._getFieldTrigger($fields.eq(0)),
+                events  = $.map(trigger, function(item) {
+                    return item + '.' + namespace + '.' + ns;
+                }).join(' ');
+
+            switch (this.options.live) {
+                case 'submitted':
+                    break;
+                case 'disabled':
+                    $fields.off(events);
+                    break;
+                case 'enabled':
+                /* falls through */
+                default:
+                    $fields.off(events).on(events, function(e) {
+                        handler.apply(this, arguments);
+                    });
+                    break;
+            }
+
+            return this;
+        },
+
+        /**
+         * Update the error message
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} validator The validator name
+         * @param {String} message The message
+         * @returns {FormValidation.Base}
+         */
+        updateMessage: function(field, validator, message) {
+            var ns      = this._namespace,
+                $fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    $fields = field;
+                    field   = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    $fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            var clazz = this.options.err.clazz.split(' ').join('.');
+            $fields.each(function() {
+                $(this)
+                    .data(ns + '.messages')
+                    .find('.' + clazz + '[data-' + ns + '-validator="' + validator + '"][data-' + ns + '-for="' + field + '"]').html(message);
+            });
+
+            return this;
+        },
+
+        /**
+         * Update all validating results of field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} status The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID', 'VALID' or 'IGNORED'
+         * @param {String} [validatorName] The validator name. If null, the method updates validity result for all validators
+         * @returns {FormValidation.Base}
+         */
+        updateStatus: function(field, status, validatorName) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            if (!field || !this.options.fields[field]) {
+                return this;
+            }
+
+            if (status === this.STATUS_NOT_VALIDATED) {
+                // Reset the flag
+                // To prevent the form from doing submit when a deferred validator returns true while typing
+                this._submitIfValid = false;
+            }
+
+            var that  = this,
+                type  = fields.attr('type'),
+                row   = this.options.fields[field].row || this.options.row.selector,
+                total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length,
+                clazz = this.options.err.clazz.split(' ').join('.');
+
+            for (var i = 0; i < total; i++) {
+                var $field       = fields.eq(i);
+                if (this._isExcluded($field)) {
+                    continue;
+                }
+
+                var $parent      = $field.closest(row),
+                    $message     = $field.data(ns + '.messages'),
+                    $allErrors   = $message.find('.' + clazz + '[data-' + ns + '-validator][data-' + ns + '-for="' + field + '"]'),
+                    $errors      = validatorName ? $allErrors.filter('[data-' + ns + '-validator="' + validatorName + '"]') : $allErrors,
+                    $icon        = $field.data(ns + '.icon'),
+                    // Support backward
+                    container    = ('function' === typeof (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container))
+                                    ? (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container).call(this, $field, this)
+                                    : (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container),
+                    isValidField = null,
+                    isValidating,
+                    isNotValidated;
+
+                // Update status
+                if (validatorName) {
+                    $field.data(ns + '.result.' + validatorName, status);
+                } else {
+                    for (var v in this.options.fields[field].validators) {
+                        $field.data(ns + '.result.' + v, status);
+                    }
+                }
+
+                // Show/hide error elements and feedback icons
+                $errors.attr('data-' + ns + '-result', status);
+
+                switch (status) {
+                    case this.STATUS_VALIDATING:
+                        isValidField = null;
+                        this.disableSubmitButtons(true);
+                        $field.removeClass(this.options.control.valid).removeClass(this.options.control.invalid);
+                        $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid);
+                        if ($icon) {
+                            $icon.removeClass(this.options.icon.valid).removeClass(this.options.icon.invalid).addClass(this.options.icon.validating).show();
+                        }
+                        break;
+
+                    case this.STATUS_INVALID:
+                        isValidField = false;
+                        this.disableSubmitButtons(true);
+                        $field.removeClass(this.options.control.valid).addClass(this.options.control.invalid);
+                        $parent.removeClass(this.options.row.valid).addClass(this.options.row.invalid);
+                        if ($icon) {
+                            $icon.removeClass(this.options.icon.valid).removeClass(this.options.icon.validating).addClass(this.options.icon.invalid).show();
+                        }
+                        break;
+
+                    case this.STATUS_IGNORED:       // Treat ignored fields like they are valid with some specialties
+                    case this.STATUS_VALID:
+                        isValidating   = ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_VALIDATING +'"]').length > 0);
+                        isNotValidated = ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_NOT_VALIDATED +'"]').length > 0);
+
+                        var numIgnored = $allErrors.filter('[data-' + ns + '-result="' + this.STATUS_IGNORED +'"]').length;
+
+                        // If the field is valid (passes all validators)
+                        isValidField   = (isValidating || isNotValidated)     // There are some validators that have not done
+                                        ? null
+                                        // All validators are completed
+                                        : ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_VALID +'"]').length + numIgnored === $allErrors.length);
+
+                        $field.removeClass(this.options.control.valid).removeClass(this.options.control.invalid);
+
+                        if (isValidField === true) {
+                            this.disableSubmitButtons(this.isValid() === false);
+                            if (status === this.STATUS_VALID) {
+                                $field.addClass(this.options.control.valid);
+                            }
+                        } else if (isValidField === false) {
+                            this.disableSubmitButtons(true);
+                            if (status === this.STATUS_VALID) {
+                                $field.addClass(this.options.control.invalid);
+                            }
+                        }
+
+                        if ($icon) {
+                            $icon.removeClass(this.options.icon.invalid).removeClass(this.options.icon.validating).removeClass(this.options.icon.valid);
+                            if (status === this.STATUS_VALID || numIgnored !== $allErrors.length) {
+                                $icon.addClass(isValidating
+                                                ? this.options.icon.validating
+                                                : (isValidField === null ? '' : (isValidField ? this.options.icon.valid : this.options.icon.invalid)))
+                                     .show();
+                            }
+                        }
+
+                        var isValidContainer = this.isValidContainer($parent);
+                        if (isValidContainer !== null) {
+                            $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid);
+                            if (status === this.STATUS_VALID || numIgnored !== $allErrors.length) {
+                                $parent.addClass(isValidContainer ? this.options.row.valid : this.options.row.invalid);
+                            }
+                        }
+                        break;
+
+                    case this.STATUS_NOT_VALIDATED:
+                    /* falls through */
+                    default:
+                        isValidField = null;
+                        this.disableSubmitButtons(false);
+                        $field.removeClass(this.options.control.valid).removeClass(this.options.control.invalid);
+                        $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid);
+                        if ($icon) {
+                            $icon.removeClass(this.options.icon.valid).removeClass(this.options.icon.invalid).removeClass(this.options.icon.validating).hide();
+                        }
+                        break;
+                }
+
+                if ($icon && ('tooltip' === container || 'popover' === container)) {
+                    (isValidField === false)
+                        // Only show the first error message
+                        ? this._createTooltip($field, $allErrors.filter('[data-' + ns + '-result="' + that.STATUS_INVALID + '"]').eq(0).html(), container)
+                        : this._destroyTooltip($field, container);
+                } else {
+                    (status === this.STATUS_INVALID) ? $errors.show() : $errors.hide();
+                }
+
+                // Trigger an event
+                $field.trigger($.Event(this.options.events.fieldStatus), {
+                    bv: this,   // Support backward
+                    fv: this,
+                    field: field,
+                    element: $field,
+                    status: status,
+                    validator: validatorName
+                });
+                this._onFieldValidated($field, validatorName);
+            }
+
+            return this;
+        },
+
+        /**
+         * Validate the form
+         *
+         * @returns {FormValidation.Base}
+         */
+        validate: function() {
+            if ($.isEmptyObject(this.options.fields)) {
+                this._submit();
+                return this;
+            }
+            this.$form.trigger($.Event(this.options.events.formPreValidate));
+
+            this.disableSubmitButtons(true);
+            this._submitIfValid = false;
+            for (var field in this.options.fields) {
+                this.validateField(field);
+            }
+
+            this._submit();
+            this._submitIfValid = true;
+
+            return this;
+        },
+
+        /**
+         * Validate given field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @returns {FormValidation.Base}
+         */
+        validateField: function(field) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            if (fields.length === 0 || !this.options.fields[field]
+                || this.options.fields[field].enabled === 'false' || this.options.fields[field].enabled === false)
+            {
+                return this;
+            }
+
+            var that       = this,
+                type       = fields.attr('type'),
+                total      = (('radio' === type || 'checkbox' === type) && this.options.live !== 'disabled') ? 1 : fields.length,
+                updateAll  = ('radio' === type || 'checkbox' === type),
+                validators = this.options.fields[field].validators,
+                verbose    = this.isOptionEnabled(field, 'verbose'),
+                validatorName,
+                alias,
+                validateResult;
+
+            for (var i = 0; i < total; i++) {
+                var $field = fields.eq(i);
+                if (this._isExcluded($field)) {
+                    continue;
+                }
+
+                var stop             = false,
+                    sortedByPriority = $field.data(ns + '.validators'),
+                    numValidators    = sortedByPriority.length;
+
+                for (var j = 0; j < numValidators; j++) {
+                    validatorName = sortedByPriority[j].validator;
+                    if ($field.data(ns + '.dfs.' + validatorName)) {
+                        $field.data(ns + '.dfs.' + validatorName).reject();
+                    }
+                    if (stop) {
+                        break;
+                    }
+
+                    // Don't validate field if it is already done
+                    var result = $field.data(ns + '.result.' + validatorName);
+                    if (result === this.STATUS_VALID || result === this.STATUS_INVALID) {
+                        this._onFieldValidated($field, validatorName);
+                        continue;
+                    } else if (validators[validatorName].enabled === false) {
+                        // Changed in v0.6.2:
+                        // When the field validator is disabled, it should be treated as STATUS_IGNORED instead of STATUS_VALID
+                        // By doing that, the field with only disabled and ignored validators will not have success/error class
+                        this.updateStatus(updateAll ? field : $field, this.STATUS_IGNORED, validatorName);
+                        continue;
+                    }
+
+                    $field.data(ns + '.result.' + validatorName, this.STATUS_VALIDATING);
+
+                    // Check whether or not the validator is just an alias of another
+                    alias          = validators[validatorName].alias || validatorName;
+                    validateResult = FormValidation.Validator[alias].validate(this, $field, validators[validatorName], validatorName);
+
+                    // validateResult can be a $.Deferred object ...
+                    if ('object' === typeof validateResult && validateResult.resolve) {
+                        this.updateStatus(updateAll ? field : $field, this.STATUS_VALIDATING, validatorName);
+                        $field.data(ns + '.dfs.' + validatorName, validateResult);
+
+                        validateResult.done(function($f, v, response) {
+                            // v is validator name
+                            $f.removeData(ns + '.dfs.' + v).data(ns + '.response.' + v, response);
+                            if (response.message) {
+                                that.updateMessage($f, v, response.message);
+                            }
+
+                            that.updateStatus(updateAll ? $f.attr('data-' + ns + '-field') : $f,
+                                              response.valid === true ? that.STATUS_VALID : (response.valid === false ? that.STATUS_INVALID : that.STATUS_IGNORED),
+                                              v);
+
+                            if (response.valid && that._submitIfValid === true) {
+                                // If a remote validator returns true and the form is ready to submit, then do it
+                                that._submit();
+                            } else if (response.valid === false && !verbose) {
+                                stop = true;
+                            }
+                        });
+                    }
+                    // ... or object { valid: true/false/null, message: 'dynamic message', otherKey: value, ... }
+                    else if ('object' === typeof validateResult && validateResult.valid !== undefined) {
+                        $field.data(ns + '.response.' + validatorName, validateResult);
+                        if (validateResult.message) {
+                            this.updateMessage(updateAll ? field : $field, validatorName, validateResult.message);
+                        }
+                        this.updateStatus(updateAll ? field : $field,
+                                          validateResult.valid === true ? this.STATUS_VALID : (validateResult.valid === false ? this.STATUS_INVALID : this.STATUS_IGNORED),
+                                          validatorName);
+                        if (validateResult.valid === false && !verbose) {
+                            break;
+                        }
+                    }
+                    // ... or a boolean value
+                    else if ('boolean' === typeof validateResult) {
+                        $field.data(ns + '.response.' + validatorName, validateResult);
+                        this.updateStatus(updateAll ? field : $field, validateResult ? this.STATUS_VALID : this.STATUS_INVALID, validatorName);
+                        if (!validateResult && !verbose) {
+                            break;
+                        }
+                    }
+                    // ... or null
+                    // to indicate that the field should be ignored for current validator
+                    else if (null === validateResult) {
+                        $field.data(ns + '.response.' + validatorName, validateResult);
+                        this.updateStatus(updateAll ? field : $field, this.STATUS_IGNORED, validatorName);
+                    }
+                }
+            }
+
+            return this;
+        },
+
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        // Useful APIs which aren't used internally
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        /**
+         * Add a new field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {Object} [options] The validator rules
+         * @returns {FormValidation.Base}
+         */
+        addField: function(field, options) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field') || field.attr('name');
+                    break;
+                case 'string':
+                    delete this._cacheFields[field];
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            fields.attr('data-' + ns + '-field', field);
+
+            var type  = fields.attr('type'),
+                total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length;
+
+            for (var i = 0; i < total; i++) {
+                var $field = fields.eq(i);
+
+                // Try to parse the options from HTML attributes
+                var opts = this._parseOptions($field);
+                opts = (opts === null) ? options : $.extend(true, opts, options);
+
+                this.options.fields[field] = $.extend(true, this.options.fields[field], opts);
+
+                // Update the cache
+                this._cacheFields[field] = this._cacheFields[field] ? this._cacheFields[field].add($field) : $field;
+
+                // Init the element
+                this._initField(('checkbox' === type || 'radio' === type) ? field : $field);
+            }
+
+            this.disableSubmitButtons(false);
+            // Trigger an event
+            this.$form.trigger($.Event(this.options.events.fieldAdded), {
+                field: field,
+                element: fields,
+                options: this.options.fields[field]
+            });
+
+            return this;
+        },
+
+        /**
+         * Destroy the plugin
+         * It will remove all error messages, feedback icons and turn off the events
+         */
+        destroy: function() {
+            var ns = this._namespace, i, field, fields, $field, validator, $icon, row, alias;
+
+            // Destroy the validators first
+            for (field in this.options.fields) {
+                fields = this.getFieldElements(field);
+                for (i = 0; i < fields.length; i++) {
+                    $field = fields.eq(i);
+                    for (validator in this.options.fields[field].validators) {
+                        if ($field.data(ns + '.dfs.' + validator)) {
+                            $field.data(ns + '.dfs.' + validator).reject();
+                        }
+                        $field.removeData(ns + '.result.' + validator)
+                              .removeData(ns + '.response.' + validator)
+                              .removeData(ns + '.dfs.' + validator);
+
+                        // Destroy the validator
+                        alias = this.options.fields[field].validators[validator].alias || validator;
+                        if ('function' === typeof FormValidation.Validator[alias].destroy) {
+                            FormValidation.Validator[alias].destroy(this, $field, this.options.fields[field].validators[validator], validator);
+                        }
+                    }
+                }
+            }
+
+            // Remove messages and icons
+            var clazz = this.options.err.clazz.split(' ').join('.');
+            for (field in this.options.fields) {
+                fields = this.getFieldElements(field);
+                row    = this.options.fields[field].row || this.options.row.selector;
+                for (i = 0; i < fields.length; i++) {
+                    $field = fields.eq(i);
+                    // Remove all error messages
+                    var $messages = $field.data(ns + '.messages');
+                    if ($messages) {
+                        $messages.find('.' + clazz + '[data-' + ns + '-validator][data-' + ns + '-for="' + field + '"]').remove();
+                    }
+                    $field
+                        .removeData(ns + '.messages')
+                        .removeData(ns + '.validators')
+                        // Remove feedback classes
+                        .closest(row)
+                            .removeClass(this.options.row.valid)
+                            .removeClass(this.options.row.invalid)
+                            .removeClass(this.options.row.feedback)
+                            .end()
+                        // Turn off events
+                        .off('.' + ns)
+                        .removeAttr('data-' + ns + '-field');
+
+                    // Remove feedback icons, tooltip/popover container
+                    // Support backward
+                    var container = ('function' === typeof (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container))
+                                    ? (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container).call(this, $field, this)
+                                    : (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container);
+                    if ('tooltip' === container || 'popover' === container) {
+                        this._destroyTooltip($field, container);
+                    }
+
+                    $icon = $field.data(ns + '.icon');
+                    if ($icon) {
+                        $icon.remove();
+                    }
+                    $field.removeData(ns + '.icon')
+                          // It's safe to remove trigger data here, because it might be used when destroying the validator
+                          .removeData(ns + '.trigger');
+                }
+            }
+
+            // Destroy the add-ons
+            for (var addOn in this.options.addOns) {
+                if ('function' === typeof FormValidation.AddOn[addOn].destroy) {
+                    FormValidation.AddOn[addOn].destroy(this, this.options.addOns[addOn]);
+                }
+            }
+
+            this.disableSubmitButtons(false);   // Enable submit buttons
+            this.$hiddenButton.remove();        // Remove the hidden button
+
+            this.$form
+                .removeClass(this.options.elementClass)
+                .off('.' + ns)
+                .removeData('bootstrapValidator')   // Support backward
+                .removeData('formValidation')
+                // Remove generated hidden elements
+                .find('[data-' + ns + '-submit-hidden]').remove().end()
+                .find('[type="submit"]')
+                    .off('click.' + ns);
+        },
+
+        /**
+         * Enable/Disable all validators to given field
+         *
+         * @param {String} field The field name
+         * @param {Boolean} enabled Enable/Disable field validators
+         * @param {String} [validatorName] The validator name. If null, all validators will be enabled/disabled
+         * @returns {FormValidation.Base}
+         */
+        enableFieldValidators: function(field, enabled, validatorName) {
+            var validators = this.options.fields[field].validators;
+
+            // Enable/disable particular validator
+            if (validatorName
+                && validators
+                && validators[validatorName] && validators[validatorName].enabled !== enabled)
+            {
+                this.options.fields[field].validators[validatorName].enabled = enabled;
+                this.updateStatus(field, this.STATUS_NOT_VALIDATED, validatorName);
+            }
+            // Enable/disable all validators
+            else if (!validatorName && this.options.fields[field].enabled !== enabled) {
+                this.options.fields[field].enabled = enabled;
+                for (var v in validators) {
+                    this.enableFieldValidators(field, enabled, v);
+                }
+            }
+
+            return this;
+        },
+
+        /**
+         * Some validators have option which its value is dynamic.
+         * For example, the zipCode validator has the country option which might be changed dynamically by a select element.
+         *
+         * @param {jQuery|String} field The field name or element
+         * @param {String|Function} option The option which can be determined by:
+         * - a string
+         * - name of field which defines the value
+         * - name of function which returns the value
+         * - a function returns the value
+         *
+         * The callback function has the format of
+         *      callback: function(value, validator, $field) {
+         *          // value is the value of field
+         *          // validator is the BootstrapValidator instance
+         *          // $field is the field element
+         *      }
+         *
+         * @returns {String}
+         */
+        getDynamicOption: function(field, option) {
+            var $field = ('string' === typeof field) ? this.getFieldElements(field) : field,
+                value  = $field.val();
+
+            // Option can be determined by
+            // ... a function
+            if ('function' === typeof option) {
+                return FormValidation.Helper.call(option, [value, this, $field]);
+            }
+            // ... value of other field
+            else if ('string' === typeof option) {
+                var $f = this.getFieldElements(option);
+                if ($f.length) {
+                    return $f.val();
+                }
+                // ... return value of callback
+                else {
+                    return FormValidation.Helper.call(option, [value, this, $field]) || option;
+                }
+            }
+
+            return null;
+        },
+
+        /**
+         * Get the form element
+         *
+         * @returns {jQuery}
+         */
+        getForm: function() {
+            return this.$form;
+        },
+
+        /**
+         * Get the list of invalid fields
+         *
+         * @returns {jQuery[]}
+         */
+        getInvalidFields: function() {
+            return this.$invalidFields;
+        },
+
+        /**
+         * Get the current locale
+         *
+         * @return {String}
+         */
+        getLocale: function() {
+            return this.options.locale;
+        },
+
+        /**
+         * Get the error messages
+         *
+         * @param {String|jQuery} [field] The field name or field element
+         * If the field is not defined, the method returns all error messages of all fields
+         * @param {String} [validator] The name of validator
+         * If the validator is not defined, the method returns error messages of all validators
+         * @returns {String[]}
+         */
+        getMessages: function(field, validator) {
+            var that     = this,
+                ns       = this._namespace,
+                messages = [],
+                $fields  = $([]);
+
+            switch (true) {
+                case (field && 'object' === typeof field):
+                    $fields = field;
+                    break;
+                case (field && 'string' === typeof field):
+                    var f = this.getFieldElements(field);
+                    if (f.length > 0) {
+                        var type = f.attr('type');
+                        $fields = ('radio' === type || 'checkbox' === type) ? f.eq(0) : f;
+                    }
+                    break;
+                default:
+                    $fields = this.$invalidFields;
+                    break;
+            }
+
+            var filter = validator ? '[data-' + ns + '-validator="' + validator + '"]' : '',
+                clazz  = this.options.err.clazz.split(' ').join('.');
+            $fields.each(function() {
+                messages = messages.concat(
+                    $(this)
+                        .data(ns + '.messages')
+                        .find('.' + clazz + '[data-' + ns + '-for="' + $(this).attr('data-' + ns + '-field') + '"][data-' + ns + '-result="' + that.STATUS_INVALID + '"]' + filter)
+                        .map(function() {
+                            var v = $(this).attr('data-' + ns + '-validator'),
+                                f = $(this).attr('data-' + ns + '-for');
+                            return (that.options.fields[f].validators[v].enabled === false) ? '' : $(this).html();
+                        })
+                        .get()
+                );
+            });
+
+            return messages;
+        },
+
+        /**
+         * Returns the clicked submit button
+         *
+         * @returns {jQuery}
+         */
+        getSubmitButton: function() {
+            return this.$submitButton;
+        },
+
+        /**
+         * Remove a given field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @returns {FormValidation.Base}
+         */
+        removeField: function(field) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field') || field.attr('name');
+                    fields.attr('data-' + ns + '-field', field);
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            if (fields.length === 0) {
+                return this;
+            }
+
+            var type  = fields.attr('type'),
+                total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length;
+
+            for (var i = 0; i < total; i++) {
+                var $field = fields.eq(i);
+
+                // Remove from the list of invalid fields
+                this.$invalidFields = this.$invalidFields.not($field);
+
+                // Update the cache
+                this._cacheFields[field] = this._cacheFields[field].not($field);
+            }
+
+            if (!this._cacheFields[field] || this._cacheFields[field].length === 0) {
+                delete this.options.fields[field];
+            }
+            if ('checkbox' === type || 'radio' === type) {
+                this._initField(field);
+            }
+
+            this.disableSubmitButtons(false);
+            // Trigger an event
+            this.$form.trigger($.Event(this.options.events.fieldRemoved), {
+                field: field,
+                element: fields
+            });
+
+            return this;
+        },
+
+        /**
+         * Reset given field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {Boolean} [resetValue] If true, the method resets field value to empty or remove checked/selected attribute (for radio/checkbox)
+         * @returns {FormValidation.Base}
+         */
+        resetField: function(field, resetValue) {
+            var ns      = this._namespace,
+                $fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    $fields = field;
+                    field   = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    $fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            var i     = 0,
+                total = $fields.length;
+            if (this.options.fields[field]) {
+                for (i = 0; i < total; i++) {
+                    for (var validator in this.options.fields[field].validators) {
+                        $fields.eq(i).removeData(ns + '.dfs.' + validator);
+                    }
+                }
+            }
+
+            if (resetValue) {
+                var type = $fields.attr('type');
+                ('radio' === type || 'checkbox' === type) ? $fields.prop('checked', false).removeAttr('selected') : $fields.val('');
+            }
+
+            // Mark field as not validated yet
+            this.updateStatus(field, this.STATUS_NOT_VALIDATED);
+
+            for (i = 0; i < total; i++) {
+                $fields.eq(i).trigger($.Event(this.options.events.fieldReset), {
+                    fv: this,
+                    field: field,
+                    element: $fields.eq(i),
+                    resetValue: resetValue
+                });
+            }
+
+            return this;
+        },
+
+        /**
+         * Reset the form
+         *
+         * @param {Boolean} [resetValue] If true, the method resets field value to empty or remove checked/selected attribute (for radio/checkbox)
+         * @returns {FormValidation.Base}
+         */
+        resetForm: function(resetValue) {
+            for (var field in this.options.fields) {
+                this.resetField(field, resetValue);
+            }
+
+            this.$invalidFields = $([]);
+            this.$submitButton  = null;
+
+            // Enable submit buttons
+            this.disableSubmitButtons(false);
+
+            this.$form.trigger($.Event(this.options.events.formReset), {
+                fv: this,
+                resetValue: resetValue
+            });
+
+            return this;
+        },
+
+        /**
+         * Revalidate given field
+         * It's used when you need to revalidate the field which its value is updated by other plugin
+         *
+         * @param {String|jQuery} field The field name of field element
+         * @returns {FormValidation.Base}
+         */
+        revalidateField: function(field) {
+            this.updateStatus(field, this.STATUS_NOT_VALIDATED)
+                .validateField(field);
+
+            return this;
+        },
+
+        /**
+         * Set the locale
+         *
+         * @param {String} locale The locale in format of countrycode_LANGUAGECODE
+         * @returns {FormValidation.Base}
+         */
+        setLocale: function(locale) {
+            this.options.locale = locale;
+            this.$form.trigger($.Event(this.options.events.localeChanged), {
+                locale: locale,
+                bv: this,   // Support backward
+                fv: this
+            });
+
+            return this;
+        },
+
+        /**
+         * Update the option of a specific validator
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} validator The validator name
+         * @param {String} option The option name
+         * @param {String} value The value to set
+         * @returns {FormValidation.Base}
+         */
+        updateOption: function(field, validator, option, value) {
+            var ns = this._namespace;
+            if ('object' === typeof field) {
+                field = field.attr('data-' + ns + '-field');
+            }
+            if (this.options.fields[field] && this.options.fields[field].validators[validator]) {
+                this.options.fields[field].validators[validator][option] = value;
+                this.updateStatus(field, this.STATUS_NOT_VALIDATED, validator);
+            }
+
+            return this;
+        },
+
+        /**
+         * Validate given container
+         * It can be used with isValidContainer() when you want to work with wizard form
+         *
+         * @param {String|jQuery} container The container selector or element
+         * @returns {FormValidation.Base}
+         */
+        validateContainer: function(container) {
+            var that       = this,
+                ns         = this._namespace,
+                fields     = [],
+                $container = ('string' === typeof container) ? $(container) : container;
+            if ($container.length === 0) {
+                return this;
+            }
+
+            $container.find('[data-' + ns + '-field]').each(function() {
+                var $field = $(this);
+                if (!that._isExcluded($field)) {
+                    fields.push($field);
+                }
+            });
+
+            var total = fields.length;
+            for (var i = 0; i < total; i++) {
+                this.validateField(fields[i]);
+            }
+
+            return this;
+        }
+    };
+
+    // Plugin definition
+    $.fn.formValidation = function(option) {
+        var params = arguments;
+        return this.each(function() {
+            var $this   = $(this),
+                data    = $this.data('formValidation'),
+                options = 'object' === typeof option && option;
+            if (!data) {
+                var framework = (options.framework || $this.attr('data-fv-framework') || 'bootstrap').toLowerCase(),
+                    clazz     = framework.substr(0, 1).toUpperCase() + framework.substr(1);
+
+                if (typeof FormValidation.Framework[clazz] === 'undefined') {
+                    throw new Error('The class FormValidation.Framework.' + clazz + ' is not implemented');
+                }
+
+                data = new FormValidation.Framework[clazz](this, options);
+                $this.addClass('fv-form-' + framework)
+                     .data('formValidation', data);
+            }
+
+            // Allow to call plugin method
+            if ('string' === typeof option) {
+                data[option].apply(data, Array.prototype.slice.call(params, 1));
+            }
+        });
+    };
+
+    $.fn.formValidation.Constructor = FormValidation.Base;
+
+    // Default message
+    $.fn.formValidation.DEFAULT_MESSAGE = 'This value is not valid';
+
+    // The default options sorted in alphabetical order
+    $.fn.formValidation.DEFAULT_OPTIONS = {
+        // The first invalid field will be focused automatically
+        autoFocus: true,
+
+        // Support declarative usage (setting options via HTML 5 attributes)
+        // Setting to false can improve the performance
+        declarative: true,
+
+        // The form CSS class
+        elementClass: 'fv-form',
+
+        // Use custom event name to avoid window.onerror being invoked by jQuery
+        // See #630
+        events: {
+            // Support backward
+            formInit: 'init.form.fv',
+            formPreValidate: 'prevalidate.form.fv',
+            formError: 'err.form.fv',
+            formReset: 'rst.form.fv',
+            formSuccess: 'success.form.fv',
+            fieldAdded: 'added.field.fv',
+            fieldRemoved: 'removed.field.fv',
+            fieldInit: 'init.field.fv',
+            fieldError: 'err.field.fv',
+            fieldReset: 'rst.field.fv',
+            fieldSuccess: 'success.field.fv',
+            fieldStatus: 'status.field.fv',
+            localeChanged: 'changed.locale.fv',
+            validatorError: 'err.validator.fv',
+            validatorSuccess: 'success.validator.fv',
+            validatorIgnored: 'ignored.validator.fv'
+        },
+
+        // Indicate fields which won't be validated
+        // By default, the plugin will not validate the following kind of fields:
+        // - disabled
+        // - hidden
+        // - invisible
+        //
+        // The setting consists of jQuery filters. Accept 3 formats:
+        // - A string. Use a comma to separate filter
+        // - An array. Each element is a filter
+        // - An array. Each element can be a callback function
+        //      function($field, validator) {
+        //          $field is jQuery object representing the field element
+        //          validator is the BootstrapValidator instance
+        //          return true or false;
+        //      }
+        //
+        // The 3 following settings are equivalent:
+        //
+        // 1) ':disabled, :hidden, :not(:visible)'
+        // 2) [':disabled', ':hidden', ':not(:visible)']
+        // 3) [':disabled', ':hidden', function($field) {
+        //        return !$field.is(':visible');
+        //    }]
+        excluded: [':disabled', ':hidden', ':not(:visible)'],
+
+        // Map the field name with validator rules
+        fields: null,
+
+        // Live validating option
+        // Can be one of 3 values:
+        // - enabled: The plugin validates fields as soon as they are changed
+        // - disabled: Disable the live validating. The error messages are only shown after the form is submitted
+        // - submitted: The live validating is enabled after the form is submitted
+        live: 'enabled',
+
+        // Locale in the format of languagecode_COUNTRYCODE
+        locale: 'en_US',
+
+        // Default invalid message
+        message: null,
+
+        // The field will not be live validated if its length is less than this number of characters
+        threshold: null,
+
+        // Whether to be verbose when validating a field or not.
+        // Possible values:
+        // - true:  when a field has multiple validators, all of them will be checked, and respectively - if errors occur in
+        //          multiple validators, all of them will be displayed to the user
+        // - false: when a field has multiple validators, validation for this field will be terminated upon the first encountered error.
+        //          Thus, only the very first error message related to this field will be displayed to the user
+        verbose: true,
+
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        // These options mostly are overridden by specific framework
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        button: {
+            // The submit buttons selector
+            // These buttons will be disabled to prevent the valid form from multiple submissions
+            // Don't perform validation when clicking on the submit button/input which have formnovalidate attribute
+            selector: '[type="submit"]:not([formnovalidate])',
+
+            // The disabled class
+            disabled: ''
+        },
+
+        control: {
+            // The CSS class for valid control
+            valid: '',
+
+            // The CSS class for invalid control
+            invalid: ''
+        },
+
+        err: {
+            // The CSS class of each message element
+            clazz: '',
+
+            // The error messages container. It can be:
+            // - 'tooltip' if you want to use Bootstrap tooltip to show error messages
+            // - 'popover' if you want to use Bootstrap popover to show error messages
+            // - a CSS selector indicating the container
+            // In the first two cases, since the tooltip/popover should be small enough, the plugin only shows only one error message
+            // You also can define the message container for particular field
+            container: null,
+
+            // Used to determine where the messages are placed
+            parent: null
+        },
+
+        // Shows ok/error/loading icons based on the field validity.
+        icon: {
+            valid: null,
+            invalid: null,
+            validating: null,
+            feedback: ''
+        },
+
+        row: {
+            // The CSS selector for indicating the element consists of the field
+            // You should adjust this option if your form group consists of many fields which not all of them need to be validated
+            selector: null,
+            valid: '',
+            invalid: '',
+            feedback: ''
+        }
+    };
+}(jQuery));
+;(function($) {
+    // Helper methods, which can be used in validator class
+    FormValidation.Helper = {
+        /**
+         * Execute a callback function
+         *
+         * @param {String|Function} functionName Can be
+         * - name of global function
+         * - name of namespace function (such as A.B.C)
+         * - a function
+         * @param {Array} args The callback arguments
+         */
+        call: function(functionName, args) {
+            if ('function' === typeof functionName) {
+                return functionName.apply(this, args);
+            } else if ('string' === typeof functionName) {
+                if ('()' === functionName.substring(functionName.length - 2)) {
+                    functionName = functionName.substring(0, functionName.length - 2);
+                }
+                var ns      = functionName.split('.'),
+                    func    = ns.pop(),
+                    context = window;
+                for (var i = 0; i < ns.length; i++) {
+                    context = context[ns[i]];
+                }
+
+                return (typeof context[func] === 'undefined') ? null : context[func].apply(this, args);
+            }
+        },
+
+        /**
+         * Validate a date
+         *
+         * @param {Number} year The full year in 4 digits
+         * @param {Number} month The month number
+         * @param {Number} day The day number
+         * @param {Boolean} [notInFuture] If true, the date must not be in the future
+         * @returns {Boolean}
+         */
+        date: function(year, month, day, notInFuture) {
+            if (isNaN(year) || isNaN(month) || isNaN(day)) {
+                return false;
+            }
+            if (day.length > 2 || month.length > 2 || year.length > 4) {
+                return false;
+            }
+
+            day   = parseInt(day, 10);
+            month = parseInt(month, 10);
+            year  = parseInt(year, 10);
+
+            if (year < 1000 || year > 9999 || month <= 0 || month > 12) {
+                return false;
+            }
+            var numDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+            // Update the number of days in Feb of leap year
+            if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) {
+                numDays[1] = 29;
+            }
+
+            // Check the day
+            if (day <= 0 || day > numDays[month - 1]) {
+                return false;
+            }
+
+            if (notInFuture === true) {
+                var currentDate  = new Date(),
+                    currentYear  = currentDate.getFullYear(),
+                    currentMonth = currentDate.getMonth(),
+                    currentDay   = currentDate.getDate();
+                return (year < currentYear
+                || (year === currentYear && month - 1 < currentMonth)
+                || (year === currentYear && month - 1 === currentMonth && day < currentDay));
+            }
+
+            return true;
+        },
+
+        /**
+         * Format a string
+         * It's used to format the error message
+         * format('The field must between %s and %s', [10, 20]) = 'The field must between 10 and 20'
+         *
+         * @param {String} message
+         * @param {Array} parameters
+         * @returns {String}
+         */
+        format: function(message, parameters) {
+            if (!$.isArray(parameters)) {
+                parameters = [parameters];
+            }
+
+            for (var i in parameters) {
+                message = message.replace('%s', parameters[i]);
+            }
+
+            return message;
+        },
+
+        /**
+         * Implement Luhn validation algorithm
+         * Credit to https://gist.github.com/ShirtlessKirk/2134376
+         *
+         * @see http://en.wikipedia.org/wiki/Luhn
+         * @param {String} value
+         * @returns {Boolean}
+         */
+        luhn: function(value) {
+            var length  = value.length,
+                mul     = 0,
+                prodArr = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]],
+                sum     = 0;
+
+            while (length--) {
+                sum += prodArr[mul][parseInt(value.charAt(length), 10)];
+                mul ^= 1;
+            }
+
+            return (sum % 10 === 0 && sum > 0);
+        },
+
+        /**
+         * Implement modulus 11, 10 (ISO 7064) algorithm
+         *
+         * @param {String} value
+         * @returns {Boolean}
+         */
+        mod11And10: function(value) {
+            var check  = 5,
+                length = value.length;
+            for (var i = 0; i < length; i++) {
+                check = (((check || 10) * 2) % 11 + parseInt(value.charAt(i), 10)) % 10;
+            }
+            return (check === 1);
+        },
+
+        /**
+         * Implements Mod 37, 36 (ISO 7064) algorithm
+         * Usages:
+         * mod37And36('A12425GABC1234002M')
+         * mod37And36('002006673085', '0123456789')
+         *
+         * @param {String} value
+         * @param {String} [alphabet]
+         * @returns {Boolean}
+         */
+        mod37And36: function(value, alphabet) {
+            alphabet = alphabet || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+            var modulus = alphabet.length,
+                length  = value.length,
+                check   = Math.floor(modulus / 2);
+            for (var i = 0; i < length; i++) {
+                check = (((check || modulus) * 2) % (modulus + 1) + alphabet.indexOf(value.charAt(i))) % modulus;
+            }
+            return (check === 1);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            base64: {
+                'default': 'Please enter a valid base 64 encoded'
+            }
+        }
+    });
+
+    FormValidation.Validator.base64 = {
+        /**
+         * Return true if the input value is a base 64 encoded string.
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            between: {
+                'default': 'Please enter a value between %s and %s',
+                notInclusive: 'Please enter a value between %s and %s strictly'
+            }
+        }
+    });
+
+    FormValidation.Validator.between = {
+        html5Attributes: {
+            message: 'message',
+            min: 'min',
+            max: 'max',
+            inclusive: 'inclusive'
+        },
+
+        enableByHtml5: function($field) {
+            if ('range' === $field.attr('type')) {
+                return {
+                    min: $field.attr('min'),
+                    max: $field.attr('max')
+                };
+            }
+
+            return false;
+        },
+
+        /**
+         * Return true if the input value is between (strictly or not) two given numbers
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - min
+         * - max
+         *
+         * The min, max keys define the number which the field value compares to. min, max can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - inclusive [optional]: Can be true or false. Default is true
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+			value = this._format(value);
+
+            var locale   = validator.getLocale(),
+                min      = $.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min),
+                max      = $.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max),
+                minValue = this._format(min),
+                maxValue = this._format(max);
+
+			return (options.inclusive === true || options.inclusive === undefined)
+                    ? {
+                        valid: $.isNumeric(value) && parseFloat(value) >= minValue && parseFloat(value) <= maxValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].between['default'], [min, max])
+                    }
+                    : {
+                        valid: $.isNumeric(value) && parseFloat(value) > minValue && parseFloat(value) < maxValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].between.notInclusive, [min, max])
+                    };
+        },
+
+        _format: function(value) {
+            return (value + '').replace(',', '.');
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            bic: {
+                'default': 'Please enter a valid BIC number'
+            }
+        }
+    });
+
+    FormValidation.Validator.bic = {
+        /**
+         * Validate an Business Identifier Code (BIC), also known as ISO 9362, SWIFT-BIC, SWIFT ID or SWIFT code
+         *
+         * For more information see http://en.wikipedia.org/wiki/ISO_9362
+         *
+         * @todo The 5 and 6 characters are an ISO 3166-1 country code, this could also be validated
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+            return /^[a-zA-Z]{6}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?$/.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.Validator.blank = {
+        /**
+         * Placeholder validator that can be used to display a custom validation message
+         * returned from the server
+         * Example:
+         *
+         * (1) a "blank" validator is applied to an input field.
+         * (2) data is entered via the UI that is unable to be validated client-side.
+         * (3) server returns a 400 with JSON data that contains the field that failed
+         *     validation and an associated message.
+         * (4) ajax 400 call handler does the following:
+         *
+         *      fv.updateMessage(field, 'blank', errorMessage);
+         *      fv.updateStatus(field, 'INVALID', 'blank');
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            return true;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            callback: {
+                'default': 'Please enter a valid value'
+            }
+        }
+    });
+
+    FormValidation.Validator.callback = {
+        priority: 999,
+
+        html5Attributes: {
+            message: 'message',
+            callback: 'callback'
+        },
+
+        /**
+         * Return result from the callback method
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - callback: The callback method that passes parameters:
+         *      callback: function(fieldValue, validator, $field) {
+         *          // fieldValue is the value of field
+         *          // validator is instance of FormValidation.Base
+         *          // $field is the field element
+         *      }
+         * - message: The invalid message
+         * @returns {Deferred}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value  = validator.getFieldValue($field, validatorName),
+                dfd    = new $.Deferred(),
+                result = { valid: true };
+
+            if (options.callback) {
+                var response = FormValidation.Helper.call(options.callback, [value, validator, $field]);
+                result = ('boolean' === typeof response || null === response) ? { valid: response } : response;
+            }
+
+            dfd.resolve($field, validatorName, result);
+            return dfd;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            choice: {
+                'default': 'Please enter a valid value',
+                less: 'Please choose %s options at minimum',
+                more: 'Please choose %s options at maximum',
+                between: 'Please choose %s - %s options'
+            }
+        }
+    });
+
+    FormValidation.Validator.choice = {
+        html5Attributes: {
+            message: 'message',
+            min: 'min',
+            max: 'max'
+        },
+
+        /**
+         * Check if the number of checked boxes are less or more than a given number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of following keys:
+         * - min
+         * - max
+         *
+         * At least one of two keys is required
+         * The min, max keys define the number which the field value compares to. min, max can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - message: The invalid message
+         * @returns {Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var locale     = validator.getLocale(),
+                ns         = validator.getNamespace(),
+                numChoices = $field.is('select')
+                            ? validator.getFieldElements($field.attr('data-' + ns + '-field')).find('option').filter(':selected').length
+                            : validator.getFieldElements($field.attr('data-' + ns + '-field')).filter(':checked').length,
+                min        = options.min ? ($.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min)) : null,
+                max        = options.max ? ($.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max)) : null,
+                isValid    = true,
+                message    = options.message || FormValidation.I18n[locale].choice['default'];
+
+            if ((min && numChoices < parseInt(min, 10)) || (max && numChoices > parseInt(max, 10))) {
+                isValid = false;
+            }
+
+            switch (true) {
+                case (!!min && !!max):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].choice.between, [parseInt(min, 10), parseInt(max, 10)]);
+                    break;
+
+                case (!!min):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].choice.less, parseInt(min, 10));
+                    break;
+
+                case (!!max):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].choice.more, parseInt(max, 10));
+                    break;
+
+                default:
+                    break;
+            }
+
+            return { valid: isValid, message: message };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            color: {
+                'default': 'Please enter a valid color'
+            }
+        }
+    });
+
+    FormValidation.Validator.color = {
+        html5Attributes: {
+            message: 'message',
+            type: 'type'
+        },
+
+        enableByHtml5: function($field) {
+            return ('color' === $field.attr('type'));
+        },
+
+        SUPPORTED_TYPES: [
+            'hex', 'rgb', 'rgba', 'hsl', 'hsla', 'keyword'
+        ],
+
+        KEYWORD_COLORS: [
+            // Colors start with A
+            'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure',
+            // B
+            'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood',
+            // C
+            'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan',
+            // D
+            'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta',
+            'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue',
+            'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray',
+            'dimgrey', 'dodgerblue',
+            // F
+            'firebrick', 'floralwhite', 'forestgreen', 'fuchsia',
+            // G
+            'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey',
+            // H
+            'honeydew', 'hotpink',
+            // I
+            'indianred', 'indigo', 'ivory',
+            // K
+            'khaki',
+            // L
+            'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan',
+            'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen',
+            'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen',
+            'linen',
+            // M
+            'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen',
+            'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream',
+            'mistyrose', 'moccasin',
+            // N
+            'navajowhite', 'navy',
+            // O
+            'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid',
+            // P
+            'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink',
+            'plum', 'powderblue', 'purple',
+            // R
+            'red', 'rosybrown', 'royalblue',
+            // S
+            'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue',
+            'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue',
+            // T
+            'tan', 'teal', 'thistle', 'tomato', 'transparent', 'turquoise',
+            // V
+            'violet',
+            // W
+            'wheat', 'white', 'whitesmoke',
+            // Y
+            'yellow', 'yellowgreen'
+        ],
+
+        /**
+         * Return true if the input value is a valid color
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * - type: The array of valid color types
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Only accept 6 hex character values due to the HTML 5 spec
+            // See http://www.w3.org/TR/html-markup/input.color.html#input.color.attrs.value
+            if (this.enableByHtml5($field)) {
+                return /^#[0-9A-F]{6}$/i.test(value);
+            }
+
+            var types = options.type || this.SUPPORTED_TYPES;
+            if (!$.isArray(types)) {
+                types = types.replace(/s/g, '').split(',');
+            }
+
+            var method,
+                type,
+                isValid = false;
+
+            for (var i = 0; i < types.length; i++) {
+                type    = types[i];
+                method  = '_' + type.toLowerCase();
+                isValid = isValid || this[method](value);
+                if (isValid) {
+                    return true;
+                }
+            }
+
+            return false;
+        },
+
+        _hex: function(value) {
+            return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(value);
+        },
+
+        _hsl: function(value) {
+            return /^hsl\((\s*(-?\d+)\s*,)(\s*(\b(0?\d{1,2}|100)\b%)\s*,)(\s*(\b(0?\d{1,2}|100)\b%)\s*)\)$/.test(value);
+        },
+
+        _hsla: function(value) {
+            return /^hsla\((\s*(-?\d+)\s*,)(\s*(\b(0?\d{1,2}|100)\b%)\s*,){2}(\s*(0?(\.\d+)?|1(\.0+)?)\s*)\)$/.test(value);
+        },
+
+        _keyword: function(value) {
+            return $.inArray(value, this.KEYWORD_COLORS) >= 0;
+        },
+
+        _rgb: function(value) {
+            var regexInteger = /^rgb\((\s*(\b([01]?\d{1,2}|2[0-4]\d|25[0-5])\b)\s*,){2}(\s*(\b([01]?\d{1,2}|2[0-4]\d|25[0-5])\b)\s*)\)$/,
+                regexPercent = /^rgb\((\s*(\b(0?\d{1,2}|100)\b%)\s*,){2}(\s*(\b(0?\d{1,2}|100)\b%)\s*)\)$/;
+            return regexInteger.test(value) || regexPercent.test(value);
+        },
+
+        _rgba: function(value) {
+            var regexInteger = /^rgba\((\s*(\b([01]?\d{1,2}|2[0-4]\d|25[0-5])\b)\s*,){3}(\s*(0?(\.\d+)?|1(\.0+)?)\s*)\)$/,
+                regexPercent = /^rgba\((\s*(\b(0?\d{1,2}|100)\b%)\s*,){3}(\s*(0?(\.\d+)?|1(\.0+)?)\s*)\)$/;
+            return regexInteger.test(value) || regexPercent.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            creditCard: {
+                'default': 'Please enter a valid credit card number'
+            }
+        }
+    });
+
+    FormValidation.Validator.creditCard = {
+        /**
+         * Return true if the input value is valid credit card number
+         * Based on https://gist.github.com/DiegoSalazar/4075533
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} [options] Can consist of the following key:
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Accept only digits, dashes or spaces
+            if (/[^0-9-\s]+/.test(value)) {
+                return false;
+            }
+            value = value.replace(/\D/g, '');
+
+            if (!FormValidation.Helper.luhn(value)) {
+                return false;
+            }
+
+            // Validate the card number based on prefix (IIN ranges) and length
+            var cards = {
+                AMERICAN_EXPRESS: {
+                    length: [15],
+                    prefix: ['34', '37']
+                },
+                DANKORT: {
+                    length: [16],
+                    prefix: ['5019']
+                },
+                DINERS_CLUB: {
+                    length: [14],
+                    prefix: ['300', '301', '302', '303', '304', '305', '36']
+                },
+                DINERS_CLUB_US: {
+                    length: [16],
+                    prefix: ['54', '55']
+                },
+                DISCOVER: {
+                    length: [16],
+                    prefix: ['6011', '622126', '622127', '622128', '622129', '62213',
+                             '62214', '62215', '62216', '62217', '62218', '62219',
+                             '6222', '6223', '6224', '6225', '6226', '6227', '6228',
+                             '62290', '62291', '622920', '622921', '622922', '622923',
+                             '622924', '622925', '644', '645', '646', '647', '648',
+                             '649', '65']
+                },
+                ELO: {
+                    length: [16],
+                    prefix: ['4011', '4312', '4389', '4514', '4573', '4576',
+                             '5041', '5066', '5067', '509',
+                             '6277', '6362', '6363', '650', '6516', '6550']
+                },
+                FORBRUGSFORENINGEN: {
+                    length: [16],
+                    prefix: ['600722']
+                },
+                JCB: {
+                    length: [16],
+                    prefix: ['3528', '3529', '353', '354', '355', '356', '357', '358']
+                },
+                LASER: {
+                    length: [16, 17, 18, 19],
+                    prefix: ['6304', '6706', '6771', '6709']
+                },
+                MAESTRO: {
+                    length: [12, 13, 14, 15, 16, 17, 18, 19],
+                    prefix: ['5018', '5020', '5038', '5868', '6304', '6759', '6761', '6762', '6763', '6764', '6765', '6766']
+                },
+                MASTERCARD: {
+                    length: [16],
+                    prefix: ['51', '52', '53', '54', '55']
+                },
+                SOLO: {
+                    length: [16, 18, 19],
+                    prefix: ['6334', '6767']
+                },
+                UNIONPAY: {
+                    length: [16, 17, 18, 19],
+                    prefix: ['622126', '622127', '622128', '622129', '62213', '62214',
+                             '62215', '62216', '62217', '62218', '62219', '6222', '6223',
+                             '6224', '6225', '6226', '6227', '6228', '62290', '62291',
+                             '622920', '622921', '622922', '622923', '622924', '622925']
+                },
+                VISA_ELECTRON: {
+                    length: [16],
+                    prefix: ['4026', '417500', '4405', '4508', '4844', '4913', '4917']
+                },
+                VISA: {
+                    length: [16],
+                    prefix: ['4']
+                }
+            };
+
+            var type, i;
+            for (type in cards) {
+                for (i in cards[type].prefix) {
+                    if (value.substr(0, cards[type].prefix[i].length) === cards[type].prefix[i]     // Check the prefix
+                        && $.inArray(value.length, cards[type].length) !== -1)                      // and length
+                    {
+                        return {
+                            valid: true,
+                            type: type
+                        };
+                    }
+                }
+            }
+
+            return false;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            cusip: {
+                'default': 'Please enter a valid CUSIP number'
+            }
+        }
+    });
+
+    FormValidation.Validator.cusip = {
+        /**
+         * Validate a CUSIP number
+         *
+         * @see http://en.wikipedia.org/wiki/CUSIP
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} [options] Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            value = value.toUpperCase();
+            if (!/^[0-9A-Z]{9}$/.test(value)) {
+                return false;
+            }
+
+            var converted = $.map(value.split(''), function(item) {
+                                var code = item.charCodeAt(0);
+                                return (code >= 'A'.charCodeAt(0) && code <= 'Z'.charCodeAt(0))
+                                            // Replace A, B, C, ..., Z with 10, 11, ..., 35
+                                            ? (code - 'A'.charCodeAt(0) + 10)
+                                            : item;
+                            }),
+                length    = converted.length,
+                sum       = 0;
+            for (var i = 0; i < length - 1; i++) {
+                var num = parseInt(converted[i], 10);
+                if (i % 2 !== 0) {
+                    num *= 2;
+                }
+                if (num > 9) {
+                    num -= 9;
+                }
+                sum += num;
+            }
+
+            sum = (10 - (sum % 10)) % 10;
+            return sum === parseInt(converted[length - 1], 10);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            cvv: {
+                'default': 'Please enter a valid CVV number'
+            }
+        }
+    });
+
+    FormValidation.Validator.cvv = {
+        html5Attributes: {
+            message: 'message',
+            ccfield: 'creditCardField'
+        },
+
+        /**
+         * Bind the validator on the live change of the credit card field
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - creditCardField: The credit card number field
+         */
+        init: function(validator, $field, options, validatorName) {
+            if (options.creditCardField) {
+                var creditCardField = validator.getFieldElements(options.creditCardField);
+                validator.onLiveChange(creditCardField, 'live_' + validatorName, function() {
+                    var status = validator.getStatus($field, validatorName);
+                    if (status !== validator.STATUS_NOT_VALIDATED) {
+                        validator.revalidateField($field);
+                    }
+                });
+            }
+        },
+
+        /**
+         * Unbind the validator on the live change of the credit card field
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - creditCardField: The credit card number field
+         */
+        destroy: function(validator, $field, options, validatorName) {
+            if (options.creditCardField) {
+                var creditCardField = validator.getFieldElements(options.creditCardField);
+                validator.offLiveChange(creditCardField, 'live_' + validatorName);
+            }
+        },
+
+        /**
+         * Return true if the input value is a valid CVV number.
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - creditCardField: The credit card number field. It can be null
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            if (!/^[0-9]{3,4}$/.test(value)) {
+                return false;
+            }
+
+            if (!options.creditCardField) {
+                return true;
+            }
+
+            // Get the credit card number
+            var creditCard = validator.getFieldValue(options.creditCardField, 'creditCard');
+            if (creditCard === null || creditCard === '') {
+                return true;
+            }
+            
+            creditCard = creditCard.replace(/\D/g, '');
+
+            // Supported credit card types
+            var cards = {
+                AMERICAN_EXPRESS: {
+                    length: [15],
+                    prefix: ['34', '37']
+                },
+                DANKORT: {
+                    length: [16],
+                    prefix: ['5019']
+                },
+                DINERS_CLUB: {
+                    length: [14],
+                    prefix: ['300', '301', '302', '303', '304', '305', '36']
+                },
+                DINERS_CLUB_US: {
+                    length: [16],
+                    prefix: ['54', '55']
+                },
+                DISCOVER: {
+                    length: [16],
+                    prefix: ['6011', '622126', '622127', '622128', '622129', '62213',
+                             '62214', '62215', '62216', '62217', '62218', '62219',
+                             '6222', '6223', '6224', '6225', '6226', '6227', '6228',
+                             '62290', '62291', '622920', '622921', '622922', '622923',
+                             '622924', '622925', '644', '645', '646', '647', '648',
+                             '649', '65']
+                },
+                ELO: {
+                    length: [16],
+                    prefix: ['4011', '4312', '4389', '4514', '4573', '4576',
+                             '5041', '5066', '5067', '509',
+                             '6277', '6362', '6363', '650', '6516', '6550']
+                },
+                FORBRUGSFORENINGEN: {
+                    length: [16],
+                    prefix: ['600722']
+                },
+                JCB: {
+                    length: [16],
+                    prefix: ['3528', '3529', '353', '354', '355', '356', '357', '358']
+                },
+                LASER: {
+                    length: [16, 17, 18, 19],
+                    prefix: ['6304', '6706', '6771', '6709']
+                },
+                MAESTRO: {
+                    length: [12, 13, 14, 15, 16, 17, 18, 19],
+                    prefix: ['5018', '5020', '5038', '5868', '6304', '6759', '6761', '6762', '6763', '6764', '6765', '6766']
+                },
+                MASTERCARD: {
+                    length: [16],
+                    prefix: ['51', '52', '53', '54', '55']
+                },
+                SOLO: {
+                    length: [16, 18, 19],
+                    prefix: ['6334', '6767']
+                },
+                UNIONPAY: {
+                    length: [16, 17, 18, 19],
+                    prefix: ['622126', '622127', '622128', '622129', '62213', '62214',
+                             '62215', '62216', '62217', '62218', '62219', '6222', '6223',
+                             '6224', '6225', '6226', '6227', '6228', '62290', '62291',
+                             '622920', '622921', '622922', '622923', '622924', '622925']
+                },
+                VISA_ELECTRON: {
+                    length: [16],
+                    prefix: ['4026', '417500', '4405', '4508', '4844', '4913', '4917']
+                },
+                VISA: {
+                    length: [16],
+                    prefix: ['4']
+                }
+            };
+            var type, i, creditCardType = null;
+            for (type in cards) {
+                for (i in cards[type].prefix) {
+                    if (creditCard.substr(0, cards[type].prefix[i].length) === cards[type].prefix[i]    // Check the prefix
+                        && $.inArray(creditCard.length, cards[type].length) !== -1)                     // and length
+                    {
+                        creditCardType = type;
+                        break;
+                    }
+                }
+            }
+
+            return (creditCardType === null)
+                        ? false
+                        : (('AMERICAN_EXPRESS' === creditCardType) ? (value.length === 4) : (value.length === 3));
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            date: {
+                'default': 'Please enter a valid date',
+                min: 'Please enter a date after %s',
+                max: 'Please enter a date before %s',
+                range: 'Please enter a date in the range %s - %s'
+            }
+        }
+    });
+
+    FormValidation.Validator.date = {
+        html5Attributes: {
+            message: 'message',
+            format: 'format',
+            min: 'min',
+            max: 'max',
+            separator: 'separator'
+        },
+
+        /**
+         * Return true if the input value is valid date
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * - min: the minimum date
+         * - max: the maximum date
+         * - separator: Use to separate the date, month, and year.
+         * By default, it is /
+         * - format: The date format. Default is MM/DD/YYYY
+         * The format can be:
+         *
+         * i) date: Consist of DD, MM, YYYY parts which are separated by the separator option
+         * ii) date and time:
+         * The time can consist of h, m, s parts which are separated by :
+         * ii) date, time and A (indicating AM or PM)
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            options.format = options.format || 'MM/DD/YYYY';
+
+            // #683: Force the format to YYYY-MM-DD as the default browser behaviour when using type="date" attribute
+            if ($field.attr('type') === 'date') {
+                options.format = 'YYYY-MM-DD';
+            }
+
+            var locale     = validator.getLocale(),
+                message    = options.message || FormValidation.I18n[locale].date['default'],
+                formats    = options.format.split(' '),
+                dateFormat = formats[0],
+                timeFormat = (formats.length > 1) ? formats[1] : null,
+                amOrPm     = (formats.length > 2) ? formats[2] : null,
+                sections   = value.split(' '),
+                date       = sections[0],
+                time       = (sections.length > 1) ? sections[1] : null;
+
+            if (formats.length !== sections.length) {
+                return {
+                    valid: false,
+                    message: message
+                };
+            }
+
+            // Determine the separator
+            var separator = options.separator;
+            if (!separator) {
+                separator = (date.indexOf('/') !== -1)
+                            ? '/'
+                            : ((date.indexOf('-') !== -1) ? '-' : ((date.indexOf('.') !== -1) ? '.' : null));
+            }
+            if (separator === null || date.indexOf(separator) === -1) {
+                return {
+                    valid: false,
+                    message: message
+                };
+            }
+
+            // Determine the date
+            date       = date.split(separator);
+            dateFormat = dateFormat.split(separator);
+            if (date.length !== dateFormat.length) {
+                return {
+                    valid: false,
+                    message: message
+                };
+            }
+
+            var year  = date[$.inArray('YYYY', dateFormat)],
+                month = date[$.inArray('MM', dateFormat)],
+                day   = date[$.inArray('DD', dateFormat)];
+
+            if (!year || !month || !day || year.length !== 4) {
+                return {
+                    valid: false,
+                    message: message
+                };
+            }
+
+            // Determine the time
+            var minutes = null, hours = null, seconds = null;
+            if (timeFormat) {
+                timeFormat = timeFormat.split(':');
+                time       = time.split(':');
+
+                if (timeFormat.length !== time.length) {
+                    return {
+                        valid: false,
+                        message: message
+                    };
+                }
+
+                hours   = time.length > 0 ? time[0] : null;
+                minutes = time.length > 1 ? time[1] : null;
+                seconds = time.length > 2 ? time[2] : null;
+
+                if (hours === '' || minutes === '' || seconds === '') {
+                    return {
+                        valid: false,
+                        message: message
+                    };
+                }
+
+                // Validate seconds
+                if (seconds) {
+                    if (isNaN(seconds) || seconds.length > 2) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                    seconds = parseInt(seconds, 10);
+                    if (seconds < 0 || seconds > 60) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                }
+
+                // Validate hours
+                if (hours) {
+                    if (isNaN(hours) || hours.length > 2) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                    hours = parseInt(hours, 10);
+                    if (hours < 0 || hours >= 24 || (amOrPm && hours > 12)) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                }
+
+                // Validate minutes
+                if (minutes) {
+                    if (isNaN(minutes) || minutes.length > 2) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                    minutes = parseInt(minutes, 10);
+                    if (minutes < 0 || minutes > 59) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                }
+            }
+
+            // Validate day, month, and year
+            var valid     = FormValidation.Helper.date(year, month, day),
+                min       = null,
+                max       = null,
+                minOption = options.min,
+                maxOption = options.max;
+
+            if (minOption) {
+                min = (minOption instanceof Date)
+                    ? minOption
+                    : (this._parseDate(minOption, dateFormat, separator) ||
+                       this._parseDate(validator.getDynamicOption($field, minOption), dateFormat, separator));
+
+                // In order to avoid displaying a date string like "Mon Dec 08 2014 19:14:12 GMT+0000 (WET)"
+                minOption = this._formatDate(min, options.format);
+            }
+
+            if (maxOption) {
+                max = (maxOption instanceof Date)
+                    ? maxOption
+                    : (this._parseDate(maxOption, dateFormat, separator) ||
+                       this._parseDate(validator.getDynamicOption($field, maxOption), dateFormat, separator));
+
+                // In order to avoid displaying a date string like "Mon Dec 08 2014 19:14:12 GMT+0000 (WET)"
+                maxOption = this._formatDate(max, options.format);
+            }
+
+            date = new Date(year, month -1, day, hours, minutes, seconds);
+
+            switch (true) {
+                case (minOption && !maxOption && valid):
+                    valid   = date.getTime() >= min.getTime();
+                    message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.min, minOption);
+                    break;
+
+                case (maxOption && !minOption && valid):
+                    valid   = date.getTime() <= max.getTime();
+                    message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.max, maxOption);
+                    break;
+
+                case (maxOption && minOption && valid):
+                    valid   = date.getTime() <= max.getTime() && date.getTime() >= min.getTime();
+                    message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.range, [minOption, maxOption]);
+                    break;
+
+                default:
+                    break;
+            }
+
+            return {
+                valid: valid,
+                date: date,
+                message: message
+            };
+        },
+
+        /**
+         * Return a date object after parsing the date string
+         *
+         * @param {Date|String} date   The date string to parse
+         * @param {String} format The date format
+         * The format can be:
+         *   - date: Consist of DD, MM, YYYY parts which are separated by the separator option
+         *   - date and time:
+         *     The time can consist of h, m, s parts which are separated by :
+         * @param {String} separator The separator used to separate the date, month, and year
+         * @returns {Date}
+         */
+        _parseDate: function(date, format, separator) {
+            if (date instanceof Date) {
+                return date;
+            }
+            if (typeof date !== 'string') {
+                return null;
+            }
+
+            // Ensure that the format must consist of year, month and day patterns
+            var yearIndex   = $.inArray('YYYY', format),
+                monthIndex  = $.inArray('MM', format),
+                dayIndex    = $.inArray('DD', format);
+            if (yearIndex === -1 || monthIndex === -1 || dayIndex === -1) {
+                return null;
+            }
+
+            var minutes     = 0, hours = 0, seconds = 0,
+                sections    = date.split(' '),
+                dateSection = sections[0].split(separator);
+            if (dateSection.length < 3) {
+                return null;
+            }
+
+            if (sections.length > 1) {
+                var timeSection = sections[1].split(':');
+                hours   = timeSection.length > 0 ? timeSection[0] : null;
+                minutes = timeSection.length > 1 ? timeSection[1] : null;
+                seconds = timeSection.length > 2 ? timeSection[2] : null;
+            }
+
+            return new Date(dateSection[yearIndex], dateSection[monthIndex] - 1, dateSection[dayIndex],
+                            hours, minutes, seconds);
+        },
+
+        /**
+         * Format date
+         *
+         * @param {Date} date The date object to format
+         * @param {String} format The date format
+         * The format can consist of the following tokens:
+         *      d       Day of the month without leading zeros (1 through 31)
+         *      dd      Day of the month with leading zeros (01 through 31)
+         *      m       Month without leading zeros (1 through 12)
+         *      mm      Month with leading zeros (01 through 12)
+         *      yy      Last two digits of year (for example: 14)
+         *      yyyy    Full four digits of year (for example: 2014)
+         *      h       Hours without leading zeros (1 through 12)
+         *      hh      Hours with leading zeros (01 through 12)
+         *      H       Hours without leading zeros (0 through 23)
+         *      HH      Hours with leading zeros (00 through 23)
+         *      M       Minutes without leading zeros (0 through 59)
+         *      MM      Minutes with leading zeros (00 through 59)
+         *      s       Seconds without leading zeros (0 through 59)
+         *      ss      Seconds with leading zeros (00 through 59)
+         * @returns {String}
+         */
+        _formatDate: function(date, format) {
+            format = format
+                        .replace(/Y/g, 'y')
+                        .replace(/M/g, 'm')
+                        .replace(/D/g, 'd')
+                        .replace(/:m/g, ':M')
+                        .replace(/:mm/g, ':MM')
+                        .replace(/:S/, ':s')
+                        .replace(/:SS/, ':ss');
+
+            var replacer = {
+                d: function(date) {
+                    return date.getDate();
+                },
+                dd: function(date) {
+                    var d = date.getDate();
+                    return (d < 10) ? '0' + d : d;
+                },
+                m: function(date) {
+                    return date.getMonth() + 1;
+                },
+                mm: function(date) {
+                    var m = date.getMonth() + 1;
+                    return m < 10 ? '0' + m : m;
+                },
+                yy: function(date) {
+                    return ('' + date.getFullYear()).substr(2);
+                },
+                yyyy: function(date) {
+                    return date.getFullYear();
+                },
+                h: function(date) {
+                    return date.getHours() % 12 || 12;
+                },
+                hh: function(date) {
+                    var h = date.getHours() % 12 || 12;
+                    return h < 10 ? '0' + h : h;
+                },
+                H: function(date) {
+                    return date.getHours();
+                },
+                HH: function(date) {
+                    var H = date.getHours();
+                    return H < 10 ? '0' + H : H;
+                },
+                M: function(date) {
+                    return date.getMinutes();
+                },
+                MM: function(date) {
+                    var M = date.getMinutes();
+                    return M < 10 ? '0' + M : M;
+                },
+                s: function(date) {
+                    return date.getSeconds();
+                },
+                ss: function(date) {
+                    var s = date.getSeconds();
+                    return s < 10 ? '0' + s : s;
+                }
+            };
+
+            return format.replace(/d{1,4}|m{1,4}|yy(?:yy)?|([HhMs])\1?|"[^"]*"|'[^']*'/g, function(match) {
+                return replacer[match] ? replacer[match](date) : match.slice(1, match.length - 1);
+            });
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            different: {
+                'default': 'Please enter a different value'
+            }
+        }
+    });
+
+    FormValidation.Validator.different = {
+        html5Attributes: {
+            message: 'message',
+            field: 'field'
+        },
+
+        /**
+         * Bind the validator on the live change of the field to compare with current one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         */
+        init: function(validator, $field, options, validatorName) {
+            var fields = options.field.split(',');
+            for (var i = 0; i < fields.length; i++) {
+                var compareWith = validator.getFieldElements($.trim(fields[i]));
+                validator.onLiveChange(compareWith, 'live_' + validatorName, function() {
+                    var status = validator.getStatus($field, validatorName);
+                    if (status !== validator.STATUS_NOT_VALIDATED) {
+                        validator.revalidateField($field);
+                    }
+                });
+            }
+        },
+
+        /**
+         * Unbind the validator on the live change of the field to compare with current one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         */
+        destroy: function(validator, $field, options, validatorName) {
+            var fields = options.field.split(',');
+            for (var i = 0; i < fields.length; i++) {
+                var compareWith = validator.getFieldElements($.trim(fields[i]));
+                validator.offLiveChange(compareWith, 'live_' + validatorName);
+            }
+        },
+
+        /**
+         * Return true if the input value is different with given field's value
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var fields  = options.field.split(','),
+                isValid = true;
+
+            for (var i = 0; i < fields.length; i++) {
+                var compareWith = validator.getFieldElements($.trim(fields[i]));
+                if (compareWith == null || compareWith.length === 0) {
+                    continue;
+                }
+
+                var compareValue = validator.getFieldValue(compareWith, validatorName);
+                if (value === compareValue) {
+                    isValid = false;
+                } else if (compareValue !== '') {
+                    validator.updateStatus(compareWith, validator.STATUS_VALID, validatorName);
+                }
+            }
+
+            return isValid;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            digits: {
+                'default': 'Please enter only digits'
+            }
+        }
+    });
+
+    FormValidation.Validator.digits = {
+        /**
+         * Return true if the input value contains digits only
+         *
+         * @param {FormValidation.Base} validator Validate plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} [options]
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            return /^\d+$/.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            ean: {
+                'default': 'Please enter a valid EAN number'
+            }
+        }
+    });
+
+    FormValidation.Validator.ean = {
+        /**
+         * Validate EAN (International Article Number)
+         *
+         * @see http://en.wikipedia.org/wiki/European_Article_Number
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            if (!/^(\d{8}|\d{12}|\d{13})$/.test(value)) {
+                return false;
+            }
+
+            var length = value.length,
+                sum    = 0,
+                weight = (length === 8) ? [3, 1] : [1, 3];
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i % 2];
+            }
+            sum = (10 - sum % 10) % 10;
+            return (sum + '' === value.charAt(length - 1));
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            ein: {
+                'default': 'Please enter a valid EIN number'
+            }
+        }
+    });
+
+    FormValidation.Validator.ein = {
+        // The first two digits are called campus
+        // See http://en.wikipedia.org/wiki/Employer_Identification_Number
+        // http://www.irs.gov/Businesses/Small-Businesses-&-Self-Employed/How-EINs-are-Assigned-and-Valid-EIN-Prefixes
+        CAMPUS: {
+            ANDOVER: ['10', '12'],
+            ATLANTA: ['60', '67'],
+            AUSTIN: ['50', '53'],
+            BROOKHAVEN: ['01', '02', '03', '04', '05', '06', '11', '13', '14', '16', '21', '22', '23', '25', '34', '51', '52', '54', '55', '56', '57', '58', '59', '65'],
+            CINCINNATI: ['30', '32', '35', '36', '37', '38', '61'],
+            FRESNO: ['15', '24'],
+            KANSAS_CITY: ['40', '44'],
+            MEMPHIS: ['94', '95'],
+            OGDEN: ['80', '90'],
+            PHILADELPHIA: ['33', '39', '41', '42', '43', '48', '62', '63', '64', '66', '68', '71', '72', '73', '74', '75', '76', '77', '81', '82', '83', '84', '85', '86', '87', '88', '91', '92', '93', '98', '99'],
+            INTERNET: ['20', '26', '27', '45', '46', '47'],
+            SMALL_BUSINESS_ADMINISTRATION: ['31']
+        },
+
+        /**
+         * Validate EIN (Employer Identification Number) which is also known as
+         * Federal Employer Identification Number (FEIN) or Federal Tax Identification Number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Object|Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            if (!/^[0-9]{2}-?[0-9]{7}$/.test(value)) {
+                return false;
+            }
+            // Check the first two digits
+            var campus = value.substr(0, 2) + '';
+            for (var key in this.CAMPUS) {
+                if ($.inArray(campus, this.CAMPUS[key]) !== -1) {
+                    return {
+                        valid: true,
+                        campus: key
+                    };
+                }
+            }
+
+            return false;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            emailAddress: {
+                'default': 'Please enter a valid email address'
+            }
+        }
+    });
+
+    FormValidation.Validator.emailAddress = {
+        html5Attributes: {
+            message: 'message',
+            multiple: 'multiple',
+            separator: 'separator'
+        },
+
+        enableByHtml5: function($field) {
+            return ('email' === $field.attr('type'));
+        },
+
+        /**
+         * Return true if and only if the input value is a valid email address
+         *
+         * @param {FormValidation.Base} validator Validate plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} [options]
+         * - multiple: Allow multiple email addresses, separated by a comma or semicolon; default is false.
+         * - separator: Regex for character or characters expected as separator between addresses; default is comma /[,;]/, i.e. comma or semicolon.
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Email address regular expression
+            // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
+            var emailRegExp   = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
+                allowMultiple = options.multiple === true || options.multiple === 'true';
+
+            if (allowMultiple) {
+                var separator = options.separator || /[,;]/,
+                    addresses = this._splitEmailAddresses(value, separator);
+
+                for (var i = 0; i < addresses.length; i++) {
+                    if (!emailRegExp.test(addresses[i])) {
+                        return false;
+                    }
+                }
+
+                return true;
+            } else {
+                return emailRegExp.test(value);
+            }
+        },
+
+        _splitEmailAddresses: function(emailAddresses, separator) {
+            var quotedFragments     = emailAddresses.split(/"/),
+                quotedFragmentCount = quotedFragments.length,
+                emailAddressArray   = [],
+                nextEmailAddress    = '';
+
+            for (var i = 0; i < quotedFragmentCount; i++) {
+                if (i % 2 === 0) {
+                    var splitEmailAddressFragments     = quotedFragments[i].split(separator),
+                        splitEmailAddressFragmentCount = splitEmailAddressFragments.length;
+
+                    if (splitEmailAddressFragmentCount === 1) {
+                        nextEmailAddress += splitEmailAddressFragments[0];
+                    } else {
+                        emailAddressArray.push(nextEmailAddress + splitEmailAddressFragments[0]);
+
+                        for (var j = 1; j < splitEmailAddressFragmentCount - 1; j++) {
+                            emailAddressArray.push(splitEmailAddressFragments[j]);
+                        }
+                        nextEmailAddress = splitEmailAddressFragments[splitEmailAddressFragmentCount - 1];
+                    }
+                } else {
+                    nextEmailAddress += '"' + quotedFragments[i];
+                    if (i < quotedFragmentCount - 1) {
+                        nextEmailAddress += '"';
+                    }
+                }
+            }
+
+            emailAddressArray.push(nextEmailAddress);
+            return emailAddressArray;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            file: {
+                'default': 'Please choose a valid file'
+            }
+        }
+    });
+
+    FormValidation.Validator.file = {
+        Error: {
+            EXTENSION: 'EXTENSION',
+            MAX_FILES: 'MAX_FILES',
+            MAX_SIZE: 'MAX_SIZE',
+            MAX_TOTAL_SIZE: 'MAX_TOTAL_SIZE',
+            MIN_FILES: 'MIN_FILES',
+            MIN_SIZE: 'MIN_SIZE',
+            MIN_TOTAL_SIZE: 'MIN_TOTAL_SIZE',
+            TYPE: 'TYPE'
+        },
+
+        html5Attributes: {
+            extension: 'extension',
+            maxfiles: 'maxFiles',
+            minfiles: 'minFiles',
+            maxsize: 'maxSize',
+            minsize: 'minSize',
+            maxtotalsize: 'maxTotalSize',
+            mintotalsize: 'minTotalSize',
+            message: 'message',
+            type: 'type'
+        },
+
+        /**
+         * Validate upload file. Use HTML 5 API if the browser supports
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - extension: The allowed extensions, separated by a comma
+         * - maxFiles: The maximum number of files
+         * - minFiles: The minimum number of files
+         * - maxSize: The maximum size in bytes
+         * - minSize: The minimum size in bytes
+         * - maxTotalSize: The maximum size in bytes for all files
+         * - minTotalSize: The minimum size in bytes for all files
+         * - message: The invalid message
+         * - type: The allowed MIME type, separated by a comma
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var ext,
+                extensions = options.extension ? options.extension.toLowerCase().split(',') : null,
+                types      = options.type      ? options.type.toLowerCase().split(',')      : null,
+                html5      = (window.File && window.FileList && window.FileReader);
+
+            if (html5) {
+                // Get FileList instance
+                var files     = $field.get(0).files,
+                    total     = files.length,
+                    totalSize = 0;
+
+                // Check the maxFiles
+                if (options.maxFiles && total > parseInt(options.maxFiles, 10)) {
+                    return {
+                        valid: false,
+                        error: this.Error.MAX_FILES
+                    };
+                }
+
+                // Check the minFiles
+                if (options.minFiles && total < parseInt(options.minFiles, 10)) {
+                    return {
+                        valid: false,
+                        error: this.Error.MIN_FILES
+                    };
+                }
+
+                var metaData = {};
+                for (var i = 0; i < total; i++) {
+                    totalSize += files[i].size;
+                    ext        = files[i].name.substr(files[i].name.lastIndexOf('.') + 1);
+                    metaData   = {
+                        file: files[i],
+                        size: files[i].size,
+                        ext: ext,
+                        type: files[i].type
+                    };
+
+                    // Check the minSize
+                    if (options.minSize && files[i].size < parseInt(options.minSize, 10)) {
+                       return {
+                           valid: false,
+                           error: this.Error.MIN_SIZE,
+                           metaData: metaData
+                       };
+                    }
+
+                    // Check the maxSize
+                    if (options.maxSize && files[i].size > parseInt(options.maxSize, 10)) {
+                        return {
+                            valid: false,
+                            error: this.Error.MAX_SIZE,
+                            metaData: metaData
+                        };
+                    }
+
+                    // Check file extension
+                    if (extensions && $.inArray(ext.toLowerCase(), extensions) === -1) {
+                        return {
+                            valid: false,
+                            error: this.Error.EXTENSION,
+                            metaData: metaData
+                        };
+                    }
+
+                    // Check file type
+                    if (files[i].type && types && $.inArray(files[i].type.toLowerCase(), types) === -1) {
+                        return {
+                            valid: false,
+                            error: this.Error.TYPE,
+                            metaData: metaData
+                        };
+                    }
+                }
+
+                // Check the maxTotalSize
+                if (options.maxTotalSize && totalSize > parseInt(options.maxTotalSize, 10)) {
+                    return {
+                        valid: false,
+                        error: this.Error.MAX_TOTAL_SIZE,
+                        metaData: {
+                            totalSize: totalSize
+                        }
+                    };
+                }
+
+                // Check the minTotalSize
+                if (options.minTotalSize && totalSize < parseInt(options.minTotalSize, 10)) {
+                    return {
+                        valid: false,
+                        error: this.Error.MIN_TOTAL_SIZE,
+                        metaData: {
+                            totalSize: totalSize
+                        }
+                    };
+                }
+            } else {
+                // Check file extension
+                ext = value.substr(value.lastIndexOf('.') + 1);
+                if (extensions && $.inArray(ext.toLowerCase(), extensions) === -1) {
+                    return {
+                        valid: false,
+                        error: this.Error.EXTENSION,
+                        metaData: {
+                            ext: ext
+                        }
+                    };
+                }
+            }
+
+            return true;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            greaterThan: {
+                'default': 'Please enter a value greater than or equal to %s',
+                notInclusive: 'Please enter a value greater than %s'
+            }
+        }
+    });
+
+    FormValidation.Validator.greaterThan = {
+        html5Attributes: {
+            message: 'message',
+            value: 'value',
+            inclusive: 'inclusive'
+        },
+
+        enableByHtml5: function($field) {
+            var type = $field.attr('type'),
+                min  = $field.attr('min');
+            if (min && type !== 'date') {
+                return {
+                    value: min
+                };
+            }
+
+            return false;
+        },
+
+        /**
+         * Return true if the input value is greater than or equals to given number
+         *
+         * @param {FormValidation.Base} validator Validate plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - value: Define the number to compare with. It can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - inclusive [optional]: Can be true or false. Default is true
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+            
+            value = this._format(value);
+
+            var locale         = validator.getLocale(),
+                compareTo      = $.isNumeric(options.value) ? options.value : validator.getDynamicOption($field, options.value),
+                compareToValue = this._format(compareTo);
+
+			return (options.inclusive === true || options.inclusive === undefined)
+                    ? {
+                        valid: $.isNumeric(value) && parseFloat(value) >= compareToValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].greaterThan['default'], compareTo)
+                    }
+                    : {
+                        valid: $.isNumeric(value) && parseFloat(value) > compareToValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].greaterThan.notInclusive, compareTo)
+                    };
+        },
+
+        _format: function(value) {
+            return (value + '').replace(',', '.');
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            grid: {
+                'default': 'Please enter a valid GRId number'
+            }
+        }
+    });
+
+    FormValidation.Validator.grid = {
+        /**
+         * Validate GRId (Global Release Identifier)
+         *
+         * @see http://en.wikipedia.org/wiki/Global_Release_Identifier
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            value = value.toUpperCase();
+            if (!/^[GRID:]*([0-9A-Z]{2})[-\s]*([0-9A-Z]{5})[-\s]*([0-9A-Z]{10})[-\s]*([0-9A-Z]{1})$/g.test(value)) {
+                return false;
+            }
+            value = value.replace(/\s/g, '').replace(/-/g, '');
+            if ('GRID:' === value.substr(0, 5)) {
+                value = value.substr(5);
+            }
+            return FormValidation.Helper.mod37And36(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            hex: {
+                'default': 'Please enter a valid hexadecimal number'
+            }
+        }
+    });
+
+    FormValidation.Validator.hex = {
+        /**
+         * Return true if and only if the input value is a valid hexadecimal number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            return /^[0-9a-fA-F]+$/.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            iban: {
+                'default': 'Please enter a valid IBAN number',
+                country: 'Please enter a valid IBAN number in %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'United Arab Emirates',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbaijan',
+                    BA: 'Bosnia and Herzegovina',
+                    BE: 'Belgium',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CI: 'Ivory Coast',
+                    CM: 'Cameroon',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Cyprus',
+                    CZ: 'Czech Republic',
+                    DE: 'Germany',
+                    DK: 'Denmark',
+                    DO: 'Dominican Republic',
+                    DZ: 'Algeria',
+                    EE: 'Estonia',
+                    ES: 'Spain',
+                    FI: 'Finland',
+                    FO: 'Faroe Islands',
+                    FR: 'France',
+                    GB: 'United Kingdom',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Greenland',
+                    GR: 'Greece',
+                    GT: 'Guatemala',
+                    HR: 'Croatia',
+                    HU: 'Hungary',
+                    IE: 'Ireland',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Iceland',
+                    IT: 'Italy',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakhstan',
+                    LB: 'Lebanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MC: 'Monaco',
+                    MD: 'Moldova',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Netherlands',
+                    NO: 'Norway',
+                    PK: 'Pakistan',
+                    PL: 'Poland',
+                    PS: 'Palestine',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SA: 'Saudi Arabia',
+                    SE: 'Sweden',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'East Timor',
+                    TN: 'Tunisia',
+                    TR: 'Turkey',
+                    VG: 'Virgin Islands, British',
+                    XK: 'Republic of Kosovo'
+                }
+            }
+        }
+    });
+
+    FormValidation.Validator.iban = {
+        html5Attributes: {
+            message: 'message',
+            country: 'country',
+            sepa: 'sepa'
+        },
+
+        // http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf
+        // http://en.wikipedia.org/wiki/International_Bank_Account_Number#IBAN_formats_by_country
+        REGEX: {
+            AD: 'AD[0-9]{2}[0-9]{4}[0-9]{4}[A-Z0-9]{12}',                       // Andorra
+            AE: 'AE[0-9]{2}[0-9]{3}[0-9]{16}',                                  // United Arab Emirates
+            AL: 'AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}',                               // Albania
+            AO: 'AO[0-9]{2}[0-9]{21}',                                          // Angola
+            AT: 'AT[0-9]{2}[0-9]{5}[0-9]{11}',                                  // Austria
+            AZ: 'AZ[0-9]{2}[A-Z]{4}[A-Z0-9]{20}',                               // Azerbaijan
+            BA: 'BA[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{8}[0-9]{2}',                   // Bosnia and Herzegovina
+            BE: 'BE[0-9]{2}[0-9]{3}[0-9]{7}[0-9]{2}',                           // Belgium
+            BF: 'BF[0-9]{2}[0-9]{23}',                                          // Burkina Faso
+            BG: 'BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}',                // Bulgaria
+            BH: 'BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}',                               // Bahrain
+            BI: 'BI[0-9]{2}[0-9]{12}',                                          // Burundi
+            BJ: 'BJ[0-9]{2}[A-Z]{1}[0-9]{23}',                                  // Benin
+            BR: 'BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z][A-Z0-9]',             // Brazil
+            CH: 'CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}',                               // Switzerland
+            CI: 'CI[0-9]{2}[A-Z]{1}[0-9]{23}',                                  // Ivory Coast
+            CM: 'CM[0-9]{2}[0-9]{23}',                                          // Cameroon
+            CR: 'CR[0-9]{2}[0-9]{3}[0-9]{14}',                                  // Costa Rica
+            CV: 'CV[0-9]{2}[0-9]{21}',                                          // Cape Verde
+            CY: 'CY[0-9]{2}[0-9]{3}[0-9]{5}[A-Z0-9]{16}',                       // Cyprus
+            CZ: 'CZ[0-9]{2}[0-9]{20}',                                          // Czech Republic
+            DE: 'DE[0-9]{2}[0-9]{8}[0-9]{10}',                                  // Germany
+            DK: 'DK[0-9]{2}[0-9]{14}',                                          // Denmark
+            DO: 'DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}',                               // Dominican Republic
+            DZ: 'DZ[0-9]{2}[0-9]{20}',                                          // Algeria
+            EE: 'EE[0-9]{2}[0-9]{2}[0-9]{2}[0-9]{11}[0-9]{1}',                  // Estonia
+            ES: 'ES[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{1}[0-9]{1}[0-9]{10}',          // Spain
+            FI: 'FI[0-9]{2}[0-9]{6}[0-9]{7}[0-9]{1}',                           // Finland
+            FO: 'FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}',                           // Faroe Islands
+            FR: 'FR[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}',               // France
+            GB: 'GB[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}',                           // United Kingdom
+            GE: 'GE[0-9]{2}[A-Z]{2}[0-9]{16}',                                  // Georgia
+            GI: 'GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}',                               // Gibraltar
+            GL: 'GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}',                           // Greenland
+            GR: 'GR[0-9]{2}[0-9]{3}[0-9]{4}[A-Z0-9]{16}',                       // Greece
+            GT: 'GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}',                            // Guatemala
+            HR: 'HR[0-9]{2}[0-9]{7}[0-9]{10}',                                  // Croatia
+            HU: 'HU[0-9]{2}[0-9]{3}[0-9]{4}[0-9]{1}[0-9]{15}[0-9]{1}',          // Hungary
+            IE: 'IE[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}',                           // Ireland
+            IL: 'IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}',                          // Israel
+            IR: 'IR[0-9]{2}[0-9]{22}',                                          // Iran
+            IS: 'IS[0-9]{2}[0-9]{4}[0-9]{2}[0-9]{6}[0-9]{10}',                  // Iceland
+            IT: 'IT[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}',               // Italy
+            JO: 'JO[0-9]{2}[A-Z]{4}[0-9]{4}[0]{8}[A-Z0-9]{10}',                 // Jordan
+            KW: 'KW[0-9]{2}[A-Z]{4}[0-9]{22}',                                  // Kuwait
+            KZ: 'KZ[0-9]{2}[0-9]{3}[A-Z0-9]{13}',                               // Kazakhstan
+            LB: 'LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}',                               // Lebanon
+            LI: 'LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}',                               // Liechtenstein
+            LT: 'LT[0-9]{2}[0-9]{5}[0-9]{11}',                                  // Lithuania
+            LU: 'LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}',                               // Luxembourg
+            LV: 'LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}',                               // Latvia
+            MC: 'MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}',               // Monaco
+            MD: 'MD[0-9]{2}[A-Z0-9]{20}',                                       // Moldova
+            ME: 'ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}',                          // Montenegro
+            MG: 'MG[0-9]{2}[0-9]{23}',                                          // Madagascar
+            MK: 'MK[0-9]{2}[0-9]{3}[A-Z0-9]{10}[0-9]{2}',                       // Macedonia
+            ML: 'ML[0-9]{2}[A-Z]{1}[0-9]{23}',                                  // Mali
+            MR: 'MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}',                        // Mauritania
+            MT: 'MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}',                       // Malta
+            MU: 'MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{3}',  // Mauritius
+            MZ: 'MZ[0-9]{2}[0-9]{21}',                                          // Mozambique
+            NL: 'NL[0-9]{2}[A-Z]{4}[0-9]{10}',                                  // Netherlands
+            NO: 'NO[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{1}',                           // Norway
+            PK: 'PK[0-9]{2}[A-Z]{4}[A-Z0-9]{16}',                               // Pakistan
+            PL: 'PL[0-9]{2}[0-9]{8}[0-9]{16}',                                  // Poland
+            PS: 'PS[0-9]{2}[A-Z]{4}[A-Z0-9]{21}',                               // Palestinian
+            PT: 'PT[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{11}[0-9]{2}',                  // Portugal
+            QA: 'QA[0-9]{2}[A-Z]{4}[A-Z0-9]{21}',                               // Qatar
+            RO: 'RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}',                               // Romania
+            RS: 'RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}',                          // Serbia
+            SA: 'SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}',                               // Saudi Arabia
+            SE: 'SE[0-9]{2}[0-9]{3}[0-9]{16}[0-9]{1}',                          // Sweden
+            SI: 'SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}',                           // Slovenia
+            SK: 'SK[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{10}',                          // Slovakia
+            SM: 'SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}',               // San Marino
+            SN: 'SN[0-9]{2}[A-Z]{1}[0-9]{23}',                                  // Senegal
+            TL: 'TL38[0-9]{3}[0-9]{14}[0-9]{2}',                                // East Timor
+            TN: 'TN59[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}',                        // Tunisia
+            TR: 'TR[0-9]{2}[0-9]{5}[A-Z0-9]{1}[A-Z0-9]{16}',                    // Turkey
+            VG: 'VG[0-9]{2}[A-Z]{4}[0-9]{16}',                                  // Virgin Islands, British
+            XK: 'XK[0-9]{2}[0-9]{4}[0-9]{10}[0-9]{2}'                           // Republic of Kosovo
+        },
+
+        // List of SEPA country codes
+        SEPA_COUNTRIES: [
+            'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES',
+            'FI', 'FR', 'GB', 'GI', 'GR', 'HR', 'HU', 'IE', 'IS', 'IT',
+            'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT',
+            'RO', 'SE', 'SI', 'SK', 'SM'
+        ],
+
+        /**
+         * Validate an International Bank Account Number (IBAN)
+         * To test it, take the sample IBAN from
+         * http://www.nordea.com/Our+services/International+products+and+services/Cash+Management/IBAN+countries/908462.html
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * - country: The ISO 3166-1 country code. It can be
+         *      - A country code
+         *      - Name of field which its value defines the country code
+         *      - Name of callback function that returns the country code
+         *      - A callback function that returns the country code
+         * - sepa: Set it to true (false) to indicate that the IBAN number must be (not be) from SEPA countries
+         * By default, this option is not defined
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            value = value.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
+            var country = options.country;
+            if (!country) {
+                country = value.substr(0, 2);
+            } else if (typeof country !== 'string' || !this.REGEX[country]) {
+                // Determine the country code
+                country = validator.getDynamicOption($field, country);
+            }
+
+            var locale = validator.getLocale();
+            if (!this.REGEX[country]) {
+                return false;
+            }
+
+            // Check whether or not the sepa option is enabled
+            if (typeof options.sepa !== undefined) {
+                var isSepaCountry = $.inArray(country, this.SEPA_COUNTRIES) !== -1;
+                if (((options.sepa === 'true' || options.sepa === true) && !isSepaCountry)
+                    || ((options.sepa === 'false' || options.sepa === false) && isSepaCountry))
+                {
+                    return false;
+                }
+            }
+
+            if (!(new RegExp('^' + this.REGEX[country] + '$')).test(value)) {
+                return {
+                    valid: false,
+                    message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].iban.country, FormValidation.I18n[locale].iban.countries[country])
+                };
+            }
+
+            value = value.substr(4) + value.substr(0, 4);
+            value = $.map(value.split(''), function(n) {
+                var code = n.charCodeAt(0);
+                return (code >= 'A'.charCodeAt(0) && code <= 'Z'.charCodeAt(0))
+                        // Replace A, B, C, ..., Z with 10, 11, ..., 35
+                        ? (code - 'A'.charCodeAt(0) + 10)
+                        : n;
+            });
+            value = value.join('');
+
+            var temp   = parseInt(value.substr(0, 1), 10),
+                length = value.length;
+            for (var i = 1; i < length; ++i) {
+                temp = (temp * 10 + parseInt(value.substr(i, 1), 10)) % 97;
+            }
+
+            return {
+                valid: (temp === 1),
+                message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].iban.country, FormValidation.I18n[locale].iban.countries[country])
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            id: {
+                'default': 'Please enter a valid identification number',
+                country: 'Please enter a valid identification number in %s',
+                countries: {
+                    BA: 'Bosnia and Herzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CL: 'Chile',
+                    CN: 'China',
+                    CZ: 'Czech Republic',
+                    DK: 'Denmark',
+                    EE: 'Estonia',
+                    ES: 'Spain',
+                    FI: 'Finland',
+                    HR: 'Croatia',
+                    IE: 'Ireland',
+                    IS: 'Iceland',
+                    LT: 'Lithuania',
+                    LV: 'Latvia',
+                    ME: 'Montenegro',
+                    MK: 'Macedonia',
+                    NL: 'Netherlands',
+                    PL: 'Poland',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Sweden',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Turkey',
+                    ZA: 'South Africa'
+                }
+            }
+        }
+    });
+
+    FormValidation.Validator.id = {
+        html5Attributes: {
+            message: 'message',
+            country: 'country'
+        },
+
+        // Supported country codes
+        COUNTRY_CODES: [
+            'BA', 'BG', 'BR', 'CH', 'CL', 'CN', 'CZ', 'DK', 'EE', 'ES', 'FI', 'HR', 'IE', 'IS', 'LT', 'LV', 'ME', 'MK', 'NL',
+            'PL', 'RO', 'RS', 'SE', 'SI', 'SK', 'SM', 'TH', 'TR', 'ZA'
+        ],
+
+        /**
+         * Validate identification number in different countries
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - country: The ISO 3166-1 country code. It can be
+         *      - One of country code defined in COUNTRY_CODES
+         *      - Name of field which its value defines the country code
+         *      - Name of callback function that returns the country code
+         *      - A callback function that returns the country code
+         * @returns {Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var locale  = validator.getLocale(),
+                country = options.country;
+            if (!country) {
+                country = value.substr(0, 2);
+            } else if (typeof country !== 'string' || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) {
+                // Determine the country code
+                country = validator.getDynamicOption($field, country);
+            }
+
+            if ($.inArray(country, this.COUNTRY_CODES) === -1) {
+                return true;
+            }
+
+            var method = ['_', country.toLowerCase()].join(''),
+                result = this[method](value);
+            result         = (result === true || result === false) ? { valid: result } : result;
+            result.message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].id.country, FormValidation.I18n[locale].id.countries[country.toUpperCase()]);
+
+            return result;
+        },
+
+        /**
+         * Validate Unique Master Citizen Number which uses in
+         * - Bosnia and Herzegovina (country code: BA)
+         * - Macedonia (MK)
+         * - Montenegro (ME)
+         * - Serbia (RS)
+         * - Slovenia (SI)
+         *
+         * @see http://en.wikipedia.org/wiki/Unique_Master_Citizen_Number
+         * @param {String} value The ID
+         * @param {String} countryCode The ISO country code, can be BA, MK, ME, RS, SI
+         * @returns {Boolean}
+         */
+        _validateJMBG: function(value, countryCode) {
+            if (!/^\d{13}$/.test(value)) {
+                return false;
+            }
+            var day   = parseInt(value.substr(0, 2), 10),
+                month = parseInt(value.substr(2, 2), 10),
+                year  = parseInt(value.substr(4, 3), 10),
+                rr    = parseInt(value.substr(7, 2), 10),
+                k     = parseInt(value.substr(12, 1), 10);
+
+            // Validate date of birth
+            // FIXME: Validate the year of birth
+            if (day > 31 || month > 12) {
+                return false;
+            }
+
+            // Validate checksum
+            var sum = 0;
+            for (var i = 0; i < 6; i++) {
+                sum += (7 - i) * (parseInt(value.charAt(i), 10) + parseInt(value.charAt(i + 6), 10));
+            }
+            sum = 11 - sum % 11;
+            if (sum === 10 || sum === 11) {
+                sum = 0;
+            }
+            if (sum !== k) {
+                return false;
+            }
+
+            // Validate political region
+            // rr is the political region of birth, which can be in ranges:
+            // 10-19: Bosnia and Herzegovina
+            // 20-29: Montenegro
+            // 30-39: Croatia (not used anymore)
+            // 41-49: Macedonia
+            // 50-59: Slovenia (only 50 is used)
+            // 70-79: Central Serbia
+            // 80-89: Serbian province of Vojvodina
+            // 90-99: Kosovo
+            switch (countryCode.toUpperCase()) {
+                case 'BA':
+                    return (10 <= rr && rr <= 19);
+                case 'MK':
+                    return (41 <= rr && rr <= 49);
+                case 'ME':
+                    return (20 <= rr && rr <= 29);
+                case 'RS':
+                    return (70 <= rr && rr <= 99);
+                case 'SI':
+                    return (50 <= rr && rr <= 59);
+                default:
+                    return true;
+            }
+        },
+
+        _ba: function(value) {
+            return this._validateJMBG(value, 'BA');
+        },
+        _mk: function(value) {
+            return this._validateJMBG(value, 'MK');
+        },
+        _me: function(value) {
+            return this._validateJMBG(value, 'ME');
+        },
+        _rs: function(value) {
+            return this._validateJMBG(value, 'RS');
+        },
+
+        /**
+         * Examples: 0101006500006
+         */
+        _si: function(value) {
+            return this._validateJMBG(value, 'SI');
+        },
+
+        /**
+         * Validate Bulgarian national identification number (EGN)
+         *
+         * @see http://en.wikipedia.org/wiki/Uniform_civil_number
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _bg: function(value) {
+            if (!/^\d{10}$/.test(value) && !/^\d{6}\s\d{3}\s\d{1}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/\s/g, '');
+            // Check the birth date
+            var year  = parseInt(value.substr(0, 2), 10) + 1900,
+                month = parseInt(value.substr(2, 2), 10),
+                day   = parseInt(value.substr(4, 2), 10);
+            if (month > 40) {
+                year += 100;
+                month -= 40;
+            } else if (month > 20) {
+                year -= 100;
+                month -= 20;
+            }
+
+            if (!FormValidation.Helper.date(year, month, day)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [2, 4, 8, 5, 10, 9, 7, 3, 6];
+            for (var i = 0; i < 9; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = (sum % 11) % 10;
+            return (sum + '' === value.substr(9, 1));
+        },
+
+        /**
+         * Validate Brazilian national identification number (CPF)
+         *
+         * @see http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _br: function(value) {
+            value = value.replace(/\D/g, '');
+
+            if (!/^\d{11}$/.test(value) || /^1{11}|2{11}|3{11}|4{11}|5{11}|6{11}|7{11}|8{11}|9{11}|0{11}$/.test(value)) {
+                return false;
+            }
+
+            var d1 = 0;
+            for (var i = 0; i < 9; i++) {
+                d1 += (10 - i) * parseInt(value.charAt(i), 10);
+            }
+            d1 = 11 - d1 % 11;
+            if (d1 === 10 || d1 === 11) {
+                d1 = 0;
+            }
+            if (d1 + '' !== value.charAt(9)) {
+                return false;
+            }
+
+            var d2 = 0;
+            for (i = 0; i < 10; i++) {
+                d2 += (11 - i) * parseInt(value.charAt(i), 10);
+            }
+            d2 = 11 - d2 % 11;
+            if (d2 === 10 || d2 === 11) {
+                d2 = 0;
+            }
+
+            return (d2 + '' === value.charAt(10));
+        },
+
+        /**
+         * Validate Swiss Social Security Number (AHV-Nr/No AVS)
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#Switzerland
+         * @see http://www.bsv.admin.ch/themen/ahv/00011/02185/index.html?lang=de
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _ch: function(value) {
+            if (!/^756[\.]{0,1}[0-9]{4}[\.]{0,1}[0-9]{4}[\.]{0,1}[0-9]{2}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/\D/g, '').substr(3);
+            var length = value.length,
+                sum    = 0,
+                weight = (length === 8) ? [3, 1] : [1, 3];
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i % 2];
+            }
+            sum = 10 - sum % 10;
+            return (sum + '' === value.charAt(length - 1));
+        },
+
+        /**
+         * Validate Chilean national identification number (RUN/RUT)
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#Chile
+         * @see https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html for samples
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _cl: function(value) {
+            if (!/^\d{7,8}[-]{0,1}[0-9K]$/i.test(value)) {
+                return false;
+            }
+            value = value.replace(/\-/g, '');
+            while (value.length < 9) {
+                value = '0' + value;
+            }
+            var sum    = 0,
+                weight = [3, 2, 7, 6, 5, 4, 3, 2];
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = 11 - sum % 11;
+            if (sum === 11) {
+                sum = 0;
+            } else if (sum === 10) {
+                sum = 'K';
+            }
+            return sum + '' === value.charAt(8).toUpperCase();
+        },
+
+        /**
+         * Validate Chinese citizen identification number
+         *
+         * Rules:
+         * - For current 18-digit system (since 1st Oct 1999, defined by GB11643—1999 national standard):
+         *     - Digit 0-5: Must be a valid administrative division code of China PR.
+         *     - Digit 6-13: Must be a valid YYYYMMDD date of birth. A future date is tolerated.
+         *     - Digit 14-16: Order code, any integer.
+         *     - Digit 17: An ISO 7064:1983, MOD 11-2 checksum.
+         *       Both upper/lower case of X are tolerated.
+         * - For deprecated 15-digit system:
+         *     - Digit 0-5: Must be a valid administrative division code of China PR.
+         *     - Digit 6-11: Must be a valid YYMMDD date of birth, indicating the year of 19XX.
+         *     - Digit 12-14: Order code, any integer.
+         * Lists of valid administrative division codes of China PR can be seen here:
+         * <http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/>
+         * Published and maintained by National Bureau of Statistics of China PR.
+         * NOTE: Current and deprecated codes MUST BOTH be considered valid.
+         * Many Chinese citizens born in once existed administrative divisions!
+         *
+         * @see http://en.wikipedia.org/wiki/Resident_Identity_Card#Identity_card_number
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _cn: function(value) {
+            // Basic format check (18 or 15 digits, considering X in checksum)
+            value = value.trim();
+            if (!/^\d{15}$/.test(value) && !/^\d{17}[\dXx]{1}$/.test(value)) {
+                return false;
+            }
+            
+            // Check China PR Administrative division code
+            var adminDivisionCodes = {
+                11: {
+                    0: [0],
+                    1: [[0, 9], [11, 17]],
+                    2: [0, 28, 29]
+                },
+                12: {
+                    0: [0],
+                    1: [[0, 16]],
+                    2: [0, 21, 23, 25]
+                },
+                13: {
+                    0: [0],
+                    1: [[0, 5], 7, 8, 21, [23, 33], [81, 85]],
+                    2: [[0, 5], [7, 9], [23, 25], 27, 29, 30, 81, 83],
+                    3: [[0, 4], [21, 24]],
+                    4: [[0, 4], 6, 21, [23, 35], 81],
+                    5: [[0, 3], [21, 35], 81, 82],
+                    6: [[0, 4], [21, 38], [81, 84]],
+                    7: [[0, 3], 5, 6, [21, 33]],
+                    8: [[0, 4], [21, 28]],
+                    9: [[0, 3], [21, 30], [81, 84]],
+                    10: [[0, 3], [22, 26], 28, 81, 82],
+                    11: [[0, 2], [21, 28], 81, 82]
+                },
+                14: {
+                    0: [0],
+                    1: [0, 1, [5, 10], [21, 23], 81],
+                    2: [[0, 3], 11, 12, [21, 27]],
+                    3: [[0, 3], 11, 21, 22],
+                    4: [[0, 2], 11, 21, [23, 31], 81],
+                    5: [[0, 2], 21, 22, 24, 25, 81],
+                    6: [[0, 3], [21, 24]],
+                    7: [[0, 2], [21, 29], 81],
+                    8: [[0, 2], [21, 30], 81, 82],
+                    9: [[0, 2], [21, 32], 81],
+                    10: [[0, 2], [21, 34], 81, 82],
+                    11: [[0, 2], [21, 30], 81, 82],
+                    23: [[0, 3], 22, 23, [25, 30], 32, 33]
+                },
+                15: {
+                    0: [0],
+                    1: [[0, 5], [21, 25]],
+                    2: [[0, 7], [21, 23]],
+                    3: [[0, 4]],
+                    4: [[0, 4], [21, 26], [28, 30]],
+                    5: [[0, 2], [21, 26], 81],
+                    6: [[0, 2], [21, 27]],
+                    7: [[0, 3], [21, 27], [81, 85]],
+                    8: [[0, 2], [21, 26]],
+                    9: [[0, 2], [21, 29], 81],
+                    22: [[0, 2], [21, 24]],
+                    25: [[0, 2], [22, 31]],
+                    26: [[0, 2], [24, 27], [29, 32], 34],
+                    28: [0, 1, [22, 27]],
+                    29: [0, [21, 23]]
+                },
+                21: {
+                    0: [0],
+                    1: [[0, 6], [11, 14], [22, 24], 81],
+                    2: [[0, 4], [11, 13], 24, [81, 83]],
+                    3: [[0, 4], 11, 21, 23, 81],
+                    4: [[0, 4], 11, [21, 23]],
+                    5: [[0, 5], 21, 22],
+                    6: [[0, 4], 24, 81, 82],
+                    7: [[0, 3], 11, 26, 27, 81, 82],
+                    8: [[0, 4], 11, 81, 82],
+                    9: [[0, 5], 11, 21, 22],
+                    10: [[0, 5], 11, 21, 81],
+                    11: [[0, 3], 21, 22],
+                    12: [[0, 2], 4, 21, 23, 24, 81, 82],
+                    13: [[0, 3], 21, 22, 24, 81, 82],
+                    14: [[0, 4], 21, 22, 81]
+                },
+                22: {
+                    0: [0],
+                    1: [[0, 6], 12, 22, [81, 83]],
+                    2: [[0, 4], 11, 21, [81, 84]],
+                    3: [[0, 3], 22, 23, 81, 82],
+                    4: [[0, 3], 21, 22],
+                    5: [[0, 3], 21, 23, 24, 81, 82],
+                    6: [[0, 2], 4, 5, [21, 23], 25, 81],
+                    7: [[0, 2], [21, 24], 81],
+                    8: [[0, 2], 21, 22, 81, 82],
+                    24: [[0, 6], 24, 26]
+                },
+                23: {
+                    0: [0],
+                    1: [[0, 12], 21, [23, 29], [81, 84]],
+                    2: [[0, 8], 21, [23, 25], 27, [29, 31], 81],
+                    3: [[0, 7], 21, 81, 82],
+                    4: [[0, 7], 21, 22],
+                    5: [[0, 3], 5, 6, [21, 24]],
+                    6: [[0, 6], [21, 24]],
+                    7: [[0, 16], 22, 81],
+                    8: [[0, 5], 11, 22, 26, 28, 33, 81, 82],
+                    9: [[0, 4], 21],
+                    10: [[0, 5], 24, 25, 81, [83, 85]],
+                    11: [[0, 2], 21, 23, 24, 81, 82],
+                    12: [[0, 2], [21, 26], [81, 83]],
+                    27: [[0, 4], [21, 23]]
+                },
+                31: {
+                    0: [0],
+                    1: [0, 1, [3, 10], [12, 20]],
+                    2: [0, 30]
+                },
+                32: {
+                    0: [0],
+                    1: [[0, 7], 11, [13, 18], 24, 25],
+                    2: [[0, 6], 11, 81, 82],
+                    3: [[0, 5], 11, 12, [21, 24], 81, 82],
+                    4: [[0, 2], 4, 5, 11, 12, 81, 82],
+                    5: [[0, 9], [81, 85]],
+                    6: [[0, 2], 11, 12, 21, 23, [81, 84]],
+                    7: [0, 1, 3, 5, 6, [21, 24]],
+                    8: [[0, 4], 11, 26, [29, 31]],
+                    9: [[0, 3], [21, 25], 28, 81, 82],
+                    10: [[0, 3], 11, 12, 23, 81, 84, 88],
+                    11: [[0, 2], 11, 12, [81, 83]],
+                    12: [[0, 4], [81, 84]],
+                    13: [[0, 2], 11, [21, 24]]
+                },
+                33: {
+                    0: [0],
+                    1: [[0, 6], [8, 10], 22, 27, 82, 83, 85],
+                    2: [0, 1, [3, 6], 11, 12, 25, 26, [81, 83]],
+                    3: [[0, 4], 22, 24, [26, 29], 81, 82],
+                    4: [[0, 2], 11, 21, 24, [81, 83]],
+                    5: [[0, 3], [21, 23]],
+                    6: [[0, 2], 21, 24, [81, 83]],
+                    7: [[0, 3], 23, 26, 27, [81, 84]],
+                    8: [[0, 3], 22, 24, 25, 81],
+                    9: [[0, 3], 21, 22],
+                    10: [[0, 4], [21, 24], 81, 82],
+                    11: [[0, 2], [21, 27], 81]
+                },
+                34: {
+                    0: [0],
+                    1: [[0, 4], 11, [21, 24], 81],
+                    2: [[0, 4], 7, 8, [21, 23], 25],
+                    3: [[0, 4], 11, [21, 23]],
+                    4: [[0, 6], 21],
+                    5: [[0, 4], 6, [21, 23]],
+                    6: [[0, 4], 21],
+                    7: [[0, 3], 11, 21],
+                    8: [[0, 3], 11, [22, 28], 81],
+                    10: [[0, 4], [21, 24]],
+                    11: [[0, 3], 22, [24, 26], 81, 82],
+                    12: [[0, 4], 21, 22, 25, 26, 82],
+                    13: [[0, 2], [21, 24]],
+                    14: [[0, 2], [21, 24]],
+                    15: [[0, 3], [21, 25]],
+                    16: [[0, 2], [21, 23]],
+                    17: [[0, 2], [21, 23]],
+                    18: [[0, 2], [21, 25], 81]
+                },
+                35: {
+                    0: [0],
+                    1: [[0, 5], 11, [21, 25], 28, 81, 82],
+                    2: [[0, 6], [11, 13]],
+                    3: [[0, 5], 22],
+                    4: [[0, 3], 21, [23, 30], 81],
+                    5: [[0, 5], 21, [24, 27], [81, 83]],
+                    6: [[0, 3], [22, 29], 81],
+                    7: [[0, 2], [21, 25], [81, 84]],
+                    8: [[0, 2], [21, 25], 81],
+                    9: [[0, 2], [21, 26], 81, 82]
+                },
+                36: {
+                    0: [0],
+                    1: [[0, 5], 11, [21, 24]],
+                    2: [[0, 3], 22, 81],
+                    3: [[0, 2], 13, [21, 23]],
+                    4: [[0, 3], 21, [23, 30], 81, 82],
+                    5: [[0, 2], 21],
+                    6: [[0, 2], 22, 81],
+                    7: [[0, 2], [21, 35], 81, 82],
+                    8: [[0, 3], [21, 30], 81],
+                    9: [[0, 2], [21, 26], [81, 83]],
+                    10: [[0, 2], [21, 30]],
+                    11: [[0, 2], [21, 30], 81]
+                },
+                37: {
+                    0: [0],
+                    1: [[0, 5], 12, 13, [24, 26], 81],
+                    2: [[0, 3], 5, [11, 14], [81, 85]],
+                    3: [[0, 6], [21, 23]],
+                    4: [[0, 6], 81],
+                    5: [[0, 3], [21, 23]],
+                    6: [[0, 2], [11, 13], 34, [81, 87]],
+                    7: [[0, 5], 24, 25, [81, 86]],
+                    8: [[0, 2], 11, [26, 32], [81, 83]],
+                    9: [[0, 3], 11, 21, 23, 82, 83],
+                    10: [[0, 2], [81, 83]],
+                    11: [[0, 3], 21, 22],
+                    12: [[0, 3]],
+                    13: [[0, 2], 11, 12, [21, 29]],
+                    14: [[0, 2], [21, 28], 81, 82],
+                    15: [[0, 2], [21, 26], 81],
+                    16: [[0, 2], [21, 26]],
+                    17: [[0, 2], [21, 28]]
+                },
+                41: {
+                    0: [0],
+                    1: [[0, 6], 8, 22, [81, 85]],
+                    2: [[0, 5], 11, [21, 25]],
+                    3: [[0, 7], 11, [22, 29], 81],
+                    4: [[0, 4], 11, [21, 23], 25, 81, 82],
+                    5: [[0, 3], 5, 6, 22, 23, 26, 27, 81],
+                    6: [[0, 3], 11, 21, 22],
+                    7: [[0, 4], 11, 21, [24, 28], 81, 82],
+                    8: [[0, 4], 11, [21, 23], 25, [81, 83]],
+                    9: [[0, 2], 22, 23, [26, 28]],
+                    10: [[0, 2], [23, 25], 81, 82],
+                    11: [[0, 4], [21, 23]],
+                    12: [[0, 2], 21, 22, 24, 81, 82],
+                    13: [[0, 3], [21, 30], 81],
+                    14: [[0, 3], [21, 26], 81],
+                    15: [[0, 3], [21, 28]],
+                    16: [[0, 2], [21, 28], 81],
+                    17: [[0, 2], [21, 29]],
+                    90: [0, 1]
+                },
+                42: {
+                    0: [0],
+                    1: [[0, 7], [11, 17]],
+                    2: [[0, 5], 22, 81],
+                    3: [[0, 3], [21, 25], 81],
+                    5: [[0, 6], [25, 29], [81, 83]],
+                    6: [[0, 2], 6, 7, [24, 26], [82, 84]],
+                    7: [[0, 4]],
+                    8: [[0, 2], 4, 21, 22, 81],
+                    9: [[0, 2], [21, 23], 81, 82, 84],
+                    10: [[0, 3], [22, 24], 81, 83, 87],
+                    11: [[0, 2], [21, 27], 81, 82],
+                    12: [[0, 2], [21, 24], 81],
+                    13: [[0, 3], 21, 81],
+                    28: [[0, 2], 22, 23, [25, 28]],
+                    90: [0, [4, 6], 21]
+                },
+                43: {
+                    0: [0],
+                    1: [[0, 5], 11, 12, 21, 22, 24, 81],
+                    2: [[0, 4], 11, 21, [23, 25], 81],
+                    3: [[0, 2], 4, 21, 81, 82],
+                    4: [0, 1, [5, 8], 12, [21, 24], 26, 81, 82],
+                    5: [[0, 3], 11, [21, 25], [27, 29], 81],
+                    6: [[0, 3], 11, 21, 23, 24, 26, 81, 82],
+                    7: [[0, 3], [21, 26], 81],
+                    8: [[0, 2], 11, 21, 22],
+                    9: [[0, 3], [21, 23], 81],
+                    10: [[0, 3], [21, 28], 81],
+                    11: [[0, 3], [21, 29]],
+                    12: [[0, 2], [21, 30], 81],
+                    13: [[0, 2], 21, 22, 81, 82],
+                    31: [0, 1, [22, 27], 30]
+                },
+                44: {
+                    0: [0],
+                    1: [[0, 7], [11, 16], 83, 84],
+                    2: [[0, 5], 21, 22, 24, 29, 32, 33, 81, 82],
+                    3: [0, 1, [3, 8]],
+                    4: [[0, 4]],
+                    5: [0, 1, [6, 15], 23, 82, 83],
+                    6: [0, 1, [4, 8]],
+                    7: [0, 1, [3, 5], 81, [83, 85]],
+                    8: [[0, 4], 11, 23, 25, [81, 83]],
+                    9: [[0, 3], 23, [81, 83]],
+                    12: [[0, 3], [23, 26], 83, 84],
+                    13: [[0, 3], [22, 24], 81],
+                    14: [[0, 2], [21, 24], 26, 27, 81],
+                    15: [[0, 2], 21, 23, 81],
+                    16: [[0, 2], [21, 25]],
+                    17: [[0, 2], 21, 23, 81],
+                    18: [[0, 3], 21, 23, [25, 27], 81, 82],
+                    19: [0],
+                    20: [0],
+                    51: [[0, 3], 21, 22],
+                    52: [[0, 3], 21, 22, 24, 81],
+                    53: [[0, 2], [21, 23], 81]
+                },
+                45: {
+                    0: [0],
+                    1: [[0, 9], [21, 27]],
+                    2: [[0, 5], [21, 26]],
+                    3: [[0, 5], 11, 12, [21, 32]],
+                    4: [0, 1, [3, 6], 11, [21, 23], 81],
+                    5: [[0, 3], 12, 21],
+                    6: [[0, 3], 21, 81],
+                    7: [[0, 3], 21, 22],
+                    8: [[0, 4], 21, 81],
+                    9: [[0, 3], [21, 24], 81],
+                    10: [[0, 2], [21, 31]],
+                    11: [[0, 2], [21, 23]],
+                    12: [[0, 2], [21, 29], 81],
+                    13: [[0, 2], [21, 24], 81],
+                    14: [[0, 2], [21, 25], 81]
+                },
+                46: {
+                    0: [0],
+                    1: [0, 1, [5, 8]],
+                    2: [0, 1],
+                    3: [0, [21, 23]],
+                    90: [[0, 3], [5, 7], [21, 39]]
+                },
+                50: {
+                    0: [0],
+                    1: [[0, 19]],
+                    2: [0, [22, 38], [40, 43]],
+                    3: [0, [81, 84]]
+                },
+                51: {
+                    0: [0],
+                    1: [0, 1, [4, 8], [12, 15], [21, 24], 29, 31, 32, [81, 84]],
+                    3: [[0, 4], 11, 21, 22],
+                    4: [[0, 3], 11, 21, 22],
+                    5: [[0, 4], 21, 22, 24, 25],
+                    6: [0, 1, 3, 23, 26, [81, 83]],
+                    7: [0, 1, 3, 4, [22, 27], 81],
+                    8: [[0, 2], 11, 12, [21, 24]],
+                    9: [[0, 4], [21, 23]],
+                    10: [[0, 2], 11, 24, 25, 28],
+                    11: [[0, 2], [11, 13], 23, 24, 26, 29, 32, 33, 81],
+                    13: [[0, 4], [21, 25], 81],
+                    14: [[0, 2], [21, 25]],
+                    15: [[0, 3], [21, 29]],
+                    16: [[0, 3], [21, 23], 81],
+                    17: [[0, 3], [21, 25], 81],
+                    18: [[0, 3], [21, 27]],
+                    19: [[0, 3], [21, 23]],
+                    20: [[0, 2], 21, 22, 81],
+                    32: [0, [21, 33]],
+                    33: [0, [21, 38]],
+                    34: [0, 1, [22, 37]]
+                },
+                52: {
+                    0: [0],
+                    1: [[0, 3], [11, 15], [21, 23], 81],
+                    2: [0, 1, 3, 21, 22],
+                    3: [[0, 3], [21, 30], 81, 82],
+                    4: [[0, 2], [21, 25]],
+                    5: [[0, 2], [21, 27]],
+                    6: [[0, 3], [21, 28]],
+                    22: [0, 1, [22, 30]],
+                    23: [0, 1, [22, 28]],
+                    24: [0, 1, [22, 28]],
+                    26: [0, 1, [22, 36]],
+                    27: [[0, 2], 22, 23, [25, 32]]
+                },
+                53: {
+                    0: [0],
+                    1: [[0, 3], [11, 14], 21, 22, [24, 29], 81],
+                    3: [[0, 2], [21, 26], 28, 81],
+                    4: [[0, 2], [21, 28]],
+                    5: [[0, 2], [21, 24]],
+                    6: [[0, 2], [21, 30]],
+                    7: [[0, 2], [21, 24]],
+                    8: [[0, 2], [21, 29]],
+                    9: [[0, 2], [21, 27]],
+                    23: [0, 1, [22, 29], 31],
+                    25: [[0, 4], [22, 32]],
+                    26: [0, 1, [21, 28]],
+                    27: [0, 1, [22, 30]], 28: [0, 1, 22, 23],
+                    29: [0, 1, [22, 32]],
+                    31: [0, 2, 3, [22, 24]],
+                    34: [0, [21, 23]],
+                    33: [0, 21, [23, 25]],
+                    35: [0, [21, 28]]
+                },
+                54: {
+                    0: [0],
+                    1: [[0, 2], [21, 27]],
+                    21: [0, [21, 29], 32, 33],
+                    22: [0, [21, 29], [31, 33]],
+                    23: [0, 1, [22, 38]],
+                    24: [0, [21, 31]],
+                    25: [0, [21, 27]],
+                    26: [0, [21, 27]]
+                },
+                61: {
+                    0: [0],
+                    1: [[0, 4], [11, 16], 22, [24, 26]],
+                    2: [[0, 4], 22],
+                    3: [[0, 4], [21, 24], [26, 31]],
+                    4: [[0, 4], [22, 31], 81],
+                    5: [[0, 2], [21, 28], 81, 82],
+                    6: [[0, 2], [21, 32]],
+                    7: [[0, 2], [21, 30]],
+                    8: [[0, 2], [21, 31]],
+                    9: [[0, 2], [21, 29]],
+                    10: [[0, 2], [21, 26]]
+                },
+                62: {
+                    0: [0],
+                    1: [[0, 5], 11, [21, 23]],
+                    2: [0, 1],
+                    3: [[0, 2], 21],
+                    4: [[0, 3], [21, 23]],
+                    5: [[0, 3], [21, 25]],
+                    6: [[0, 2], [21, 23]],
+                    7: [[0, 2], [21, 25]],
+                    8: [[0, 2], [21, 26]],
+                    9: [[0, 2], [21, 24], 81, 82],
+                    10: [[0, 2], [21, 27]],
+                    11: [[0, 2], [21, 26]],
+                    12: [[0, 2], [21, 28]],
+                    24: [0, 21, [24, 29]],
+                    26: [0, 21, [23, 30]],
+                    29: [0, 1, [21, 27]],
+                    30: [0, 1, [21, 27]]
+                },
+                63: {
+                    0: [0],
+                    1: [[0, 5], [21, 23]],
+                    2: [0, 2, [21, 25]],
+                    21: [0, [21, 23], [26, 28]],
+                    22: [0, [21, 24]],
+                    23: [0, [21, 24]],
+                    25: [0, [21, 25]],
+                    26: [0, [21, 26]],
+                    27: [0, 1, [21, 26]],
+                    28: [[0, 2], [21, 23]]
+                },
+                64: {
+                    0: [0],
+                    1: [0, 1, [4, 6], 21, 22, 81],
+                    2: [[0, 3], 5, [21, 23]],
+                    3: [[0, 3], [21, 24], 81],
+                    4: [[0, 2], [21, 25]],
+                    5: [[0, 2], 21, 22]
+                },
+                65: {
+                    0: [0],
+                    1: [[0, 9], 21],
+                    2: [[0, 5]],
+                    21: [0, 1, 22, 23],
+                    22: [0, 1, 22, 23],
+                    23: [[0, 3], [23, 25], 27, 28],
+                    28: [0, 1, [22, 29]],
+                    29: [0, 1, [22, 29]],
+                    30: [0, 1, [22, 24]], 31: [0, 1, [21, 31]],
+                    32: [0, 1, [21, 27]],
+                    40: [0, 2, 3, [21, 28]],
+                    42: [[0, 2], 21, [23, 26]],
+                    43: [0, 1, [21, 26]],
+                    90: [[0, 4]], 27: [[0, 2], 22, 23]
+                },
+                71: { 0: [0] },
+                81: { 0: [0] },
+                82: { 0: [0] }
+            };
+            
+            var provincial  = parseInt(value.substr(0, 2), 10),
+                prefectural = parseInt(value.substr(2, 2), 10),
+                county      = parseInt(value.substr(4, 2), 10);
+            
+            if (!adminDivisionCodes[provincial] || !adminDivisionCodes[provincial][prefectural]) {
+                return false;
+            }
+            var inRange  = false,
+                rangeDef = adminDivisionCodes[provincial][prefectural];
+            for (var i = 0; i < rangeDef.length; i++) {
+                if (($.isArray(rangeDef[i]) && rangeDef[i][0] <= county && county <= rangeDef[i][1])
+                    || (!$.isArray(rangeDef[i]) && county === rangeDef[i]))
+                {
+                    inRange = true;
+                    break;
+                }
+            }
+
+            if (!inRange) {
+                return false;
+            }
+            
+            // Check date of birth
+            var dob;
+            if (value.length === 18) {
+                dob = value.substr(6, 8);
+            } else /* length == 15 */ { 
+                dob = '19' + value.substr(6, 6);
+            }
+            var year  = parseInt(dob.substr(0, 4), 10),
+                month = parseInt(dob.substr(4, 2), 10),
+                day   = parseInt(dob.substr(6, 2), 10);
+            if (!FormValidation.Helper.date(year, month, day)) {
+                return false;
+            }
+            
+            // Check checksum (18-digit system only)
+            if (value.length === 18) {
+                var sum    = 0,
+                    weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
+                for (i = 0; i < 17; i++) {
+                    sum += parseInt(value.charAt(i), 10) * weight[i];
+                }
+                sum = (12 - (sum % 11)) % 11;
+                var checksum = (value.charAt(17).toUpperCase() !== 'X') ? parseInt(value.charAt(17), 10) : 10;
+                return checksum === sum;
+            }
+            
+            return true;
+        },
+        
+        /**
+         * Validate Czech national identification number (RC)
+         *
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _cz: function(value) {
+            if (!/^\d{9,10}$/.test(value)) {
+                return false;
+            }
+            var year  = 1900 + parseInt(value.substr(0, 2), 10),
+                month = parseInt(value.substr(2, 2), 10) % 50 % 20,
+                day   = parseInt(value.substr(4, 2), 10);
+            if (value.length === 9) {
+                if (year >= 1980) {
+                    year -= 100;
+                }
+                if (year > 1953) {
+                    return false;
+                }
+            } else if (year < 1954) {
+                year += 100;
+            }
+
+            if (!FormValidation.Helper.date(year, month, day)) {
+                return false;
+            }
+
+            // Check that the birth date is not in the future
+            if (value.length === 10) {
+                var check = parseInt(value.substr(0, 9), 10) % 11;
+                if (year < 1985) {
+                    check = check % 10;
+                }
+                return (check + '' === value.substr(9, 1));
+            }
+
+            return true;
+        },
+
+        /**
+         * Validate Danish Personal Identification number (CPR)
+         *
+         * @see https://en.wikipedia.org/wiki/Personal_identification_number_(Denmark)
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _dk: function(value) {
+            if (!/^[0-9]{6}[-]{0,1}[0-9]{4}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/-/g, '');
+            var day   = parseInt(value.substr(0, 2), 10),
+                month = parseInt(value.substr(2, 2), 10),
+                year  = parseInt(value.substr(4, 2), 10);
+
+            switch (true) {
+                case ('5678'.indexOf(value.charAt(6)) !== -1 && year >= 58):
+                    year += 1800;
+                    break;
+                case ('0123'.indexOf(value.charAt(6)) !== -1):
+                case ('49'.indexOf(value.charAt(6)) !== -1 && year >= 37):
+                    year += 1900;
+                    break;
+                default:
+                    year += 2000;
+                    break;
+            }
+
+            return FormValidation.Helper.date(year, month, day);
+        },
+
+        /**
+         * Validate Estonian Personal Identification Code (isikukood)
+         *
+         * @see http://et.wikipedia.org/wiki/Isikukood
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _ee: function(value) {
+            // Use the same format as Lithuanian Personal Code
+            return this._lt(value);
+        },
+
+        /**
+         * Validate Spanish personal identity code (DNI)
+         * Support DNI (for Spanish citizens), NIE (for foreign people) and CIF (for legal entities)
+         *
+         * @see https://en.wikipedia.org/wiki/National_identification_number#Spain
+         * @param {String} value The ID
+         * @returns {Boolean|Object}
+         */
+        _es: function(value) {
+            var isDNI = /^[0-9]{8}[-]{0,1}[A-HJ-NP-TV-Z]$/.test(value),
+                isNIE = /^[XYZ][-]{0,1}[0-9]{7}[-]{0,1}[A-HJ-NP-TV-Z]$/.test(value),
+                isCIF = /^[A-HNPQS][-]{0,1}[0-9]{7}[-]{0,1}[0-9A-J]$/.test(value);
+            if (!isDNI && !isNIE && !isCIF) {
+                return false;
+            }
+
+            value = value.replace(/-/g, '');
+            var check, type, isValid = true;
+            if (isDNI || isNIE) {
+                type = 'DNI';
+                var index = 'XYZ'.indexOf(value.charAt(0));
+                if (index !== -1) {
+                    // It is NIE number
+                    value = index + value.substr(1) + '';
+                    type  = 'NIE';
+                }
+
+                check = parseInt(value.substr(0, 8), 10);
+                check = 'TRWAGMYFPDXBNJZSQVHLCKE'[check % 23];
+                return {
+                    valid: (check === value.substr(8, 1)),
+                    type: type
+                };
+            } else {
+                check = value.substr(1, 7);
+                type  = 'CIF';
+                var letter  = value[0],
+                    control = value.substr(-1),
+                    sum     = 0;
+
+                // The digits in the even positions are added to the sum directly.
+                // The ones in the odd positions are multiplied by 2 and then added to the sum.
+                // If the result of multiplying by 2 is 10 or higher, add the two digits
+                // together and add that to the sum instead
+                for (var i = 0; i < check.length; i++) {
+                    if (i % 2 !== 0) {
+                        sum += parseInt(check[i], 10);
+                    } else {
+                        var tmp = '' + (parseInt(check[i], 10) * 2);
+                        sum += parseInt(tmp[0], 10);
+                        if (tmp.length === 2) {
+                            sum += parseInt(tmp[1], 10);
+                        }
+                    }
+                }
+
+                // The control digit is calculated from the last digit of the sum.
+                // If that last digit is not 0, subtract it from 10
+                var lastDigit = sum - (Math.floor(sum / 10) * 10);
+                if (lastDigit !== 0) {
+                    lastDigit = 10 - lastDigit;
+                }
+                
+                if ('KQS'.indexOf(letter) !== -1) {
+                    // If the CIF starts with a K, Q or S, the control digit must be a letter
+                    isValid = (control === 'JABCDEFGHI'[lastDigit]);
+                } else if ('ABEH'.indexOf(letter) !== -1) {
+                    // If it starts with A, B, E or H, it has to be a number
+                    isValid = (control === ('' + lastDigit));
+                } else {
+                    // In any other case, it doesn't matter
+                    isValid = (control === ('' + lastDigit) || control === 'JABCDEFGHI'[lastDigit]);
+                }
+
+                return {
+                    valid: isValid,
+                    type: type
+                };
+            }
+        },
+
+        /**
+         * Validate Finnish Personal Identity Code (HETU)
+         *
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _fi: function(value) {
+            if (!/^[0-9]{6}[-+A][0-9]{3}[0-9ABCDEFHJKLMNPRSTUVWXY]$/.test(value)) {
+                return false;
+            }
+            var day       = parseInt(value.substr(0, 2), 10),
+                month     = parseInt(value.substr(2, 2), 10),
+                year      = parseInt(value.substr(4, 2), 10),
+                centuries = {
+                    '+': 1800,
+                    '-': 1900,
+                    'A': 2000
+                };
+            year = centuries[value.charAt(6)] + year;
+
+            if (!FormValidation.Helper.date(year, month, day)) {
+                return false;
+            }
+
+            var individual = parseInt(value.substr(7, 3), 10);
+            if (individual < 2) {
+                return false;
+            }
+            var n = value.substr(0, 6) + value.substr(7, 3) + '';
+            n = parseInt(n, 10);
+            return '0123456789ABCDEFHJKLMNPRSTUVWXY'.charAt(n % 31) === value.charAt(10);
+        },
+
+        /**
+         * Validate Croatian personal identification number (OIB)
+         *
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _hr: function(value) {
+            if (!/^[0-9]{11}$/.test(value)) {
+                return false;
+            }
+            return FormValidation.Helper.mod11And10(value);
+        },
+
+        /**
+         * Validate Irish Personal Public Service Number (PPS)
+         *
+         * @see https://en.wikipedia.org/wiki/Personal_Public_Service_Number
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _ie: function(value) {
+            if (!/^\d{7}[A-W][AHWTX]?$/.test(value)) {
+                return false;
+            }
+
+            var getCheckDigit = function(value) {
+                while (value.length < 7) {
+                    value = '0' + value;
+                }
+                var alphabet = 'WABCDEFGHIJKLMNOPQRSTUV',
+                    sum      = 0;
+                for (var i = 0; i < 7; i++) {
+                    sum += parseInt(value.charAt(i), 10) * (8 - i);
+                }
+                sum += 9 * alphabet.indexOf(value.substr(7));
+                return alphabet[sum % 23];
+            };
+
+            // 2013 format
+            if (value.length === 9 && ('A' === value.charAt(8) || 'H' === value.charAt(8))) {
+                return value.charAt(7) === getCheckDigit(value.substr(0, 7) + value.substr(8) + '');
+            }
+            // The old format
+            else {
+                return value.charAt(7) === getCheckDigit(value.substr(0, 7));
+            }
+        },
+
+        /**
+         * Validate Iceland national identification number (Kennitala)
+         *
+         *  @see http://en.wikipedia.org/wiki/Kennitala
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _is: function(value) {
+            if (!/^[0-9]{6}[-]{0,1}[0-9]{4}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/-/g, '');
+            var day     = parseInt(value.substr(0, 2), 10),
+                month   = parseInt(value.substr(2, 2), 10),
+                year    = parseInt(value.substr(4, 2), 10),
+                century = parseInt(value.charAt(9), 10);
+
+            year = (century === 9) ? (1900 + year) : ((20 + century) * 100 + year);
+            if (!FormValidation.Helper.date(year, month, day, true)) {
+                return false;
+            }
+            // Validate the check digit
+            var sum    = 0,
+                weight = [3, 2, 7, 6, 5, 4, 3, 2];
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = 11 - sum % 11;
+            return (sum + '' === value.charAt(8));
+        },
+
+        /**
+         * Validate Lithuanian Personal Code (Asmens kodas)
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#Lithuania
+         * @see http://www.adomas.org/midi2007/pcode.html
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _lt: function(value) {
+            if (!/^[0-9]{11}$/.test(value)) {
+                return false;
+            }
+            var gender  = parseInt(value.charAt(0), 10),
+                year    = parseInt(value.substr(1, 2), 10),
+                month   = parseInt(value.substr(3, 2), 10),
+                day     = parseInt(value.substr(5, 2), 10),
+                century = (gender % 2 === 0) ? (17 + gender / 2) : (17 + (gender + 1) / 2);
+            year = century * 100 + year;
+            if (!FormValidation.Helper.date(year, month, day, true)) {
+                return false;
+            }
+
+            // Validate the check digit
+            var sum    = 0,
+                weight = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1];
+            for (var i = 0; i < 10; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = sum % 11;
+            if (sum !== 10) {
+                return sum + '' === value.charAt(10);
+            }
+
+            // Re-calculate the check digit
+            sum    = 0;
+            weight = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3];
+            for (i = 0; i < 10; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = sum % 11;
+            if (sum === 10) {
+                sum = 0;
+            }
+            return (sum + '' === value.charAt(10));
+        },
+
+        /**
+         * Validate Latvian Personal Code (Personas kods)
+         *
+         * @see http://laacz.lv/2006/11/25/pk-parbaudes-algoritms/
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _lv: function(value) {
+            if (!/^[0-9]{6}[-]{0,1}[0-9]{5}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/\D/g, '');
+            // Check birth date
+            var day   = parseInt(value.substr(0, 2), 10),
+                month = parseInt(value.substr(2, 2), 10),
+                year  = parseInt(value.substr(4, 2), 10);
+            year = year + 1800 + parseInt(value.charAt(6), 10) * 100;
+
+            if (!FormValidation.Helper.date(year, month, day, true)) {
+                return false;
+            }
+
+            // Check personal code
+            var sum    = 0,
+                weight = [10, 5, 8, 4, 2, 1, 6, 3, 7, 9];
+            for (var i = 0; i < 10; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = (sum + 1) % 11 % 10;
+            return (sum + '' === value.charAt(10));
+        },
+
+        /**
+         * Validate Dutch national identification number (BSN)
+         *
+         * @see https://nl.wikipedia.org/wiki/Burgerservicenummer
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _nl: function(value) {
+            if (value.length < 8) {
+                return false;
+            }
+
+            if (value.length === 8) {
+                value = '0' + value;
+            }
+            if (!/^[0-9]{4}[.]{0,1}[0-9]{2}[.]{0,1}[0-9]{3}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/\./g, '');
+            if (parseInt(value, 10) === 0) {
+                return false;
+            }
+            var sum    = 0,
+                length = value.length;
+            for (var i = 0; i < length - 1; i++) {
+                sum += (9 - i) * parseInt(value.charAt(i), 10);
+            }
+            sum = sum % 11;
+            if (sum === 10) {
+                sum = 0;
+            }
+            return (sum + '' === value.charAt(length - 1));
+        },
+        
+        /**
+         * Validate Poland citizen number (PESEL)
+         * 
+         * @see http://en.wikipedia.org/wiki/National_identification_number#Poland
+         * @see http://en.wikipedia.org/wiki/PESEL
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _pl: function(value) {
+            if (!/^[0-9]{11}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                length = value.length,
+                weight = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 7];
+
+            for (var i = 0; i < length - 1; i++) {
+                sum += weight[i] * parseInt(value.charAt(i), 10);
+            }
+            sum = sum % 10;
+            if (sum === 0) {
+                sum = 10;
+            }
+            sum = 10 - sum;
+
+            return (sum + '' === value.charAt(length - 1));
+        },
+
+        /**
+         * Validate Romanian numerical personal code (CNP)
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#Romania
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _ro: function(value) {
+            if (!/^[0-9]{13}$/.test(value)) {
+                return false;
+            }
+            var gender = parseInt(value.charAt(0), 10);
+            if (gender === 0 || gender === 7 || gender === 8) {
+                return false;
+            }
+
+            // Determine the date of birth
+            var year      = parseInt(value.substr(1, 2), 10),
+                month     = parseInt(value.substr(3, 2), 10),
+                day       = parseInt(value.substr(5, 2), 10),
+                // The year of date is determined base on the gender
+                centuries = {
+                    '1': 1900,  // Male born between 1900 and 1999
+                    '2': 1900,  // Female born between 1900 and 1999
+                    '3': 1800,  // Male born between 1800 and 1899
+                    '4': 1800,  // Female born between 1800 and 1899
+                    '5': 2000,  // Male born after 2000
+                    '6': 2000   // Female born after 2000
+                };
+            if (day > 31 && month > 12) {
+                return false;
+            }
+            if (gender !== 9) {
+                year = centuries[gender + ''] + year;
+                if (!FormValidation.Helper.date(year, month, day)) {
+                    return false;
+                }
+            }
+
+            // Validate the check digit
+            var sum    = 0,
+                weight = [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9],
+                length = value.length;
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = sum % 11;
+            if (sum === 10) {
+                sum = 1;
+            }
+            return (sum + '' === value.charAt(length - 1));
+        },
+
+        /**
+         * Validate Swedish personal identity number (personnummer)
+         *
+         * @see http://en.wikipedia.org/wiki/Personal_identity_number_(Sweden)
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _se: function(value) {
+            if (!/^[0-9]{10}$/.test(value) && !/^[0-9]{6}[-|+][0-9]{4}$/.test(value)) {
+                return false;
+            }
+            value = value.replace(/[^0-9]/g, '');
+
+            var year  = parseInt(value.substr(0, 2), 10) + 1900,
+                month = parseInt(value.substr(2, 2), 10),
+                day   = parseInt(value.substr(4, 2), 10);
+            if (!FormValidation.Helper.date(year, month, day)) {
+                return false;
+            }
+
+            // Validate the last check digit
+            return FormValidation.Helper.luhn(value);
+        },
+
+        /**
+         * Validate Slovak national identifier number (RC)
+         *
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _sk: function(value) {
+            // Slovakia uses the same format as Czech Republic
+            return this._cz(value);
+        },
+
+        /**
+         * Validate San Marino citizen number
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#San_Marino
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _sm: function(value) {
+            return /^\d{5}$/.test(value);
+        },
+
+        /**
+         * Validate Thailand citizen number
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#Thailand
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _th: function(value) {
+            if (value.length !== 13) {
+                return false;
+            }
+
+            var sum = 0;
+            for (var i = 0; i < 12; i++) {
+                sum += parseInt(value.charAt(i), 10) * (13 - i);
+            }
+
+            return (11 - sum % 11) % 10 === parseInt(value.charAt(12), 10);
+        },
+
+        /**
+         * Validate Turkish Identification Number
+         *
+         * @see https://en.wikipedia.org/wiki/Turkish_Identification_Number
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _tr: function(value) {
+            if (value.length !== 11) {
+                return false;
+            }
+
+            var sum = 0;
+            for (var i = 0; i < 10; i++) {
+                sum += parseInt(value.charAt(i), 10);
+            }
+
+            return (sum % 10) === parseInt(value.charAt(10), 10);
+        },
+
+        /**
+         * Validate South African ID
+         *
+         * @see http://en.wikipedia.org/wiki/National_identification_number#South_Africa
+         * @param {String} value The ID
+         * @returns {Boolean}
+         */
+        _za: function(value) {
+            if (!/^[0-9]{10}[0|1][8|9][0-9]$/.test(value)) {
+                return false;
+            }
+            var year        = parseInt(value.substr(0, 2), 10),
+                currentYear = new Date().getFullYear() % 100,
+                month       = parseInt(value.substr(2, 2), 10),
+                day         = parseInt(value.substr(4, 2), 10);
+            year = (year >= currentYear) ? (year + 1900) : (year + 2000);
+
+            if (!FormValidation.Helper.date(year, month, day)) {
+                return false;
+            }
+
+            // Validate the last check digit
+            return FormValidation.Helper.luhn(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            identical: {
+                'default': 'Please enter the same value'
+            }
+        }
+    });
+
+    FormValidation.Validator.identical = {
+        html5Attributes: {
+            message: 'message',
+            field: 'field'
+        },
+
+        /**
+         * Bind the validator on the live change of the field to compare with current one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         */
+        init: function(validator, $field, options, validatorName) {
+            var compareWith = validator.getFieldElements(options.field);
+            validator.onLiveChange(compareWith, 'live_' + validatorName, function() {
+                var status = validator.getStatus($field, validatorName);
+                if (status !== validator.STATUS_NOT_VALIDATED) {
+                    validator.revalidateField($field);
+                }
+            });
+        },
+
+        /**
+         * Unbind the validator on the live change of the field to compare with current one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         */
+        destroy: function(validator, $field, options, validatorName) {
+            var compareWith = validator.getFieldElements(options.field);
+            validator.offLiveChange(compareWith, 'live_' + validatorName);
+        },
+
+        /**
+         * Check if input value equals to value of particular one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value       = validator.getFieldValue($field, validatorName),
+                compareWith = validator.getFieldElements(options.field);
+            if (compareWith === null || compareWith.length === 0) {
+                return true;
+            }
+
+            var compareValue = validator.getFieldValue(compareWith, validatorName);
+            if (value === compareValue) {
+                validator.updateStatus(compareWith, validator.STATUS_VALID, validatorName);
+                return true;
+            }
+
+            return false;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            imei: {
+                'default': 'Please enter a valid IMEI number'
+            }
+        }
+    });
+
+    FormValidation.Validator.imei = {
+        /**
+         * Validate IMEI (International Mobile Station Equipment Identity)
+         *
+         * @see http://en.wikipedia.org/wiki/International_Mobile_Station_Equipment_Identity
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            switch (true) {
+                case /^\d{15}$/.test(value):
+                case /^\d{2}-\d{6}-\d{6}-\d{1}$/.test(value):
+                case /^\d{2}\s\d{6}\s\d{6}\s\d{1}$/.test(value):
+                    value = value.replace(/[^0-9]/g, '');
+                    return FormValidation.Helper.luhn(value);
+
+                case /^\d{14}$/.test(value):
+                case /^\d{16}$/.test(value):
+                case /^\d{2}-\d{6}-\d{6}(|-\d{2})$/.test(value):
+                case /^\d{2}\s\d{6}\s\d{6}(|\s\d{2})$/.test(value):
+                    return true;
+
+                default:
+                    return false;
+            }
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            imo: {
+                'default': 'Please enter a valid IMO number'
+            }
+        }
+    });
+
+    FormValidation.Validator.imo = {
+        /**
+         * Validate IMO (International Maritime Organization)
+         *
+         * @see http://en.wikipedia.org/wiki/IMO_Number
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            if (!/^IMO \d{7}$/i.test(value)) {
+                return false;
+            }
+            
+            // Grab just the digits
+            var sum    = 0,
+                digits = value.replace(/^.*(\d{7})$/, '$1');
+            for (var i = 6; i >= 1; i--) {
+                sum += (digits.slice((6 - i), -i) * (i + 1));
+            }
+
+            return sum % 10 === parseInt(digits.charAt(6), 10);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            integer: {
+                'default': 'Please enter a valid number'
+            }
+        }
+    });
+
+    FormValidation.Validator.integer = {
+        html5Attributes: {
+            message: 'message',
+            thousandsseparator: 'thousandsSeparator',
+            decimalseparator: 'decimalSeparator'
+        },
+
+        enableByHtml5: function($field) {
+            return ('number' === $field.attr('type')) && ($field.attr('step') === undefined || $field.attr('step') % 1 === 0);
+        },
+
+        /**
+         * Return true if the input value is an integer
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following key:
+         * - message: The invalid message
+         * - thousandsSeparator: The thousands separator. It's empty by default
+         * - decimalSeparator: The decimal separator. It's '.' by default
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            if (this.enableByHtml5($field) && $field.get(0).validity && $field.get(0).validity.badInput === true) {
+                return false;
+            }
+
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var decimalSeparator   = options.decimalSeparator   || '.',
+                thousandsSeparator = options.thousandsSeparator || '';
+            decimalSeparator       = (decimalSeparator   === '.') ? '\\.' : decimalSeparator;
+            thousandsSeparator     = (thousandsSeparator === '.') ? '\\.' : thousandsSeparator;
+
+            var testRegexp         = new RegExp('^-?[0-9]{1,3}(' + thousandsSeparator + '[0-9]{3})*(' + decimalSeparator + '[0-9]+)?$'),
+                thousandsReplacer  = new RegExp(thousandsSeparator, 'g');
+
+            if (!testRegexp.test(value)) {
+                return false;
+            }
+
+            // Replace thousands separator with blank
+            if (thousandsSeparator) {
+                value = value.replace(thousandsReplacer, '');
+            }
+            // Replace decimal separator with a dot
+            if (decimalSeparator) {
+                value = value.replace(decimalSeparator, '.');
+            }
+
+            if (isNaN(value) || !isFinite(value)) {
+                return false;
+            }
+            // TODO: Use Number.isInteger() if available
+            value = parseFloat(value);
+            return Math.floor(value) === value;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            ip: {
+                'default': 'Please enter a valid IP address',
+                ipv4: 'Please enter a valid IPv4 address',
+                ipv6: 'Please enter a valid IPv6 address'
+            }
+        }
+    });
+
+    FormValidation.Validator.ip = {
+        html5Attributes: {
+            message: 'message',
+            ipv4: 'ipv4',
+            ipv6: 'ipv6'
+        },
+
+        /**
+         * Return true if the input value is a IP address.
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - ipv4: Enable IPv4 validator, default to true
+         * - ipv6: Enable IPv6 validator, default to true
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+            options = $.extend({}, { ipv4: true, ipv6: true }, options);
+
+            var locale    = validator.getLocale(),
+                ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\/([0-9]|[1-2][0-9]|3[0-2]))?$/,
+                ipv6Regex = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*(\/(\d|\d\d|1[0-1]\d|12[0-8]))?$/,
+                valid     = false,
+                message;
+
+            switch (true) {
+                case (options.ipv4 && !options.ipv6):
+                    valid   = ipv4Regex.test(value);
+                    message = options.message || FormValidation.I18n[locale].ip.ipv4;
+                    break;
+
+                case (!options.ipv4 && options.ipv6):
+                    valid   = ipv6Regex.test(value);
+                    message = options.message || FormValidation.I18n[locale].ip.ipv6;
+                    break;
+
+                case (options.ipv4 && options.ipv6):
+                /* falls through */
+                default:
+                    valid   = ipv4Regex.test(value) || ipv6Regex.test(value);
+                    message = options.message || FormValidation.I18n[locale].ip['default'];
+                    break;
+            }
+
+            return {
+                valid: valid,
+                message: message
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            isbn: {
+                'default': 'Please enter a valid ISBN number'
+            }
+        }
+    });
+
+    FormValidation.Validator.isbn = {
+        /**
+         * Return true if the input value is a valid ISBN 10 or ISBN 13 number
+         *
+         * @see http://en.wikipedia.org/wiki/International_Standard_Book_Number
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} [options] Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // http://en.wikipedia.org/wiki/International_Standard_Book_Number#Overview
+            // Groups are separated by a hyphen or a space
+            var type;
+            switch (true) {
+                case /^\d{9}[\dX]$/.test(value):
+                case (value.length === 13 && /^(\d+)-(\d+)-(\d+)-([\dX])$/.test(value)):
+                case (value.length === 13 && /^(\d+)\s(\d+)\s(\d+)\s([\dX])$/.test(value)):
+                    type = 'ISBN10';
+                    break;
+                case /^(978|979)\d{9}[\dX]$/.test(value):
+                case (value.length === 17 && /^(978|979)-(\d+)-(\d+)-(\d+)-([\dX])$/.test(value)):
+                case (value.length === 17 && /^(978|979)\s(\d+)\s(\d+)\s(\d+)\s([\dX])$/.test(value)):
+                    type = 'ISBN13';
+                    break;
+                default:
+                    return false;
+            }
+
+            // Replace all special characters except digits and X
+            value = value.replace(/[^0-9X]/gi, '');
+            var chars  = value.split(''),
+                length = chars.length,
+                sum    = 0,
+                i,
+                checksum;
+
+            switch (type) {
+                case 'ISBN10':
+                    sum = 0;
+                    for (i = 0; i < length - 1; i++) {
+                        sum += parseInt(chars[i], 10) * (10 - i);
+                    }
+                    checksum = 11 - (sum % 11);
+                    if (checksum === 11) {
+                        checksum = 0;
+                    } else if (checksum === 10) {
+                        checksum = 'X';
+                    }
+                    return {
+                        type: type,
+                        valid: (checksum + '' === chars[length - 1])
+                    };
+
+                case 'ISBN13':
+                    sum = 0;
+                    for (i = 0; i < length - 1; i++) {
+                        sum += ((i % 2 === 0) ? parseInt(chars[i], 10) : (parseInt(chars[i], 10) * 3));
+                    }
+                    checksum = 10 - (sum % 10);
+                    if (checksum === 10) {
+                        checksum = '0';
+                    }
+                    return {
+                        type: type,
+                        valid: (checksum + '' === chars[length - 1])
+                    };
+
+                default:
+                    return false;
+            }
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            isin: {
+                'default': 'Please enter a valid ISIN number'
+            }
+        }
+    });
+
+    FormValidation.Validator.isin = {
+        // Available country codes
+        // See http://isin.net/country-codes/
+        COUNTRY_CODES: 'AF|AX|AL|DZ|AS|AD|AO|AI|AQ|AG|AR|AM|AW|AU|AT|AZ|BS|BH|BD|BB|BY|BE|BZ|BJ|BM|BT|BO|BQ|BA|BW|BV|BR|IO|BN|BG|BF|BI|KH|CM|CA|CV|KY|CF|TD|CL|CN|CX|CC|CO|KM|CG|CD|CK|CR|CI|HR|CU|CW|CY|CZ|DK|DJ|DM|DO|EC|EG|SV|GQ|ER|EE|ET|FK|FO|FJ|FI|FR|GF|PF|TF|GA|GM|GE|DE|GH|GI|GR|GL|GD|GP|GU|GT|GG|GN|GW|GY|HT|HM|VA|HN|HK|HU|IS|IN|ID|IR|IQ|IE|IM|IL|IT|JM|JP|JE|JO|KZ|KE|KI|KP|KR|KW|KG|LA|LV|LB|LS|LR|LY|LI|LT|LU|MO|MK|MG|MW|MY|MV|ML|MT|MH|MQ|MR|MU|YT|MX|FM|MD|MC|MN|ME|MS|MA|MZ|MM|NA|NR|NP|NL|NC|NZ|NI|NE|NG|NU|NF|MP|NO|OM|PK|PW|PS|PA|PG|PY|PE|PH|PN|PL|PT|PR|QA|RE|RO|RU|RW|BL|SH|KN|LC|MF|PM|VC|WS|SM|ST|SA|SN|RS|SC|SL|SG|SX|SK|SI|SB|SO|ZA|GS|SS|ES|LK|SD|SR|SJ|SZ|SE|CH|SY|TW|TJ|TZ|TH|TL|TG|TK|TO|TT|TN|TR|TM|TC|TV|UG|UA|AE|GB|US|UM|UY|UZ|VU|VE|VN|VG|VI|WF|EH|YE|ZM|ZW',
+
+        /**
+         * Validate an ISIN (International Securities Identification Number)
+         *
+         * @see http://en.wikipedia.org/wiki/International_Securities_Identifying_Number
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            value = value.toUpperCase();
+            var regex = new RegExp('^(' + this.COUNTRY_CODES + ')[0-9A-Z]{10}$');
+            if (!regex.test(value)) {
+                return false;
+            }
+
+            var converted = '',
+                length    = value.length;
+            // Convert letters to number
+            for (var i = 0; i < length - 1; i++) {
+                var c = value.charCodeAt(i);
+                converted += ((c > 57) ? (c - 55).toString() : value.charAt(i));
+            }
+
+            var digits = '',
+                n      = converted.length,
+                group  = (n % 2 !== 0) ? 0 : 1;
+            for (i = 0; i < n; i++) {
+                digits += (parseInt(converted[i], 10) * ((i % 2) === group ? 2 : 1) + '');
+            }
+
+            var sum = 0;
+            for (i = 0; i < digits.length; i++) {
+                sum += parseInt(digits.charAt(i), 10);
+            }
+            sum = (10 - (sum % 10)) % 10;
+            return sum + '' === value.charAt(length - 1);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            ismn: {
+                'default': 'Please enter a valid ISMN number'
+            }
+        }
+    });
+
+    FormValidation.Validator.ismn = {
+        /**
+         * Validate ISMN (International Standard Music Number)
+         *
+         * @see http://en.wikipedia.org/wiki/International_Standard_Music_Number
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Groups are separated by a hyphen or a space
+            var type;
+            switch (true) {
+                case /^M\d{9}$/.test(value):
+                case /^M-\d{4}-\d{4}-\d{1}$/.test(value):
+                case /^M\s\d{4}\s\d{4}\s\d{1}$/.test(value):
+                    type = 'ISMN10';
+                    break;
+                case /^9790\d{9}$/.test(value):
+                case /^979-0-\d{4}-\d{4}-\d{1}$/.test(value):
+                case /^979\s0\s\d{4}\s\d{4}\s\d{1}$/.test(value):
+                    type = 'ISMN13';
+                    break;
+                default:
+                    return false;
+            }
+
+            if ('ISMN10' === type) {
+                value = '9790' + value.substr(1);
+            }
+
+            // Replace all special characters except digits
+            value = value.replace(/[^0-9]/gi, '');
+            var length = value.length,
+                sum    = 0,
+                weight = [1, 3];
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i % 2];
+            }
+            sum = 10 - sum % 10;
+            return {
+                type: type,
+                valid: (sum + '' === value.charAt(length - 1))
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            issn: {
+                'default': 'Please enter a valid ISSN number'
+            }
+        }
+    });
+
+    FormValidation.Validator.issn = {
+        /**
+         * Validate ISSN (International Standard Serial Number)
+         *
+         * @see http://en.wikipedia.org/wiki/International_Standard_Serial_Number
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Groups are separated by a hyphen or a space
+            if (!/^\d{4}\-\d{3}[\dX]$/.test(value)) {
+                return false;
+            }
+
+            // Replace all special characters except digits and X
+            value = value.replace(/[^0-9X]/gi, '');
+            var chars  = value.split(''),
+                length = chars.length,
+                sum    = 0;
+
+            if (chars[7] === 'X') {
+                chars[7] = 10;
+            }
+            for (var i = 0; i < length; i++) {
+                sum += parseInt(chars[i], 10) * (8 - i);
+            }
+            return (sum % 11 === 0);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            lessThan: {
+                'default': 'Please enter a value less than or equal to %s',
+                notInclusive: 'Please enter a value less than %s'
+            }
+        }
+    });
+
+    FormValidation.Validator.lessThan = {
+        html5Attributes: {
+            message: 'message',
+            value: 'value',
+            inclusive: 'inclusive'
+        },
+
+        enableByHtml5: function($field) {
+            var type = $field.attr('type'),
+                max  = $field.attr('max');
+            if (max && type !== 'date') {
+                return {
+                    value: max
+                };
+            }
+
+            return false;
+        },
+
+        /**
+         * Return true if the input value is less than or equal to given number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - value: The number used to compare to. It can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - inclusive [optional]: Can be true or false. Default is true
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+            
+			value = this._format(value);
+
+            var locale         = validator.getLocale(),
+                compareTo      = $.isNumeric(options.value) ? options.value : validator.getDynamicOption($field, options.value),
+                compareToValue = this._format(compareTo);
+
+            return (options.inclusive === true || options.inclusive === undefined)
+                    ? {
+                        valid: $.isNumeric(value) && parseFloat(value) <= compareToValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].lessThan['default'], compareTo)
+                    }
+                    : {
+                        valid: $.isNumeric(value) && parseFloat(value) < compareToValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].lessThan.notInclusive, compareTo)
+                    };
+        },
+
+        _format: function(value) {
+            return (value + '').replace(',', '.');
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            mac: {
+                'default': 'Please enter a valid MAC address'
+            }
+        }
+    });
+
+    FormValidation.Validator.mac = {
+        /**
+         * Return true if the input value is a MAC address.
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            return /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(value) || /^([0-9A-Fa-f]{4}\.){2}([0-9A-Fa-f]{4})$/.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            meid: {
+                'default': 'Please enter a valid MEID number'
+            }
+        }
+    });
+
+    FormValidation.Validator.meid = {
+        /**
+         * Validate MEID (Mobile Equipment Identifier)
+         *
+         * @see http://en.wikipedia.org/wiki/Mobile_equipment_identifier
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            switch (true) {
+                // 14 digit hex representation (no check digit)
+                case /^[0-9A-F]{15}$/i.test(value):
+                // 14 digit hex representation + dashes or spaces (no check digit)
+                case /^[0-9A-F]{2}[- ][0-9A-F]{6}[- ][0-9A-F]{6}[- ][0-9A-F]$/i.test(value):
+                // 18 digit decimal representation (no check digit)
+                case /^\d{19}$/.test(value):
+                // 18 digit decimal representation + dashes or spaces (no check digit)
+                case /^\d{5}[- ]\d{5}[- ]\d{4}[- ]\d{4}[- ]\d$/.test(value):
+                    // Grab the check digit
+                    var cd = value.charAt(value.length - 1);
+
+                    // Strip any non-hex chars
+                    value = value.replace(/[- ]/g, '');
+
+                    // If it's all digits, luhn base 10 is used
+                    if (value.match(/^\d*$/i)) {
+                        return FormValidation.Helper.luhn(value);
+                    }
+
+                    // Strip the check digit
+                    value = value.slice(0, -1);
+
+                    // Get every other char, and double it
+                    var cdCalc = '';
+                    for (var i = 1; i <= 13; i += 2) {
+                        cdCalc += (parseInt(value.charAt(i), 16) * 2).toString(16);
+                    }
+
+                    // Get the sum of each char in the string
+                    var sum = 0;
+                    for (i = 0; i < cdCalc.length; i++) {
+                        sum += parseInt(cdCalc.charAt(i), 16);
+                    }
+
+                    // If the last digit of the calc is 0, the check digit is 0
+                    return (sum % 10 === 0)
+                            ? (cd === '0')
+                            // Subtract it from the next highest 10s number (64 goes to 70) and subtract the sum
+                            // Double it and turn it into a hex char
+                            : (cd === ((Math.floor((sum + 10) / 10) * 10 - sum) * 2).toString(16));
+
+                // 14 digit hex representation (no check digit)
+                case /^[0-9A-F]{14}$/i.test(value):
+                // 14 digit hex representation + dashes or spaces (no check digit)
+                case /^[0-9A-F]{2}[- ][0-9A-F]{6}[- ][0-9A-F]{6}$/i.test(value):
+                // 18 digit decimal representation (no check digit)
+                case /^\d{18}$/.test(value):
+                // 18 digit decimal representation + dashes or spaces (no check digit)
+                case /^\d{5}[- ]\d{5}[- ]\d{4}[- ]\d{4}$/.test(value):
+                    return true;
+
+                default:
+                    return false;
+            }
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            notEmpty: {
+                'default': 'Please enter a value'
+            }
+        }
+    });
+
+    FormValidation.Validator.notEmpty = {
+        enableByHtml5: function($field) {
+            var required = $field.attr('required') + '';
+            return ('required' === required || 'true' === required);
+        },
+
+        /**
+         * Check if input value is empty or not
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var type = $field.attr('type');
+            if ('radio' === type || 'checkbox' === type) {
+                var ns = validator.getNamespace();
+                return validator
+                            .getFieldElements($field.attr('data-' + ns + '-field'))
+                            .filter(':checked')
+                            .length > 0;
+            }
+
+            if ('number' === type && $field.get(0).validity && $field.get(0).validity.badInput === true) {
+                return true;
+            }
+
+            var value = validator.getFieldValue($field, validatorName);
+            return $.trim(value) !== '';
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            numeric: {
+                'default': 'Please enter a valid float number'
+            }
+        }
+    });
+
+    FormValidation.Validator.numeric = {
+        html5Attributes: {
+            message: 'message',
+            separator: 'separator',     // deprecated
+            thousandsseparator: 'thousandsSeparator',
+            decimalseparator: 'decimalSeparator'
+        },
+
+        enableByHtml5: function($field) {
+            return ('number' === $field.attr('type')) && ($field.attr('step') !== undefined) && ($field.attr('step') % 1 !== 0);
+        },
+
+        /**
+         * Validate decimal number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - thousandsSeparator: The thousands separator. It's empty by default
+         * - separator, decimalSeparator: The decimal separator. It's '.' by default
+         * The separator option is deprecated and should be replaced with decimalSeparator
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            if (this.enableByHtml5($field) && $field.get(0).validity && $field.get(0).validity.badInput === true) {
+                return false;
+            }
+
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var decimalSeparator   = options.separator || options.decimalSeparator || '.',
+                thousandsSeparator = options.thousandsSeparator || '';
+
+            // Support preceding zero numbers such as .5, -.5
+            if (value.substr(0, 1) === decimalSeparator) {
+                value = '0' + decimalSeparator + value.substr(1);
+            } else if (value.substr(0, 2) === '-' + decimalSeparator) {
+                value = '-0' + decimalSeparator + value.substr(2);
+            }
+
+            decimalSeparator   = (decimalSeparator   === '.') ? '\\.' : decimalSeparator;
+            thousandsSeparator = (thousandsSeparator === '.') ? '\\.' : thousandsSeparator;
+
+            var testRegexp         = new RegExp('^-?[0-9]{1,3}(' + thousandsSeparator + '[0-9]{3})*(' + decimalSeparator + '[0-9]+)?$'),
+                thousandsReplacer  = new RegExp(thousandsSeparator, 'g');
+
+            if (!testRegexp.test(value)) {
+                return false;
+            }
+
+            // Replace thousands separator with blank
+            if (thousandsSeparator) {
+                value = value.replace(thousandsReplacer, '');
+            }
+            // Replace decimal separator with a dot
+            if (decimalSeparator) {
+                value = value.replace(decimalSeparator, '.');
+            }
+
+            return !isNaN(parseFloat(value)) && isFinite(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            phone: {
+                'default': 'Please enter a valid phone number',
+                country: 'Please enter a valid phone number in %s',
+                countries: {
+                    AE: 'United Arab Emirates',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CN: 'China',
+                    CZ: 'Czech Republic',
+                    DE: 'Germany',
+                    DK: 'Denmark',
+                    ES: 'Spain',
+                    FR: 'France',
+                    GB: 'United Kingdom',
+                    IN: 'India',
+                    MA: 'Morocco',
+                    NL: 'Netherlands',
+                    PK: 'Pakistan',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    SK: 'Slovakia',
+                    TH: 'Thailand',
+                    US: 'USA',
+                    VE: 'Venezuela'
+                }
+            }
+        }
+    });
+
+    FormValidation.Validator.phone = {
+        html5Attributes: {
+            message: 'message',
+            country: 'country'
+        },
+
+        // The supported countries
+        COUNTRY_CODES: ['AE', 'BG', 'BR', 'CN', 'CZ', 'DE', 'DK', 'ES', 'FR', 'GB', 'IN', 'MA', 'NL', 'PK', 'RO', 'RU', 'SK', 'TH', 'US', 'VE'],
+
+        /**
+         * Return true if the input value contains a valid phone number for the country
+         * selected in the options
+         *
+         * @param {FormValidation.Base} validator Validate plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - country: The ISO-3166 country code. It can be
+         *      - A country code
+         *      - Name of field which its value defines the country code
+         *      - Name of callback function that returns the country code
+         *      - A callback function that returns the country code
+         *
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var locale  = validator.getLocale(),
+                country = options.country;
+            if (typeof country !== 'string' || $.inArray(country, this.COUNTRY_CODES) === -1) {
+                // Try to determine the country
+                country = validator.getDynamicOption($field, country);
+            }
+
+            if (!country || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) {
+                return true;
+            }
+
+            var isValid = true;
+            switch (country.toUpperCase()) {
+                case 'AE':
+                    // http://regexr.com/39tak
+                    value   = $.trim(value);
+                    isValid = (/^(((\+|00)?971[\s\.-]?(\(0\)[\s\.-]?)?|0)(\(5(0|2|5|6)\)|5(0|2|5|6)|2|3|4|6|7|9)|60)([\s\.-]?[0-9]){7}$/).test(value);
+                    break;
+                    
+                case 'BG':
+                    // https://regex101.com/r/yE6vN4/1
+                    // See http://en.wikipedia.org/wiki/Telephone_numbers_in_Bulgaria
+                    value   = value.replace(/\+|\s|-|\/|\(|\)/gi,'');
+                    isValid = (/^(0|359|00)(((700|900)[0-9]{5}|((800)[0-9]{5}|(800)[0-9]{4}))|(87|88|89)([0-9]{7})|((2[0-9]{7})|(([3-9][0-9])(([0-9]{6})|([0-9]{5})))))$/).test(value);
+                    break;
+
+                case 'BR':
+                    // http://regexr.com/399m1
+                    value   = $.trim(value);
+                    isValid = (/^(([\d]{4}[-.\s]{1}[\d]{2,3}[-.\s]{1}[\d]{2}[-.\s]{1}[\d]{2})|([\d]{4}[-.\s]{1}[\d]{3}[-.\s]{1}[\d]{4})|((\(?\+?[0-9]{2}\)?\s?)?(\(?\d{2}\)?\s?)?\d{4,5}[-.\s]?\d{4}))$/).test(value);
+                    break;
+
+                case 'CN':
+                    // http://regexr.com/39dq4
+                    value   = $.trim(value);
+                    isValid = (/^((00|\+)?(86(?:-| )))?((\d{11})|(\d{3}[- ]{1}\d{4}[- ]{1}\d{4})|((\d{2,4}[- ]){1}(\d{7,8}|(\d{3,4}[- ]{1}\d{4}))([- ]{1}\d{1,4})?))$/).test(value);
+                    break;
+
+                case 'CZ':
+                    // http://regexr.com/39hhl
+                    isValid = /^(((00)([- ]?)|\+)(420)([- ]?))?((\d{3})([- ]?)){2}(\d{3})$/.test(value);
+                    break;
+
+                case 'DE':
+                    // http://regexr.com/39pkg
+                    value   = $.trim(value);
+                    isValid = (/^(((((((00|\+)49[ \-/]?)|0)[1-9][0-9]{1,4})[ \-/]?)|((((00|\+)49\()|\(0)[1-9][0-9]{1,4}\)[ \-/]?))[0-9]{1,7}([ \-/]?[0-9]{1,5})?)$/).test(value);
+                    break;
+
+                case 'DK':
+                    // Mathing DK phone numbers with country code in 1 of 3 formats and an
+                    // 8 digit phone number not starting with a 0 or 1. Can have 1 space
+                    // between each character except inside the country code.
+                    // http://regex101.com/r/sS8fO4/1
+                    value   = $.trim(value);
+                    isValid = (/^(\+45|0045|\(45\))?\s?[2-9](\s?\d){7}$/).test(value);
+                    break;
+
+                case 'ES':
+                    // http://regex101.com/r/rB9mA9/1
+                    // Telephone numbers in Spain go like this:
+                    //     9: Landline phones and special prefixes.
+                    //     6, 7: Mobile phones.
+                    //     5: VoIP lines.
+                    //     8: Premium-rate services.
+                    // There are also special 5-digit and 3-digit numbers, but
+                    // maybe it would be overkill to include them all.
+                    value   = $.trim(value);
+                    isValid = (/^(?:(?:(?:\+|00)34\D?))?(?:5|6|7|8|9)(?:\d\D?){8}$/).test(value);
+                    break;
+
+                case 'FR':
+                    // http://regexr.com/39a2p
+                    value   = $.trim(value);
+                    isValid = (/^(?:(?:(?:\+|00)33[ ]?(?:\(0\)[ ]?)?)|0){1}[1-9]{1}([ .-]?)(?:\d{2}\1?){3}\d{2}$/).test(value);
+                    break;
+
+            	case 'GB':
+                    // http://aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers#Match_GB_telephone_number_in_any_format
+                    // http://regexr.com/38uhv
+                    value   = $.trim(value);
+                    isValid = (/^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}|\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4}|\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3})|\d{5}\)?[\s-]?\d{4,5}|8(?:00[\s-]?11[\s-]?11|45[\s-]?46[\s-]?4\d))(?:(?:[\s-]?(?:x|ext\.?\s?|\#)\d+)?)$/).test(value);
+                    break;
+            
+                case 'IN':
+                    // http://stackoverflow.com/questions/18351553/regular-expression-validation-for-indian-phone-number-and-mobile-number
+                    // http://regex101.com/r/qL6eZ5/1
+                    // May begin with +91. Supports mobile and land line numbers
+                    value   = $.trim(value);
+                    isValid = (/((\+?)((0[ -]+)*|(91 )*)(\d{12}|\d{10}))|\d{5}([- ]*)\d{6}/).test(value);
+                    break;
+                    
+                case 'MA':
+                    // http://en.wikipedia.org/wiki/Telephone_numbers_in_Morocco
+                    // http://regexr.com/399n8
+                    value   = $.trim(value);
+                    isValid = (/^(?:(?:(?:\+|00)212[\s]?(?:[\s]?\(0\)[\s]?)?)|0){1}(?:5[\s.-]?[2-3]|6[\s.-]?[13-9]){1}[0-9]{1}(?:[\s.-]?\d{2}){3}$/).test(value);
+                    break;
+                
+                case 'NL':
+                    // http://en.wikipedia.org/wiki/Telephone_numbers_in_the_Netherlands
+                    // http://regexr.com/3aevr
+                    value   = $.trim(value);
+                    isValid = (/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9])((\s|\s?-\s?)?[0-9])((\s|\s?-\s?)?[0-9])\s?[0-9]\s?[0-9]\s?[0-9]\s?[0-9]\s?[0-9]$/gm).test(value);
+                    break;
+                
+                case 'PK':
+                    // http://regex101.com/r/yH8aV9/2
+                    value   = $.trim(value);
+                    isValid = (/^0?3[0-9]{2}[0-9]{7}$/).test(value);
+                    break;
+
+                case 'RO':
+                    // All mobile network and land line
+                    // http://regexr.com/39fv1
+                    isValid = (/^(\+4|)?(07[0-8]{1}[0-9]{1}|02[0-9]{2}|03[0-9]{2}){1}?(\s|\.|\-)?([0-9]{3}(\s|\.|\-|)){2}$/g).test(value);
+                    break;
+
+                case 'RU':
+                    // http://regex101.com/r/gW7yT5/5
+                    isValid = (/^((8|\+7|007)[\-\.\/ ]?)?([\(\/\.]?\d{3}[\)\/\.]?[\-\.\/ ]?)?[\d\-\.\/ ]{7,10}$/g).test(value);
+                    break;
+
+                case 'SK':
+                    // http://regexr.com/3a95f
+                    isValid = /^(((00)([- ]?)|\+)(421)([- ]?))?((\d{3})([- ]?)){2}(\d{3})$/.test(value);
+                    break;
+
+                case 'TH':
+                    // http://regex101.com/r/vM5mZ4/2
+                    isValid = (/^0\(?([6|8-9]{2})*-([0-9]{3})*-([0-9]{4})$/).test(value);
+                    break;
+
+                case 'VE':
+                    // http://regex101.com/r/eM2yY0/6
+                    value   = $.trim(value);
+                    isValid = (/^0(?:2(?:12|4[0-9]|5[1-9]|6[0-9]|7[0-8]|8[1-35-8]|9[1-5]|3[45789])|4(?:1[246]|2[46]))\d{7}$/).test(value);
+                    break;
+  
+                case 'US':
+                /* falls through */
+                default:
+                    // Make sure US phone numbers have 10 digits
+                    // May start with 1, +1, or 1-; should discard
+                    // Area code may be delimited with (), & sections may be delimited with . or -
+                    // http://regexr.com/38mqi
+                    isValid = (/^(?:(1\-?)|(\+1 ?))?\(?\d{3}\)?[\-\.\s]?\d{3}[\-\.\s]?\d{4}$/).test(value);
+                    break;
+            }
+
+            return {
+                valid: isValid,
+                message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].phone.country, FormValidation.I18n[locale].phone.countries[country])
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            promise: {
+                'default': 'Please enter a valid value'
+            }
+        }
+    });
+
+    FormValidation.Validator.promise = {
+        priority: 999,
+
+        html5Attributes: {
+            message: 'message',
+            promise: 'promise'
+        },
+
+        /**
+         * Return result from a jQuery's Deferred object
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - promise: The method that passes parameters:
+         *      promise: function(fieldValue, validator, $field) {
+         *          // fieldValue is the value of field
+         *          // validator is instance of FormValidation.Base
+         *          // $field is the field element
+         *
+         *          var dfd = new $.Deferred();
+         *
+         *          // Do something ...
+         *
+         *          // Resolve when particular task is done
+         *          dfd.resolve({
+         *              valid: true or false,       // Required
+         *              message: 'Other message',   // Optional
+         *              key: value                  // You can attach more data to reuse later
+         *          });
+         *
+         *          // You can reject if there's error
+         *          dfd.reject({
+         *              message: 'Other message',   // Optional
+         *              key: value                  // You can attach more data to reuse later
+         *          });
+         *
+         *          return dfd.promise();
+         *      }
+         * - message: The invalid message
+         * @returns {Deferred}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value   = validator.getFieldValue($field, validatorName),
+                dfd     = new $.Deferred(),
+                promise = FormValidation.Helper.call(options.promise, [value, validator, $field]);
+
+            promise
+                .done(function(result) {
+                    dfd.resolve($field, validatorName, result);
+                })
+                .fail(function(result) {
+                    result = result || {};
+                    result.valid = false;
+                    dfd.resolve($field, validatorName, result);
+                });
+
+            return dfd;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            regexp: {
+                'default': 'Please enter a value matching the pattern'
+            }
+        }
+    });
+
+    FormValidation.Validator.regexp = {
+        html5Attributes: {
+            message: 'message',
+            flags: 'flags',
+            regexp: 'regexp'
+        },
+
+        enableByHtml5: function($field) {
+            var pattern = $field.attr('pattern');
+            if (pattern) {
+                return {
+                    regexp: pattern
+                };
+            }
+
+            return false;
+        },
+
+        /**
+         * Check if the element value matches given regular expression
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - regexp: The regular expression you need to check
+         * - flags: If specified, flags can have any combination of Javascript regular expression flags such as:
+         *      g: global match
+         *      i: ignore case
+         *      m: multiple line
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var regexp = ('string' === typeof options.regexp)
+                        ? (options.flags ? new RegExp(options.regexp, options.flags) : new RegExp(options.regexp))
+                        : options.regexp;
+            return regexp.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            remote: {
+                'default': 'Please enter a valid value'
+            }
+        }
+    });
+
+    FormValidation.Validator.remote = {
+        priority: 1000,
+
+        html5Attributes: {
+            async: 'async',
+            crossdomain: 'crossDomain',
+            data: 'data',
+            datatype: 'dataType',
+            delay: 'delay',
+            message: 'message',
+            name: 'name',
+            type: 'type',
+            url: 'url',
+            validkey: 'validKey'
+        },
+
+        /**
+         * Destroy the timer when destroying the FormValidation (using validator.destroy() method)
+         */
+        destroy: function(validator, $field, options, validatorName) {
+            var ns    = validator.getNamespace(),
+                timer = $field.data(ns + '.' + validatorName + '.timer');
+            if (timer) {
+                clearTimeout(timer);
+                $field.removeData(ns + '.' + validatorName + '.timer');
+            }
+        },
+
+        /**
+         * Request a remote server to check the input value
+         *
+         * @param {FormValidation.Base} validator Plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - async {Boolean} [optional] Indicate the Ajax request will be asynchronous or not. It's true by default
+         * - crossDomain {Boolean} [optional]
+         * - data {Object|Function} [optional]: By default, it will take the value
+         *  {
+         *      <fieldName>: <fieldValue>
+         *  }
+         * - dataType {String} [optional]: The type of data which is returned by remote server.
+         * It can be json (default), text, script
+         * - delay {Number} [optional]
+         * - headers {String[]} [optional]: Additional headers
+         * - message {String} [optional]: The invalid message
+         * - name {String} [optional]: Override the field name for the request.
+         * - type {String} [optional] Can be GET or POST (default)
+         * - url {String|Function}
+         * - validKey {String} [optional]: The valid key. It's "valid" by default
+         * This is useful when connecting to external remote server or APIs provided by 3rd parties
+         * @returns {Deferred}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var ns    = validator.getNamespace(),
+                value = validator.getFieldValue($field, validatorName),
+                dfd   = new $.Deferred();
+            if (value === '') {
+                dfd.resolve($field, validatorName, { valid: true });
+                return dfd;
+            }
+            var name     = $field.attr('data-' + ns + '-field'),
+                data     = options.data || {},
+                url      = options.url,
+                validKey = options.validKey || 'valid';
+
+            // Support dynamic data
+            if ('function' === typeof data) {
+                data = data.call(this, validator, $field, value);
+            }
+
+            // Parse string data from HTML5 attribute
+            if ('string' === typeof data) {
+                data = JSON.parse(data);
+            }
+
+            // Support dynamic url
+            if ('function' === typeof url) {
+                url = url.call(this, validator, $field, value);
+            }
+
+            data[options.name || name] = value;
+
+            var ajaxOptions = {
+                async: options.async === null || options.async === true || options.async === 'true',
+                data: data,
+                dataType: options.dataType || 'json',
+                headers: options.headers || {},
+                type: options.type || 'GET',
+                url: url
+            };
+            if (options.crossDomain !== null) {
+                ajaxOptions.crossDomain = (options.crossDomain === true || options.crossDomain === 'true');
+            }
+
+            function runCallback() {
+                var xhr = $.ajax(ajaxOptions);
+
+                xhr
+                    .success(function(response) {
+                        response.valid = (response[validKey] === true || response[validKey] === 'true')
+                                        ? true
+                                        : (response[validKey] === false || response[validKey] === 'false' ? false : null);
+                        dfd.resolve($field, validatorName, response);
+                    })
+                    .error(function(response) {
+                        dfd.resolve($field, validatorName, {
+                            valid: false
+                        });
+                    });
+
+                dfd.fail(function() {
+                    xhr.abort();
+                });
+
+                return dfd;
+            }
+            
+            if (options.delay) {
+                // Since the form might have multiple fields with the same name
+                // I have to attach the timer to the field element
+                if ($field.data(ns + '.' + validatorName + '.timer')) {
+                    clearTimeout($field.data(ns + '.' + validatorName + '.timer'));
+                }
+
+                $field.data(ns + '.' + validatorName + '.timer', setTimeout(runCallback, options.delay));
+                return dfd;
+            } else {
+                return runCallback();
+            }
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            rtn: {
+                'default': 'Please enter a valid RTN number'
+            }
+        }
+    });
+
+    FormValidation.Validator.rtn = {
+        /**
+         * Validate a RTN (Routing transit number)
+         *
+         * @see http://en.wikipedia.org/wiki/Routing_transit_number
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            if (!/^\d{9}$/.test(value)) {
+                return false;
+            }
+
+            var sum = 0;
+            for (var i = 0; i < value.length; i += 3) {
+                sum += parseInt(value.charAt(i),     10) * 3
+                    +  parseInt(value.charAt(i + 1), 10) * 7
+                    +  parseInt(value.charAt(i + 2), 10);
+            }
+            return (sum !== 0 && sum % 10 === 0);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            sedol: {
+                'default': 'Please enter a valid SEDOL number'
+            }
+        }
+    });
+
+    FormValidation.Validator.sedol = {
+        /**
+         * Validate a SEDOL (Stock Exchange Daily Official List)
+         *
+         * @see http://en.wikipedia.org/wiki/SEDOL
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            value = value.toUpperCase();
+            if (!/^[0-9A-Z]{7}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [1, 3, 1, 7, 3, 9, 1],
+                length = value.length;
+            for (var i = 0; i < length - 1; i++) {
+	            sum += weight[i] * parseInt(value.charAt(i), 36);
+	        }
+	        sum = (10 - sum % 10) % 10;
+            return sum + '' === value.charAt(length - 1);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+		'en_US': {
+			siren: {
+				'default': 'Please enter a valid SIREN number'
+			}
+		}
+    });
+
+	FormValidation.Validator.siren = {
+		/**
+		 * Check if a string is a siren number
+		 *
+		 * @param {FormValidation.Base} validator The validator plugin instance
+		 * @param {jQuery} $field Field element
+		 * @param {Object} options Consist of key:
+         * - message: The invalid message
+		 * @returns {Boolean}
+		 */
+		validate: function(validator, $field, options, validatorName) {
+			var value = validator.getFieldValue($field, validatorName);
+			if (value === '') {
+				return true;
+			}
+
+            if (!/^\d{9}$/.test(value)) {
+                return false;
+            }
+            return FormValidation.Helper.luhn(value);
+		}
+	};
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+		'en_US': {
+			siret: {
+				'default': 'Please enter a valid SIRET number'
+			}
+		}
+    });
+
+	FormValidation.Validator.siret = {
+        /**
+         * Check if a string is a siret number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+		validate: function(validator, $field, options, validatorName) {
+			var value = validator.getFieldValue($field, validatorName);
+			if (value === '') {
+				return true;
+			}
+
+			var sum    = 0,
+                length = value.length,
+                tmp;
+			for (var i = 0; i < length; i++) {
+                tmp = parseInt(value.charAt(i), 10);
+				if ((i % 2) === 0) {
+					tmp = tmp * 2;
+					if (tmp > 9) {
+						tmp -= 9;
+					}
+				}
+				sum += tmp;
+			}
+			return (sum % 10 === 0);
+		}
+	};
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            step: {
+                'default': 'Please enter a valid step of %s'
+            }
+        }
+    });
+
+    FormValidation.Validator.step = {
+        html5Attributes: {
+            message: 'message',
+            base: 'baseValue',
+            step: 'step'
+        },
+
+        /**
+         * Return true if the input value is valid step one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - baseValue: The base value
+         * - step: The step
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            options = $.extend({}, { baseValue: 0, step: 1 }, options);
+            value   = parseFloat(value);
+            if (!$.isNumeric(value)) {
+                return false;
+            }
+
+            var round = function(x, precision) {
+                    var m = Math.pow(10, precision);
+                    x = x * m;
+                    var sign   = (x > 0) | -(x < 0),
+                        isHalf = (x % 1 === 0.5 * sign);
+                    if (isHalf) {
+                        return (Math.floor(x) + (sign > 0)) / m;
+                    } else {
+                        return Math.round(x) / m;
+                    }
+                },
+                floatMod = function(x, y) {
+                    if (y === 0.0) {
+                        return 1.0;
+                    }
+                    var dotX      = (x + '').split('.'),
+                        dotY      = (y + '').split('.'),
+                        precision = ((dotX.length === 1) ? 0 : dotX[1].length) + ((dotY.length === 1) ? 0 : dotY[1].length);
+                    return round(x - y * Math.floor(x / y), precision);
+                };
+
+            var locale = validator.getLocale(),
+                mod    = floatMod(value - options.baseValue, options.step);
+            return {
+                valid: mod === 0.0 || mod === options.step,
+                message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].step['default'], [options.step])
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            stringCase: {
+                'default': 'Please enter only lowercase characters',
+                upper: 'Please enter only uppercase characters'
+            }
+        }
+    });
+
+    FormValidation.Validator.stringCase = {
+        html5Attributes: {
+            message: 'message',
+            'case': 'case'
+        },
+
+        /**
+         * Check if a string is a lower or upper case one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - case: Can be 'lower' (default) or 'upper'
+         * @returns {Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var locale     = validator.getLocale(),
+                stringCase = (options['case'] || 'lower').toLowerCase();
+            return {
+                valid: ('upper' === stringCase) ? value === value.toUpperCase() : value === value.toLowerCase(),
+                message: options.message || (('upper' === stringCase) ? FormValidation.I18n[locale].stringCase.upper : FormValidation.I18n[locale].stringCase['default'])
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            stringLength: {
+                'default': 'Please enter a value with valid length',
+                less: 'Please enter less than %s characters',
+                more: 'Please enter more than %s characters',
+                between: 'Please enter value between %s and %s characters long'
+            }
+        }
+    });
+
+    FormValidation.Validator.stringLength = {
+        html5Attributes: {
+            message: 'message',
+            min: 'min',
+            max: 'max',
+            trim: 'trim',
+            utf8bytes: 'utf8Bytes'
+        },
+
+        enableByHtml5: function($field) {
+            var options   = {},
+                maxLength = $field.attr('maxlength'),
+                minLength = $field.attr('minlength');
+            if (maxLength) {
+                options.max = parseInt(maxLength, 10);
+            }
+            if (minLength) {
+                options.min = parseInt(minLength, 10);
+            }
+
+            return $.isEmptyObject(options) ? false : options;
+        },
+
+        /**
+         * Check if the length of element value is less or more than given number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of following keys:
+         * - min
+         * - max
+         * At least one of two keys is required
+         * The min, max keys define the number which the field value compares to. min, max can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - message: The invalid message
+         * - trim: Indicate the length will be calculated after trimming the value or not. It is false, by default
+         * - utf8bytes: Evaluate string length in UTF-8 bytes, default to false
+         * @returns {Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (options.trim === true || options.trim === 'true') {
+                value = $.trim(value);
+            }
+
+            if (value === '') {
+                return true;
+            }
+
+            var locale     = validator.getLocale(),
+                min        = $.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min),
+                max        = $.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max),
+                // Credit to http://stackoverflow.com/a/23329386 (@lovasoa) for UTF-8 byte length code
+                utf8Length = function(str) {
+                                 var s = str.length;
+                                 for (var i = str.length - 1; i >= 0; i--) {
+                                     var code = str.charCodeAt(i);
+                                     if (code > 0x7f && code <= 0x7ff) {
+                                         s++;
+                                     } else if (code > 0x7ff && code <= 0xffff) {
+                                         s += 2;
+                                     }
+                                     if (code >= 0xDC00 && code <= 0xDFFF) {
+                                         i--;
+                                     }
+                                 }
+                                 return s;
+                             },
+                length     = options.utf8Bytes ? utf8Length(value) : value.length,
+                isValid    = true,
+                message    = options.message || FormValidation.I18n[locale].stringLength['default'];
+
+            if ((min && length < parseInt(min, 10)) || (max && length > parseInt(max, 10))) {
+                isValid = false;
+            }
+
+            switch (true) {
+                case (!!min && !!max):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].stringLength.between, [parseInt(min, 10), parseInt(max, 10)]);
+                    break;
+
+                case (!!min):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].stringLength.more, parseInt(min, 10) - 1);
+                    break;
+
+                case (!!max):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].stringLength.less, parseInt(max, 10) + 1);
+                    break;
+
+                default:
+                    break;
+            }
+
+            return {
+                valid: isValid,
+                message: message
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            uri: {
+                'default': 'Please enter a valid URI'
+            }
+        }
+    });
+
+    FormValidation.Validator.uri = {
+        html5Attributes: {
+            message: 'message',
+            allowlocal: 'allowLocal',
+            allowemptyprotocol: 'allowEmptyProtocol',
+            protocol: 'protocol'
+        },
+
+        enableByHtml5: function($field) {
+            return ('url' === $field.attr('type'));
+        },
+
+        /**
+         * Return true if the input value is a valid URL
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options
+         * - message: The error message
+         * - allowLocal: Allow the private and local network IP. Default to false
+         * - allowEmptyProtocol: Allow the URI without protocol. Default to false
+         * - protocol: The protocols, separated by a comma. Default to "http, https, ftp"
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Credit to https://gist.github.com/dperini/729294
+            //
+            // Regular Expression for URL validation
+            //
+            // Author: Diego Perini
+            // Updated: 2010/12/05
+            //
+            // the regular expression composed & commented
+            // could be easily tweaked for RFC compliance,
+            // it was expressly modified to fit & satisfy
+            // these test for an URL shortener:
+            //
+            //   http://mathiasbynens.be/demo/url-regex
+            //
+            // Notes on possible differences from a standard/generic validation:
+            //
+            // - utf-8 char class take in consideration the full Unicode range
+            // - TLDs are mandatory unless `allowLocal` is true
+            // - protocols have been restricted to ftp, http and https only as requested
+            //
+            // Changes:
+            //
+            // - IP address dotted notation validation, range: 1.0.0.0 - 223.255.255.255
+            //   first and last IP address of each class is considered invalid
+            //   (since they are broadcast/network addresses)
+            //
+            // - Added exclusion of private, reserved and/or local networks ranges
+            //   unless `allowLocal` is true
+            //
+            // - Added possibility of choosing a custom protocol
+            //
+            // - Add option to validate without protocol
+            //
+            var allowLocal         = options.allowLocal === true || options.allowLocal === 'true',
+                allowEmptyProtocol = options.allowEmptyProtocol === true || options.allowEmptyProtocol === 'true',
+                protocol           = (options.protocol || 'http, https, ftp').split(',').join('|').replace(/\s/g, ''),
+                urlExp             = new RegExp(
+                    "^" +
+                    // protocol identifier
+                    "(?:(?:" + protocol + ")://)" +
+                    // allow empty protocol
+                    (allowEmptyProtocol ? '?' : '') +
+                    // user:pass authentication
+                    "(?:\\S+(?::\\S*)?@)?" +
+                    "(?:" +
+                    // IP address exclusion
+                    // private & local networks
+                    (allowLocal
+                        ? ''
+                        : ("(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
+                           "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
+                           "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})")) +
+                    // IP address dotted notation octets
+                    // excludes loopback network 0.0.0.0
+                    // excludes reserved space >= 224.0.0.0
+                    // excludes network & broadcast addresses
+                    // (first & last IP address of each class)
+                    "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
+                    "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
+                    "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
+                    "|" +
+                    // host name
+                    "(?:(?:[a-z\\u00a1-\\uffff0-9]-?)*[a-z\\u00a1-\\uffff0-9]+)" +
+                    // domain name
+                    "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-?)*[a-z\\u00a1-\\uffff0-9])*" +
+                    // TLD identifier
+                    "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
+                    // Allow intranet sites (no TLD) if `allowLocal` is true
+                    (allowLocal ? '?' : '') +
+                    ")" +
+                    // port number
+                    "(?::\\d{2,5})?" +
+                    // resource path
+                    "(?:/[^\\s]*)?" +
+                    "$", "i"
+                );
+
+            return urlExp.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            uuid: {
+                'default': 'Please enter a valid UUID number',
+                version: 'Please enter a valid UUID version %s number'
+            }
+        }
+    });
+
+    FormValidation.Validator.uuid = {
+        html5Attributes: {
+            message: 'message',
+            version: 'version'
+        },
+
+        /**
+         * Return true if and only if the input value is a valid UUID string
+         *
+         * @see http://en.wikipedia.org/wiki/Universally_unique_identifier
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - version: Can be 3, 4, 5, null
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // See the format at http://en.wikipedia.org/wiki/Universally_unique_identifier#Variants_and_versions
+            var locale   = validator.getLocale(),
+                patterns = {
+                    '3': /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
+                    '4': /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
+                    '5': /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
+                    all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
+                },
+                version = options.version ? (options.version + '') : 'all';
+            return {
+                valid: (null === patterns[version]) ? true : patterns[version].test(value),
+                message: options.version
+                            ? FormValidation.Helper.format(options.message || FormValidation.I18n[locale].uuid.version, options.version)
+                            : (options.message || FormValidation.I18n[locale].uuid['default'])
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            vat: {
+                'default': 'Please enter a valid VAT number',
+                country: 'Please enter a valid VAT number in %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Belgium',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CY: 'Cyprus',
+                    CZ: 'Czech Republic',
+                    DE: 'Germany',
+                    DK: 'Denmark',
+                    EE: 'Estonia',
+                    ES: 'Spain',
+                    FI: 'Finland',
+                    FR: 'France',
+                    GB: 'United Kingdom',
+                    GR: 'Greek',
+                    EL: 'Greek',
+                    HU: 'Hungary',
+                    HR: 'Croatia',
+                    IE: 'Ireland',
+                    IS: 'Iceland',
+                    IT: 'Italy',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MT: 'Malta',
+                    NL: 'Netherlands',
+                    NO: 'Norway',
+                    PL: 'Poland',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    RS: 'Serbia',
+                    SE: 'Sweden',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    VE: 'Venezuela',
+                    ZA: 'South Africa'
+                }
+            }
+        }
+    });
+
+    FormValidation.Validator.vat = {
+        html5Attributes: {
+            message: 'message',
+            country: 'country'
+        },
+
+        // Supported country codes
+        COUNTRY_CODES: [
+            'AT', 'BE', 'BG', 'BR', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'EL', 'ES', 'FI', 'FR', 'GB', 'GR', 'HR', 'HU',
+            'IE', 'IS', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'RS', 'SE', 'SK', 'SI', 'VE',
+            'ZA'
+        ],
+
+        /**
+         * Validate an European VAT number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - country: The ISO 3166-1 country code. It can be
+         *      - One of country code defined in COUNTRY_CODES
+         *      - Name of field which its value defines the country code
+         *      - Name of callback function that returns the country code
+         *      - A callback function that returns the country code
+         * @returns {Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var locale  = validator.getLocale(),
+                country = options.country;
+            if (!country) {
+                country = value.substr(0, 2);
+            } else if (typeof country !== 'string' || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) {
+                // Determine the country code
+                country = validator.getDynamicOption($field, country);
+            }
+
+            if ($.inArray(country, this.COUNTRY_CODES) === -1) {
+                return true;
+            }
+
+            var method  = ['_', country.toLowerCase()].join(''),
+                result = this[method](value);
+            result         = (result === true || result === false) ? { valid: result } : result;
+            result.message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].vat.country, FormValidation.I18n[locale].vat.countries[country.toUpperCase()]);
+
+            return result;
+        },
+
+        // VAT validators
+
+        /**
+         * Validate Austrian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _at: function(value) {
+            if (/^ATU[0-9]{8}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^U[0-9]{8}$/.test(value)) {
+                return false;
+            }
+
+            value = value.substr(1);
+            var sum    = 0,
+                weight = [1, 2, 1, 2, 1, 2, 1],
+                temp   = 0;
+            for (var i = 0; i < 7; i++) {
+                temp = parseInt(value.charAt(i), 10) * weight[i];
+                if (temp > 9) {
+                    temp = Math.floor(temp / 10) + temp % 10;
+                }
+                sum += temp;
+            }
+
+            sum = 10 - (sum + 4) % 10;
+            if (sum === 10) {
+                sum = 0;
+            }
+
+            return (sum + '' === value.substr(7, 1));
+        },
+
+        /**
+         * Validate Belgian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _be: function(value) {
+            if (/^BE[0]{0,1}[0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0]{0,1}[0-9]{9}$/.test(value)) {
+                return false;
+            }
+
+            if (value.length === 9) {
+                value = '0' + value;
+            }
+            if (value.substr(1, 1) === '0') {
+                return false;
+            }
+
+            var sum = parseInt(value.substr(0, 8), 10) + parseInt(value.substr(8, 2), 10);
+            return (sum % 97 === 0);
+        },
+
+        /**
+         * Validate Bulgarian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _bg: function(value) {
+            if (/^BG[0-9]{9,10}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{9,10}$/.test(value)) {
+                return false;
+            }
+
+            var sum = 0, i = 0;
+
+            // Legal entities
+            if (value.length === 9) {
+                for (i = 0; i < 8; i++) {
+                    sum += parseInt(value.charAt(i), 10) * (i + 1);
+                }
+                sum = sum % 11;
+                if (sum === 10) {
+                    sum = 0;
+                    for (i = 0; i < 8; i++) {
+                        sum += parseInt(value.charAt(i), 10) * (i + 3);
+                    }
+                }
+                sum = sum % 10;
+                return (sum + '' === value.substr(8));
+            }
+            // Physical persons, foreigners and others
+            else if (value.length === 10) {
+                // Validate Bulgarian national identification numbers
+                var egn = function(value) {
+                        // Check the birth date
+                        var year  = parseInt(value.substr(0, 2), 10) + 1900,
+                            month = parseInt(value.substr(2, 2), 10),
+                            day   = parseInt(value.substr(4, 2), 10);
+                        if (month > 40) {
+                            year += 100;
+                            month -= 40;
+                        } else if (month > 20) {
+                            year -= 100;
+                            month -= 20;
+                        }
+
+                        if (!FormValidation.Helper.date(year, month, day)) {
+                            return false;
+                        }
+
+                        var sum    = 0,
+                            weight = [2, 4, 8, 5, 10, 9, 7, 3, 6];
+                        for (var i = 0; i < 9; i++) {
+                            sum += parseInt(value.charAt(i), 10) * weight[i];
+                        }
+                        sum = (sum % 11) % 10;
+                        return (sum + '' === value.substr(9, 1));
+                    },
+                    // Validate Bulgarian personal number of a foreigner
+                    pnf = function(value) {
+                        var sum    = 0,
+                            weight = [21, 19, 17, 13, 11, 9, 7, 3, 1];
+                        for (var i = 0; i < 9; i++) {
+                            sum += parseInt(value.charAt(i), 10) * weight[i];
+                        }
+                        sum = sum % 10;
+                        return (sum + '' === value.substr(9, 1));
+                    },
+                    // Finally, consider it as a VAT number
+                    vat = function(value) {
+                        var sum    = 0,
+                            weight = [4, 3, 2, 7, 6, 5, 4, 3, 2];
+                        for (var i = 0; i < 9; i++) {
+                            sum += parseInt(value.charAt(i), 10) * weight[i];
+                        }
+                        sum = 11 - sum % 11;
+                        if (sum === 10) {
+                            return false;
+                        }
+                        if (sum === 11) {
+                            sum = 0;
+                        }
+                        return (sum + '' === value.substr(9, 1));
+                    };
+                return (egn(value) || pnf(value) || vat(value));
+            }
+
+            return false;
+        },
+        
+        /**
+         * Validate Brazilian VAT number (CNPJ)
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _br: function(value) {
+            if (value === '') {
+                return true;
+            }
+            var cnpj = value.replace(/[^\d]+/g, '');
+            if (cnpj === '' || cnpj.length !== 14) {
+                return false;
+            }
+
+            // Remove invalids CNPJs
+            if (cnpj === '00000000000000' || cnpj === '11111111111111' || cnpj === '22222222222222' ||
+                cnpj === '33333333333333' || cnpj === '44444444444444' || cnpj === '55555555555555' ||
+                cnpj === '66666666666666' || cnpj === '77777777777777' || cnpj === '88888888888888' ||
+                cnpj === '99999999999999')
+            {
+                return false;
+            }
+
+            // Validate verification digits
+            var length  = cnpj.length - 2,
+                numbers = cnpj.substring(0, length),
+                digits  = cnpj.substring(length),
+                sum     = 0,
+                pos     = length - 7;
+
+            for (var i = length; i >= 1; i--) {
+                sum += parseInt(numbers.charAt(length - i), 10) * pos--;
+                if (pos < 2) {
+                    pos = 9;
+                }
+            }
+
+            var result = sum % 11 < 2 ? 0 : 11 - sum % 11;
+            if (result !== parseInt(digits.charAt(0), 10)) {
+                return false;
+            }
+
+            length  = length + 1;
+            numbers = cnpj.substring(0, length);
+            sum     = 0;
+            pos     = length - 7;
+            for (i = length; i >= 1; i--) {
+                sum += parseInt(numbers.charAt(length - i), 10) * pos--;
+                if (pos < 2) {
+                    pos = 9;
+                }
+            }
+
+            result = sum % 11 < 2 ? 0 : 11 - sum % 11;
+            return (result === parseInt(digits.charAt(1), 10));
+        },
+
+        /**
+         * Validate Swiss VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _ch: function(value) {
+            if (/^CHE[0-9]{9}(MWST)?$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^E[0-9]{9}(MWST)?$/.test(value)) {
+                return false;
+            }
+
+            value = value.substr(1);
+            var sum    = 0,
+                weight = [5, 4, 3, 2, 7, 6, 5, 4];
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            sum = 11 - sum % 11;
+            if (sum === 10) {
+                return false;
+            }
+            if (sum === 11) {
+                sum = 0;
+            }
+
+            return (sum + '' === value.substr(8, 1));
+        },
+
+        /**
+         * Validate Cypriot VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _cy: function(value) {
+            if (/^CY[0-5|9]{1}[0-9]{7}[A-Z]{1}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-5|9]{1}[0-9]{7}[A-Z]{1}$/.test(value)) {
+                return false;
+            }
+
+            // Do not allow to start with "12"
+            if (value.substr(0, 2) === '12') {
+                return false;
+            }
+
+            // Extract the next digit and multiply by the counter.
+            var sum         = 0,
+                translation = {
+                    '0': 1,  '1': 0,  '2': 5,  '3': 7,  '4': 9,
+                    '5': 13, '6': 15, '7': 17, '8': 19, '9': 21
+                };
+            for (var i = 0; i < 8; i++) {
+                var temp = parseInt(value.charAt(i), 10);
+                if (i % 2 === 0) {
+                    temp = translation[temp + ''];
+                }
+                sum += temp;
+            }
+
+            sum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[sum % 26];
+            return (sum + '' === value.substr(8, 1));
+        },
+
+        /**
+         * Validate Czech Republic VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _cz: function(value) {
+            if (/^CZ[0-9]{8,10}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{8,10}$/.test(value)) {
+                return false;
+            }
+
+            var sum = 0,
+                i   = 0;
+            if (value.length === 8) {
+                // Do not allow to start with '9'
+                if (value.charAt(0) + '' === '9') {
+                    return false;
+                }
+
+                sum = 0;
+                for (i = 0; i < 7; i++) {
+                    sum += parseInt(value.charAt(i), 10) * (8 - i);
+                }
+                sum = 11 - sum % 11;
+                if (sum === 10) {
+                    sum = 0;
+                }
+                if (sum === 11) {
+                    sum = 1;
+                }
+
+                return (sum + '' === value.substr(7, 1));
+            } else if (value.length === 9 && (value.charAt(0) + '' === '6')) {
+                sum = 0;
+                // Skip the first (which is 6)
+                for (i = 0; i < 7; i++) {
+                    sum += parseInt(value.charAt(i + 1), 10) * (8 - i);
+                }
+                sum = 11 - sum % 11;
+                if (sum === 10) {
+                    sum = 0;
+                }
+                if (sum === 11) {
+                    sum = 1;
+                }
+                sum = [8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 10][sum - 1];
+                return (sum + '' === value.substr(8, 1));
+            } else if (value.length === 9 || value.length === 10) {
+                // Validate Czech birth number (Rodné číslo), which is also national identifier
+                var year  = 1900 + parseInt(value.substr(0, 2), 10),
+                    month = parseInt(value.substr(2, 2), 10) % 50 % 20,
+                    day   = parseInt(value.substr(4, 2), 10);
+                if (value.length === 9) {
+                    if (year >= 1980) {
+                        year -= 100;
+                    }
+                    if (year > 1953) {
+                        return false;
+                    }
+                } else if (year < 1954) {
+                    year += 100;
+                }
+
+                if (!FormValidation.Helper.date(year, month, day)) {
+                    return false;
+                }
+
+                // Check that the birth date is not in the future
+                if (value.length === 10) {
+                    var check = parseInt(value.substr(0, 9), 10) % 11;
+                    if (year < 1985) {
+                        check = check % 10;
+                    }
+                    return (check + '' === value.substr(9, 1));
+                }
+
+                return true;
+            }
+
+            return false;
+        },
+
+        /**
+         * Validate German VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _de: function(value) {
+            if (/^DE[0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{9}$/.test(value)) {
+                return false;
+            }
+
+            return FormValidation.Helper.mod11And10(value);
+        },
+
+        /**
+         * Validate Danish VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _dk: function(value) {
+            if (/^DK[0-9]{8}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{8}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [2, 7, 6, 5, 4, 3, 2, 1];
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            return (sum % 11 === 0);
+        },
+
+        /**
+         * Validate Estonian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _ee: function(value) {
+            if (/^EE[0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{9}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [3, 7, 1, 3, 7, 1, 3, 7, 1];
+            for (var i = 0; i < 9; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            return (sum % 10 === 0);
+        },
+
+        /**
+         * Validate Spanish VAT number (NIF - Número de Identificación Fiscal)
+         * Can be:
+         * i) DNI (Documento nacional de identidad), for Spaniards
+         * ii) NIE (Número de Identificación de Extranjeros), for foreigners
+         * iii) CIF (Certificado de Identificación Fiscal), for legal entities and others
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean|Object}
+         */
+        _es: function(value) {
+            if (/^ES[0-9A-Z][0-9]{7}[0-9A-Z]$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9A-Z][0-9]{7}[0-9A-Z]$/.test(value)) {
+                return false;
+            }
+
+            var dni = function(value) {
+                    var check = parseInt(value.substr(0, 8), 10);
+                    check = 'TRWAGMYFPDXBNJZSQVHLCKE'[check % 23];
+                    return (check + '' === value.substr(8, 1));
+                },
+                nie = function(value) {
+                    var check = ['XYZ'.indexOf(value.charAt(0)), value.substr(1)].join('');
+                    check = parseInt(check, 10);
+                    check = 'TRWAGMYFPDXBNJZSQVHLCKE'[check % 23];
+                    return (check + '' === value.substr(8, 1));
+                },
+                cif = function(value) {
+                    var first = value.charAt(0), check;
+                    if ('KLM'.indexOf(first) !== -1) {
+                        // K: Spanish younger than 14 year old
+                        // L: Spanish living outside Spain without DNI
+                        // M: Granted the tax to foreigners who have no NIE
+                        check = parseInt(value.substr(1, 8), 10);
+                        check = 'TRWAGMYFPDXBNJZSQVHLCKE'[check % 23];
+                        return (check + '' === value.substr(8, 1));
+                    } else if ('ABCDEFGHJNPQRSUVW'.indexOf(first) !== -1) {
+                        var sum    = 0,
+                            weight = [2, 1, 2, 1, 2, 1, 2],
+                            temp   = 0;
+
+                        for (var i = 0; i < 7; i++) {
+                            temp = parseInt(value.charAt(i + 1), 10) * weight[i];
+                            if (temp > 9) {
+                                temp = Math.floor(temp / 10) + temp % 10;
+                            }
+                            sum += temp;
+                        }
+                        sum = 10 - sum % 10;
+                        if (sum === 10) {
+                            sum = 0;
+                        }
+                        return (sum + '' === value.substr(8, 1) || 'JABCDEFGHI'[sum] === value.substr(8, 1));
+                    }
+
+                    return false;
+                };
+
+            var first = value.charAt(0);
+            if (/^[0-9]$/.test(first)) {
+                return {
+                    valid: dni(value),
+                    type: 'DNI'
+                };
+            } else if (/^[XYZ]$/.test(first)) {
+                return {
+                    valid: nie(value),
+                    type: 'NIE'
+                };
+            } else {
+                return {
+                    valid: cif(value),
+                    type: 'CIF'
+                };
+            }
+        },
+
+        /**
+         * Validate Finnish VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _fi: function(value) {
+            if (/^FI[0-9]{8}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{8}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [7, 9, 10, 5, 8, 4, 2, 1];
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            return (sum % 11 === 0);
+        },
+
+        /**
+         * Validate French VAT number (TVA - taxe sur la valeur ajoutée)
+         * It's constructed by a SIREN number, prefixed by two characters.
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _fr: function(value) {
+            if (/^FR[0-9A-Z]{2}[0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9A-Z]{2}[0-9]{9}$/.test(value)) {
+                return false;
+            }
+
+            if (!FormValidation.Helper.luhn(value.substr(2))) {
+                return false;
+            }
+
+            if (/^[0-9]{2}$/.test(value.substr(0, 2))) {
+                // First two characters are digits
+                return value.substr(0, 2) === (parseInt(value.substr(2) + '12', 10) % 97 + '');
+            } else {
+                // The first characters cann't be O and I
+                var alphabet = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ',
+                    check;
+                // First one is digit
+                if (/^[0-9]{1}$/.test(value.charAt(0))) {
+                    check = alphabet.indexOf(value.charAt(0)) * 24 + alphabet.indexOf(value.charAt(1)) - 10;
+                } else {
+                    check = alphabet.indexOf(value.charAt(0)) * 34 + alphabet.indexOf(value.charAt(1)) - 100;
+                }
+                return ((parseInt(value.substr(2), 10) + 1 + Math.floor(check / 11)) % 11) === (check % 11);
+            }
+        },
+
+        /**
+         * Validate United Kingdom VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _gb: function(value) {
+            if (/^GB[0-9]{9}$/.test(value)             /* Standard */
+                || /^GB[0-9]{12}$/.test(value)         /* Branches */
+                || /^GBGD[0-9]{3}$/.test(value)        /* Government department */
+                || /^GBHA[0-9]{3}$/.test(value)        /* Health authority */
+                || /^GB(GD|HA)8888[0-9]{5}$/.test(value))
+            {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{9}$/.test(value)
+                && !/^[0-9]{12}$/.test(value)
+                && !/^GD[0-9]{3}$/.test(value)
+                && !/^HA[0-9]{3}$/.test(value)
+                && !/^(GD|HA)8888[0-9]{5}$/.test(value))
+            {
+                return false;
+            }
+
+            var length = value.length;
+            if (length === 5) {
+                var firstTwo  = value.substr(0, 2),
+                    lastThree = parseInt(value.substr(2), 10);
+                return ('GD' === firstTwo && lastThree < 500) || ('HA' === firstTwo && lastThree >= 500);
+            } else if (length === 11 && ('GD8888' === value.substr(0, 6) || 'HA8888' === value.substr(0, 6))) {
+                if (('GD' === value.substr(0, 2) && parseInt(value.substr(6, 3), 10) >= 500)
+                    || ('HA' === value.substr(0, 2) && parseInt(value.substr(6, 3), 10) < 500))
+                {
+                    return false;
+                }
+                return (parseInt(value.substr(6, 3), 10) % 97 === parseInt(value.substr(9, 2), 10));
+            } else if (length === 9 || length === 12) {
+                var sum    = 0,
+                    weight = [8, 7, 6, 5, 4, 3, 2, 10, 1];
+                for (var i = 0; i < 9; i++) {
+                    sum += parseInt(value.charAt(i), 10) * weight[i];
+                }
+                sum = sum % 97;
+
+                if (parseInt(value.substr(0, 3), 10) >= 100) {
+                    return (sum === 0 || sum === 42 || sum === 55);
+                } else {
+                    return (sum === 0);
+                }
+            }
+
+            return true;
+        },
+
+        /**
+         * Validate Greek VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _gr: function(value) {
+            if (/^(GR|EL)[0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{9}$/.test(value)) {
+                return false;
+            }
+
+            if (value.length === 8) {
+                value = '0' + value;
+            }
+
+            var sum    = 0,
+                weight = [256, 128, 64, 32, 16, 8, 4, 2];
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = (sum % 11) % 10;
+
+            return (sum + '' === value.substr(8, 1));
+        },
+
+        // EL is traditionally prefix of Greek VAT numbers
+        _el: function(value) {
+            return this._gr(value);
+        },
+
+        /**
+         * Validate Hungarian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _hu: function(value) {
+            if (/^HU[0-9]{8}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{8}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [9, 7, 3, 1, 9, 7, 3, 1];
+
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            return (sum % 10 === 0);
+        },
+
+        /**
+         * Validate Croatian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _hr: function(value) {
+            if (/^HR[0-9]{11}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{11}$/.test(value)) {
+                return false;
+            }
+
+            return FormValidation.Helper.mod11And10(value);
+        },
+
+        /**
+         * Validate Irish VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _ie: function(value) {
+            if (/^IE[0-9]{1}[0-9A-Z\*\+]{1}[0-9]{5}[A-Z]{1,2}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{1}[0-9A-Z\*\+]{1}[0-9]{5}[A-Z]{1,2}$/.test(value)) {
+                return false;
+            }
+
+            var getCheckDigit = function(value) {
+                while (value.length < 7) {
+                    value = '0' + value;
+                }
+                var alphabet = 'WABCDEFGHIJKLMNOPQRSTUV',
+                    sum      = 0;
+                for (var i = 0; i < 7; i++) {
+                    sum += parseInt(value.charAt(i), 10) * (8 - i);
+                }
+                sum += 9 * alphabet.indexOf(value.substr(7));
+                return alphabet[sum % 23];
+            };
+
+            // The first 7 characters are digits
+            if (/^[0-9]+$/.test(value.substr(0, 7))) {
+                // New system
+                return value.charAt(7) === getCheckDigit(value.substr(0, 7) + value.substr(8) + '');
+            } else if ('ABCDEFGHIJKLMNOPQRSTUVWXYZ+*'.indexOf(value.charAt(1)) !== -1) {
+                // Old system
+                return value.charAt(7) === getCheckDigit(value.substr(2, 5) + value.substr(0, 1) + '');
+            }
+
+            return true;
+        },
+
+        /**
+         * Validate Icelandic VAT (VSK) number
+         *
+         * @params {String} value VAT number
+         * @returns {Boolean}
+         */
+        _is: function(value) {
+            if (/^IS[0-9]{5,6}$/.test(value)) {
+                value = value.substr(2);
+            }
+            return /^[0-9]{5,6}$/.test(value);
+        },
+
+        /**
+         * Validate Italian VAT number, which consists of 11 digits.
+         * - First 7 digits are a company identifier
+         * - Next 3 are the province of residence
+         * - The last one is a check digit
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _it: function(value) {
+            if (/^IT[0-9]{11}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{11}$/.test(value)) {
+                return false;
+            }
+
+            if (parseInt(value.substr(0, 7), 10) === 0) {
+                return false;
+            }
+
+            var lastThree = parseInt(value.substr(7, 3), 10);
+            if ((lastThree < 1) || (lastThree > 201) && lastThree !== 999 && lastThree !== 888) {
+                return false;
+            }
+
+            return FormValidation.Helper.luhn(value);
+        },
+
+        /**
+         * Validate Lithuanian VAT number
+         * It can be:
+         * - 9 digits, for legal entities
+         * - 12 digits, for temporarily registered taxpayers
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _lt: function(value) {
+            if (/^LT([0-9]{7}1[0-9]{1}|[0-9]{10}1[0-9]{1})$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^([0-9]{7}1[0-9]{1}|[0-9]{10}1[0-9]{1})$/.test(value)) {
+                return false;
+            }
+
+            var length = value.length,
+                sum    = 0,
+                i;
+            for (i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i), 10) * (1 + i % 9);
+            }
+            var check = sum % 11;
+            if (check === 10) {
+                sum = 0;
+                for (i = 0; i < length - 1; i++) {
+                    sum += parseInt(value.charAt(i), 10) * (1 + (i + 2) % 9);
+                }
+            }
+            check = check % 11 % 10;
+            return (check + '' === value.charAt(length - 1));
+        },
+
+        /**
+         * Validate Luxembourg VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _lu: function(value) {
+            if (/^LU[0-9]{8}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{8}$/.test(value)) {
+                return false;
+            }
+
+            return ((parseInt(value.substr(0, 6), 10) % 89) + '' === value.substr(6, 2));
+        },
+
+        /**
+         * Validate Latvian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _lv: function(value) {
+            if (/^LV[0-9]{11}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{11}$/.test(value)) {
+                return false;
+            }
+
+            var first  = parseInt(value.charAt(0), 10),
+                sum    = 0,
+                weight = [],
+                i,
+                length = value.length;
+            if (first > 3) {
+                // Legal entity
+                sum    = 0;
+                weight = [9, 1, 4, 8, 3, 10, 2, 5, 7, 6, 1];
+                for (i = 0; i < length; i++) {
+                    sum += parseInt(value.charAt(i), 10) * weight[i];
+                }
+                sum = sum % 11;
+                return (sum === 3);
+            } else {
+                // Check birth date
+                var day   = parseInt(value.substr(0, 2), 10),
+                    month = parseInt(value.substr(2, 2), 10),
+                    year  = parseInt(value.substr(4, 2), 10);
+                year = year + 1800 + parseInt(value.charAt(6), 10) * 100;
+
+                if (!FormValidation.Helper.date(year, month, day)) {
+                    return false;
+                }
+
+                // Check personal code
+                sum    = 0;
+                weight = [10, 5, 8, 4, 2, 1, 6, 3, 7, 9];
+                for (i = 0; i < length - 1; i++) {
+                    sum += parseInt(value.charAt(i), 10) * weight[i];
+                }
+                sum = (sum + 1) % 11 % 10;
+                return (sum + '' === value.charAt(length - 1));
+            }
+        },
+
+        /**
+         * Validate Maltese VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _mt: function(value) {
+            if (/^MT[0-9]{8}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{8}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [3, 4, 6, 7, 8, 9, 10, 1];
+
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            return (sum % 37 === 0);
+        },
+
+        /**
+         * Validate Dutch VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _nl: function(value) {
+            if (/^NL[0-9]{9}B[0-9]{2}$/.test(value)) {
+               value = value.substr(2);
+            }
+            if (!/^[0-9]{9}B[0-9]{2}$/.test(value)) {
+               return false;
+            }
+
+            var sum    = 0,
+                weight = [9, 8, 7, 6, 5, 4, 3, 2];
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            sum = sum % 11;
+            if (sum > 9) {
+                sum = 0;
+            }
+            return (sum + '' === value.substr(8, 1));
+        },
+
+        /**
+         * Validate Norwegian VAT number
+         *
+         * @see http://www.brreg.no/english/coordination/number.html
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _no: function(value) {
+            if (/^NO[0-9]{9}$/.test(value)) {
+               value = value.substr(2);
+            }
+            if (!/^[0-9]{9}$/.test(value)) {
+               return false;
+            }
+
+            var sum    = 0,
+                weight = [3, 2, 7, 6, 5, 4, 3, 2];
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            sum = 11 - sum % 11;
+            if (sum === 11) {
+                sum = 0;
+            }
+            return (sum + '' === value.substr(8, 1));
+        },
+
+        /**
+         * Validate Polish VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _pl: function(value) {
+            if (/^PL[0-9]{10}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{10}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [6, 5, 7, 2, 3, 4, 5, 6, 7, -1];
+
+            for (var i = 0; i < 10; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            return (sum % 11 === 0);
+        },
+
+        /**
+         * Validate Portuguese VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _pt: function(value) {
+            if (/^PT[0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{9}$/.test(value)) {
+                return false;
+            }
+
+            var sum    = 0,
+                weight = [9, 8, 7, 6, 5, 4, 3, 2];
+
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = 11 - sum % 11;
+            if (sum > 9) {
+                sum = 0;
+            }
+            return (sum + '' === value.substr(8, 1));
+        },
+
+        /**
+         * Validate Romanian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _ro: function(value) {
+            if (/^RO[1-9][0-9]{1,9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[1-9][0-9]{1,9}$/.test(value)) {
+                return false;
+            }
+
+            var length = value.length,
+                weight = [7, 5, 3, 2, 1, 7, 5, 3, 2].slice(10 - length),
+                sum    = 0;
+            for (var i = 0; i < length - 1; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+
+            sum = (10 * sum) % 11 % 10;
+            return (sum + '' === value.substr(length - 1, 1));
+        },
+
+        /**
+         * Validate Russian VAT number (Taxpayer Identification Number - INN)
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _ru: function(value) {
+            if (/^RU([0-9]{10}|[0-9]{12})$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^([0-9]{10}|[0-9]{12})$/.test(value)) {
+                return false;
+            }
+
+            var i = 0;
+            if (value.length === 10) {
+                var sum    = 0,
+                    weight = [2, 4, 10, 3, 5, 9, 4, 6, 8, 0];
+                for (i = 0; i < 10; i++) {
+                    sum += parseInt(value.charAt(i), 10) * weight[i];
+                }
+                sum = sum % 11;
+                if (sum > 9) {
+                    sum = sum % 10;
+                }
+
+                return (sum + '' === value.substr(9, 1));
+            } else if (value.length === 12) {
+                var sum1    = 0,
+                    weight1 = [7, 2, 4, 10, 3, 5, 9, 4, 6, 8, 0],
+                    sum2    = 0,
+                    weight2 = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8, 0];
+
+                for (i = 0; i < 11; i++) {
+                    sum1 += parseInt(value.charAt(i), 10) * weight1[i];
+                    sum2 += parseInt(value.charAt(i), 10) * weight2[i];
+                }
+                sum1 = sum1 % 11;
+                if (sum1 > 9) {
+                    sum1 = sum1 % 10;
+                }
+                sum2 = sum2 % 11;
+                if (sum2 > 9) {
+                    sum2 = sum2 % 10;
+                }
+
+                return (sum1 + '' === value.substr(10, 1) && sum2 + '' === value.substr(11, 1));
+            }
+
+            return false;
+        },
+
+        /**
+         * Validate Serbian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _rs: function(value) {
+            if (/^RS[0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{9}$/.test(value)) {
+                return false;
+            }
+
+            var sum  = 10,
+                temp = 0;
+            for (var i = 0; i < 8; i++) {
+                temp = (parseInt(value.charAt(i), 10) + sum) % 10;
+                if (temp === 0) {
+                    temp = 10;
+                }
+                sum = (2 * temp) % 11;
+            }
+
+            return ((sum + parseInt(value.substr(8, 1), 10)) % 10 === 1);
+        },
+
+        /**
+         * Validate Swedish VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _se: function(value) {
+            if (/^SE[0-9]{10}01$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[0-9]{10}01$/.test(value)) {
+                return false;
+            }
+
+            value = value.substr(0, 10);
+            return FormValidation.Helper.luhn(value);
+        },
+
+        /**
+         * Validate Slovenian VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _si: function(value) {
+            // The Slovenian VAT numbers don't start with zero
+            var res = value.match(/^(SI)?([1-9][0-9]{7})$/);
+            if (!res) {
+                return false;
+            }
+            if (res[1]) {
+                value = value.substr(2);
+            }
+
+            var sum    = 0,
+                weight = [8, 7, 6, 5, 4, 3, 2];
+
+            for (var i = 0; i < 7; i++) {
+                sum += parseInt(value.charAt(i), 10) * weight[i];
+            }
+            sum = 11 - sum % 11;
+            if (sum === 10) {
+                sum = 0;
+            }
+            return (sum + '' === value.substr(7, 1));
+        },
+
+        /**
+         * Validate Slovak VAT number
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _sk: function(value) {
+            if (/^SK[1-9][0-9][(2-4)|(6-9)][0-9]{7}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[1-9][0-9][(2-4)|(6-9)][0-9]{7}$/.test(value)) {
+                return false;
+            }
+
+            return (parseInt(value, 10) % 11 === 0);
+        },
+
+        /**
+         * Validate Venezuelan VAT number (RIF)
+         *
+         * @param {String} value VAT number
+         * @returns {Boolean}
+         */
+        _ve: function(value) {
+            if (/^VE[VEJPG][0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+            if (!/^[VEJPG][0-9]{9}$/.test(value)) {
+                return false;
+            }
+
+            var types  = {
+                    'V': 4,
+                    'E': 8,
+                    'J': 12,
+                    'P': 16,
+                    'G': 20
+                },
+                sum    = types[value.charAt(0)],
+                weight = [3, 2, 7, 6, 5, 4, 3, 2];
+
+            for (var i = 0; i < 8; i++) {
+                sum += parseInt(value.charAt(i + 1), 10) * weight[i];
+            }
+
+            sum = 11 - sum % 11;
+            if (sum === 11 || sum === 10) {
+                sum = 0;
+            }
+            return (sum + '' === value.substr(9, 1));
+        },
+
+        /**
+         * Validate South African VAT number
+         *
+         * @params {String} value VAT number
+         * @returns {Boolean}
+         */
+         _za: function(value) {
+            if (/^ZA4[0-9]{9}$/.test(value)) {
+                value = value.substr(2);
+            }
+
+            return /^4[0-9]{9}$/.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            vin: {
+                'default': 'Please enter a valid VIN number'
+            }
+        }
+    });
+
+    FormValidation.Validator.vin = {
+        /**
+         * Validate an US VIN (Vehicle Identification Number)
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Don't accept I, O, Q characters
+            if (!/^[a-hj-npr-z0-9]{8}[0-9xX][a-hj-npr-z0-9]{8}$/i.test(value)) {
+                return false;
+            }
+
+            value = value.toUpperCase();
+            var chars   = {
+                    A: 1,   B: 2,   C: 3,   D: 4,   E: 5,   F: 6,   G: 7,   H: 8,
+                    J: 1,   K: 2,   L: 3,   M: 4,   N: 5,           P: 7,           R: 9,
+                            S: 2,   T: 3,   U: 4,   V: 5,   W: 6,   X: 7,   Y: 8,   Z: 9,
+                    '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '0': 0
+                },
+                weights = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2],
+                sum     = 0,
+                length  = value.length;
+            for (var i = 0; i < length; i++) {
+                sum += chars[value.charAt(i) + ''] * weights[i];
+            }
+
+            var reminder = sum % 11;
+            if (reminder === 10) {
+                reminder = 'X';
+            }
+
+            return (reminder + '') === value.charAt(8);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            zipCode: {
+                'default': 'Please enter a valid postal code',
+                country: 'Please enter a valid postal code in %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CA: 'Canada',
+                    CH: 'Switzerland',
+                    CZ: 'Czech Republic',
+                    DE: 'Germany',
+                    DK: 'Denmark',
+                    ES: 'Spain',
+                    FR: 'France',
+                    GB: 'United Kingdom',
+                    IE: 'Ireland',
+                    IN: 'India',
+                    IT: 'Italy',
+                    MA: 'Morocco',
+                    NL: 'Netherlands',
+                    PL: 'Poland',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    SE: 'Sweden',
+                    SG: 'Singapore',
+                    SK: 'Slovakia',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+
+    FormValidation.Validator.zipCode = {
+        html5Attributes: {
+            message: 'message',
+            country: 'country'
+        },
+
+        COUNTRY_CODES: ['AT', 'BG', 'BR', 'CA', 'CH', 'CZ', 'DE', 'DK', 'ES', 'FR', 'GB', 'IE', 'IN', 'IT', 'MA', 'NL', 'PL', 'PT', 'RO', 'RU', 'SE', 'SG', 'SK', 'US'],
+
+        /**
+         * Return true if and only if the input value is a valid country zip code
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - country: The country
+         *
+         * The country can be defined by:
+         * - An ISO 3166 country code
+         * - Name of field which its value defines the country code
+         * - Name of callback function that returns the country code
+         * - A callback function that returns the country code
+         *
+         *  callback: function(value, validator, $field) {
+         *      // value is the value of field
+         *      // validator is the FormValidation.Base instance
+         *      // $field is jQuery element representing the field
+         *  }
+         *
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '' || !options.country) {
+                return true;
+            }
+
+            var locale  = validator.getLocale(),
+                country = options.country;
+            if (typeof country !== 'string' || $.inArray(country, this.COUNTRY_CODES) === -1) {
+                // Try to determine the country
+                country = validator.getDynamicOption($field, country);
+            }
+
+            if (!country || $.inArray(country.toUpperCase(), this.COUNTRY_CODES) === -1) {
+                return true;
+            }
+
+            var isValid = false;
+            country = country.toUpperCase();
+            switch (country) {
+                // http://en.wikipedia.org/wiki/List_of_postal_codes_in_Austria
+                case 'AT':
+                    isValid = /^([1-9]{1})(\d{3})$/.test(value);
+                    break;
+
+                case 'BG':
+                    isValid = /^([1-9]{1}[0-9]{3})$/.test($.trim(value));
+                    break;
+
+                case 'BR':
+                    isValid = /^(\d{2})([\.]?)(\d{3})([\-]?)(\d{3})$/.test(value);
+                    break;
+
+                case 'CA':
+                    isValid = /^(?:A|B|C|E|G|H|J|K|L|M|N|P|R|S|T|V|X|Y){1}[0-9]{1}(?:A|B|C|E|G|H|J|K|L|M|N|P|R|S|T|V|W|X|Y|Z){1}\s?[0-9]{1}(?:A|B|C|E|G|H|J|K|L|M|N|P|R|S|T|V|W|X|Y|Z){1}[0-9]{1}$/i.test(value);
+                    break;
+
+                case 'CH':
+                    isValid = /^([1-9]{1})(\d{3})$/.test(value);
+                    break;
+
+                case 'CZ':
+                    // Test: http://regexr.com/39hhr
+                    isValid = /^(\d{3})([ ]?)(\d{2})$/.test(value);
+                    break;
+
+                // http://stackoverflow.com/questions/7926687/regular-expression-german-zip-codes
+                case 'DE':
+                    isValid = /^(?!01000|99999)(0[1-9]\d{3}|[1-9]\d{4})$/.test(value);
+                    break;
+
+                case 'DK':
+                    isValid = /^(DK(-|\s)?)?\d{4}$/i.test(value);
+                    break;
+
+                // Zip codes in Spain go from 01XXX to 52XXX.
+                // Test: http://refiddle.com/1ufo
+                case 'ES':
+                    isValid = /^(?:0[1-9]|[1-4][0-9]|5[0-2])\d{3}$/.test(value);
+                    break;
+
+                // http://en.wikipedia.org/wiki/Postal_codes_in_France
+                case 'FR':
+                    isValid = /^[0-9]{5}$/i.test(value);
+                    break;
+
+                case 'GB':
+                    isValid = this._gb(value);
+                    break;
+
+                // Indian PIN (Postal Index Number) validation
+                // http://en.wikipedia.org/wiki/Postal_Index_Number
+                // Test: http://regex101.com/r/kV0vH3/1
+                case 'IN':
+                    isValid = /^\d{3}\s?\d{3}$/.test(value);
+                    break;
+
+                // http://www.eircode.ie/docs/default-source/Common/prepare-your-business-for-eircode---published-v2.pdf?sfvrsn=2
+                // Test: http://refiddle.com/1kpl
+                case 'IE':
+                    isValid = /^(D6W|[ACDEFHKNPRTVWXY]\d{2})\s[0-9ACDEFHKNPRTVWXY]{4}$/.test(value);
+                    break;
+
+                // http://en.wikipedia.org/wiki/List_of_postal_codes_in_Italy
+                case 'IT':
+                    isValid = /^(I-|IT-)?\d{5}$/i.test(value);
+                    break;
+
+                // http://en.wikipedia.org/wiki/List_of_postal_codes_in_Morocco
+                case 'MA':
+                    isValid = /^[1-9][0-9]{4}$/i.test(value);
+                    break;
+
+                // http://en.wikipedia.org/wiki/Postal_codes_in_the_Netherlands
+                case 'NL':
+                    isValid = /^[1-9][0-9]{3} ?(?!sa|sd|ss)[a-z]{2}$/i.test(value);
+                    break;
+
+                // http://en.wikipedia.org/wiki/List_of_postal_codes_in_Poland
+                case 'PL':
+                    isValid = /^[0-9]{2}\-[0-9]{3}$/.test(value);
+                    break;
+
+                // Test: http://refiddle.com/1l2t
+                case 'PT':
+                    isValid = /^[1-9]\d{3}-\d{3}$/.test(value);
+                    break;
+
+                case 'RO':
+                    isValid = /^(0[1-8]{1}|[1-9]{1}[0-5]{1})?[0-9]{4}$/i.test(value);
+                    break;
+
+                case 'RU':
+                    isValid = /^[0-9]{6}$/i.test(value);
+                    break;
+
+                case 'SE':
+                    isValid = /^(S-)?\d{3}\s?\d{2}$/i.test(value);
+                    break;
+
+                case 'SG':
+                    isValid = /^([0][1-9]|[1-6][0-9]|[7]([0-3]|[5-9])|[8][0-2])(\d{4})$/i.test(value);
+                    break;
+
+                case 'SK':
+                    // Test: http://regexr.com/39hhr
+                    isValid = /^(\d{3})([ ]?)(\d{2})$/.test(value);
+                    break;
+
+                case 'US':
+                /* falls through */
+                default:
+                    isValid = /^\d{4,5}([\-]?\d{4})?$/.test(value);
+                    break;
+            }
+
+            return {
+                valid: isValid,
+                message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].zipCode.country, FormValidation.I18n[locale].zipCode.countries[country])
+            };
+        },
+
+        /**
+         * Validate United Kingdom postcode
+         *
+         * @see http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom
+         * @param {String} value The postcode
+         * @returns {Boolean}
+         */
+        _gb: function(value) {
+            var firstChar  = '[ABCDEFGHIJKLMNOPRSTUWYZ]',     // Does not accept QVX
+                secondChar = '[ABCDEFGHKLMNOPQRSTUVWXY]',     // Does not accept IJZ
+                thirdChar  = '[ABCDEFGHJKPMNRSTUVWXY]',
+                fourthChar = '[ABEHMNPRVWXY]',
+                fifthChar  = '[ABDEFGHJLNPQRSTUWXYZ]',
+                regexps    = [
+                    // AN NAA, ANN NAA, AAN NAA, AANN NAA format
+                    new RegExp('^(' + firstChar + '{1}' + secondChar + '?[0-9]{1,2})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
+                    // ANA NAA
+                    new RegExp('^(' + firstChar + '{1}[0-9]{1}' + thirdChar + '{1})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
+                    // AANA NAA
+                    new RegExp('^(' + firstChar + '{1}' + secondChar + '{1}?[0-9]{1}' + fourthChar + '{1})(\\s*)([0-9]{1}' + fifthChar + '{2})$', 'i'),
+
+                    new RegExp('^(BF1)(\\s*)([0-6]{1}[ABDEFGHJLNPQRST]{1}[ABDEFGHJLNPQRSTUWZYZ]{1})$', 'i'),        // BFPO postcodes
+                    /^(GIR)(\s*)(0AA)$/i,                       // Special postcode GIR 0AA
+                    /^(BFPO)(\s*)([0-9]{1,4})$/i,               // Standard BFPO numbers
+                    /^(BFPO)(\s*)(c\/o\s*[0-9]{1,3})$/i,        // c/o BFPO numbers
+                    /^([A-Z]{4})(\s*)(1ZZ)$/i,                  // Overseas Territories
+                    /^(AI-2640)$/i                              // Anguilla
+                ];
+            for (var i = 0; i < regexps.length; i++) {
+                if (regexps[i].test(value)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    };
+}(jQuery));

File diff ditekan karena terlalu besar
+ 9 - 0
static/formvalidation/js/formValidation.min.js


+ 4768 - 0
static/formvalidation/js/formValidation.popular.js

@@ -0,0 +1,4768 @@
+/*!
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ * 
+ * This is a custom build that does NOT consist of all validators. Only popular validators are included:
+ * - between
+ * - callback
+ * - choice
+ * - color
+ * - creditCard
+ * - date
+ * - different
+ * - digits
+ * - emailAddress
+ * - file
+ * - greaterThan
+ * - identical
+ * - integer
+ * - lessThan
+ * - notEmpty
+ * - numeric
+ * - promise
+ * - regexp
+ * - remote
+ * - stringLength
+ * - uri
+ *
+ * Use formValidation(.min).js file if you want to have all validators.
+ *
+ * @version     v0.8.1, built on 2016-07-29 1:10:54 AM
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+// Register the namespace
+window.FormValidation = {
+    AddOn:     {},  // Add-ons
+    Framework: {},  // Supported frameworks
+    I18n:      {},  // i18n
+    Validator: {}   // Available validators
+};
+
+if (typeof jQuery === 'undefined') {
+    throw new Error('FormValidation requires jQuery');
+}
+
+(function($) {
+    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('FormValidation requires jQuery version 1.9.1 or higher');
+    }
+}(jQuery));
+
+(function($) {
+    // TODO: Remove backward compatibility
+    /**
+     * Constructor
+     *
+     * @param {jQuery|String} form The form element or selector
+     * @param {Object} options The options
+     * @param {String} [namespace] The optional namespace which is used for data-{namespace}-xxx attributes and internal data.
+     * Currently, it's used to support backward version
+     * @constructor
+     */
+    FormValidation.Base = function(form, options, namespace) {
+        this.$form      = $(form);
+        this.options    = $.extend({}, $.fn.formValidation.DEFAULT_OPTIONS, options);
+        this._namespace = namespace || 'fv';
+
+        this.$invalidFields = $([]);    // Array of invalid fields
+        this.$submitButton  = null;     // The submit button which is clicked to submit form
+        this.$hiddenButton  = null;
+
+        // Validating status
+        this.STATUS_NOT_VALIDATED = 'NOT_VALIDATED';
+        this.STATUS_VALIDATING    = 'VALIDATING';
+        this.STATUS_INVALID       = 'INVALID';
+        this.STATUS_VALID         = 'VALID';
+        this.STATUS_IGNORED       = 'IGNORED';
+
+        // Default message
+        this.DEFAULT_MESSAGE      = $.fn.formValidation.DEFAULT_MESSAGE;
+
+        // Determine the event that is fired when user change the field value
+        // Most modern browsers supports input event except IE 7, 8.
+        // IE 9 supports input event but the event is still not fired if I press the backspace key.
+        // Get IE version
+        // https://gist.github.com/padolsey/527683/#comment-7595
+        this._ieVersion = (function() {
+            var v = 3, div = document.createElement('div'), a = div.all || [];
+            while (div.innerHTML = '<!--[if gt IE '+(++v)+']><br><![endif]-->', a[0]) {}
+            return v > 4 ? v : document.documentMode;
+        }());
+
+        var el = document.createElement('div');
+        this._changeEvent = (this._ieVersion === 9 || !('oninput' in el)) ? 'keyup' : 'input';
+
+        // The flag to indicate that the form is ready to submit when a remote/callback validator returns
+        this._submitIfValid = null;
+
+        // Field elements
+        this._cacheFields = {};
+
+        this._init();
+    };
+
+    FormValidation.Base.prototype = {
+        constructor: FormValidation.Base,
+
+        /**
+         * Check if the number of characters of field value exceed the threshold or not
+         *
+         * @param {jQuery} $field The field element
+         * @returns {Boolean}
+         */
+        _exceedThreshold: function($field) {
+            var ns        = this._namespace,
+                field     = $field.attr('data-' + ns + '-field'),
+                threshold = this.options.fields[field].threshold || this.options.threshold;
+            if (!threshold) {
+                return true;
+            }
+            var cannotType = $.inArray($field.attr('type'), ['button', 'checkbox', 'file', 'hidden', 'image', 'radio', 'reset', 'submit']) !== -1;
+            return (cannotType || $field.val().length >= threshold);
+        },
+
+        /**
+         * Init form
+         */
+        _init: function() {
+            var that    = this,
+                ns      = this._namespace,
+                options = {
+                    addOns:         {},
+                    autoFocus:      this.$form.attr('data-' + ns + '-autofocus'),
+                    button: {
+                        selector: this.$form.attr('data-' + ns + '-button-selector') || this.$form.attr('data-' + ns + '-submitbuttons'), // Support backward
+                        disabled: this.$form.attr('data-' + ns + '-button-disabled')
+                    },
+                    control: {
+                        valid:   this.$form.attr('data-' + ns + '-control-valid'),
+                        invalid: this.$form.attr('data-' + ns + '-control-invalid')
+                    },
+                    err: {
+                        clazz:     this.$form.attr('data-' + ns + '-err-clazz'),
+                        container: this.$form.attr('data-' + ns + '-err-container') || this.$form.attr('data-' + ns + '-container'), // Support backward
+                        parent:    this.$form.attr('data-' + ns + '-err-parent')
+                    },
+                    events: {
+                        formInit:         this.$form.attr('data-' + ns + '-events-form-init'),
+                        formPreValidate:  this.$form.attr('data-' + ns + '-events-form-prevalidate'),
+                        formError:        this.$form.attr('data-' + ns + '-events-form-error'),
+                        formReset:        this.$form.attr('data-' + ns + '-events-form-reset'),
+                        formSuccess:      this.$form.attr('data-' + ns + '-events-form-success'),
+                        fieldAdded:       this.$form.attr('data-' + ns + '-events-field-added'),
+                        fieldRemoved:     this.$form.attr('data-' + ns + '-events-field-removed'),
+                        fieldInit:        this.$form.attr('data-' + ns + '-events-field-init'),
+                        fieldError:       this.$form.attr('data-' + ns + '-events-field-error'),
+                        fieldReset:       this.$form.attr('data-' + ns + '-events-field-reset'),
+                        fieldSuccess:     this.$form.attr('data-' + ns + '-events-field-success'),
+                        fieldStatus:      this.$form.attr('data-' + ns + '-events-field-status'),
+                        localeChanged:    this.$form.attr('data-' + ns + '-events-locale-changed'),
+                        validatorError:   this.$form.attr('data-' + ns + '-events-validator-error'),
+                        validatorSuccess: this.$form.attr('data-' + ns + '-events-validator-success'),
+                        validatorIgnored: this.$form.attr('data-' + ns + '-events-validator-ignored')
+                    },
+                    excluded:      this.$form.attr('data-' + ns + '-excluded'),
+                    icon: {
+                        valid:      this.$form.attr('data-' + ns + '-icon-valid')      || this.$form.attr('data-' + ns + '-feedbackicons-valid'),      // Support backward
+                        invalid:    this.$form.attr('data-' + ns + '-icon-invalid')    || this.$form.attr('data-' + ns + '-feedbackicons-invalid'),    // Support backward
+                        validating: this.$form.attr('data-' + ns + '-icon-validating') || this.$form.attr('data-' + ns + '-feedbackicons-validating'), // Support backward
+                        feedback:   this.$form.attr('data-' + ns + '-icon-feedback')
+                    },
+                    live:          this.$form.attr('data-' + ns + '-live'),
+                    locale:        this.$form.attr('data-' + ns + '-locale'),
+                    message:       this.$form.attr('data-' + ns + '-message'),
+                    onPreValidate: this.$form.attr('data-' + ns + '-onprevalidate'),
+                    onError:       this.$form.attr('data-' + ns + '-onerror'),
+                    onReset:       this.$form.attr('data-' + ns + '-onreset'),
+                    onSuccess:     this.$form.attr('data-' + ns + '-onsuccess'),
+                    row: {
+                        selector: this.$form.attr('data-' + ns + '-row-selector') || this.$form.attr('data-' + ns + '-group'), // Support backward
+                        valid:    this.$form.attr('data-' + ns + '-row-valid'),
+                        invalid:  this.$form.attr('data-' + ns + '-row-invalid'),
+                        feedback: this.$form.attr('data-' + ns + '-row-feedback')
+                    },
+                    threshold:     this.$form.attr('data-' + ns + '-threshold'),
+                    trigger:       this.$form.attr('data-' + ns + '-trigger'),
+                    verbose:       this.$form.attr('data-' + ns + '-verbose'),
+                    fields:        {}
+                };
+
+            this.$form
+                // Disable client side validation in HTML 5
+                .attr('novalidate', 'novalidate')
+                .addClass(this.options.elementClass)
+                // Disable the default submission first
+                .on('submit.' + ns, function(e) {
+                    e.preventDefault();
+                    that.validate();
+                })
+                .on('click.' + ns, this.options.button.selector, function() {
+                    that.$submitButton  = $(this);
+                    // The user just click the submit button
+                    that._submitIfValid = true;
+                });
+
+            if (this.options.declarative === true || this.options.declarative === 'true') {
+                // Find all fields which have either "name" or "data-{namespace}-field" attribute
+                this.$form
+                    .find('[name], [data-' + ns + '-field]')
+                    .each(function() {
+                        var $field = $(this),
+                            field  = $field.attr('name') || $field.attr('data-' + ns + '-field'),
+                            opts   = that._parseOptions($field);
+                        if (opts) {
+                            $field.attr('data-' + ns + '-field', field);
+                            options.fields[field] = $.extend({}, opts, options.fields[field]);
+                        }
+                    });
+            }
+
+            this.options = $.extend(true, this.options, options);
+
+            // Normalize the err.parent option
+            if ('string' === typeof this.options.err.parent) {
+                this.options.err.parent = new RegExp(this.options.err.parent);
+            }
+
+            // Support backward
+            if (this.options.container) {
+                this.options.err.container = this.options.container;
+                delete this.options.container;
+            }
+            if (this.options.feedbackIcons) {
+                this.options.icon = $.extend(true, this.options.icon, this.options.feedbackIcons);
+                delete this.options.feedbackIcons;
+            }
+            if (this.options.group) {
+                this.options.row.selector = this.options.group;
+                delete this.options.group;
+            }
+            if (this.options.submitButtons) {
+                this.options.button.selector = this.options.submitButtons;
+                delete this.options.submitButtons;
+            }
+
+            // If the locale is not found, reset it to default one
+            if (!FormValidation.I18n[this.options.locale]) {
+                this.options.locale = $.fn.formValidation.DEFAULT_OPTIONS.locale;
+            }
+
+            // Parse the add-on options from HTML attributes
+            if (this.options.declarative === true || this.options.declarative === 'true') {
+                this.options = $.extend(true, this.options, { addOns: this._parseAddOnOptions() });
+            }
+
+            // When pressing Enter on any field in the form, the first submit button will do its job.
+            // The form then will be submitted.
+            // I create a first hidden submit button
+            this.$hiddenButton = $('<button/>')
+                                    .attr('type', 'submit')
+                                    .prependTo(this.$form)
+                                    .addClass('fv-hidden-submit')
+                                    .css({ display: 'none', width: 0, height: 0 });
+
+            this.$form
+                .on('click.' +  this._namespace, '[type="submit"]', function(e) {
+                    // #746: Check if the button click handler returns false
+                    if (!e.isDefaultPrevented()) {
+                        var $target = $(e.target),
+                            // The button might contain HTML tag
+                            $button = $target.is('[type="submit"]') ? $target.eq(0) : $target.parent('[type="submit"]').eq(0);
+
+                        // Don't perform validation when clicking on the submit button/input which
+                        // aren't defined by the 'button.selector' option
+                        if (that.options.button.selector && !$button.is(that.options.button.selector) && !$button.is(that.$hiddenButton)) {
+                            that.$form.off('submit.' + that._namespace).submit();
+                            // Fix the issue where 'formnovalidate' causes IE to send two postbacks to server
+                            return false;
+                        }
+                    }
+                });
+
+            for (var field in this.options.fields) {
+                this._initField(field);
+            }
+
+            // Init the add-ons
+            for (var addOn in this.options.addOns) {
+                if ('function' === typeof FormValidation.AddOn[addOn].init) {
+                    FormValidation.AddOn[addOn].init(this, this.options.addOns[addOn]);
+                }
+            }
+
+            this.$form.trigger($.Event(this.options.events.formInit), {
+                bv: this,   // Support backward
+                fv: this,
+                options: this.options
+            });
+
+            // Prepare the events
+            if (this.options.onPreValidate) {
+                this.$form.on(this.options.events.formPreValidate, function(e) {
+                    FormValidation.Helper.call(that.options.onPreValidate, [e]);
+                });
+            }
+            if (this.options.onSuccess) {
+                this.$form.on(this.options.events.formSuccess, function(e) {
+                    FormValidation.Helper.call(that.options.onSuccess, [e]);
+                });
+            }
+            if (this.options.onError) {
+                this.$form.on(this.options.events.formError, function(e) {
+                    FormValidation.Helper.call(that.options.onError, [e]);
+                });
+            }
+            if (this.options.onReset) {
+                this.$form.on(this.options.events.formReset, function(e) {
+                    FormValidation.Helper.call(that.options.onReset, [e]);
+                });
+            }
+        },
+
+        /**
+         * Init field
+         *
+         * @param {String|jQuery} field The field name or field element
+         */
+        _initField: function(field) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    fields.attr('data-' + ns + '-field', field);
+                    break;
+                default:
+                    break;
+            }
+
+            // We don't need to validate non-existing fields
+            if (fields.length === 0) {
+                return;
+            }
+
+            if (this.options.fields[field] === null || this.options.fields[field].validators === null) {
+                return;
+            }
+
+            var validators = this.options.fields[field].validators,
+                validatorName,
+                alias;
+            for (validatorName in validators) {
+                alias = validators[validatorName].alias || validatorName;
+                if (!FormValidation.Validator[alias]) {
+                    delete this.options.fields[field].validators[validatorName];
+                }
+            }
+            if (this.options.fields[field].enabled === null) {
+                this.options.fields[field].enabled = true;
+            }
+
+            var that      = this,
+                total     = fields.length,
+                type      = fields.attr('type'),
+                updateAll = (total === 1) || ('radio' === type) || ('checkbox' === type),
+                trigger   = this._getFieldTrigger(fields.eq(0)),
+                clazz     = this.options.err.clazz.split(' ').join('.'),
+                events    = $.map(trigger, function(item) {
+                    return item + '.update.' + ns;
+                }).join(' ');
+
+            for (var i = 0; i < total; i++) {
+                var $field    = fields.eq(i),
+                    row       = this.options.fields[field].row || this.options.row.selector,
+                    $parent   = $field.closest(row),
+                    // Allow user to indicate where the error messages are shown
+                    // Support backward
+                    container = ('function' === typeof (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container))
+                                ? (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container).call(this, $field, this)
+                                : (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container),
+                    $message  = (container && container !== 'tooltip' && container !== 'popover') ? $(container) : this._getMessageContainer($field, row);
+
+                if (container && container !== 'tooltip' && container !== 'popover') {
+                    $message.addClass(this.options.err.clazz);
+                }
+
+                // Remove all error messages and feedback icons
+                $message.find('.' + clazz + '[data-' + ns + '-validator][data-' + ns + '-for="' + field + '"]').remove();
+                $parent.find('i[data-' + ns + '-icon-for="' + field + '"]').remove();
+
+                // Whenever the user change the field value, mark it as not validated yet
+                $field.off(events).on(events, function() {
+                    that.updateStatus($(this), that.STATUS_NOT_VALIDATED);
+                });
+
+                // Create help block elements for showing the error messages
+                $field.data(ns + '.messages', $message);
+                for (validatorName in validators) {
+                    $field.data(ns + '.result.' + validatorName, this.STATUS_NOT_VALIDATED);
+
+                    if (!updateAll || i === total - 1) {
+                        $('<small/>')
+                            .css('display', 'none')
+                            .addClass(this.options.err.clazz)
+                            .attr('data-' + ns + '-validator', validatorName)
+                            .attr('data-' + ns + '-for', field)
+                            .attr('data-' + ns + '-result', this.STATUS_NOT_VALIDATED)
+                            .html(this._getMessage(field, validatorName))
+                            .appendTo($message);
+                    }
+
+                    // Init the validator
+                    alias = validators[validatorName].alias || validatorName;
+                    if ('function' === typeof FormValidation.Validator[alias].init) {
+                        FormValidation.Validator[alias].init(this, $field, this.options.fields[field].validators[validatorName], validatorName);
+                    }
+                }
+
+                // Prepare the feedback icons
+                if (this.options.fields[field].icon !== false && this.options.fields[field].icon !== 'false'
+                    && this.options.icon
+                    && this.options.icon.valid && this.options.icon.invalid && this.options.icon.validating
+                    && (!updateAll || i === total - 1))
+                {
+                    // $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid).addClass(this.options.row.feedback);
+                    // Keep error messages which are populated from back-end
+                    $parent.addClass(this.options.row.feedback);
+                    var $icon = $('<i/>')
+                                    .css('display', 'none')
+                                    .addClass(this.options.icon.feedback)
+                                    .attr('data-' + ns + '-icon-for', field)
+                                    .insertAfter($field);
+
+                    // Store the icon as a data of field element
+                    (!updateAll ? $field : fields).data(ns + '.icon', $icon);
+
+                    if ('tooltip' === container || 'popover' === container) {
+                        (!updateAll ? $field : fields)
+                            .on(this.options.events.fieldError, function() {
+                                $parent.addClass('fv-has-tooltip');
+                            })
+                            .on(this.options.events.fieldSuccess, function() {
+                                $parent.removeClass('fv-has-tooltip');
+                            });
+
+                        $field
+                            // Show tooltip/popover message when field gets focus
+                            .off('focus.container.' + ns)
+                            .on('focus.container.' + ns, function() {
+                                that._showTooltip($(this), container);
+                            })
+                            // and hide them when losing focus
+                            .off('blur.container.' + ns)
+                            .on('blur.container.' + ns, function() {
+                                that._hideTooltip($(this), container);
+                            });
+                    }
+
+                    if ('string' === typeof this.options.fields[field].icon && this.options.fields[field].icon !== 'true') {
+                        $icon.appendTo($(this.options.fields[field].icon));
+                    } else {
+                        this._fixIcon($field, $icon);
+                    }
+                }
+            }
+
+            // Sort the validators by priority
+            var sortedByPriority = [];
+            for (validatorName in validators) {
+                alias = validators[validatorName].alias || validatorName;
+
+                // Determine the priority
+                validators[validatorName].priority = parseInt(validators[validatorName].priority
+                                                            || FormValidation.Validator[alias].priority
+                                                            || 1, 10);
+                sortedByPriority.push({
+                    validator: validatorName,
+                    priority: validators[validatorName].priority
+                });
+            }
+            sortedByPriority = sortedByPriority.sort(function(a, b) {
+                return a.priority - b.priority;
+            });
+
+            // Prepare the events
+            fields
+                .data(ns + '.validators', sortedByPriority)
+                .on(this.options.events.fieldSuccess, function(e, data) {
+                    var onSuccess = that.getOptions(data.field, null, 'onSuccess');
+                    if (onSuccess) {
+                        FormValidation.Helper.call(onSuccess, [e, data]);
+                    }
+                })
+                .on(this.options.events.fieldError, function(e, data) {
+                    var onError = that.getOptions(data.field, null, 'onError');
+                    if (onError) {
+                        FormValidation.Helper.call(onError, [e, data]);
+                    }
+                })
+                .on(this.options.events.fieldReset, function(e, data) {
+                    var onReset = that.getOptions(data.field, null, 'onReset');
+                    if (onReset) {
+                        FormValidation.Helper.call(onReset, [e, data]);
+                    }
+                })
+                .on(this.options.events.fieldStatus, function(e, data) {
+                    var onStatus = that.getOptions(data.field, null, 'onStatus');
+                    if (onStatus) {
+                        FormValidation.Helper.call(onStatus, [e, data]);
+                    }
+                })
+                .on(this.options.events.validatorError, function(e, data) {
+                    var onError = that.getOptions(data.field, data.validator, 'onError');
+                    if (onError) {
+                        FormValidation.Helper.call(onError, [e, data]);
+                    }
+                })
+                .on(this.options.events.validatorIgnored, function(e, data) {
+                    var onIgnored = that.getOptions(data.field, data.validator, 'onIgnored');
+                    if (onIgnored) {
+                        FormValidation.Helper.call(onIgnored, [e, data]);
+                    }
+                })
+                .on(this.options.events.validatorSuccess, function(e, data) {
+                    var onSuccess = that.getOptions(data.field, data.validator, 'onSuccess');
+                    if (onSuccess) {
+                        FormValidation.Helper.call(onSuccess, [e, data]);
+                    }
+                });
+
+            // Set live mode
+            this.onLiveChange(fields, 'live', function() {
+                if (that._exceedThreshold($(this))) {
+                    that.validateField($(this));
+                }
+            });
+
+            fields.trigger($.Event(this.options.events.fieldInit), {
+                bv: this,   // Support backward
+                fv: this,
+                field: field,
+                element: fields
+            });
+        },
+
+        /**
+         * Check if the field is excluded.
+         * Returning true means that the field will not be validated
+         *
+         * @param {jQuery} $field The field element
+         * @returns {Boolean}
+         */
+        _isExcluded: function($field) {
+            var ns           = this._namespace,
+                excludedAttr = $field.attr('data-' + ns + '-excluded'),
+                // I still need to check the 'name' attribute while initializing the field
+                field        = $field.attr('data-' + ns + '-field') || $field.attr('name');
+
+            switch (true) {
+                case (!!field && this.options.fields && this.options.fields[field] && (this.options.fields[field].excluded === 'true' || this.options.fields[field].excluded === true)):
+                case (excludedAttr === 'true'):
+                case (excludedAttr === ''):
+                    return true;
+
+                case (!!field && this.options.fields && this.options.fields[field] && (this.options.fields[field].excluded === 'false' || this.options.fields[field].excluded === false)):
+                case (excludedAttr === 'false'):
+                    return false;
+
+                case (!!field && this.options.fields && this.options.fields[field] && 'function' === typeof this.options.fields[field].excluded):
+                    return this.options.fields[field].excluded.call(this, $field, this);
+
+                case (!!field && this.options.fields && this.options.fields[field] && 'string' === typeof this.options.fields[field].excluded):
+                case (excludedAttr):
+                    return FormValidation.Helper.call(this.options.fields[field].excluded, [$field, this]);
+
+                default:
+                    if (this.options.excluded) {
+                        // Convert to array first
+                        if ('string' === typeof this.options.excluded) {
+                            this.options.excluded = $.map(this.options.excluded.split(','), function(item) {
+                                // Trim the spaces
+                                return $.trim(item);
+                            });
+                        }
+
+                        var length = this.options.excluded.length;
+                        for (var i = 0; i < length; i++) {
+                            if (('string' === typeof this.options.excluded[i] && $field.is(this.options.excluded[i]))
+                                || ('function' === typeof this.options.excluded[i] && this.options.excluded[i].call(this, $field, this) === true))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                    return false;
+            }
+        },
+
+        /**
+         * Get a field changed trigger event
+         *
+         * @param {jQuery} $field The field element
+         * @returns {String[]} The event names triggered on field change
+         */
+        _getFieldTrigger: function($field) {
+            var ns      = this._namespace,
+                trigger = $field.data(ns + '.trigger');
+            if (trigger) {
+                return trigger;
+            }
+
+            // IE10/11 auto fires input event of elements using the placeholder attribute
+            // https://connect.microsoft.com/IE/feedback/details/856700/
+            var type  = $field.attr('type'),
+                name  = $field.attr('data-' + ns + '-field'),
+                event = ('radio' === type || 'checkbox' === type || 'file' === type || 'SELECT' === $field.get(0).tagName)
+                        ? 'change'
+                        : (this._ieVersion >= 10 && $field.attr('placeholder') ? 'keyup' : this._changeEvent);
+            trigger   = ((this.options.fields[name] ? this.options.fields[name].trigger : null) || this.options.trigger || event).split(' ');
+
+            // Since the trigger data is used many times, I need to cache it to use later
+            $field.data(ns + '.trigger', trigger);
+
+            return trigger;
+        },
+
+        /**
+         * Get the error message for given field and validator
+         *
+         * @param {String} field The field name
+         * @param {String} validatorName The validator name
+         * @returns {String}
+         */
+        _getMessage: function(field, validatorName) {
+            if (!this.options.fields[field] || !this.options.fields[field].validators) {
+                return '';
+            }
+            var validators = this.options.fields[field].validators,
+                alias      = (validators[validatorName] && validators[validatorName].alias) ? validators[validatorName].alias : validatorName;
+            if (!FormValidation.Validator[alias]) {
+                return '';
+            }
+
+            switch (true) {
+                case !!validators[validatorName].message:
+                    return validators[validatorName].message;
+                case !!this.options.fields[field].message:
+                    return this.options.fields[field].message;
+                case !!this.options.message:
+                    return this.options.message;
+                case (!!FormValidation.I18n[this.options.locale] && !!FormValidation.I18n[this.options.locale][alias] && !!FormValidation.I18n[this.options.locale][alias]['default']):
+                    return FormValidation.I18n[this.options.locale][alias]['default'];
+                default:
+                    return this.DEFAULT_MESSAGE;
+            }
+        },
+
+        /**
+         * Get the element to place the error messages
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} row
+         * @returns {jQuery}
+         */
+        _getMessageContainer: function($field, row) {
+            if (!this.options.err.parent) {
+                throw new Error('The err.parent option is not defined');
+            }
+
+            var $parent = $field.parent();
+            if ($parent.is(row)) {
+                return $parent;
+            }
+
+            var cssClasses = $parent.attr('class');
+            if (!cssClasses) {
+                return this._getMessageContainer($parent, row);
+            }
+
+            if (this.options.err.parent.test(cssClasses)) {
+                return $parent;
+            }
+
+            return this._getMessageContainer($parent, row);
+        },
+
+        /**
+         * Parse the add-on options from HTML attributes
+         *
+         * @returns {Object}
+         */
+        _parseAddOnOptions: function() {
+            var ns     = this._namespace,
+                names  = this.$form.attr('data-' + ns + '-addons'),
+                addOns = this.options.addOns || {};
+
+            if (names) {
+                names = names.replace(/\s/g, '').split(',');
+                for (var i = 0; i < names.length; i++) {
+                    if (!addOns[names[i]]) {
+                        addOns[names[i]] = {};
+                    }
+                }
+            }
+
+            // Try to parse each add-on options
+            var addOn, attrMap, attr, option;
+            for (addOn in addOns) {
+                if (!FormValidation.AddOn[addOn]) {
+                    // Add-on is not found
+                    delete addOns[addOn];
+                    continue;
+                }
+
+                attrMap = FormValidation.AddOn[addOn].html5Attributes;
+                if (attrMap) {
+                    for (attr in attrMap) {
+                        option = this.$form.attr('data-' + ns + '-addons-' + addOn.toLowerCase() + '-' + attr.toLowerCase());
+                        if (option) {
+                            addOns[addOn][attrMap[attr]] = option;
+                        }
+                    }
+                }
+            }
+
+            return addOns;
+        },
+
+        /**
+         * Parse the validator options from HTML attributes
+         *
+         * @param {jQuery} $field The field element
+         * @returns {Object}
+         */
+        _parseOptions: function($field) {
+            var ns           = this._namespace,
+                field        = $field.attr('name') || $field.attr('data-' + ns + '-field'),
+                validators   = {},
+                aliasAttr    = new RegExp('^data-' + ns + '-([a-z]+)-alias$'),
+                validatorSet = $.extend({}, FormValidation.Validator),
+                validator,
+                v,          // Validator name
+                attrName,
+                enabled,
+                optionName,
+                optionAttrName,
+                optionValue,
+                html5AttrName,
+                html5AttrMap;
+
+            // Determine whether the alias validator is used by checking the data-fv-validator-alias attribute
+            $.each($field.get(0).attributes, function(i, attribute) {
+                if (attribute.value && aliasAttr.test(attribute.name)) {
+                    v = attribute.name.split('-')[2];
+                    if (validatorSet[attribute.value]) {
+                        validatorSet[v]       = validatorSet[attribute.value];
+                        validatorSet[v].alias = attribute.value;
+                    }
+                }
+            });
+
+            for (v in validatorSet) {
+                validator    = validatorSet[v];
+                attrName     = 'data-' + ns + '-' + v.toLowerCase(),
+                enabled      = $field.attr(attrName) + '';
+                html5AttrMap = ('function' === typeof validator.enableByHtml5) ? validator.enableByHtml5($field) : null;
+
+                if ((html5AttrMap && enabled !== 'false')
+                    || (html5AttrMap !== true && ('' === enabled || 'true' === enabled || attrName === enabled.toLowerCase())))
+                {
+                    // Try to parse the options via attributes
+                    validator.html5Attributes = $.extend({}, {
+                                                    message: 'message',
+                                                    onerror: 'onError',
+                                                    onreset: 'onReset',
+                                                    onsuccess: 'onSuccess',
+                                                    priority: 'priority',
+                                                    transformer: 'transformer'
+                                                }, validator.html5Attributes);
+                    validators[v] = $.extend({}, html5AttrMap === true ? {} : html5AttrMap, validators[v]);
+                    if (validator.alias) {
+                        validators[v].alias = validator.alias;
+                    }
+
+                    for (html5AttrName in validator.html5Attributes) {
+                        optionName     = validator.html5Attributes[html5AttrName];
+                        optionAttrName = 'data-' + ns + '-' + v.toLowerCase() + '-' + html5AttrName;
+                        optionValue    = $field.attr(optionAttrName);
+                        if (optionValue) {
+                            if ('true' === optionValue || optionAttrName === optionValue.toLowerCase()) {
+                                optionValue = true;
+                            } else if ('false' === optionValue) {
+                                optionValue = false;
+                            }
+                            validators[v][optionName] = optionValue;
+                        }
+                    }
+                }
+            }
+
+            var opts = {
+                    autoFocus:   $field.attr('data-' + ns + '-autofocus'),
+                    err:         $field.attr('data-' + ns + '-err-container') || $field.attr('data-' + ns + '-container'), // Support backward
+                    enabled:     $field.attr('data-' + ns + '-enabled'),
+                    excluded:    $field.attr('data-' + ns + '-excluded'),
+                    icon:        $field.attr('data-' + ns + '-icon') || $field.attr('data-' + ns + '-feedbackicons') || (this.options.fields && this.options.fields[field] ? this.options.fields[field].feedbackIcons : null), // Support backward
+                    message:     $field.attr('data-' + ns + '-message'),
+                    onError:     $field.attr('data-' + ns + '-onerror'),
+                    onReset:     $field.attr('data-' + ns + '-onreset'),
+                    onStatus:    $field.attr('data-' + ns + '-onstatus'),
+                    onSuccess:   $field.attr('data-' + ns + '-onsuccess'),
+                    row:         $field.attr('data-' + ns + '-row') || $field.attr('data-' + ns + '-group') || (this.options.fields && this.options.fields[field] ? this.options.fields[field].group : null), // Support backward
+                    selector:    $field.attr('data-' + ns + '-selector'),
+                    threshold:   $field.attr('data-' + ns + '-threshold'),
+                    transformer: $field.attr('data-' + ns + '-transformer'),
+                    trigger:     $field.attr('data-' + ns + '-trigger'),
+                    verbose:     $field.attr('data-' + ns + '-verbose'),
+                    validators:  validators
+                },
+                emptyOptions    = $.isEmptyObject(opts),        // Check if the field options are set using HTML attributes
+                emptyValidators = $.isEmptyObject(validators);  // Check if the field validators are set using HTML attributes
+
+            if (!emptyValidators || (!emptyOptions && this.options.fields && this.options.fields[field])) {
+                //opts.validators = validators;
+                return opts;
+            } else {
+                return null;
+            }
+        },
+
+        /**
+         * Called when all validations are completed
+         */
+        _submit: function() {
+            var isValid = this.isValid();
+            if (isValid === null) {
+                return;
+            }
+
+            var eventType = isValid ? this.options.events.formSuccess : this.options.events.formError,
+                e         = $.Event(eventType);
+
+            this.$form.trigger(e);
+
+            // Call default handler
+            // Check if whether the submit button is clicked
+            if (this.$submitButton) {
+                isValid ? this._onSuccess(e) : this._onError(e);
+            }
+        },
+
+        // ~~~~~~
+        // Events
+        // ~~~~~~
+
+        /**
+         * The default handler of error.form.fv event.
+         * It will be called when there is a invalid field
+         *
+         * @param {jQuery.Event} e The jQuery event object
+         */
+        _onError: function(e) {
+            if (e.isDefaultPrevented()) {
+                return;
+            }
+
+            if ('submitted' === this.options.live) {
+                // Enable live mode
+                this.options.live = 'enabled';
+
+                var that = this;
+                for (var field in this.options.fields) {
+                    (function(f) {
+                        var fields  = that.getFieldElements(f);
+                        if (fields.length) {
+                            that.onLiveChange(fields, 'live', function() {
+                                if (that._exceedThreshold($(this))) {
+                                    that.validateField($(this));
+                                }
+                            });
+                        }
+                    })(field);
+                }
+            }
+
+            // Determined the first invalid field which will be focused on automatically
+            var ns = this._namespace;
+            for (var i = 0; i < this.$invalidFields.length; i++) {
+                var $field    = this.$invalidFields.eq(i),
+                    autoFocus = this.isOptionEnabled($field.attr('data-' + ns + '-field'), 'autoFocus');
+                if (autoFocus) {
+                    // Focus the field
+                    $field.focus();
+                    break;
+                }
+            }
+        },
+
+        /**
+         * Called after validating a field element
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} [validatorName] The validator name
+         */
+        _onFieldValidated: function($field, validatorName) {
+            var ns            = this._namespace,
+                field         = $field.attr('data-' + ns + '-field'),
+                validators    = this.options.fields[field].validators,
+                counter       = {},
+                numValidators = 0,
+                data          = {
+                    bv: this,   // Support backward
+                    fv: this,
+                    field: field,
+                    element: $field,
+                    validator: validatorName,
+                    result: $field.data(ns + '.response.' + validatorName)
+                };
+
+            // Trigger an event after given validator completes
+            if (validatorName) {
+                switch ($field.data(ns + '.result.' + validatorName)) {
+                    case this.STATUS_INVALID:
+                        $field.trigger($.Event(this.options.events.validatorError), data);
+                        break;
+                    case this.STATUS_VALID:
+                        $field.trigger($.Event(this.options.events.validatorSuccess), data);
+                        break;
+                    case this.STATUS_IGNORED:
+                        $field.trigger($.Event(this.options.events.validatorIgnored), data);
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            counter[this.STATUS_NOT_VALIDATED] = 0;
+            counter[this.STATUS_VALIDATING]    = 0;
+            counter[this.STATUS_INVALID]       = 0;
+            counter[this.STATUS_VALID]         = 0;
+            counter[this.STATUS_IGNORED]       = 0;
+
+            for (var v in validators) {
+                if (validators[v].enabled === false) {
+                    continue;
+                }
+
+                numValidators++;
+                var result = $field.data(ns + '.result.' + v);
+                if (result) {
+                    counter[result]++;
+                }
+            }
+
+            // The sum of valid fields now also include ignored fields
+            if (counter[this.STATUS_VALID] + counter[this.STATUS_IGNORED] === numValidators) {
+                // Remove from the list of invalid fields
+                this.$invalidFields = this.$invalidFields.not($field);
+
+                $field.trigger($.Event(this.options.events.fieldSuccess), data);
+            }
+            // If all validators are completed and there is at least one validator which doesn't pass
+            else if ((counter[this.STATUS_NOT_VALIDATED] === 0 || !this.isOptionEnabled(field, 'verbose')) && counter[this.STATUS_VALIDATING] === 0 && counter[this.STATUS_INVALID] > 0) {
+                // Add to the list of invalid fields
+                this.$invalidFields = this.$invalidFields.add($field);
+
+                $field.trigger($.Event(this.options.events.fieldError), data);
+            }
+        },
+
+        /**
+         * The default handler of success.form.fv event.
+         * It will be called when all the fields are valid
+         *
+         * @param {jQuery.Event} e The jQuery event object
+         */
+        _onSuccess: function(e) {
+            if (e.isDefaultPrevented()) {
+                return;
+            }
+
+            // Submit the form
+            this.disableSubmitButtons(true).defaultSubmit();
+        },
+
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        // Abstract methods
+        // Need to be implemented by sub-class that supports specific framework
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+        },
+
+        /**
+         * Create a tooltip or popover
+         * It will be shown when focusing on the field
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} message The message
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _createTooltip: function($field, message, type) {
+        },
+
+        /**
+         * Destroy the tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _destroyTooltip: function($field, type) {
+        },
+
+        /**
+         * Hide a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _hideTooltip: function($field, type) {
+        },
+
+        /**
+         * Show a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _showTooltip: function($field, type) {
+        },
+
+        // ~~~~~~~~~~~~~~
+        // Public methods
+        // ~~~~~~~~~~~~~~
+
+        /**
+         * Submit the form using default submission.
+         * It also does not perform any validations when submitting the form
+         */
+        defaultSubmit: function() {
+            var ns = this._namespace;
+            if (this.$submitButton) {
+                // Create hidden input to send the submit buttons
+                $('<input/>')
+                    .attr({
+                        'type': 'hidden',
+                        name: this.$submitButton.attr('name')
+                    })
+                    .attr('data-' + ns + '-submit-hidden', '')
+                    .val(this.$submitButton.val())
+                    .appendTo(this.$form);
+            }
+
+            // Submit form
+            this.$form.off('submit.' + ns).submit();
+        },
+
+        /**
+         * Disable/enable submit buttons
+         *
+         * @param {Boolean} disabled Can be true or false
+         * @returns {FormValidation.Base}
+         */
+        disableSubmitButtons: function(disabled) {
+            if (!disabled) {
+                this.$form
+                    .find(this.options.button.selector)
+                        .removeAttr('disabled')
+                        .removeClass(this.options.button.disabled);
+            } else if (this.options.live !== 'disabled') {
+                // Don't disable if the live validating mode is disabled
+                this.$form
+                    .find(this.options.button.selector)
+                        .attr('disabled', 'disabled')
+                        .addClass(this.options.button.disabled);
+            }
+
+            return this;
+        },
+
+        /**
+         * Retrieve the field elements by given name
+         *
+         * @param {String} field The field name
+         * @returns {null|jQuery[]}
+         */
+        getFieldElements: function(field) {
+            if (!this._cacheFields[field]) {
+                if (this.options.fields[field] && this.options.fields[field].selector) {
+                    // Look for the field inside the form first
+                    var f = this.$form.find(this.options.fields[field].selector);
+                    // If not found, search in entire document
+                    this._cacheFields[field] = f.length ? f : $(this.options.fields[field].selector);
+                } else {
+                    this._cacheFields[field] = this.$form.find('[name="' + field + '"]');
+                }
+            }
+
+            return this._cacheFields[field];
+        },
+
+        /**
+         * Get the field value after applying transformer
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} validatorName The validator name
+         * @returns {String}
+         */
+        getFieldValue: function(field, validatorName) {
+            var $field, ns = this._namespace;
+            if ('string' === typeof field) {
+                $field = this.getFieldElements(field);
+                if ($field.length === 0) {
+                    return null;
+                }
+            } else {
+                $field = field;
+                field  = $field.attr('data-' + ns + '-field');
+            }
+
+            if (!field || !this.options.fields[field]) {
+                return $field.val();
+            }
+
+            var transformer = (this.options.fields[field].validators && this.options.fields[field].validators[validatorName]
+                                ? this.options.fields[field].validators[validatorName].transformer : null)
+                                || this.options.fields[field].transformer;
+            return transformer ? FormValidation.Helper.call(transformer, [$field, validatorName, this]) : $field.val();
+        },
+
+        /**
+         * Get the namespace
+         *
+         * @returns {String}
+         */
+        getNamespace: function() {
+            return this._namespace;
+        },
+
+        /**
+         * Get the field options
+         *
+         * @param {String|jQuery} [field] The field name or field element. If it is not set, the method returns the form options
+         * @param {String} [validator] The name of validator. It null, the method returns form options
+         * @param {String} [option] The option name
+         * @return {String|Object}
+         */
+        getOptions: function(field, validator, option) {
+            var ns = this._namespace;
+            if (!field) {
+                return option ? this.options[option] : this.options;
+            }
+            if ('object' === typeof field) {
+                field = field.attr('data-' + ns + '-field');
+            }
+            if (!this.options.fields[field]) {
+                return null;
+            }
+
+            var options = this.options.fields[field];
+            if (!validator) {
+                return option ? options[option] : options;
+            }
+            if (!options.validators || !options.validators[validator]) {
+                return null;
+            }
+
+            return option ? options.validators[validator][option] : options.validators[validator];
+        },
+
+        /**
+         * Get the validating result of field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} validatorName The validator name
+         * @returns {String} The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID', 'VALID' or 'IGNORED'
+         */
+        getStatus: function(field, validatorName) {
+            var ns = this._namespace;
+            switch (typeof field) {
+                case 'object':
+                    return field.data(ns + '.result.' + validatorName);
+                case 'string':
+                /* falls through */
+                default:
+                    return this.getFieldElements(field).eq(0).data(ns + '.result.' + validatorName);
+            }
+        },
+
+        /**
+         * Check whether or not a field option is enabled
+         *
+         * @param {String} field The field name
+         * @param {String} option The option name, "verbose", "autoFocus", for example
+         * @returns {Boolean}
+         */
+        isOptionEnabled: function(field, option) {
+            if (this.options.fields[field] && (this.options.fields[field][option] === 'true' || this.options.fields[field][option] === true)) {
+                return true;
+            }
+            if (this.options.fields[field] && (this.options.fields[field][option] === 'false' || this.options.fields[field][option] === false)) {
+                return false;
+            }
+            return this.options[option] === 'true' || this.options[option] === true;
+        },
+
+        /**
+         * Check the form validity
+         *
+         * @returns {Boolean|null} Returns one of three values
+         * - true, if all fields are valid
+         * - false, if there is one invalid field
+         * - null, if there is at least one field which is not validated yet or being validated
+         */
+        isValid: function() {
+            for (var field in this.options.fields) {
+                var isValidField = this.isValidField(field);
+                if (isValidField === null) {
+                    return null;
+                }
+                if (isValidField === false) {
+                    return false;
+                }
+            }
+
+            return true;
+        },
+
+        /**
+         * Check if all fields inside a given container are valid.
+         * It's useful when working with a wizard-like such as tab, collapse
+         *
+         * @param {String|jQuery} container The container selector or element
+         * @returns {Boolean|null} Returns one of three values
+         * - true, if all fields inside the container are valid
+         * - false, if there is one invalid field inside the container
+         * - null, if the container consists of at least one field which is not validated yet or being validated
+         */
+        isValidContainer: function(container) {
+            var that       = this,
+                ns         = this._namespace,
+                fields     = [],
+                $container = ('string' === typeof container) ? $(container) : container;
+            if ($container.length === 0) {
+                return true;
+            }
+
+            $container.find('[data-' + ns + '-field]').each(function() {
+                var $field = $(this);
+                if (!that._isExcluded($field)) {
+                    fields.push($field);
+                }
+            });
+
+            var total = fields.length,
+                clazz = this.options.err.clazz.split(' ').join('.');
+            for (var i = 0; i < total; i++) {
+                var $f      = fields[i],
+                    field   = $f.attr('data-' + ns + '-field'),
+                    $errors = $f.data(ns + '.messages')
+                                .find('.' + clazz + '[data-' + ns + '-validator][data-' + ns + '-for="' + field + '"]');
+
+                if (this.options.fields && this.options.fields[field]
+                    && (this.options.fields[field].enabled === 'false' || this.options.fields[field].enabled === false))
+                {
+                    continue;
+                }
+
+                if ($errors.filter('[data-' + ns + '-result="' + this.STATUS_INVALID + '"]').length > 0) {
+                    return false;
+                }
+
+                // If the field is not validated
+                if ($errors.filter('[data-' + ns + '-result="' + this.STATUS_NOT_VALIDATED + '"]').length > 0
+                    || $errors.filter('[data-' + ns + '-result="' + this.STATUS_VALIDATING + '"]').length > 0)
+                {
+                    return null;
+                }
+            }
+
+            return true;
+        },
+
+        /**
+         * Check if the field is valid or not
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @returns {Boolean|null} Returns one of three values
+         * - true, if the field passes all validators
+         * - false, if the field doesn't pass any validator
+         * - null, if there is at least one validator which isn't validated yet or being validated
+         */
+        isValidField: function(field) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+            if (fields.length === 0 || !this.options.fields[field]
+                || this.options.fields[field].enabled === 'false' || this.options.fields[field].enabled === false)
+            {
+                return true;
+            }
+
+            var type  = fields.attr('type'),
+                total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length,
+                $field, validatorName, status;
+            for (var i = 0; i < total; i++) {
+                $field = fields.eq(i);
+                if (this._isExcluded($field)) {
+                    continue;
+                }
+
+                for (validatorName in this.options.fields[field].validators) {
+                    if (this.options.fields[field].validators[validatorName].enabled === false) {
+                        continue;
+                    }
+
+                    status = $field.data(ns + '.result.' + validatorName);
+                    if (status === this.STATUS_VALIDATING || status === this.STATUS_NOT_VALIDATED) {
+                        return null;
+                    } else if (status === this.STATUS_INVALID) {
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        },
+
+        /**
+         * Detach a handler function for a field live change event
+         *
+         * @param {jQuery[]} $fields The field elements
+         * @param {String} namespace The event namespace
+         * @returns {FormValidation.Base}
+         */
+        offLiveChange: function($fields, namespace) {
+            if ($fields === null || $fields.length === 0) {
+                return this;
+            }
+
+            var ns      = this._namespace,
+                trigger = this._getFieldTrigger($fields.eq(0)),
+                events  = $.map(trigger, function(item) {
+                    return item + '.' + namespace + '.' + ns;
+                }).join(' ');
+
+            $fields.off(events);
+            return this;
+        },
+
+        /**
+         * Attach a handler function for a field live change event
+         *
+         * @param {jQuery[]} $fields The field elements
+         * @param {String} namespace The event namespace
+         * @param {Function} handler The handler function
+         * @returns {FormValidation.Base}
+         */
+        onLiveChange: function($fields, namespace, handler) {
+            if ($fields === null || $fields.length === 0) {
+                return this;
+            }
+
+            var ns      = this._namespace,
+                trigger = this._getFieldTrigger($fields.eq(0)),
+                events  = $.map(trigger, function(item) {
+                    return item + '.' + namespace + '.' + ns;
+                }).join(' ');
+
+            switch (this.options.live) {
+                case 'submitted':
+                    break;
+                case 'disabled':
+                    $fields.off(events);
+                    break;
+                case 'enabled':
+                /* falls through */
+                default:
+                    $fields.off(events).on(events, function(e) {
+                        handler.apply(this, arguments);
+                    });
+                    break;
+            }
+
+            return this;
+        },
+
+        /**
+         * Update the error message
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} validator The validator name
+         * @param {String} message The message
+         * @returns {FormValidation.Base}
+         */
+        updateMessage: function(field, validator, message) {
+            var ns      = this._namespace,
+                $fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    $fields = field;
+                    field   = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    $fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            var clazz = this.options.err.clazz.split(' ').join('.');
+            $fields.each(function() {
+                $(this)
+                    .data(ns + '.messages')
+                    .find('.' + clazz + '[data-' + ns + '-validator="' + validator + '"][data-' + ns + '-for="' + field + '"]').html(message);
+            });
+
+            return this;
+        },
+
+        /**
+         * Update all validating results of field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} status The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID', 'VALID' or 'IGNORED'
+         * @param {String} [validatorName] The validator name. If null, the method updates validity result for all validators
+         * @returns {FormValidation.Base}
+         */
+        updateStatus: function(field, status, validatorName) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            if (!field || !this.options.fields[field]) {
+                return this;
+            }
+
+            if (status === this.STATUS_NOT_VALIDATED) {
+                // Reset the flag
+                // To prevent the form from doing submit when a deferred validator returns true while typing
+                this._submitIfValid = false;
+            }
+
+            var that  = this,
+                type  = fields.attr('type'),
+                row   = this.options.fields[field].row || this.options.row.selector,
+                total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length,
+                clazz = this.options.err.clazz.split(' ').join('.');
+
+            for (var i = 0; i < total; i++) {
+                var $field       = fields.eq(i);
+                if (this._isExcluded($field)) {
+                    continue;
+                }
+
+                var $parent      = $field.closest(row),
+                    $message     = $field.data(ns + '.messages'),
+                    $allErrors   = $message.find('.' + clazz + '[data-' + ns + '-validator][data-' + ns + '-for="' + field + '"]'),
+                    $errors      = validatorName ? $allErrors.filter('[data-' + ns + '-validator="' + validatorName + '"]') : $allErrors,
+                    $icon        = $field.data(ns + '.icon'),
+                    // Support backward
+                    container    = ('function' === typeof (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container))
+                                    ? (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container).call(this, $field, this)
+                                    : (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container),
+                    isValidField = null,
+                    isValidating,
+                    isNotValidated;
+
+                // Update status
+                if (validatorName) {
+                    $field.data(ns + '.result.' + validatorName, status);
+                } else {
+                    for (var v in this.options.fields[field].validators) {
+                        $field.data(ns + '.result.' + v, status);
+                    }
+                }
+
+                // Show/hide error elements and feedback icons
+                $errors.attr('data-' + ns + '-result', status);
+
+                switch (status) {
+                    case this.STATUS_VALIDATING:
+                        isValidField = null;
+                        this.disableSubmitButtons(true);
+                        $field.removeClass(this.options.control.valid).removeClass(this.options.control.invalid);
+                        $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid);
+                        if ($icon) {
+                            $icon.removeClass(this.options.icon.valid).removeClass(this.options.icon.invalid).addClass(this.options.icon.validating).show();
+                        }
+                        break;
+
+                    case this.STATUS_INVALID:
+                        isValidField = false;
+                        this.disableSubmitButtons(true);
+                        $field.removeClass(this.options.control.valid).addClass(this.options.control.invalid);
+                        $parent.removeClass(this.options.row.valid).addClass(this.options.row.invalid);
+                        if ($icon) {
+                            $icon.removeClass(this.options.icon.valid).removeClass(this.options.icon.validating).addClass(this.options.icon.invalid).show();
+                        }
+                        break;
+
+                    case this.STATUS_IGNORED:       // Treat ignored fields like they are valid with some specialties
+                    case this.STATUS_VALID:
+                        isValidating   = ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_VALIDATING +'"]').length > 0);
+                        isNotValidated = ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_NOT_VALIDATED +'"]').length > 0);
+
+                        var numIgnored = $allErrors.filter('[data-' + ns + '-result="' + this.STATUS_IGNORED +'"]').length;
+
+                        // If the field is valid (passes all validators)
+                        isValidField   = (isValidating || isNotValidated)     // There are some validators that have not done
+                                        ? null
+                                        // All validators are completed
+                                        : ($allErrors.filter('[data-' + ns + '-result="' + this.STATUS_VALID +'"]').length + numIgnored === $allErrors.length);
+
+                        $field.removeClass(this.options.control.valid).removeClass(this.options.control.invalid);
+
+                        if (isValidField === true) {
+                            this.disableSubmitButtons(this.isValid() === false);
+                            if (status === this.STATUS_VALID) {
+                                $field.addClass(this.options.control.valid);
+                            }
+                        } else if (isValidField === false) {
+                            this.disableSubmitButtons(true);
+                            if (status === this.STATUS_VALID) {
+                                $field.addClass(this.options.control.invalid);
+                            }
+                        }
+
+                        if ($icon) {
+                            $icon.removeClass(this.options.icon.invalid).removeClass(this.options.icon.validating).removeClass(this.options.icon.valid);
+                            if (status === this.STATUS_VALID || numIgnored !== $allErrors.length) {
+                                $icon.addClass(isValidating
+                                                ? this.options.icon.validating
+                                                : (isValidField === null ? '' : (isValidField ? this.options.icon.valid : this.options.icon.invalid)))
+                                     .show();
+                            }
+                        }
+
+                        var isValidContainer = this.isValidContainer($parent);
+                        if (isValidContainer !== null) {
+                            $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid);
+                            if (status === this.STATUS_VALID || numIgnored !== $allErrors.length) {
+                                $parent.addClass(isValidContainer ? this.options.row.valid : this.options.row.invalid);
+                            }
+                        }
+                        break;
+
+                    case this.STATUS_NOT_VALIDATED:
+                    /* falls through */
+                    default:
+                        isValidField = null;
+                        this.disableSubmitButtons(false);
+                        $field.removeClass(this.options.control.valid).removeClass(this.options.control.invalid);
+                        $parent.removeClass(this.options.row.valid).removeClass(this.options.row.invalid);
+                        if ($icon) {
+                            $icon.removeClass(this.options.icon.valid).removeClass(this.options.icon.invalid).removeClass(this.options.icon.validating).hide();
+                        }
+                        break;
+                }
+
+                if ($icon && ('tooltip' === container || 'popover' === container)) {
+                    (isValidField === false)
+                        // Only show the first error message
+                        ? this._createTooltip($field, $allErrors.filter('[data-' + ns + '-result="' + that.STATUS_INVALID + '"]').eq(0).html(), container)
+                        : this._destroyTooltip($field, container);
+                } else {
+                    (status === this.STATUS_INVALID) ? $errors.show() : $errors.hide();
+                }
+
+                // Trigger an event
+                $field.trigger($.Event(this.options.events.fieldStatus), {
+                    bv: this,   // Support backward
+                    fv: this,
+                    field: field,
+                    element: $field,
+                    status: status,
+                    validator: validatorName
+                });
+                this._onFieldValidated($field, validatorName);
+            }
+
+            return this;
+        },
+
+        /**
+         * Validate the form
+         *
+         * @returns {FormValidation.Base}
+         */
+        validate: function() {
+            if ($.isEmptyObject(this.options.fields)) {
+                this._submit();
+                return this;
+            }
+            this.$form.trigger($.Event(this.options.events.formPreValidate));
+
+            this.disableSubmitButtons(true);
+            this._submitIfValid = false;
+            for (var field in this.options.fields) {
+                this.validateField(field);
+            }
+
+            this._submit();
+            this._submitIfValid = true;
+
+            return this;
+        },
+
+        /**
+         * Validate given field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @returns {FormValidation.Base}
+         */
+        validateField: function(field) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            if (fields.length === 0 || !this.options.fields[field]
+                || this.options.fields[field].enabled === 'false' || this.options.fields[field].enabled === false)
+            {
+                return this;
+            }
+
+            var that       = this,
+                type       = fields.attr('type'),
+                total      = (('radio' === type || 'checkbox' === type) && this.options.live !== 'disabled') ? 1 : fields.length,
+                updateAll  = ('radio' === type || 'checkbox' === type),
+                validators = this.options.fields[field].validators,
+                verbose    = this.isOptionEnabled(field, 'verbose'),
+                validatorName,
+                alias,
+                validateResult;
+
+            for (var i = 0; i < total; i++) {
+                var $field = fields.eq(i);
+                if (this._isExcluded($field)) {
+                    continue;
+                }
+
+                var stop             = false,
+                    sortedByPriority = $field.data(ns + '.validators'),
+                    numValidators    = sortedByPriority.length;
+
+                for (var j = 0; j < numValidators; j++) {
+                    validatorName = sortedByPriority[j].validator;
+                    if ($field.data(ns + '.dfs.' + validatorName)) {
+                        $field.data(ns + '.dfs.' + validatorName).reject();
+                    }
+                    if (stop) {
+                        break;
+                    }
+
+                    // Don't validate field if it is already done
+                    var result = $field.data(ns + '.result.' + validatorName);
+                    if (result === this.STATUS_VALID || result === this.STATUS_INVALID) {
+                        this._onFieldValidated($field, validatorName);
+                        continue;
+                    } else if (validators[validatorName].enabled === false) {
+                        // Changed in v0.6.2:
+                        // When the field validator is disabled, it should be treated as STATUS_IGNORED instead of STATUS_VALID
+                        // By doing that, the field with only disabled and ignored validators will not have success/error class
+                        this.updateStatus(updateAll ? field : $field, this.STATUS_IGNORED, validatorName);
+                        continue;
+                    }
+
+                    $field.data(ns + '.result.' + validatorName, this.STATUS_VALIDATING);
+
+                    // Check whether or not the validator is just an alias of another
+                    alias          = validators[validatorName].alias || validatorName;
+                    validateResult = FormValidation.Validator[alias].validate(this, $field, validators[validatorName], validatorName);
+
+                    // validateResult can be a $.Deferred object ...
+                    if ('object' === typeof validateResult && validateResult.resolve) {
+                        this.updateStatus(updateAll ? field : $field, this.STATUS_VALIDATING, validatorName);
+                        $field.data(ns + '.dfs.' + validatorName, validateResult);
+
+                        validateResult.done(function($f, v, response) {
+                            // v is validator name
+                            $f.removeData(ns + '.dfs.' + v).data(ns + '.response.' + v, response);
+                            if (response.message) {
+                                that.updateMessage($f, v, response.message);
+                            }
+
+                            that.updateStatus(updateAll ? $f.attr('data-' + ns + '-field') : $f,
+                                              response.valid === true ? that.STATUS_VALID : (response.valid === false ? that.STATUS_INVALID : that.STATUS_IGNORED),
+                                              v);
+
+                            if (response.valid && that._submitIfValid === true) {
+                                // If a remote validator returns true and the form is ready to submit, then do it
+                                that._submit();
+                            } else if (response.valid === false && !verbose) {
+                                stop = true;
+                            }
+                        });
+                    }
+                    // ... or object { valid: true/false/null, message: 'dynamic message', otherKey: value, ... }
+                    else if ('object' === typeof validateResult && validateResult.valid !== undefined) {
+                        $field.data(ns + '.response.' + validatorName, validateResult);
+                        if (validateResult.message) {
+                            this.updateMessage(updateAll ? field : $field, validatorName, validateResult.message);
+                        }
+                        this.updateStatus(updateAll ? field : $field,
+                                          validateResult.valid === true ? this.STATUS_VALID : (validateResult.valid === false ? this.STATUS_INVALID : this.STATUS_IGNORED),
+                                          validatorName);
+                        if (validateResult.valid === false && !verbose) {
+                            break;
+                        }
+                    }
+                    // ... or a boolean value
+                    else if ('boolean' === typeof validateResult) {
+                        $field.data(ns + '.response.' + validatorName, validateResult);
+                        this.updateStatus(updateAll ? field : $field, validateResult ? this.STATUS_VALID : this.STATUS_INVALID, validatorName);
+                        if (!validateResult && !verbose) {
+                            break;
+                        }
+                    }
+                    // ... or null
+                    // to indicate that the field should be ignored for current validator
+                    else if (null === validateResult) {
+                        $field.data(ns + '.response.' + validatorName, validateResult);
+                        this.updateStatus(updateAll ? field : $field, this.STATUS_IGNORED, validatorName);
+                    }
+                }
+            }
+
+            return this;
+        },
+
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        // Useful APIs which aren't used internally
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        /**
+         * Add a new field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {Object} [options] The validator rules
+         * @returns {FormValidation.Base}
+         */
+        addField: function(field, options) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field') || field.attr('name');
+                    break;
+                case 'string':
+                    delete this._cacheFields[field];
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            fields.attr('data-' + ns + '-field', field);
+
+            var type  = fields.attr('type'),
+                total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length;
+
+            for (var i = 0; i < total; i++) {
+                var $field = fields.eq(i);
+
+                // Try to parse the options from HTML attributes
+                var opts = this._parseOptions($field);
+                opts = (opts === null) ? options : $.extend(true, opts, options);
+
+                this.options.fields[field] = $.extend(true, this.options.fields[field], opts);
+
+                // Update the cache
+                this._cacheFields[field] = this._cacheFields[field] ? this._cacheFields[field].add($field) : $field;
+
+                // Init the element
+                this._initField(('checkbox' === type || 'radio' === type) ? field : $field);
+            }
+
+            this.disableSubmitButtons(false);
+            // Trigger an event
+            this.$form.trigger($.Event(this.options.events.fieldAdded), {
+                field: field,
+                element: fields,
+                options: this.options.fields[field]
+            });
+
+            return this;
+        },
+
+        /**
+         * Destroy the plugin
+         * It will remove all error messages, feedback icons and turn off the events
+         */
+        destroy: function() {
+            var ns = this._namespace, i, field, fields, $field, validator, $icon, row, alias;
+
+            // Destroy the validators first
+            for (field in this.options.fields) {
+                fields = this.getFieldElements(field);
+                for (i = 0; i < fields.length; i++) {
+                    $field = fields.eq(i);
+                    for (validator in this.options.fields[field].validators) {
+                        if ($field.data(ns + '.dfs.' + validator)) {
+                            $field.data(ns + '.dfs.' + validator).reject();
+                        }
+                        $field.removeData(ns + '.result.' + validator)
+                              .removeData(ns + '.response.' + validator)
+                              .removeData(ns + '.dfs.' + validator);
+
+                        // Destroy the validator
+                        alias = this.options.fields[field].validators[validator].alias || validator;
+                        if ('function' === typeof FormValidation.Validator[alias].destroy) {
+                            FormValidation.Validator[alias].destroy(this, $field, this.options.fields[field].validators[validator], validator);
+                        }
+                    }
+                }
+            }
+
+            // Remove messages and icons
+            var clazz = this.options.err.clazz.split(' ').join('.');
+            for (field in this.options.fields) {
+                fields = this.getFieldElements(field);
+                row    = this.options.fields[field].row || this.options.row.selector;
+                for (i = 0; i < fields.length; i++) {
+                    $field = fields.eq(i);
+                    // Remove all error messages
+                    var $messages = $field.data(ns + '.messages');
+                    if ($messages) {
+                        $messages.find('.' + clazz + '[data-' + ns + '-validator][data-' + ns + '-for="' + field + '"]').remove();
+                    }
+                    $field
+                        .removeData(ns + '.messages')
+                        .removeData(ns + '.validators')
+                        // Remove feedback classes
+                        .closest(row)
+                            .removeClass(this.options.row.valid)
+                            .removeClass(this.options.row.invalid)
+                            .removeClass(this.options.row.feedback)
+                            .end()
+                        // Turn off events
+                        .off('.' + ns)
+                        .removeAttr('data-' + ns + '-field');
+
+                    // Remove feedback icons, tooltip/popover container
+                    // Support backward
+                    var container = ('function' === typeof (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container))
+                                    ? (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container).call(this, $field, this)
+                                    : (this.options.fields[field].container || this.options.fields[field].err || this.options.err.container);
+                    if ('tooltip' === container || 'popover' === container) {
+                        this._destroyTooltip($field, container);
+                    }
+
+                    $icon = $field.data(ns + '.icon');
+                    if ($icon) {
+                        $icon.remove();
+                    }
+                    $field.removeData(ns + '.icon')
+                          // It's safe to remove trigger data here, because it might be used when destroying the validator
+                          .removeData(ns + '.trigger');
+                }
+            }
+
+            // Destroy the add-ons
+            for (var addOn in this.options.addOns) {
+                if ('function' === typeof FormValidation.AddOn[addOn].destroy) {
+                    FormValidation.AddOn[addOn].destroy(this, this.options.addOns[addOn]);
+                }
+            }
+
+            this.disableSubmitButtons(false);   // Enable submit buttons
+            this.$hiddenButton.remove();        // Remove the hidden button
+
+            this.$form
+                .removeClass(this.options.elementClass)
+                .off('.' + ns)
+                .removeData('bootstrapValidator')   // Support backward
+                .removeData('formValidation')
+                // Remove generated hidden elements
+                .find('[data-' + ns + '-submit-hidden]').remove().end()
+                .find('[type="submit"]')
+                    .off('click.' + ns);
+        },
+
+        /**
+         * Enable/Disable all validators to given field
+         *
+         * @param {String} field The field name
+         * @param {Boolean} enabled Enable/Disable field validators
+         * @param {String} [validatorName] The validator name. If null, all validators will be enabled/disabled
+         * @returns {FormValidation.Base}
+         */
+        enableFieldValidators: function(field, enabled, validatorName) {
+            var validators = this.options.fields[field].validators;
+
+            // Enable/disable particular validator
+            if (validatorName
+                && validators
+                && validators[validatorName] && validators[validatorName].enabled !== enabled)
+            {
+                this.options.fields[field].validators[validatorName].enabled = enabled;
+                this.updateStatus(field, this.STATUS_NOT_VALIDATED, validatorName);
+            }
+            // Enable/disable all validators
+            else if (!validatorName && this.options.fields[field].enabled !== enabled) {
+                this.options.fields[field].enabled = enabled;
+                for (var v in validators) {
+                    this.enableFieldValidators(field, enabled, v);
+                }
+            }
+
+            return this;
+        },
+
+        /**
+         * Some validators have option which its value is dynamic.
+         * For example, the zipCode validator has the country option which might be changed dynamically by a select element.
+         *
+         * @param {jQuery|String} field The field name or element
+         * @param {String|Function} option The option which can be determined by:
+         * - a string
+         * - name of field which defines the value
+         * - name of function which returns the value
+         * - a function returns the value
+         *
+         * The callback function has the format of
+         *      callback: function(value, validator, $field) {
+         *          // value is the value of field
+         *          // validator is the BootstrapValidator instance
+         *          // $field is the field element
+         *      }
+         *
+         * @returns {String}
+         */
+        getDynamicOption: function(field, option) {
+            var $field = ('string' === typeof field) ? this.getFieldElements(field) : field,
+                value  = $field.val();
+
+            // Option can be determined by
+            // ... a function
+            if ('function' === typeof option) {
+                return FormValidation.Helper.call(option, [value, this, $field]);
+            }
+            // ... value of other field
+            else if ('string' === typeof option) {
+                var $f = this.getFieldElements(option);
+                if ($f.length) {
+                    return $f.val();
+                }
+                // ... return value of callback
+                else {
+                    return FormValidation.Helper.call(option, [value, this, $field]) || option;
+                }
+            }
+
+            return null;
+        },
+
+        /**
+         * Get the form element
+         *
+         * @returns {jQuery}
+         */
+        getForm: function() {
+            return this.$form;
+        },
+
+        /**
+         * Get the list of invalid fields
+         *
+         * @returns {jQuery[]}
+         */
+        getInvalidFields: function() {
+            return this.$invalidFields;
+        },
+
+        /**
+         * Get the current locale
+         *
+         * @return {String}
+         */
+        getLocale: function() {
+            return this.options.locale;
+        },
+
+        /**
+         * Get the error messages
+         *
+         * @param {String|jQuery} [field] The field name or field element
+         * If the field is not defined, the method returns all error messages of all fields
+         * @param {String} [validator] The name of validator
+         * If the validator is not defined, the method returns error messages of all validators
+         * @returns {String[]}
+         */
+        getMessages: function(field, validator) {
+            var that     = this,
+                ns       = this._namespace,
+                messages = [],
+                $fields  = $([]);
+
+            switch (true) {
+                case (field && 'object' === typeof field):
+                    $fields = field;
+                    break;
+                case (field && 'string' === typeof field):
+                    var f = this.getFieldElements(field);
+                    if (f.length > 0) {
+                        var type = f.attr('type');
+                        $fields = ('radio' === type || 'checkbox' === type) ? f.eq(0) : f;
+                    }
+                    break;
+                default:
+                    $fields = this.$invalidFields;
+                    break;
+            }
+
+            var filter = validator ? '[data-' + ns + '-validator="' + validator + '"]' : '',
+                clazz  = this.options.err.clazz.split(' ').join('.');
+            $fields.each(function() {
+                messages = messages.concat(
+                    $(this)
+                        .data(ns + '.messages')
+                        .find('.' + clazz + '[data-' + ns + '-for="' + $(this).attr('data-' + ns + '-field') + '"][data-' + ns + '-result="' + that.STATUS_INVALID + '"]' + filter)
+                        .map(function() {
+                            var v = $(this).attr('data-' + ns + '-validator'),
+                                f = $(this).attr('data-' + ns + '-for');
+                            return (that.options.fields[f].validators[v].enabled === false) ? '' : $(this).html();
+                        })
+                        .get()
+                );
+            });
+
+            return messages;
+        },
+
+        /**
+         * Returns the clicked submit button
+         *
+         * @returns {jQuery}
+         */
+        getSubmitButton: function() {
+            return this.$submitButton;
+        },
+
+        /**
+         * Remove a given field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @returns {FormValidation.Base}
+         */
+        removeField: function(field) {
+            var ns     = this._namespace,
+                fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    fields = field;
+                    field  = field.attr('data-' + ns + '-field') || field.attr('name');
+                    fields.attr('data-' + ns + '-field', field);
+                    break;
+                case 'string':
+                    fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            if (fields.length === 0) {
+                return this;
+            }
+
+            var type  = fields.attr('type'),
+                total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length;
+
+            for (var i = 0; i < total; i++) {
+                var $field = fields.eq(i);
+
+                // Remove from the list of invalid fields
+                this.$invalidFields = this.$invalidFields.not($field);
+
+                // Update the cache
+                this._cacheFields[field] = this._cacheFields[field].not($field);
+            }
+
+            if (!this._cacheFields[field] || this._cacheFields[field].length === 0) {
+                delete this.options.fields[field];
+            }
+            if ('checkbox' === type || 'radio' === type) {
+                this._initField(field);
+            }
+
+            this.disableSubmitButtons(false);
+            // Trigger an event
+            this.$form.trigger($.Event(this.options.events.fieldRemoved), {
+                field: field,
+                element: fields
+            });
+
+            return this;
+        },
+
+        /**
+         * Reset given field
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {Boolean} [resetValue] If true, the method resets field value to empty or remove checked/selected attribute (for radio/checkbox)
+         * @returns {FormValidation.Base}
+         */
+        resetField: function(field, resetValue) {
+            var ns      = this._namespace,
+                $fields = $([]);
+            switch (typeof field) {
+                case 'object':
+                    $fields = field;
+                    field   = field.attr('data-' + ns + '-field');
+                    break;
+                case 'string':
+                    $fields = this.getFieldElements(field);
+                    break;
+                default:
+                    break;
+            }
+
+            var i     = 0,
+                total = $fields.length;
+            if (this.options.fields[field]) {
+                for (i = 0; i < total; i++) {
+                    for (var validator in this.options.fields[field].validators) {
+                        $fields.eq(i).removeData(ns + '.dfs.' + validator);
+                    }
+                }
+            }
+
+            if (resetValue) {
+                var type = $fields.attr('type');
+                ('radio' === type || 'checkbox' === type) ? $fields.prop('checked', false).removeAttr('selected') : $fields.val('');
+            }
+
+            // Mark field as not validated yet
+            this.updateStatus(field, this.STATUS_NOT_VALIDATED);
+
+            for (i = 0; i < total; i++) {
+                $fields.eq(i).trigger($.Event(this.options.events.fieldReset), {
+                    fv: this,
+                    field: field,
+                    element: $fields.eq(i),
+                    resetValue: resetValue
+                });
+            }
+
+            return this;
+        },
+
+        /**
+         * Reset the form
+         *
+         * @param {Boolean} [resetValue] If true, the method resets field value to empty or remove checked/selected attribute (for radio/checkbox)
+         * @returns {FormValidation.Base}
+         */
+        resetForm: function(resetValue) {
+            for (var field in this.options.fields) {
+                this.resetField(field, resetValue);
+            }
+
+            this.$invalidFields = $([]);
+            this.$submitButton  = null;
+
+            // Enable submit buttons
+            this.disableSubmitButtons(false);
+
+            this.$form.trigger($.Event(this.options.events.formReset), {
+                fv: this,
+                resetValue: resetValue
+            });
+
+            return this;
+        },
+
+        /**
+         * Revalidate given field
+         * It's used when you need to revalidate the field which its value is updated by other plugin
+         *
+         * @param {String|jQuery} field The field name of field element
+         * @returns {FormValidation.Base}
+         */
+        revalidateField: function(field) {
+            this.updateStatus(field, this.STATUS_NOT_VALIDATED)
+                .validateField(field);
+
+            return this;
+        },
+
+        /**
+         * Set the locale
+         *
+         * @param {String} locale The locale in format of countrycode_LANGUAGECODE
+         * @returns {FormValidation.Base}
+         */
+        setLocale: function(locale) {
+            this.options.locale = locale;
+            this.$form.trigger($.Event(this.options.events.localeChanged), {
+                locale: locale,
+                bv: this,   // Support backward
+                fv: this
+            });
+
+            return this;
+        },
+
+        /**
+         * Update the option of a specific validator
+         *
+         * @param {String|jQuery} field The field name or field element
+         * @param {String} validator The validator name
+         * @param {String} option The option name
+         * @param {String} value The value to set
+         * @returns {FormValidation.Base}
+         */
+        updateOption: function(field, validator, option, value) {
+            var ns = this._namespace;
+            if ('object' === typeof field) {
+                field = field.attr('data-' + ns + '-field');
+            }
+            if (this.options.fields[field] && this.options.fields[field].validators[validator]) {
+                this.options.fields[field].validators[validator][option] = value;
+                this.updateStatus(field, this.STATUS_NOT_VALIDATED, validator);
+            }
+
+            return this;
+        },
+
+        /**
+         * Validate given container
+         * It can be used with isValidContainer() when you want to work with wizard form
+         *
+         * @param {String|jQuery} container The container selector or element
+         * @returns {FormValidation.Base}
+         */
+        validateContainer: function(container) {
+            var that       = this,
+                ns         = this._namespace,
+                fields     = [],
+                $container = ('string' === typeof container) ? $(container) : container;
+            if ($container.length === 0) {
+                return this;
+            }
+
+            $container.find('[data-' + ns + '-field]').each(function() {
+                var $field = $(this);
+                if (!that._isExcluded($field)) {
+                    fields.push($field);
+                }
+            });
+
+            var total = fields.length;
+            for (var i = 0; i < total; i++) {
+                this.validateField(fields[i]);
+            }
+
+            return this;
+        }
+    };
+
+    // Plugin definition
+    $.fn.formValidation = function(option) {
+        var params = arguments;
+        return this.each(function() {
+            var $this   = $(this),
+                data    = $this.data('formValidation'),
+                options = 'object' === typeof option && option;
+            if (!data) {
+                var framework = (options.framework || $this.attr('data-fv-framework') || 'bootstrap').toLowerCase(),
+                    clazz     = framework.substr(0, 1).toUpperCase() + framework.substr(1);
+
+                if (typeof FormValidation.Framework[clazz] === 'undefined') {
+                    throw new Error('The class FormValidation.Framework.' + clazz + ' is not implemented');
+                }
+
+                data = new FormValidation.Framework[clazz](this, options);
+                $this.addClass('fv-form-' + framework)
+                     .data('formValidation', data);
+            }
+
+            // Allow to call plugin method
+            if ('string' === typeof option) {
+                data[option].apply(data, Array.prototype.slice.call(params, 1));
+            }
+        });
+    };
+
+    $.fn.formValidation.Constructor = FormValidation.Base;
+
+    // Default message
+    $.fn.formValidation.DEFAULT_MESSAGE = 'This value is not valid';
+
+    // The default options sorted in alphabetical order
+    $.fn.formValidation.DEFAULT_OPTIONS = {
+        // The first invalid field will be focused automatically
+        autoFocus: true,
+
+        // Support declarative usage (setting options via HTML 5 attributes)
+        // Setting to false can improve the performance
+        declarative: true,
+
+        // The form CSS class
+        elementClass: 'fv-form',
+
+        // Use custom event name to avoid window.onerror being invoked by jQuery
+        // See #630
+        events: {
+            // Support backward
+            formInit: 'init.form.fv',
+            formPreValidate: 'prevalidate.form.fv',
+            formError: 'err.form.fv',
+            formReset: 'rst.form.fv',
+            formSuccess: 'success.form.fv',
+            fieldAdded: 'added.field.fv',
+            fieldRemoved: 'removed.field.fv',
+            fieldInit: 'init.field.fv',
+            fieldError: 'err.field.fv',
+            fieldReset: 'rst.field.fv',
+            fieldSuccess: 'success.field.fv',
+            fieldStatus: 'status.field.fv',
+            localeChanged: 'changed.locale.fv',
+            validatorError: 'err.validator.fv',
+            validatorSuccess: 'success.validator.fv',
+            validatorIgnored: 'ignored.validator.fv'
+        },
+
+        // Indicate fields which won't be validated
+        // By default, the plugin will not validate the following kind of fields:
+        // - disabled
+        // - hidden
+        // - invisible
+        //
+        // The setting consists of jQuery filters. Accept 3 formats:
+        // - A string. Use a comma to separate filter
+        // - An array. Each element is a filter
+        // - An array. Each element can be a callback function
+        //      function($field, validator) {
+        //          $field is jQuery object representing the field element
+        //          validator is the BootstrapValidator instance
+        //          return true or false;
+        //      }
+        //
+        // The 3 following settings are equivalent:
+        //
+        // 1) ':disabled, :hidden, :not(:visible)'
+        // 2) [':disabled', ':hidden', ':not(:visible)']
+        // 3) [':disabled', ':hidden', function($field) {
+        //        return !$field.is(':visible');
+        //    }]
+        excluded: [':disabled', ':hidden', ':not(:visible)'],
+
+        // Map the field name with validator rules
+        fields: null,
+
+        // Live validating option
+        // Can be one of 3 values:
+        // - enabled: The plugin validates fields as soon as they are changed
+        // - disabled: Disable the live validating. The error messages are only shown after the form is submitted
+        // - submitted: The live validating is enabled after the form is submitted
+        live: 'enabled',
+
+        // Locale in the format of languagecode_COUNTRYCODE
+        locale: 'en_US',
+
+        // Default invalid message
+        message: null,
+
+        // The field will not be live validated if its length is less than this number of characters
+        threshold: null,
+
+        // Whether to be verbose when validating a field or not.
+        // Possible values:
+        // - true:  when a field has multiple validators, all of them will be checked, and respectively - if errors occur in
+        //          multiple validators, all of them will be displayed to the user
+        // - false: when a field has multiple validators, validation for this field will be terminated upon the first encountered error.
+        //          Thus, only the very first error message related to this field will be displayed to the user
+        verbose: true,
+
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        // These options mostly are overridden by specific framework
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        button: {
+            // The submit buttons selector
+            // These buttons will be disabled to prevent the valid form from multiple submissions
+            // Don't perform validation when clicking on the submit button/input which have formnovalidate attribute
+            selector: '[type="submit"]:not([formnovalidate])',
+
+            // The disabled class
+            disabled: ''
+        },
+
+        control: {
+            // The CSS class for valid control
+            valid: '',
+
+            // The CSS class for invalid control
+            invalid: ''
+        },
+
+        err: {
+            // The CSS class of each message element
+            clazz: '',
+
+            // The error messages container. It can be:
+            // - 'tooltip' if you want to use Bootstrap tooltip to show error messages
+            // - 'popover' if you want to use Bootstrap popover to show error messages
+            // - a CSS selector indicating the container
+            // In the first two cases, since the tooltip/popover should be small enough, the plugin only shows only one error message
+            // You also can define the message container for particular field
+            container: null,
+
+            // Used to determine where the messages are placed
+            parent: null
+        },
+
+        // Shows ok/error/loading icons based on the field validity.
+        icon: {
+            valid: null,
+            invalid: null,
+            validating: null,
+            feedback: ''
+        },
+
+        row: {
+            // The CSS selector for indicating the element consists of the field
+            // You should adjust this option if your form group consists of many fields which not all of them need to be validated
+            selector: null,
+            valid: '',
+            invalid: '',
+            feedback: ''
+        }
+    };
+}(jQuery));
+;(function($) {
+    // Helper methods, which can be used in validator class
+    FormValidation.Helper = {
+        /**
+         * Execute a callback function
+         *
+         * @param {String|Function} functionName Can be
+         * - name of global function
+         * - name of namespace function (such as A.B.C)
+         * - a function
+         * @param {Array} args The callback arguments
+         */
+        call: function(functionName, args) {
+            if ('function' === typeof functionName) {
+                return functionName.apply(this, args);
+            } else if ('string' === typeof functionName) {
+                if ('()' === functionName.substring(functionName.length - 2)) {
+                    functionName = functionName.substring(0, functionName.length - 2);
+                }
+                var ns      = functionName.split('.'),
+                    func    = ns.pop(),
+                    context = window;
+                for (var i = 0; i < ns.length; i++) {
+                    context = context[ns[i]];
+                }
+
+                return (typeof context[func] === 'undefined') ? null : context[func].apply(this, args);
+            }
+        },
+
+        /**
+         * Validate a date
+         *
+         * @param {Number} year The full year in 4 digits
+         * @param {Number} month The month number
+         * @param {Number} day The day number
+         * @param {Boolean} [notInFuture] If true, the date must not be in the future
+         * @returns {Boolean}
+         */
+        date: function(year, month, day, notInFuture) {
+            if (isNaN(year) || isNaN(month) || isNaN(day)) {
+                return false;
+            }
+            if (day.length > 2 || month.length > 2 || year.length > 4) {
+                return false;
+            }
+
+            day   = parseInt(day, 10);
+            month = parseInt(month, 10);
+            year  = parseInt(year, 10);
+
+            if (year < 1000 || year > 9999 || month <= 0 || month > 12) {
+                return false;
+            }
+            var numDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+            // Update the number of days in Feb of leap year
+            if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) {
+                numDays[1] = 29;
+            }
+
+            // Check the day
+            if (day <= 0 || day > numDays[month - 1]) {
+                return false;
+            }
+
+            if (notInFuture === true) {
+                var currentDate  = new Date(),
+                    currentYear  = currentDate.getFullYear(),
+                    currentMonth = currentDate.getMonth(),
+                    currentDay   = currentDate.getDate();
+                return (year < currentYear
+                || (year === currentYear && month - 1 < currentMonth)
+                || (year === currentYear && month - 1 === currentMonth && day < currentDay));
+            }
+
+            return true;
+        },
+
+        /**
+         * Format a string
+         * It's used to format the error message
+         * format('The field must between %s and %s', [10, 20]) = 'The field must between 10 and 20'
+         *
+         * @param {String} message
+         * @param {Array} parameters
+         * @returns {String}
+         */
+        format: function(message, parameters) {
+            if (!$.isArray(parameters)) {
+                parameters = [parameters];
+            }
+
+            for (var i in parameters) {
+                message = message.replace('%s', parameters[i]);
+            }
+
+            return message;
+        },
+
+        /**
+         * Implement Luhn validation algorithm
+         * Credit to https://gist.github.com/ShirtlessKirk/2134376
+         *
+         * @see http://en.wikipedia.org/wiki/Luhn
+         * @param {String} value
+         * @returns {Boolean}
+         */
+        luhn: function(value) {
+            var length  = value.length,
+                mul     = 0,
+                prodArr = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]],
+                sum     = 0;
+
+            while (length--) {
+                sum += prodArr[mul][parseInt(value.charAt(length), 10)];
+                mul ^= 1;
+            }
+
+            return (sum % 10 === 0 && sum > 0);
+        },
+
+        /**
+         * Implement modulus 11, 10 (ISO 7064) algorithm
+         *
+         * @param {String} value
+         * @returns {Boolean}
+         */
+        mod11And10: function(value) {
+            var check  = 5,
+                length = value.length;
+            for (var i = 0; i < length; i++) {
+                check = (((check || 10) * 2) % 11 + parseInt(value.charAt(i), 10)) % 10;
+            }
+            return (check === 1);
+        },
+
+        /**
+         * Implements Mod 37, 36 (ISO 7064) algorithm
+         * Usages:
+         * mod37And36('A12425GABC1234002M')
+         * mod37And36('002006673085', '0123456789')
+         *
+         * @param {String} value
+         * @param {String} [alphabet]
+         * @returns {Boolean}
+         */
+        mod37And36: function(value, alphabet) {
+            alphabet = alphabet || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+            var modulus = alphabet.length,
+                length  = value.length,
+                check   = Math.floor(modulus / 2);
+            for (var i = 0; i < length; i++) {
+                check = (((check || modulus) * 2) % (modulus + 1) + alphabet.indexOf(value.charAt(i))) % modulus;
+            }
+            return (check === 1);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            between: {
+                'default': 'Please enter a value between %s and %s',
+                notInclusive: 'Please enter a value between %s and %s strictly'
+            }
+        }
+    });
+
+    FormValidation.Validator.between = {
+        html5Attributes: {
+            message: 'message',
+            min: 'min',
+            max: 'max',
+            inclusive: 'inclusive'
+        },
+
+        enableByHtml5: function($field) {
+            if ('range' === $field.attr('type')) {
+                return {
+                    min: $field.attr('min'),
+                    max: $field.attr('max')
+                };
+            }
+
+            return false;
+        },
+
+        /**
+         * Return true if the input value is between (strictly or not) two given numbers
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - min
+         * - max
+         *
+         * The min, max keys define the number which the field value compares to. min, max can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - inclusive [optional]: Can be true or false. Default is true
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+			value = this._format(value);
+
+            var locale   = validator.getLocale(),
+                min      = $.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min),
+                max      = $.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max),
+                minValue = this._format(min),
+                maxValue = this._format(max);
+
+			return (options.inclusive === true || options.inclusive === undefined)
+                    ? {
+                        valid: $.isNumeric(value) && parseFloat(value) >= minValue && parseFloat(value) <= maxValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].between['default'], [min, max])
+                    }
+                    : {
+                        valid: $.isNumeric(value) && parseFloat(value) > minValue && parseFloat(value) < maxValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].between.notInclusive, [min, max])
+                    };
+        },
+
+        _format: function(value) {
+            return (value + '').replace(',', '.');
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            callback: {
+                'default': 'Please enter a valid value'
+            }
+        }
+    });
+
+    FormValidation.Validator.callback = {
+        priority: 999,
+
+        html5Attributes: {
+            message: 'message',
+            callback: 'callback'
+        },
+
+        /**
+         * Return result from the callback method
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - callback: The callback method that passes parameters:
+         *      callback: function(fieldValue, validator, $field) {
+         *          // fieldValue is the value of field
+         *          // validator is instance of FormValidation.Base
+         *          // $field is the field element
+         *      }
+         * - message: The invalid message
+         * @returns {Deferred}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value  = validator.getFieldValue($field, validatorName),
+                dfd    = new $.Deferred(),
+                result = { valid: true };
+
+            if (options.callback) {
+                var response = FormValidation.Helper.call(options.callback, [value, validator, $field]);
+                result = ('boolean' === typeof response || null === response) ? { valid: response } : response;
+            }
+
+            dfd.resolve($field, validatorName, result);
+            return dfd;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            choice: {
+                'default': 'Please enter a valid value',
+                less: 'Please choose %s options at minimum',
+                more: 'Please choose %s options at maximum',
+                between: 'Please choose %s - %s options'
+            }
+        }
+    });
+
+    FormValidation.Validator.choice = {
+        html5Attributes: {
+            message: 'message',
+            min: 'min',
+            max: 'max'
+        },
+
+        /**
+         * Check if the number of checked boxes are less or more than a given number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of following keys:
+         * - min
+         * - max
+         *
+         * At least one of two keys is required
+         * The min, max keys define the number which the field value compares to. min, max can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - message: The invalid message
+         * @returns {Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var locale     = validator.getLocale(),
+                ns         = validator.getNamespace(),
+                numChoices = $field.is('select')
+                            ? validator.getFieldElements($field.attr('data-' + ns + '-field')).find('option').filter(':selected').length
+                            : validator.getFieldElements($field.attr('data-' + ns + '-field')).filter(':checked').length,
+                min        = options.min ? ($.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min)) : null,
+                max        = options.max ? ($.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max)) : null,
+                isValid    = true,
+                message    = options.message || FormValidation.I18n[locale].choice['default'];
+
+            if ((min && numChoices < parseInt(min, 10)) || (max && numChoices > parseInt(max, 10))) {
+                isValid = false;
+            }
+
+            switch (true) {
+                case (!!min && !!max):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].choice.between, [parseInt(min, 10), parseInt(max, 10)]);
+                    break;
+
+                case (!!min):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].choice.less, parseInt(min, 10));
+                    break;
+
+                case (!!max):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].choice.more, parseInt(max, 10));
+                    break;
+
+                default:
+                    break;
+            }
+
+            return { valid: isValid, message: message };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            color: {
+                'default': 'Please enter a valid color'
+            }
+        }
+    });
+
+    FormValidation.Validator.color = {
+        html5Attributes: {
+            message: 'message',
+            type: 'type'
+        },
+
+        enableByHtml5: function($field) {
+            return ('color' === $field.attr('type'));
+        },
+
+        SUPPORTED_TYPES: [
+            'hex', 'rgb', 'rgba', 'hsl', 'hsla', 'keyword'
+        ],
+
+        KEYWORD_COLORS: [
+            // Colors start with A
+            'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure',
+            // B
+            'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood',
+            // C
+            'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan',
+            // D
+            'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta',
+            'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue',
+            'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray',
+            'dimgrey', 'dodgerblue',
+            // F
+            'firebrick', 'floralwhite', 'forestgreen', 'fuchsia',
+            // G
+            'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey',
+            // H
+            'honeydew', 'hotpink',
+            // I
+            'indianred', 'indigo', 'ivory',
+            // K
+            'khaki',
+            // L
+            'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan',
+            'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen',
+            'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen',
+            'linen',
+            // M
+            'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen',
+            'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream',
+            'mistyrose', 'moccasin',
+            // N
+            'navajowhite', 'navy',
+            // O
+            'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid',
+            // P
+            'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink',
+            'plum', 'powderblue', 'purple',
+            // R
+            'red', 'rosybrown', 'royalblue',
+            // S
+            'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue',
+            'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue',
+            // T
+            'tan', 'teal', 'thistle', 'tomato', 'transparent', 'turquoise',
+            // V
+            'violet',
+            // W
+            'wheat', 'white', 'whitesmoke',
+            // Y
+            'yellow', 'yellowgreen'
+        ],
+
+        /**
+         * Return true if the input value is a valid color
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * - type: The array of valid color types
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Only accept 6 hex character values due to the HTML 5 spec
+            // See http://www.w3.org/TR/html-markup/input.color.html#input.color.attrs.value
+            if (this.enableByHtml5($field)) {
+                return /^#[0-9A-F]{6}$/i.test(value);
+            }
+
+            var types = options.type || this.SUPPORTED_TYPES;
+            if (!$.isArray(types)) {
+                types = types.replace(/s/g, '').split(',');
+            }
+
+            var method,
+                type,
+                isValid = false;
+
+            for (var i = 0; i < types.length; i++) {
+                type    = types[i];
+                method  = '_' + type.toLowerCase();
+                isValid = isValid || this[method](value);
+                if (isValid) {
+                    return true;
+                }
+            }
+
+            return false;
+        },
+
+        _hex: function(value) {
+            return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(value);
+        },
+
+        _hsl: function(value) {
+            return /^hsl\((\s*(-?\d+)\s*,)(\s*(\b(0?\d{1,2}|100)\b%)\s*,)(\s*(\b(0?\d{1,2}|100)\b%)\s*)\)$/.test(value);
+        },
+
+        _hsla: function(value) {
+            return /^hsla\((\s*(-?\d+)\s*,)(\s*(\b(0?\d{1,2}|100)\b%)\s*,){2}(\s*(0?(\.\d+)?|1(\.0+)?)\s*)\)$/.test(value);
+        },
+
+        _keyword: function(value) {
+            return $.inArray(value, this.KEYWORD_COLORS) >= 0;
+        },
+
+        _rgb: function(value) {
+            var regexInteger = /^rgb\((\s*(\b([01]?\d{1,2}|2[0-4]\d|25[0-5])\b)\s*,){2}(\s*(\b([01]?\d{1,2}|2[0-4]\d|25[0-5])\b)\s*)\)$/,
+                regexPercent = /^rgb\((\s*(\b(0?\d{1,2}|100)\b%)\s*,){2}(\s*(\b(0?\d{1,2}|100)\b%)\s*)\)$/;
+            return regexInteger.test(value) || regexPercent.test(value);
+        },
+
+        _rgba: function(value) {
+            var regexInteger = /^rgba\((\s*(\b([01]?\d{1,2}|2[0-4]\d|25[0-5])\b)\s*,){3}(\s*(0?(\.\d+)?|1(\.0+)?)\s*)\)$/,
+                regexPercent = /^rgba\((\s*(\b(0?\d{1,2}|100)\b%)\s*,){3}(\s*(0?(\.\d+)?|1(\.0+)?)\s*)\)$/;
+            return regexInteger.test(value) || regexPercent.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            creditCard: {
+                'default': 'Please enter a valid credit card number'
+            }
+        }
+    });
+
+    FormValidation.Validator.creditCard = {
+        /**
+         * Return true if the input value is valid credit card number
+         * Based on https://gist.github.com/DiegoSalazar/4075533
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} [options] Can consist of the following key:
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Accept only digits, dashes or spaces
+            if (/[^0-9-\s]+/.test(value)) {
+                return false;
+            }
+            value = value.replace(/\D/g, '');
+
+            if (!FormValidation.Helper.luhn(value)) {
+                return false;
+            }
+
+            // Validate the card number based on prefix (IIN ranges) and length
+            var cards = {
+                AMERICAN_EXPRESS: {
+                    length: [15],
+                    prefix: ['34', '37']
+                },
+                DANKORT: {
+                    length: [16],
+                    prefix: ['5019']
+                },
+                DINERS_CLUB: {
+                    length: [14],
+                    prefix: ['300', '301', '302', '303', '304', '305', '36']
+                },
+                DINERS_CLUB_US: {
+                    length: [16],
+                    prefix: ['54', '55']
+                },
+                DISCOVER: {
+                    length: [16],
+                    prefix: ['6011', '622126', '622127', '622128', '622129', '62213',
+                             '62214', '62215', '62216', '62217', '62218', '62219',
+                             '6222', '6223', '6224', '6225', '6226', '6227', '6228',
+                             '62290', '62291', '622920', '622921', '622922', '622923',
+                             '622924', '622925', '644', '645', '646', '647', '648',
+                             '649', '65']
+                },
+                ELO: {
+                    length: [16],
+                    prefix: ['4011', '4312', '4389', '4514', '4573', '4576',
+                             '5041', '5066', '5067', '509',
+                             '6277', '6362', '6363', '650', '6516', '6550']
+                },
+                FORBRUGSFORENINGEN: {
+                    length: [16],
+                    prefix: ['600722']
+                },
+                JCB: {
+                    length: [16],
+                    prefix: ['3528', '3529', '353', '354', '355', '356', '357', '358']
+                },
+                LASER: {
+                    length: [16, 17, 18, 19],
+                    prefix: ['6304', '6706', '6771', '6709']
+                },
+                MAESTRO: {
+                    length: [12, 13, 14, 15, 16, 17, 18, 19],
+                    prefix: ['5018', '5020', '5038', '5868', '6304', '6759', '6761', '6762', '6763', '6764', '6765', '6766']
+                },
+                MASTERCARD: {
+                    length: [16],
+                    prefix: ['51', '52', '53', '54', '55']
+                },
+                SOLO: {
+                    length: [16, 18, 19],
+                    prefix: ['6334', '6767']
+                },
+                UNIONPAY: {
+                    length: [16, 17, 18, 19],
+                    prefix: ['622126', '622127', '622128', '622129', '62213', '62214',
+                             '62215', '62216', '62217', '62218', '62219', '6222', '6223',
+                             '6224', '6225', '6226', '6227', '6228', '62290', '62291',
+                             '622920', '622921', '622922', '622923', '622924', '622925']
+                },
+                VISA_ELECTRON: {
+                    length: [16],
+                    prefix: ['4026', '417500', '4405', '4508', '4844', '4913', '4917']
+                },
+                VISA: {
+                    length: [16],
+                    prefix: ['4']
+                }
+            };
+
+            var type, i;
+            for (type in cards) {
+                for (i in cards[type].prefix) {
+                    if (value.substr(0, cards[type].prefix[i].length) === cards[type].prefix[i]     // Check the prefix
+                        && $.inArray(value.length, cards[type].length) !== -1)                      // and length
+                    {
+                        return {
+                            valid: true,
+                            type: type
+                        };
+                    }
+                }
+            }
+
+            return false;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            date: {
+                'default': 'Please enter a valid date',
+                min: 'Please enter a date after %s',
+                max: 'Please enter a date before %s',
+                range: 'Please enter a date in the range %s - %s'
+            }
+        }
+    });
+
+    FormValidation.Validator.date = {
+        html5Attributes: {
+            message: 'message',
+            format: 'format',
+            min: 'min',
+            max: 'max',
+            separator: 'separator'
+        },
+
+        /**
+         * Return true if the input value is valid date
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - message: The invalid message
+         * - min: the minimum date
+         * - max: the maximum date
+         * - separator: Use to separate the date, month, and year.
+         * By default, it is /
+         * - format: The date format. Default is MM/DD/YYYY
+         * The format can be:
+         *
+         * i) date: Consist of DD, MM, YYYY parts which are separated by the separator option
+         * ii) date and time:
+         * The time can consist of h, m, s parts which are separated by :
+         * ii) date, time and A (indicating AM or PM)
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            options.format = options.format || 'MM/DD/YYYY';
+
+            // #683: Force the format to YYYY-MM-DD as the default browser behaviour when using type="date" attribute
+            if ($field.attr('type') === 'date') {
+                options.format = 'YYYY-MM-DD';
+            }
+
+            var locale     = validator.getLocale(),
+                message    = options.message || FormValidation.I18n[locale].date['default'],
+                formats    = options.format.split(' '),
+                dateFormat = formats[0],
+                timeFormat = (formats.length > 1) ? formats[1] : null,
+                amOrPm     = (formats.length > 2) ? formats[2] : null,
+                sections   = value.split(' '),
+                date       = sections[0],
+                time       = (sections.length > 1) ? sections[1] : null;
+
+            if (formats.length !== sections.length) {
+                return {
+                    valid: false,
+                    message: message
+                };
+            }
+
+            // Determine the separator
+            var separator = options.separator;
+            if (!separator) {
+                separator = (date.indexOf('/') !== -1)
+                            ? '/'
+                            : ((date.indexOf('-') !== -1) ? '-' : ((date.indexOf('.') !== -1) ? '.' : null));
+            }
+            if (separator === null || date.indexOf(separator) === -1) {
+                return {
+                    valid: false,
+                    message: message
+                };
+            }
+
+            // Determine the date
+            date       = date.split(separator);
+            dateFormat = dateFormat.split(separator);
+            if (date.length !== dateFormat.length) {
+                return {
+                    valid: false,
+                    message: message
+                };
+            }
+
+            var year  = date[$.inArray('YYYY', dateFormat)],
+                month = date[$.inArray('MM', dateFormat)],
+                day   = date[$.inArray('DD', dateFormat)];
+
+            if (!year || !month || !day || year.length !== 4) {
+                return {
+                    valid: false,
+                    message: message
+                };
+            }
+
+            // Determine the time
+            var minutes = null, hours = null, seconds = null;
+            if (timeFormat) {
+                timeFormat = timeFormat.split(':');
+                time       = time.split(':');
+
+                if (timeFormat.length !== time.length) {
+                    return {
+                        valid: false,
+                        message: message
+                    };
+                }
+
+                hours   = time.length > 0 ? time[0] : null;
+                minutes = time.length > 1 ? time[1] : null;
+                seconds = time.length > 2 ? time[2] : null;
+
+                if (hours === '' || minutes === '' || seconds === '') {
+                    return {
+                        valid: false,
+                        message: message
+                    };
+                }
+
+                // Validate seconds
+                if (seconds) {
+                    if (isNaN(seconds) || seconds.length > 2) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                    seconds = parseInt(seconds, 10);
+                    if (seconds < 0 || seconds > 60) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                }
+
+                // Validate hours
+                if (hours) {
+                    if (isNaN(hours) || hours.length > 2) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                    hours = parseInt(hours, 10);
+                    if (hours < 0 || hours >= 24 || (amOrPm && hours > 12)) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                }
+
+                // Validate minutes
+                if (minutes) {
+                    if (isNaN(minutes) || minutes.length > 2) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                    minutes = parseInt(minutes, 10);
+                    if (minutes < 0 || minutes > 59) {
+                        return {
+                            valid: false,
+                            message: message
+                        };
+                    }
+                }
+            }
+
+            // Validate day, month, and year
+            var valid     = FormValidation.Helper.date(year, month, day),
+                min       = null,
+                max       = null,
+                minOption = options.min,
+                maxOption = options.max;
+
+            if (minOption) {
+                min = (minOption instanceof Date)
+                    ? minOption
+                    : (this._parseDate(minOption, dateFormat, separator) ||
+                       this._parseDate(validator.getDynamicOption($field, minOption), dateFormat, separator));
+
+                // In order to avoid displaying a date string like "Mon Dec 08 2014 19:14:12 GMT+0000 (WET)"
+                minOption = this._formatDate(min, options.format);
+            }
+
+            if (maxOption) {
+                max = (maxOption instanceof Date)
+                    ? maxOption
+                    : (this._parseDate(maxOption, dateFormat, separator) ||
+                       this._parseDate(validator.getDynamicOption($field, maxOption), dateFormat, separator));
+
+                // In order to avoid displaying a date string like "Mon Dec 08 2014 19:14:12 GMT+0000 (WET)"
+                maxOption = this._formatDate(max, options.format);
+            }
+
+            date = new Date(year, month -1, day, hours, minutes, seconds);
+
+            switch (true) {
+                case (minOption && !maxOption && valid):
+                    valid   = date.getTime() >= min.getTime();
+                    message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.min, minOption);
+                    break;
+
+                case (maxOption && !minOption && valid):
+                    valid   = date.getTime() <= max.getTime();
+                    message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.max, maxOption);
+                    break;
+
+                case (maxOption && minOption && valid):
+                    valid   = date.getTime() <= max.getTime() && date.getTime() >= min.getTime();
+                    message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.range, [minOption, maxOption]);
+                    break;
+
+                default:
+                    break;
+            }
+
+            return {
+                valid: valid,
+                date: date,
+                message: message
+            };
+        },
+
+        /**
+         * Return a date object after parsing the date string
+         *
+         * @param {Date|String} date   The date string to parse
+         * @param {String} format The date format
+         * The format can be:
+         *   - date: Consist of DD, MM, YYYY parts which are separated by the separator option
+         *   - date and time:
+         *     The time can consist of h, m, s parts which are separated by :
+         * @param {String} separator The separator used to separate the date, month, and year
+         * @returns {Date}
+         */
+        _parseDate: function(date, format, separator) {
+            if (date instanceof Date) {
+                return date;
+            }
+            if (typeof date !== 'string') {
+                return null;
+            }
+
+            // Ensure that the format must consist of year, month and day patterns
+            var yearIndex   = $.inArray('YYYY', format),
+                monthIndex  = $.inArray('MM', format),
+                dayIndex    = $.inArray('DD', format);
+            if (yearIndex === -1 || monthIndex === -1 || dayIndex === -1) {
+                return null;
+            }
+
+            var minutes     = 0, hours = 0, seconds = 0,
+                sections    = date.split(' '),
+                dateSection = sections[0].split(separator);
+            if (dateSection.length < 3) {
+                return null;
+            }
+
+            if (sections.length > 1) {
+                var timeSection = sections[1].split(':');
+                hours   = timeSection.length > 0 ? timeSection[0] : null;
+                minutes = timeSection.length > 1 ? timeSection[1] : null;
+                seconds = timeSection.length > 2 ? timeSection[2] : null;
+            }
+
+            return new Date(dateSection[yearIndex], dateSection[monthIndex] - 1, dateSection[dayIndex],
+                            hours, minutes, seconds);
+        },
+
+        /**
+         * Format date
+         *
+         * @param {Date} date The date object to format
+         * @param {String} format The date format
+         * The format can consist of the following tokens:
+         *      d       Day of the month without leading zeros (1 through 31)
+         *      dd      Day of the month with leading zeros (01 through 31)
+         *      m       Month without leading zeros (1 through 12)
+         *      mm      Month with leading zeros (01 through 12)
+         *      yy      Last two digits of year (for example: 14)
+         *      yyyy    Full four digits of year (for example: 2014)
+         *      h       Hours without leading zeros (1 through 12)
+         *      hh      Hours with leading zeros (01 through 12)
+         *      H       Hours without leading zeros (0 through 23)
+         *      HH      Hours with leading zeros (00 through 23)
+         *      M       Minutes without leading zeros (0 through 59)
+         *      MM      Minutes with leading zeros (00 through 59)
+         *      s       Seconds without leading zeros (0 through 59)
+         *      ss      Seconds with leading zeros (00 through 59)
+         * @returns {String}
+         */
+        _formatDate: function(date, format) {
+            format = format
+                        .replace(/Y/g, 'y')
+                        .replace(/M/g, 'm')
+                        .replace(/D/g, 'd')
+                        .replace(/:m/g, ':M')
+                        .replace(/:mm/g, ':MM')
+                        .replace(/:S/, ':s')
+                        .replace(/:SS/, ':ss');
+
+            var replacer = {
+                d: function(date) {
+                    return date.getDate();
+                },
+                dd: function(date) {
+                    var d = date.getDate();
+                    return (d < 10) ? '0' + d : d;
+                },
+                m: function(date) {
+                    return date.getMonth() + 1;
+                },
+                mm: function(date) {
+                    var m = date.getMonth() + 1;
+                    return m < 10 ? '0' + m : m;
+                },
+                yy: function(date) {
+                    return ('' + date.getFullYear()).substr(2);
+                },
+                yyyy: function(date) {
+                    return date.getFullYear();
+                },
+                h: function(date) {
+                    return date.getHours() % 12 || 12;
+                },
+                hh: function(date) {
+                    var h = date.getHours() % 12 || 12;
+                    return h < 10 ? '0' + h : h;
+                },
+                H: function(date) {
+                    return date.getHours();
+                },
+                HH: function(date) {
+                    var H = date.getHours();
+                    return H < 10 ? '0' + H : H;
+                },
+                M: function(date) {
+                    return date.getMinutes();
+                },
+                MM: function(date) {
+                    var M = date.getMinutes();
+                    return M < 10 ? '0' + M : M;
+                },
+                s: function(date) {
+                    return date.getSeconds();
+                },
+                ss: function(date) {
+                    var s = date.getSeconds();
+                    return s < 10 ? '0' + s : s;
+                }
+            };
+
+            return format.replace(/d{1,4}|m{1,4}|yy(?:yy)?|([HhMs])\1?|"[^"]*"|'[^']*'/g, function(match) {
+                return replacer[match] ? replacer[match](date) : match.slice(1, match.length - 1);
+            });
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            different: {
+                'default': 'Please enter a different value'
+            }
+        }
+    });
+
+    FormValidation.Validator.different = {
+        html5Attributes: {
+            message: 'message',
+            field: 'field'
+        },
+
+        /**
+         * Bind the validator on the live change of the field to compare with current one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         */
+        init: function(validator, $field, options, validatorName) {
+            var fields = options.field.split(',');
+            for (var i = 0; i < fields.length; i++) {
+                var compareWith = validator.getFieldElements($.trim(fields[i]));
+                validator.onLiveChange(compareWith, 'live_' + validatorName, function() {
+                    var status = validator.getStatus($field, validatorName);
+                    if (status !== validator.STATUS_NOT_VALIDATED) {
+                        validator.revalidateField($field);
+                    }
+                });
+            }
+        },
+
+        /**
+         * Unbind the validator on the live change of the field to compare with current one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         */
+        destroy: function(validator, $field, options, validatorName) {
+            var fields = options.field.split(',');
+            for (var i = 0; i < fields.length; i++) {
+                var compareWith = validator.getFieldElements($.trim(fields[i]));
+                validator.offLiveChange(compareWith, 'live_' + validatorName);
+            }
+        },
+
+        /**
+         * Return true if the input value is different with given field's value
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         * - message: The invalid message
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var fields  = options.field.split(','),
+                isValid = true;
+
+            for (var i = 0; i < fields.length; i++) {
+                var compareWith = validator.getFieldElements($.trim(fields[i]));
+                if (compareWith == null || compareWith.length === 0) {
+                    continue;
+                }
+
+                var compareValue = validator.getFieldValue(compareWith, validatorName);
+                if (value === compareValue) {
+                    isValid = false;
+                } else if (compareValue !== '') {
+                    validator.updateStatus(compareWith, validator.STATUS_VALID, validatorName);
+                }
+            }
+
+            return isValid;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            digits: {
+                'default': 'Please enter only digits'
+            }
+        }
+    });
+
+    FormValidation.Validator.digits = {
+        /**
+         * Return true if the input value contains digits only
+         *
+         * @param {FormValidation.Base} validator Validate plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} [options]
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            return /^\d+$/.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            emailAddress: {
+                'default': 'Please enter a valid email address'
+            }
+        }
+    });
+
+    FormValidation.Validator.emailAddress = {
+        html5Attributes: {
+            message: 'message',
+            multiple: 'multiple',
+            separator: 'separator'
+        },
+
+        enableByHtml5: function($field) {
+            return ('email' === $field.attr('type'));
+        },
+
+        /**
+         * Return true if and only if the input value is a valid email address
+         *
+         * @param {FormValidation.Base} validator Validate plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} [options]
+         * - multiple: Allow multiple email addresses, separated by a comma or semicolon; default is false.
+         * - separator: Regex for character or characters expected as separator between addresses; default is comma /[,;]/, i.e. comma or semicolon.
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Email address regular expression
+            // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
+            var emailRegExp   = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
+                allowMultiple = options.multiple === true || options.multiple === 'true';
+
+            if (allowMultiple) {
+                var separator = options.separator || /[,;]/,
+                    addresses = this._splitEmailAddresses(value, separator);
+
+                for (var i = 0; i < addresses.length; i++) {
+                    if (!emailRegExp.test(addresses[i])) {
+                        return false;
+                    }
+                }
+
+                return true;
+            } else {
+                return emailRegExp.test(value);
+            }
+        },
+
+        _splitEmailAddresses: function(emailAddresses, separator) {
+            var quotedFragments     = emailAddresses.split(/"/),
+                quotedFragmentCount = quotedFragments.length,
+                emailAddressArray   = [],
+                nextEmailAddress    = '';
+
+            for (var i = 0; i < quotedFragmentCount; i++) {
+                if (i % 2 === 0) {
+                    var splitEmailAddressFragments     = quotedFragments[i].split(separator),
+                        splitEmailAddressFragmentCount = splitEmailAddressFragments.length;
+
+                    if (splitEmailAddressFragmentCount === 1) {
+                        nextEmailAddress += splitEmailAddressFragments[0];
+                    } else {
+                        emailAddressArray.push(nextEmailAddress + splitEmailAddressFragments[0]);
+
+                        for (var j = 1; j < splitEmailAddressFragmentCount - 1; j++) {
+                            emailAddressArray.push(splitEmailAddressFragments[j]);
+                        }
+                        nextEmailAddress = splitEmailAddressFragments[splitEmailAddressFragmentCount - 1];
+                    }
+                } else {
+                    nextEmailAddress += '"' + quotedFragments[i];
+                    if (i < quotedFragmentCount - 1) {
+                        nextEmailAddress += '"';
+                    }
+                }
+            }
+
+            emailAddressArray.push(nextEmailAddress);
+            return emailAddressArray;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            file: {
+                'default': 'Please choose a valid file'
+            }
+        }
+    });
+
+    FormValidation.Validator.file = {
+        Error: {
+            EXTENSION: 'EXTENSION',
+            MAX_FILES: 'MAX_FILES',
+            MAX_SIZE: 'MAX_SIZE',
+            MAX_TOTAL_SIZE: 'MAX_TOTAL_SIZE',
+            MIN_FILES: 'MIN_FILES',
+            MIN_SIZE: 'MIN_SIZE',
+            MIN_TOTAL_SIZE: 'MIN_TOTAL_SIZE',
+            TYPE: 'TYPE'
+        },
+
+        html5Attributes: {
+            extension: 'extension',
+            maxfiles: 'maxFiles',
+            minfiles: 'minFiles',
+            maxsize: 'maxSize',
+            minsize: 'minSize',
+            maxtotalsize: 'maxTotalSize',
+            mintotalsize: 'minTotalSize',
+            message: 'message',
+            type: 'type'
+        },
+
+        /**
+         * Validate upload file. Use HTML 5 API if the browser supports
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - extension: The allowed extensions, separated by a comma
+         * - maxFiles: The maximum number of files
+         * - minFiles: The minimum number of files
+         * - maxSize: The maximum size in bytes
+         * - minSize: The minimum size in bytes
+         * - maxTotalSize: The maximum size in bytes for all files
+         * - minTotalSize: The minimum size in bytes for all files
+         * - message: The invalid message
+         * - type: The allowed MIME type, separated by a comma
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var ext,
+                extensions = options.extension ? options.extension.toLowerCase().split(',') : null,
+                types      = options.type      ? options.type.toLowerCase().split(',')      : null,
+                html5      = (window.File && window.FileList && window.FileReader);
+
+            if (html5) {
+                // Get FileList instance
+                var files     = $field.get(0).files,
+                    total     = files.length,
+                    totalSize = 0;
+
+                // Check the maxFiles
+                if (options.maxFiles && total > parseInt(options.maxFiles, 10)) {
+                    return {
+                        valid: false,
+                        error: this.Error.MAX_FILES
+                    };
+                }
+
+                // Check the minFiles
+                if (options.minFiles && total < parseInt(options.minFiles, 10)) {
+                    return {
+                        valid: false,
+                        error: this.Error.MIN_FILES
+                    };
+                }
+
+                var metaData = {};
+                for (var i = 0; i < total; i++) {
+                    totalSize += files[i].size;
+                    ext        = files[i].name.substr(files[i].name.lastIndexOf('.') + 1);
+                    metaData   = {
+                        file: files[i],
+                        size: files[i].size,
+                        ext: ext,
+                        type: files[i].type
+                    };
+
+                    // Check the minSize
+                    if (options.minSize && files[i].size < parseInt(options.minSize, 10)) {
+                       return {
+                           valid: false,
+                           error: this.Error.MIN_SIZE,
+                           metaData: metaData
+                       };
+                    }
+
+                    // Check the maxSize
+                    if (options.maxSize && files[i].size > parseInt(options.maxSize, 10)) {
+                        return {
+                            valid: false,
+                            error: this.Error.MAX_SIZE,
+                            metaData: metaData
+                        };
+                    }
+
+                    // Check file extension
+                    if (extensions && $.inArray(ext.toLowerCase(), extensions) === -1) {
+                        return {
+                            valid: false,
+                            error: this.Error.EXTENSION,
+                            metaData: metaData
+                        };
+                    }
+
+                    // Check file type
+                    if (files[i].type && types && $.inArray(files[i].type.toLowerCase(), types) === -1) {
+                        return {
+                            valid: false,
+                            error: this.Error.TYPE,
+                            metaData: metaData
+                        };
+                    }
+                }
+
+                // Check the maxTotalSize
+                if (options.maxTotalSize && totalSize > parseInt(options.maxTotalSize, 10)) {
+                    return {
+                        valid: false,
+                        error: this.Error.MAX_TOTAL_SIZE,
+                        metaData: {
+                            totalSize: totalSize
+                        }
+                    };
+                }
+
+                // Check the minTotalSize
+                if (options.minTotalSize && totalSize < parseInt(options.minTotalSize, 10)) {
+                    return {
+                        valid: false,
+                        error: this.Error.MIN_TOTAL_SIZE,
+                        metaData: {
+                            totalSize: totalSize
+                        }
+                    };
+                }
+            } else {
+                // Check file extension
+                ext = value.substr(value.lastIndexOf('.') + 1);
+                if (extensions && $.inArray(ext.toLowerCase(), extensions) === -1) {
+                    return {
+                        valid: false,
+                        error: this.Error.EXTENSION,
+                        metaData: {
+                            ext: ext
+                        }
+                    };
+                }
+            }
+
+            return true;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            greaterThan: {
+                'default': 'Please enter a value greater than or equal to %s',
+                notInclusive: 'Please enter a value greater than %s'
+            }
+        }
+    });
+
+    FormValidation.Validator.greaterThan = {
+        html5Attributes: {
+            message: 'message',
+            value: 'value',
+            inclusive: 'inclusive'
+        },
+
+        enableByHtml5: function($field) {
+            var type = $field.attr('type'),
+                min  = $field.attr('min');
+            if (min && type !== 'date') {
+                return {
+                    value: min
+                };
+            }
+
+            return false;
+        },
+
+        /**
+         * Return true if the input value is greater than or equals to given number
+         *
+         * @param {FormValidation.Base} validator Validate plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - value: Define the number to compare with. It can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - inclusive [optional]: Can be true or false. Default is true
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+            
+            value = this._format(value);
+
+            var locale         = validator.getLocale(),
+                compareTo      = $.isNumeric(options.value) ? options.value : validator.getDynamicOption($field, options.value),
+                compareToValue = this._format(compareTo);
+
+			return (options.inclusive === true || options.inclusive === undefined)
+                    ? {
+                        valid: $.isNumeric(value) && parseFloat(value) >= compareToValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].greaterThan['default'], compareTo)
+                    }
+                    : {
+                        valid: $.isNumeric(value) && parseFloat(value) > compareToValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].greaterThan.notInclusive, compareTo)
+                    };
+        },
+
+        _format: function(value) {
+            return (value + '').replace(',', '.');
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            identical: {
+                'default': 'Please enter the same value'
+            }
+        }
+    });
+
+    FormValidation.Validator.identical = {
+        html5Attributes: {
+            message: 'message',
+            field: 'field'
+        },
+
+        /**
+         * Bind the validator on the live change of the field to compare with current one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         */
+        init: function(validator, $field, options, validatorName) {
+            var compareWith = validator.getFieldElements(options.field);
+            validator.onLiveChange(compareWith, 'live_' + validatorName, function() {
+                var status = validator.getStatus($field, validatorName);
+                if (status !== validator.STATUS_NOT_VALIDATED) {
+                    validator.revalidateField($field);
+                }
+            });
+        },
+
+        /**
+         * Unbind the validator on the live change of the field to compare with current one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         */
+        destroy: function(validator, $field, options, validatorName) {
+            var compareWith = validator.getFieldElements(options.field);
+            validator.offLiveChange(compareWith, 'live_' + validatorName);
+        },
+
+        /**
+         * Check if input value equals to value of particular one
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - field: The name of field that will be used to compare with current one
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value       = validator.getFieldValue($field, validatorName),
+                compareWith = validator.getFieldElements(options.field);
+            if (compareWith === null || compareWith.length === 0) {
+                return true;
+            }
+
+            var compareValue = validator.getFieldValue(compareWith, validatorName);
+            if (value === compareValue) {
+                validator.updateStatus(compareWith, validator.STATUS_VALID, validatorName);
+                return true;
+            }
+
+            return false;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            integer: {
+                'default': 'Please enter a valid number'
+            }
+        }
+    });
+
+    FormValidation.Validator.integer = {
+        html5Attributes: {
+            message: 'message',
+            thousandsseparator: 'thousandsSeparator',
+            decimalseparator: 'decimalSeparator'
+        },
+
+        enableByHtml5: function($field) {
+            return ('number' === $field.attr('type')) && ($field.attr('step') === undefined || $field.attr('step') % 1 === 0);
+        },
+
+        /**
+         * Return true if the input value is an integer
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following key:
+         * - message: The invalid message
+         * - thousandsSeparator: The thousands separator. It's empty by default
+         * - decimalSeparator: The decimal separator. It's '.' by default
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            if (this.enableByHtml5($field) && $field.get(0).validity && $field.get(0).validity.badInput === true) {
+                return false;
+            }
+
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var decimalSeparator   = options.decimalSeparator   || '.',
+                thousandsSeparator = options.thousandsSeparator || '';
+            decimalSeparator       = (decimalSeparator   === '.') ? '\\.' : decimalSeparator;
+            thousandsSeparator     = (thousandsSeparator === '.') ? '\\.' : thousandsSeparator;
+
+            var testRegexp         = new RegExp('^-?[0-9]{1,3}(' + thousandsSeparator + '[0-9]{3})*(' + decimalSeparator + '[0-9]+)?$'),
+                thousandsReplacer  = new RegExp(thousandsSeparator, 'g');
+
+            if (!testRegexp.test(value)) {
+                return false;
+            }
+
+            // Replace thousands separator with blank
+            if (thousandsSeparator) {
+                value = value.replace(thousandsReplacer, '');
+            }
+            // Replace decimal separator with a dot
+            if (decimalSeparator) {
+                value = value.replace(decimalSeparator, '.');
+            }
+
+            if (isNaN(value) || !isFinite(value)) {
+                return false;
+            }
+            // TODO: Use Number.isInteger() if available
+            value = parseFloat(value);
+            return Math.floor(value) === value;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            lessThan: {
+                'default': 'Please enter a value less than or equal to %s',
+                notInclusive: 'Please enter a value less than %s'
+            }
+        }
+    });
+
+    FormValidation.Validator.lessThan = {
+        html5Attributes: {
+            message: 'message',
+            value: 'value',
+            inclusive: 'inclusive'
+        },
+
+        enableByHtml5: function($field) {
+            var type = $field.attr('type'),
+                max  = $field.attr('max');
+            if (max && type !== 'date') {
+                return {
+                    value: max
+                };
+            }
+
+            return false;
+        },
+
+        /**
+         * Return true if the input value is less than or equal to given number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - value: The number used to compare to. It can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - inclusive [optional]: Can be true or false. Default is true
+         * - message: The invalid message
+         * @returns {Boolean|Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+            
+			value = this._format(value);
+
+            var locale         = validator.getLocale(),
+                compareTo      = $.isNumeric(options.value) ? options.value : validator.getDynamicOption($field, options.value),
+                compareToValue = this._format(compareTo);
+
+            return (options.inclusive === true || options.inclusive === undefined)
+                    ? {
+                        valid: $.isNumeric(value) && parseFloat(value) <= compareToValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].lessThan['default'], compareTo)
+                    }
+                    : {
+                        valid: $.isNumeric(value) && parseFloat(value) < compareToValue,
+                        message: FormValidation.Helper.format(options.message || FormValidation.I18n[locale].lessThan.notInclusive, compareTo)
+                    };
+        },
+
+        _format: function(value) {
+            return (value + '').replace(',', '.');
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            notEmpty: {
+                'default': 'Please enter a value'
+            }
+        }
+    });
+
+    FormValidation.Validator.notEmpty = {
+        enableByHtml5: function($field) {
+            var required = $field.attr('required') + '';
+            return ('required' === required || 'true' === required);
+        },
+
+        /**
+         * Check if input value is empty or not
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var type = $field.attr('type');
+            if ('radio' === type || 'checkbox' === type) {
+                var ns = validator.getNamespace();
+                return validator
+                            .getFieldElements($field.attr('data-' + ns + '-field'))
+                            .filter(':checked')
+                            .length > 0;
+            }
+
+            if ('number' === type && $field.get(0).validity && $field.get(0).validity.badInput === true) {
+                return true;
+            }
+
+            var value = validator.getFieldValue($field, validatorName);
+            return $.trim(value) !== '';
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            numeric: {
+                'default': 'Please enter a valid float number'
+            }
+        }
+    });
+
+    FormValidation.Validator.numeric = {
+        html5Attributes: {
+            message: 'message',
+            separator: 'separator',     // deprecated
+            thousandsseparator: 'thousandsSeparator',
+            decimalseparator: 'decimalSeparator'
+        },
+
+        enableByHtml5: function($field) {
+            return ('number' === $field.attr('type')) && ($field.attr('step') !== undefined) && ($field.attr('step') % 1 !== 0);
+        },
+
+        /**
+         * Validate decimal number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consist of key:
+         * - message: The invalid message
+         * - thousandsSeparator: The thousands separator. It's empty by default
+         * - separator, decimalSeparator: The decimal separator. It's '.' by default
+         * The separator option is deprecated and should be replaced with decimalSeparator
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            if (this.enableByHtml5($field) && $field.get(0).validity && $field.get(0).validity.badInput === true) {
+                return false;
+            }
+
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var decimalSeparator   = options.separator || options.decimalSeparator || '.',
+                thousandsSeparator = options.thousandsSeparator || '';
+
+            // Support preceding zero numbers such as .5, -.5
+            if (value.substr(0, 1) === decimalSeparator) {
+                value = '0' + decimalSeparator + value.substr(1);
+            } else if (value.substr(0, 2) === '-' + decimalSeparator) {
+                value = '-0' + decimalSeparator + value.substr(2);
+            }
+
+            decimalSeparator   = (decimalSeparator   === '.') ? '\\.' : decimalSeparator;
+            thousandsSeparator = (thousandsSeparator === '.') ? '\\.' : thousandsSeparator;
+
+            var testRegexp         = new RegExp('^-?[0-9]{1,3}(' + thousandsSeparator + '[0-9]{3})*(' + decimalSeparator + '[0-9]+)?$'),
+                thousandsReplacer  = new RegExp(thousandsSeparator, 'g');
+
+            if (!testRegexp.test(value)) {
+                return false;
+            }
+
+            // Replace thousands separator with blank
+            if (thousandsSeparator) {
+                value = value.replace(thousandsReplacer, '');
+            }
+            // Replace decimal separator with a dot
+            if (decimalSeparator) {
+                value = value.replace(decimalSeparator, '.');
+            }
+
+            return !isNaN(parseFloat(value)) && isFinite(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            promise: {
+                'default': 'Please enter a valid value'
+            }
+        }
+    });
+
+    FormValidation.Validator.promise = {
+        priority: 999,
+
+        html5Attributes: {
+            message: 'message',
+            promise: 'promise'
+        },
+
+        /**
+         * Return result from a jQuery's Deferred object
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - promise: The method that passes parameters:
+         *      promise: function(fieldValue, validator, $field) {
+         *          // fieldValue is the value of field
+         *          // validator is instance of FormValidation.Base
+         *          // $field is the field element
+         *
+         *          var dfd = new $.Deferred();
+         *
+         *          // Do something ...
+         *
+         *          // Resolve when particular task is done
+         *          dfd.resolve({
+         *              valid: true or false,       // Required
+         *              message: 'Other message',   // Optional
+         *              key: value                  // You can attach more data to reuse later
+         *          });
+         *
+         *          // You can reject if there's error
+         *          dfd.reject({
+         *              message: 'Other message',   // Optional
+         *              key: value                  // You can attach more data to reuse later
+         *          });
+         *
+         *          return dfd.promise();
+         *      }
+         * - message: The invalid message
+         * @returns {Deferred}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value   = validator.getFieldValue($field, validatorName),
+                dfd     = new $.Deferred(),
+                promise = FormValidation.Helper.call(options.promise, [value, validator, $field]);
+
+            promise
+                .done(function(result) {
+                    dfd.resolve($field, validatorName, result);
+                })
+                .fail(function(result) {
+                    result = result || {};
+                    result.valid = false;
+                    dfd.resolve($field, validatorName, result);
+                });
+
+            return dfd;
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            regexp: {
+                'default': 'Please enter a value matching the pattern'
+            }
+        }
+    });
+
+    FormValidation.Validator.regexp = {
+        html5Attributes: {
+            message: 'message',
+            flags: 'flags',
+            regexp: 'regexp'
+        },
+
+        enableByHtml5: function($field) {
+            var pattern = $field.attr('pattern');
+            if (pattern) {
+                return {
+                    regexp: pattern
+                };
+            }
+
+            return false;
+        },
+
+        /**
+         * Check if the element value matches given regular expression
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of the following key:
+         * - regexp: The regular expression you need to check
+         * - flags: If specified, flags can have any combination of Javascript regular expression flags such as:
+         *      g: global match
+         *      i: ignore case
+         *      m: multiple line
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            var regexp = ('string' === typeof options.regexp)
+                        ? (options.flags ? new RegExp(options.regexp, options.flags) : new RegExp(options.regexp))
+                        : options.regexp;
+            return regexp.test(value);
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            remote: {
+                'default': 'Please enter a valid value'
+            }
+        }
+    });
+
+    FormValidation.Validator.remote = {
+        priority: 1000,
+
+        html5Attributes: {
+            async: 'async',
+            crossdomain: 'crossDomain',
+            data: 'data',
+            datatype: 'dataType',
+            delay: 'delay',
+            message: 'message',
+            name: 'name',
+            type: 'type',
+            url: 'url',
+            validkey: 'validKey'
+        },
+
+        /**
+         * Destroy the timer when destroying the FormValidation (using validator.destroy() method)
+         */
+        destroy: function(validator, $field, options, validatorName) {
+            var ns    = validator.getNamespace(),
+                timer = $field.data(ns + '.' + validatorName + '.timer');
+            if (timer) {
+                clearTimeout(timer);
+                $field.removeData(ns + '.' + validatorName + '.timer');
+            }
+        },
+
+        /**
+         * Request a remote server to check the input value
+         *
+         * @param {FormValidation.Base} validator Plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Can consist of the following keys:
+         * - async {Boolean} [optional] Indicate the Ajax request will be asynchronous or not. It's true by default
+         * - crossDomain {Boolean} [optional]
+         * - data {Object|Function} [optional]: By default, it will take the value
+         *  {
+         *      <fieldName>: <fieldValue>
+         *  }
+         * - dataType {String} [optional]: The type of data which is returned by remote server.
+         * It can be json (default), text, script
+         * - delay {Number} [optional]
+         * - headers {String[]} [optional]: Additional headers
+         * - message {String} [optional]: The invalid message
+         * - name {String} [optional]: Override the field name for the request.
+         * - type {String} [optional] Can be GET or POST (default)
+         * - url {String|Function}
+         * - validKey {String} [optional]: The valid key. It's "valid" by default
+         * This is useful when connecting to external remote server or APIs provided by 3rd parties
+         * @returns {Deferred}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var ns    = validator.getNamespace(),
+                value = validator.getFieldValue($field, validatorName),
+                dfd   = new $.Deferred();
+            if (value === '') {
+                dfd.resolve($field, validatorName, { valid: true });
+                return dfd;
+            }
+            var name     = $field.attr('data-' + ns + '-field'),
+                data     = options.data || {},
+                url      = options.url,
+                validKey = options.validKey || 'valid';
+
+            // Support dynamic data
+            if ('function' === typeof data) {
+                data = data.call(this, validator, $field, value);
+            }
+
+            // Parse string data from HTML5 attribute
+            if ('string' === typeof data) {
+                data = JSON.parse(data);
+            }
+
+            // Support dynamic url
+            if ('function' === typeof url) {
+                url = url.call(this, validator, $field, value);
+            }
+
+            data[options.name || name] = value;
+
+            var ajaxOptions = {
+                async: options.async === null || options.async === true || options.async === 'true',
+                data: data,
+                dataType: options.dataType || 'json',
+                headers: options.headers || {},
+                type: options.type || 'GET',
+                url: url
+            };
+            if (options.crossDomain !== null) {
+                ajaxOptions.crossDomain = (options.crossDomain === true || options.crossDomain === 'true');
+            }
+
+            function runCallback() {
+                var xhr = $.ajax(ajaxOptions);
+
+                xhr
+                    .success(function(response) {
+                        response.valid = (response[validKey] === true || response[validKey] === 'true')
+                                        ? true
+                                        : (response[validKey] === false || response[validKey] === 'false' ? false : null);
+                        dfd.resolve($field, validatorName, response);
+                    })
+                    .error(function(response) {
+                        dfd.resolve($field, validatorName, {
+                            valid: false
+                        });
+                    });
+
+                dfd.fail(function() {
+                    xhr.abort();
+                });
+
+                return dfd;
+            }
+            
+            if (options.delay) {
+                // Since the form might have multiple fields with the same name
+                // I have to attach the timer to the field element
+                if ($field.data(ns + '.' + validatorName + '.timer')) {
+                    clearTimeout($field.data(ns + '.' + validatorName + '.timer'));
+                }
+
+                $field.data(ns + '.' + validatorName + '.timer', setTimeout(runCallback, options.delay));
+                return dfd;
+            } else {
+                return runCallback();
+            }
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            stringLength: {
+                'default': 'Please enter a value with valid length',
+                less: 'Please enter less than %s characters',
+                more: 'Please enter more than %s characters',
+                between: 'Please enter value between %s and %s characters long'
+            }
+        }
+    });
+
+    FormValidation.Validator.stringLength = {
+        html5Attributes: {
+            message: 'message',
+            min: 'min',
+            max: 'max',
+            trim: 'trim',
+            utf8bytes: 'utf8Bytes'
+        },
+
+        enableByHtml5: function($field) {
+            var options   = {},
+                maxLength = $field.attr('maxlength'),
+                minLength = $field.attr('minlength');
+            if (maxLength) {
+                options.max = parseInt(maxLength, 10);
+            }
+            if (minLength) {
+                options.min = parseInt(minLength, 10);
+            }
+
+            return $.isEmptyObject(options) ? false : options;
+        },
+
+        /**
+         * Check if the length of element value is less or more than given number
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options Consists of following keys:
+         * - min
+         * - max
+         * At least one of two keys is required
+         * The min, max keys define the number which the field value compares to. min, max can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
+         * - message: The invalid message
+         * - trim: Indicate the length will be calculated after trimming the value or not. It is false, by default
+         * - utf8bytes: Evaluate string length in UTF-8 bytes, default to false
+         * @returns {Object}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (options.trim === true || options.trim === 'true') {
+                value = $.trim(value);
+            }
+
+            if (value === '') {
+                return true;
+            }
+
+            var locale     = validator.getLocale(),
+                min        = $.isNumeric(options.min) ? options.min : validator.getDynamicOption($field, options.min),
+                max        = $.isNumeric(options.max) ? options.max : validator.getDynamicOption($field, options.max),
+                // Credit to http://stackoverflow.com/a/23329386 (@lovasoa) for UTF-8 byte length code
+                utf8Length = function(str) {
+                                 var s = str.length;
+                                 for (var i = str.length - 1; i >= 0; i--) {
+                                     var code = str.charCodeAt(i);
+                                     if (code > 0x7f && code <= 0x7ff) {
+                                         s++;
+                                     } else if (code > 0x7ff && code <= 0xffff) {
+                                         s += 2;
+                                     }
+                                     if (code >= 0xDC00 && code <= 0xDFFF) {
+                                         i--;
+                                     }
+                                 }
+                                 return s;
+                             },
+                length     = options.utf8Bytes ? utf8Length(value) : value.length,
+                isValid    = true,
+                message    = options.message || FormValidation.I18n[locale].stringLength['default'];
+
+            if ((min && length < parseInt(min, 10)) || (max && length > parseInt(max, 10))) {
+                isValid = false;
+            }
+
+            switch (true) {
+                case (!!min && !!max):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].stringLength.between, [parseInt(min, 10), parseInt(max, 10)]);
+                    break;
+
+                case (!!min):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].stringLength.more, parseInt(min, 10) - 1);
+                    break;
+
+                case (!!max):
+                    message = FormValidation.Helper.format(options.message || FormValidation.I18n[locale].stringLength.less, parseInt(max, 10) + 1);
+                    break;
+
+                default:
+                    break;
+            }
+
+            return {
+                valid: isValid,
+                message: message
+            };
+        }
+    };
+}(jQuery));
+;(function($) {
+    FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
+        'en_US': {
+            uri: {
+                'default': 'Please enter a valid URI'
+            }
+        }
+    });
+
+    FormValidation.Validator.uri = {
+        html5Attributes: {
+            message: 'message',
+            allowlocal: 'allowLocal',
+            allowemptyprotocol: 'allowEmptyProtocol',
+            protocol: 'protocol'
+        },
+
+        enableByHtml5: function($field) {
+            return ('url' === $field.attr('type'));
+        },
+
+        /**
+         * Return true if the input value is a valid URL
+         *
+         * @param {FormValidation.Base} validator The validator plugin instance
+         * @param {jQuery} $field Field element
+         * @param {Object} options
+         * - message: The error message
+         * - allowLocal: Allow the private and local network IP. Default to false
+         * - allowEmptyProtocol: Allow the URI without protocol. Default to false
+         * - protocol: The protocols, separated by a comma. Default to "http, https, ftp"
+         * @returns {Boolean}
+         */
+        validate: function(validator, $field, options, validatorName) {
+            var value = validator.getFieldValue($field, validatorName);
+            if (value === '') {
+                return true;
+            }
+
+            // Credit to https://gist.github.com/dperini/729294
+            //
+            // Regular Expression for URL validation
+            //
+            // Author: Diego Perini
+            // Updated: 2010/12/05
+            //
+            // the regular expression composed & commented
+            // could be easily tweaked for RFC compliance,
+            // it was expressly modified to fit & satisfy
+            // these test for an URL shortener:
+            //
+            //   http://mathiasbynens.be/demo/url-regex
+            //
+            // Notes on possible differences from a standard/generic validation:
+            //
+            // - utf-8 char class take in consideration the full Unicode range
+            // - TLDs are mandatory unless `allowLocal` is true
+            // - protocols have been restricted to ftp, http and https only as requested
+            //
+            // Changes:
+            //
+            // - IP address dotted notation validation, range: 1.0.0.0 - 223.255.255.255
+            //   first and last IP address of each class is considered invalid
+            //   (since they are broadcast/network addresses)
+            //
+            // - Added exclusion of private, reserved and/or local networks ranges
+            //   unless `allowLocal` is true
+            //
+            // - Added possibility of choosing a custom protocol
+            //
+            // - Add option to validate without protocol
+            //
+            var allowLocal         = options.allowLocal === true || options.allowLocal === 'true',
+                allowEmptyProtocol = options.allowEmptyProtocol === true || options.allowEmptyProtocol === 'true',
+                protocol           = (options.protocol || 'http, https, ftp').split(',').join('|').replace(/\s/g, ''),
+                urlExp             = new RegExp(
+                    "^" +
+                    // protocol identifier
+                    "(?:(?:" + protocol + ")://)" +
+                    // allow empty protocol
+                    (allowEmptyProtocol ? '?' : '') +
+                    // user:pass authentication
+                    "(?:\\S+(?::\\S*)?@)?" +
+                    "(?:" +
+                    // IP address exclusion
+                    // private & local networks
+                    (allowLocal
+                        ? ''
+                        : ("(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
+                           "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
+                           "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})")) +
+                    // IP address dotted notation octets
+                    // excludes loopback network 0.0.0.0
+                    // excludes reserved space >= 224.0.0.0
+                    // excludes network & broadcast addresses
+                    // (first & last IP address of each class)
+                    "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
+                    "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
+                    "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
+                    "|" +
+                    // host name
+                    "(?:(?:[a-z\\u00a1-\\uffff0-9]-?)*[a-z\\u00a1-\\uffff0-9]+)" +
+                    // domain name
+                    "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-?)*[a-z\\u00a1-\\uffff0-9])*" +
+                    // TLD identifier
+                    "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
+                    // Allow intranet sites (no TLD) if `allowLocal` is true
+                    (allowLocal ? '?' : '') +
+                    ")" +
+                    // port number
+                    "(?::\\d{2,5})?" +
+                    // resource path
+                    "(?:/[^\\s]*)?" +
+                    "$", "i"
+                );
+
+            return urlExp.test(value);
+        }
+    };
+}(jQuery));

File diff ditekan karena terlalu besar
+ 34 - 0
static/formvalidation/js/formValidation.popular.min.js


+ 276 - 0
static/formvalidation/js/framework/bootstrap.js

@@ -0,0 +1,276 @@
+/**
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+
+/**
+ * This class supports validating Bootstrap form (http://getbootstrap.com/)
+ */
+(function($) {
+    FormValidation.Framework.Bootstrap = function(element, options, namespace) {
+        options = $.extend(true, {
+            button: {
+                selector: '[type="submit"]:not([formnovalidate])',
+                // The class of disabled button
+                // http://getbootstrap.com/css/#buttons-disabled
+                disabled: 'disabled'
+            },
+            err: {
+                // http://getbootstrap.com/css/#forms-help-text
+                clazz: 'help-block',
+                parent: '^(.*)col-(xs|sm|md|lg)-(offset-){0,1}[0-9]+(.*)$'
+            },
+            // This feature requires Bootstrap v3.1.0 or later (http://getbootstrap.com/css/#forms-control-validation).
+            // Since Bootstrap doesn't provide any methods to know its version, this option cannot be on/off automatically.
+            // In other word, to use this feature you have to upgrade your Bootstrap to v3.1.0 or later.
+            //
+            // Examples:
+            // - Use Glyphicons icons:
+            //  icon: {
+            //      valid: 'glyphicon glyphicon-ok',
+            //      invalid: 'glyphicon glyphicon-remove',
+            //      validating: 'glyphicon glyphicon-refresh',
+            //      feedback: 'form-control-feedback'
+            //  }
+            // - Use FontAwesome icons:
+            //  icon: {
+            //      valid: 'fa fa-check',
+            //      invalid: 'fa fa-times',
+            //      validating: 'fa fa-refresh',
+            //      feedback: 'form-control-feedback'
+            //  }
+            icon: {
+                valid: null,
+                invalid: null,
+                validating: null,
+                feedback: 'form-control-feedback'
+            },
+            row: {
+                // By default, each field is placed inside the <div class="form-group"></div>
+                // http://getbootstrap.com/css/#forms
+                selector: '.form-group',
+                valid: 'has-success',
+                invalid: 'has-error',
+                feedback: 'has-feedback'
+            }
+        }, options);
+
+        FormValidation.Base.apply(this, [element, options, namespace]);
+    };
+
+    FormValidation.Framework.Bootstrap.prototype = $.extend({}, FormValidation.Base.prototype, {
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+            var ns      = this._namespace,
+                type    = $field.attr('type'),
+                field   = $field.attr('data-' + ns + '-field'),
+                row     = this.options.fields[field].row || this.options.row.selector,
+                $parent = $field.closest(row);
+
+            // Place it after the container of checkbox/radio
+            // so when clicking the icon, it doesn't effect to the checkbox/radio element
+            if ('checkbox' === type || 'radio' === type) {
+                var $fieldParent = $field.parent();
+                if ($fieldParent.hasClass(type)) {
+                    $icon.insertAfter($fieldParent);
+                } else if ($fieldParent.parent().hasClass(type)) {
+                    $icon.insertAfter($fieldParent.parent());
+                }
+            }
+
+            // Fix feedback icons in input-group
+            if ($parent.find('.input-group').length !== 0) {
+                $icon.addClass('fv-bootstrap-icon-input-group')
+                     .insertAfter($parent.find('.input-group').eq(0));
+            }
+        },
+
+        /**
+         * Create a tooltip or popover
+         * It will be shown when focusing on the field
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} message The message
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _createTooltip: function($field, message, type) {
+            var ns    = this._namespace,
+                $icon = $field.data(ns + '.icon');
+            if ($icon) {
+                switch (type) {
+                    case 'popover':
+                        $icon
+                            .css({
+                                'cursor': 'pointer',
+                                'pointer-events': 'auto'
+                            })
+                            .popover('destroy')
+                            .popover({
+                                container: 'body',
+                                content: message,
+                                html: true,
+                                placement: 'auto top',
+                                trigger: 'hover click'
+                            });
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon
+                            .css({
+                                'cursor': 'pointer',
+                                'pointer-events': 'auto'
+                            })
+                            .tooltip('destroy')
+                            .tooltip({
+                                container: 'body',
+                                html: true,
+                                placement: 'auto top',
+                                title: message
+                            });
+                        break;
+                }
+            }
+        },
+
+        /**
+         * Destroy the tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _destroyTooltip: function($field, type) {
+            var ns    = this._namespace,
+                $icon = $field.data(ns + '.icon');
+            if ($icon) {
+                switch (type) {
+                    case 'popover':
+                        $icon
+                            .css({
+                                'cursor': '',
+                                'pointer-events': 'none'
+                            })
+                            .popover('destroy');
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon
+                            .css({
+                                'cursor': '',
+                                'pointer-events': 'none'
+                            })
+                            .tooltip('destroy');
+                        break;
+                }
+            }
+        },
+
+        /**
+         * Hide a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _hideTooltip: function($field, type) {
+            var ns    = this._namespace,
+                $icon = $field.data(ns + '.icon');
+            if ($icon) {
+                switch (type) {
+                    case 'popover':
+                        $icon.popover('hide');
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon.tooltip('hide');
+                        break;
+                }
+            }
+        },
+
+        /**
+         * Show a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _showTooltip: function($field, type) {
+            var ns    = this._namespace,
+                $icon = $field.data(ns + '.icon');
+            if ($icon) {
+                switch (type) {
+                    case 'popover':
+                        $icon.popover('show');
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon.tooltip('show');
+                        break;
+                }
+            }
+        }
+    });
+
+    /**
+     * Plugin definition
+     * Support backward
+     * @deprecated It will be removed soon. Instead of using $(form).bootstrapValidator(), use
+     *  $(form).formValidation({
+     *      framework: 'bootstrap'  // It's equivalent to use data-fv-framework="bootstrap" for <form>
+     *  });
+     */
+    $.fn.bootstrapValidator = function(option) {
+        var params = arguments;
+        return this.each(function() {
+            var $this   = $(this),
+                data    = $this.data('formValidation') || $this.data('bootstrapValidator'),
+                options = 'object' === typeof option && option;
+            if (!data) {
+                data = new FormValidation.Framework.Bootstrap(this, $.extend({}, {
+                    events: {
+                        // Support backward
+                        formInit: 'init.form.bv',
+                        formPreValidate: 'prevalidate.form.bv',
+                        formError: 'error.form.bv',
+                        formSuccess: 'success.form.bv',
+                        fieldAdded: 'added.field.bv',
+                        fieldRemoved: 'removed.field.bv',
+                        fieldInit: 'init.field.bv',
+                        fieldError: 'error.field.bv',
+                        fieldSuccess: 'success.field.bv',
+                        fieldStatus: 'status.field.bv',
+                        localeChanged: 'changed.locale.bv',
+                        validatorError: 'error.validator.bv',
+                        validatorSuccess: 'success.validator.bv'
+                    }
+                }, options), 'bv');
+
+                $this.addClass('fv-form-bootstrap')
+                     .data('formValidation', data)
+                     .data('bootstrapValidator', data);
+            }
+
+            // Allow to call plugin method
+            if ('string' === typeof option) {
+                data[option].apply(data, Array.prototype.slice.call(params, 1));
+            }
+        });
+    };
+
+    $.fn.bootstrapValidator.Constructor = FormValidation.Framework.Bootstrap;
+}(jQuery));

File diff ditekan karena terlalu besar
+ 9 - 0
static/formvalidation/js/framework/bootstrap.min.js


+ 215 - 0
static/formvalidation/js/framework/bootstrap4.js

@@ -0,0 +1,215 @@
+/**
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+
+/**
+ * This class supports validating Bootstrap 4 alpha form (http://v4-alpha.getbootstrap.com/)
+ */
+(function($) {
+    FormValidation.Framework.Bootstrap4 = function(element, options, namespace) {
+        options = $.extend(true, {
+            button: {
+                selector: '[type="submit"]:not([formnovalidate])',
+                // The class of disabled button
+                disabled: 'disabled'
+            },
+            err: {
+                // http://v4-alpha.getbootstrap.com/components/forms/#validation
+                clazz: 'form-control-feedback',
+                parent: '^(.*)(col|offset)-(xs|sm|md|lg)-[0-9]+(.*)$'
+            },
+            // - Use FontAwesome icons:
+            //  icon: {
+            //      valid: 'fa fa-check',
+            //      invalid: 'fa fa-times',
+            //      validating: 'fa fa-refresh',
+            //      feedback: 'form-control-feedback'
+            //  }
+            icon: {
+                valid: null,
+                invalid: null,
+                validating: null,
+                feedback: 'fv-control-feedback'
+            },
+            row: {
+                // By default, each field is placed inside the <div class="form-group"></div>
+                // http://v4-alpha.getbootstrap.com/components/forms/#form-groups
+                selector: '.form-group',
+                valid: 'has-success',
+                invalid: 'has-warning',
+                feedback: 'fv-has-feedback'
+            }
+        }, options);
+
+        FormValidation.Base.apply(this, [element, options, namespace]);
+    };
+
+    FormValidation.Framework.Bootstrap4.prototype = $.extend({}, FormValidation.Base.prototype, {
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+            var ns      = this._namespace,
+                type    = $field.attr('type'),
+                field   = $field.attr('data-' + ns + '-field'),
+                row     = this.options.fields[field].row || this.options.row.selector,
+                $parent = $field.closest(row);
+
+            // Place it after the container of checkbox/radio
+            // so when clicking the icon, it doesn't effect to the checkbox/radio element
+            if ('checkbox' === type || 'radio' === type) {
+                var $fieldParent = $field.parent();
+                if ($fieldParent.hasClass('form-check')) {
+                    $icon.insertAfter($fieldParent);
+                } else if ($fieldParent.parent().hasClass('form-check')) {
+                    $icon.insertAfter($fieldParent.parent());
+                }
+            }
+
+            // Fix feedback icons in input-group
+            if ($parent.find('.input-group').length !== 0) {
+                $icon.addClass('fv-bootstrap-icon-input-group')
+                     .insertAfter($parent.find('.input-group').eq(0));
+            }
+        },
+
+        /**
+         * Create a tooltip or popover
+         * It will be shown when focusing on the field
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} message The message
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _createTooltip: function($field, message, type) {
+            var ns    = this._namespace,
+                $icon = $field.data(ns + '.icon');
+            if ($icon) {
+                switch (type) {
+                    case 'popover':
+                        $icon
+                            .css({
+                                'cursor': 'pointer',
+                                'pointer-events': 'auto'
+                            })
+                            .popover('destroy')
+                            .popover({
+                                container: 'body',
+                                content: message,
+                                html: true,
+                                placement: 'top',
+                                trigger: 'hover click'
+                            });
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon
+                            .css({
+                                'cursor': 'pointer',
+                                'pointer-events': 'auto'
+                            })
+                            .tooltip('dispose')
+                            .tooltip({
+                                container: 'body',
+                                html: true,
+                                placement: 'top',
+                                title: message
+                            });
+                        break;
+                }
+            }
+        },
+
+        /**
+         * Destroy the tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _destroyTooltip: function($field, type) {
+            var ns    = this._namespace,
+                $icon = $field.data(ns + '.icon');
+            if ($icon) {
+                switch (type) {
+                    case 'popover':
+                        $icon
+                            .css({
+                                'cursor': '',
+                                'pointer-events': 'none'
+                            })
+                            .popover('destroy');
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon
+                            .css({
+                                'cursor': '',
+                                'pointer-events': 'none'
+                            })
+                            .tooltip('dispose');
+                        break;
+                }
+            }
+        },
+
+        /**
+         * Hide a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _hideTooltip: function($field, type) {
+            var ns    = this._namespace,
+                $icon = $field.data(ns + '.icon');
+            if ($icon) {
+                switch (type) {
+                    case 'popover':
+                        $icon.popover('hide');
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon.tooltip('hide');
+                        break;
+                }
+            }
+        },
+
+        /**
+         * Show a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _showTooltip: function($field, type) {
+            var ns    = this._namespace,
+                $icon = $field.data(ns + '.icon');
+            if ($icon) {
+                switch (type) {
+                    case 'popover':
+                        $icon.popover('show');
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon.tooltip('show');
+                        break;
+                }
+            }
+        }
+    });
+}(jQuery));

File diff ditekan karena terlalu besar
+ 9 - 0
static/formvalidation/js/framework/bootstrap4.min.js


+ 149 - 0
static/formvalidation/js/framework/foundation.js

@@ -0,0 +1,149 @@
+/**
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+
+/**
+ * This class supports validating Foundation v6+ form (http://foundation.zurb.com/)
+ */
+/* global Foundation: false */
+(function($) {
+    FormValidation.Framework.Foundation = function(element, options) {
+        options = $.extend(true, {
+            button: {
+                selector: '[type="submit"]:not([formnovalidate])',
+                // The class for disabled button
+                // http://foundation.zurb.com/docs/components/buttons.html#button-colors
+                disabled: 'disabled'
+            },
+            err: {
+                // http://foundation.zurb.com/sites/docs/abide.html
+                clazz: 'form-error',
+                parent: '^.*((small|medium|large)-[0-9]+)\\s.*(columns).*$'
+            },
+            // Foundation doesn't support feedback icon
+            icon: {
+                valid: null,
+                invalid: null,
+                validating: null,
+                feedback: 'fv-control-feedback'
+            },
+            row: {
+                selector: '.row',
+                valid: 'fv-has-success',
+                invalid: 'fv-has-error',
+                feedback: 'fv-has-feedback'
+            }
+        }, options);
+
+        FormValidation.Base.apply(this, [element, options]);
+    };
+
+    FormValidation.Framework.Foundation.prototype = $.extend({}, FormValidation.Base.prototype, {
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+            var ns      = this._namespace,
+                type    = $field.attr('type'),
+                field   = $field.attr('data-' + ns + '-field'),
+                row     = this.options.fields[field].row || this.options.row.selector;
+
+            if ('checkbox' === type || 'radio' === type) {
+                var $next = $icon.next();
+                if ($next.is('label')) {
+                    $icon.insertAfter($next);
+                }
+            }
+        },
+
+        /**
+         * Create a tooltip or popover
+         * It will be shown when focusing on the field
+         *
+         * @see http://foundation.zurb.com/sites/docs/tooltip.html
+         * @param {jQuery} $field The field element
+         * @param {String} message The message
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _createTooltip: function($field, message, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                var tooltip = $icon.data('fv.foundation.tooltip');
+                if (tooltip) {
+                    tooltip.destroy();
+                }
+
+                $icon.css('cursor', 'pointer')
+                     .off('.zf.tooltip')
+                     .data('fv.foundation.tooltip', new Foundation.Tooltip($icon, {
+                         templateClasses: 'fv-foundation-tooltip',
+                         tipText: message
+                     }));
+            }
+        },
+
+        /**
+         * Destroy the tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _destroyTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon.removeAttr('title')
+                     .removeAttr('data-tooltip')
+                     .css('cursor', '')
+                     .off('.zf.tooltip');
+
+                var tooltip = $icon.data('fv.foundation.tooltip');
+                if (tooltip) {
+                    tooltip.destroy();
+                    $icon.removeData('fv.foundation.tooltip');
+                }
+            }
+        },
+
+        /**
+         * Hide a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _hideTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon.css('cursor', '');
+                var tooltip = $icon.data('fv.foundation.tooltip');
+                if (tooltip) {
+                    tooltip.hide();
+                }
+            }
+        },
+
+        /**
+         * Show a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _showTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon.css('cursor', 'pointer');
+                var tooltip = $icon.data('fv.foundation.tooltip');
+                if (tooltip) {
+                    tooltip.show();
+                }
+            }
+        }
+    });
+}(jQuery));

+ 10 - 0
static/formvalidation/js/framework/foundation.min.js

@@ -0,0 +1,10 @@
+/*!
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @version     v0.8.1, built on 2016-07-29 1:10:56 AM
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+!function(a){FormValidation.Framework.Foundation=function(b,c){c=a.extend(!0,{button:{selector:'[type="submit"]:not([formnovalidate])',disabled:"disabled"},err:{clazz:"form-error",parent:"^.*((small|medium|large)-[0-9]+)\\s.*(columns).*$"},icon:{valid:null,invalid:null,validating:null,feedback:"fv-control-feedback"},row:{selector:".row",valid:"fv-has-success",invalid:"fv-has-error",feedback:"fv-has-feedback"}},c),FormValidation.Base.apply(this,[b,c])},FormValidation.Framework.Foundation.prototype=a.extend({},FormValidation.Base.prototype,{_fixIcon:function(a,b){var c=this._namespace,d=a.attr("type"),e=a.attr("data-"+c+"-field");this.options.fields[e].row||this.options.row.selector;if("checkbox"===d||"radio"===d){var f=b.next();f.is("label")&&b.insertAfter(f)}},_createTooltip:function(a,b,c){var d=a.data("fv.icon");if(d){var e=d.data("fv.foundation.tooltip");e&&e.destroy(),d.css("cursor","pointer").off(".zf.tooltip").data("fv.foundation.tooltip",new Foundation.Tooltip(d,{templateClasses:"fv-foundation-tooltip",tipText:b}))}},_destroyTooltip:function(a,b){var c=a.data("fv.icon");if(c){c.removeAttr("title").removeAttr("data-tooltip").css("cursor","").off(".zf.tooltip");var d=c.data("fv.foundation.tooltip");d&&(d.destroy(),c.removeData("fv.foundation.tooltip"))}},_hideTooltip:function(a,b){var c=a.data("fv.icon");if(c){c.css("cursor","");var d=c.data("fv.foundation.tooltip");d&&d.hide()}},_showTooltip:function(a,b){var c=a.data("fv.icon");if(c){c.css("cursor","pointer");var d=c.data("fv.foundation.tooltip");d&&d.show()}}})}(jQuery);

+ 161 - 0
static/formvalidation/js/framework/foundation5.js

@@ -0,0 +1,161 @@
+/**
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+
+/**
+ * This class supports validating Foundation v5 form
+ * The latest supported version is Foundation v5.3.3
+ * @see http://foundation.zurb.com/sites/docs/v/5.5.3/
+ */
+/* global Foundation: false */
+(function($) {
+    FormValidation.Framework.Foundation5 = function(element, options) {
+        options = $.extend(true, {
+            button: {
+                selector: '[type="submit"]:not([formnovalidate])',
+                // The class for disabled button
+                // http://foundation.zurb.com/sites/docs/v/5.5.3/components/buttons.html
+                disabled: 'disabled'
+            },
+            err: {
+                // http://foundation.zurb.com/sites/docs/v/5.5.3/components/forms.html
+                clazz: 'error',
+                parent: '^.*((small|medium|large)-[0-9]+)\\s.*(columns).*$'
+            },
+            // Foundation doesn't support feedback icon
+            icon: {
+                valid: null,
+                invalid: null,
+                validating: null,
+                feedback: 'fv-control-feedback'
+            },
+            row: {
+                // http://foundation.zurb.com/sites/docs/v/5.5.3/components/forms.html
+                selector: '.row',
+                valid: 'fv-has-success',
+                invalid: 'error',
+                feedback: 'fv-has-feedback'
+            }
+        }, options);
+
+        FormValidation.Base.apply(this, [element, options]);
+    };
+
+    FormValidation.Framework.Foundation5.prototype = $.extend({}, FormValidation.Base.prototype, {
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+            var ns      = this._namespace,
+                type    = $field.attr('type'),
+                field   = $field.attr('data-' + ns + '-field'),
+                row     = this.options.fields[field].row || this.options.row.selector,
+                $parent = $field.closest(row);
+
+            if ('checkbox' === type || 'radio' === type) {
+                var $next = $icon.next();
+                if ($next.is('label')) {
+                    $icon.insertAfter($next);
+                }
+            }
+        },
+
+        /**
+         * Create a tooltip or popover
+         * It will be shown when focusing on the field
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} message The message
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _createTooltip: function($field, message, type) {
+            var that  = this,
+                $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon
+                    .attr('title', message)
+                    .css({
+                        'cursor': 'pointer'
+                    })
+                    .off('mouseenter.container.fv focusin.container.fv')
+                    .on('mouseenter.container.fv', function() {
+                        that._showTooltip($field, type);
+                    })
+                    .off('mouseleave.container.fv focusout.container.fv')
+                    .on('mouseleave.container.fv focusout.container.fv', function() {
+                        that._hideTooltip($field, type);
+                    });
+                Foundation.libs.tooltip.create($icon);
+                $icon.data('fv.foundation.tooltip', $icon);
+            }
+        },
+
+        /**
+         * Destroy the tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _destroyTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon.css({
+                    'cursor': ''
+                });
+                var $tooltip = $icon.data('fv.foundation.tooltip');
+                if ($tooltip) {
+                    // Foundation doesn't provide method to destroy particular tooltip instance
+                    $tooltip.off('.fndtn.tooltip');
+                    Foundation.libs.tooltip.hide($tooltip);
+                    $icon.removeData('fv.foundation.tooltip');
+                }
+            }
+        },
+
+        /**
+         * Hide a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _hideTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon.css({
+                    'cursor': ''
+                });
+                var $tooltip = $icon.data('fv.foundation.tooltip');
+                if ($tooltip) {
+                    Foundation.libs.tooltip.hide($tooltip);
+                }
+            }
+        },
+
+        /**
+         * Show a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _showTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                var $tooltip = $icon.data('fv.foundation.tooltip');
+                if ($tooltip) {
+                    $icon.css({
+                        'cursor': 'pointer'
+                    });
+                    Foundation.libs.tooltip.show($tooltip);
+                }
+            }
+        }
+    });
+}(jQuery));

+ 10 - 0
static/formvalidation/js/framework/foundation5.min.js

@@ -0,0 +1,10 @@
+/*!
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @version     v0.8.1, built on 2016-07-29 1:10:56 AM
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+!function(a){FormValidation.Framework.Foundation5=function(b,c){c=a.extend(!0,{button:{selector:'[type="submit"]:not([formnovalidate])',disabled:"disabled"},err:{clazz:"error",parent:"^.*((small|medium|large)-[0-9]+)\\s.*(columns).*$"},icon:{valid:null,invalid:null,validating:null,feedback:"fv-control-feedback"},row:{selector:".row",valid:"fv-has-success",invalid:"error",feedback:"fv-has-feedback"}},c),FormValidation.Base.apply(this,[b,c])},FormValidation.Framework.Foundation5.prototype=a.extend({},FormValidation.Base.prototype,{_fixIcon:function(a,b){var c=this._namespace,d=a.attr("type"),e=a.attr("data-"+c+"-field"),f=this.options.fields[e].row||this.options.row.selector;a.closest(f);if("checkbox"===d||"radio"===d){var g=b.next();g.is("label")&&b.insertAfter(g)}},_createTooltip:function(a,b,c){var d=this,e=a.data("fv.icon");e&&(e.attr("title",b).css({cursor:"pointer"}).off("mouseenter.container.fv focusin.container.fv").on("mouseenter.container.fv",function(){d._showTooltip(a,c)}).off("mouseleave.container.fv focusout.container.fv").on("mouseleave.container.fv focusout.container.fv",function(){d._hideTooltip(a,c)}),Foundation.libs.tooltip.create(e),e.data("fv.foundation.tooltip",e))},_destroyTooltip:function(a,b){var c=a.data("fv.icon");if(c){c.css({cursor:""});var d=c.data("fv.foundation.tooltip");d&&(d.off(".fndtn.tooltip"),Foundation.libs.tooltip.hide(d),c.removeData("fv.foundation.tooltip"))}},_hideTooltip:function(a,b){var c=a.data("fv.icon");if(c){c.css({cursor:""});var d=c.data("fv.foundation.tooltip");d&&Foundation.libs.tooltip.hide(d)}},_showTooltip:function(a,b){var c=a.data("fv.icon");if(c){var d=c.data("fv.foundation.tooltip");d&&(c.css({cursor:"pointer"}),Foundation.libs.tooltip.show(d))}}})}(jQuery);

+ 65 - 0
static/formvalidation/js/framework/pure.js

@@ -0,0 +1,65 @@
+/**
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+
+/**
+ * This class supports validating Pure framework (http://purecss.io/)
+ */
+(function($) {
+    FormValidation.Framework.Pure = function(element, options) {
+        options = $.extend(true, {
+            button: {
+                selector: '[type="submit"]:not([formnovalidate])',
+                // The class of disabled button
+                // http://purecss.io/buttons/#disabled-buttons
+                disabled: 'pure-button-disabled'
+            },
+            err: {
+                clazz: 'fv-help-block',
+                parent: '^.*pure-control-group.*$'
+            },
+            // Pure doesn't support feedback icon
+            icon: {
+                valid: null,
+                invalid: null,
+                validating: null,
+                feedback: 'fv-control-feedback'
+            },
+            row: {
+                // http://purecss.io/forms/#aligned-form
+                selector: '.pure-control-group',
+                valid: 'fv-has-success',
+                invalid: 'fv-has-error',
+                feedback: 'fv-has-feedback'
+            }
+        }, options);
+
+        FormValidation.Base.apply(this, [element, options]);
+    };
+
+    FormValidation.Framework.Pure.prototype = $.extend({}, FormValidation.Base.prototype, {
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+            var ns      = this._namespace,
+                type    = $field.attr('type'),
+                field   = $field.attr('data-' + ns + '-field'),
+                $parent = $field.parent();
+
+            if ('checkbox' === type || 'radio' === type) {
+                if ($parent.is('label')) {
+                    $icon.insertAfter($parent);
+                }
+            }
+        }
+    });
+}(jQuery));

+ 10 - 0
static/formvalidation/js/framework/pure.min.js

@@ -0,0 +1,10 @@
+/*!
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @version     v0.8.1, built on 2016-07-29 1:10:56 AM
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+!function(a){FormValidation.Framework.Pure=function(b,c){c=a.extend(!0,{button:{selector:'[type="submit"]:not([formnovalidate])',disabled:"pure-button-disabled"},err:{clazz:"fv-help-block",parent:"^.*pure-control-group.*$"},icon:{valid:null,invalid:null,validating:null,feedback:"fv-control-feedback"},row:{selector:".pure-control-group",valid:"fv-has-success",invalid:"fv-has-error",feedback:"fv-has-feedback"}},c),FormValidation.Base.apply(this,[b,c])},FormValidation.Framework.Pure.prototype=a.extend({},FormValidation.Base.prototype,{_fixIcon:function(a,b){var c=this._namespace,d=a.attr("type"),e=(a.attr("data-"+c+"-field"),a.parent());("checkbox"===d||"radio"===d)&&e.is("label")&&b.insertAfter(e)}})}(jQuery);

+ 163 - 0
static/formvalidation/js/framework/semantic.js

@@ -0,0 +1,163 @@
+/**
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+
+/**
+ * This class supports validating SemanticUI form (http://semantic-ui.com/)
+ */
+(function($) {
+    FormValidation.Framework.Semantic = function(element, options) {
+        options = $.extend(true, {
+            button: {
+                selector: '[type="submit"]:not([formnovalidate])',
+                // CSS class of disabled button
+                // http://semantic-ui.com/elements/button.html#disabled
+                disabled: 'disabled'
+            },
+            control: {
+                valid: '',
+                invalid: ''
+            },
+            err: {
+                // http://semantic-ui.com/elements/label.html#pointing
+                clazz: 'ui red pointing label',
+                parent: '^.*(field|column).*$'
+            },
+            // When using feedback icon, the input must place inside 'ui input icon' element
+            //  <div class="ui input icon">
+            //      <input type="text" />
+            //  </div>
+            // See http://semantic-ui.com/elements/input.html#icon
+            icon: {
+                // http://semantic-ui.com/elements/icon.html
+                valid: null,        // 'checkmark icon'
+                invalid: null,      // 'remove icon'
+                validating: null,   // 'refresh icon'
+                feedback: 'fv-control-feedback'
+            },
+            row: {
+                // http://semantic-ui.com/collections/form.html
+                selector: '.fields',
+                valid: 'fv-has-success',
+                invalid: 'error',
+                feedback: 'fv-has-feedback'
+            }
+        }, options);
+
+        FormValidation.Base.apply(this, [element, options]);
+    };
+
+    FormValidation.Framework.Semantic.prototype = $.extend({}, FormValidation.Base.prototype, {
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+            var type = $field.attr('type');
+            if ('checkbox' === type || 'radio' === type) {
+                var $fieldParent = $field.parent();
+                if ($fieldParent.hasClass(type)) {
+                    $icon.insertAfter($fieldParent);
+                }
+            }
+        },
+
+        /**
+         * Create a tooltip or popover
+         * It will be shown when focusing on the field
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} message The message
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _createTooltip: function($field, message, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                // Remove the popup if it's already exists
+                if ($icon.popup('exists')) {
+                    $icon.popup('remove popup')
+                         .popup('destroy');
+                }
+
+                // http://semantic-ui.com/modules/popup.html
+                switch (type) {
+                    case 'popover':
+                        $icon
+                            .css({
+                                'cursor': 'pointer'
+                            })
+                            .popup({
+                                content: message,
+                                position: 'top center'
+                            });
+                        break;
+
+                    case 'tooltip':
+                    /* falls through */
+                    default:
+                        $icon
+                            .css({
+                                'cursor': 'pointer'
+                            })
+                            .popup({
+                                content: message,
+                                position: 'top center',
+                                variation: 'inverted'
+                            });
+                        break;
+                }
+            }
+        },
+
+        /**
+         * Destroy the tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _destroyTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon && $icon.popup('exists')) {
+                $icon
+                    .css({
+                        'cursor': ''
+                    })
+                    .popup('remove popup')
+                    .popup('destroy');
+            }
+        },
+
+        /**
+         * Hide a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _hideTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon.popup('hide');
+            }
+        },
+
+        /**
+         * Show a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _showTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon.popup('show');
+            }
+        }
+    });
+}(jQuery));

+ 10 - 0
static/formvalidation/js/framework/semantic.min.js

@@ -0,0 +1,10 @@
+/*!
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @version     v0.8.1, built on 2016-07-29 1:10:56 AM
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+!function(a){FormValidation.Framework.Semantic=function(b,c){c=a.extend(!0,{button:{selector:'[type="submit"]:not([formnovalidate])',disabled:"disabled"},control:{valid:"",invalid:""},err:{clazz:"ui red pointing label",parent:"^.*(field|column).*$"},icon:{valid:null,invalid:null,validating:null,feedback:"fv-control-feedback"},row:{selector:".fields",valid:"fv-has-success",invalid:"error",feedback:"fv-has-feedback"}},c),FormValidation.Base.apply(this,[b,c])},FormValidation.Framework.Semantic.prototype=a.extend({},FormValidation.Base.prototype,{_fixIcon:function(a,b){var c=a.attr("type");if("checkbox"===c||"radio"===c){var d=a.parent();d.hasClass(c)&&b.insertAfter(d)}},_createTooltip:function(a,b,c){var d=a.data("fv.icon");if(d)switch(d.popup("exists")&&d.popup("remove popup").popup("destroy"),c){case"popover":d.css({cursor:"pointer"}).popup({content:b,position:"top center"});break;case"tooltip":default:d.css({cursor:"pointer"}).popup({content:b,position:"top center",variation:"inverted"})}},_destroyTooltip:function(a,b){var c=a.data("fv.icon");c&&c.popup("exists")&&c.css({cursor:""}).popup("remove popup").popup("destroy")},_hideTooltip:function(a,b){var c=a.data("fv.icon");c&&c.popup("hide")},_showTooltip:function(a,b){var c=a.data("fv.icon");c&&c.popup("show")}})}(jQuery);

+ 165 - 0
static/formvalidation/js/framework/uikit.js

@@ -0,0 +1,165 @@
+/**
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+
+/**
+ * This class supports validating UIKit form (http://getuikit.com/)
+ */
+(function($) {
+    FormValidation.Framework.Uikit = function(element, options) {
+        options = $.extend(true, {
+            button: {
+                selector: '[type="submit"]:not([formnovalidate])',
+                // The class for disabled button
+                // http://getuikit.com/docs/button.html
+                disabled: 'disabled'
+            },
+            control: {
+                valid: 'uk-form-success',
+                invalid: 'uk-form-danger'
+            },
+            err: {
+                // http://getuikit.com/docs/text.html#text-styles
+                clazz: 'uk-text-danger',
+                parent: '^.*(uk-form-controls|uk-width-[\\d+]-[\\d+]).*$'
+            },
+            // UIKit doesn't support feedback icon
+            icon: {
+                valid: null,
+                invalid: null,
+                validating: null,
+                feedback: 'fv-control-feedback'
+            },
+            row: {
+                // http://getuikit.com/docs/form.html
+                selector: '.uk-form-row',
+                valid: 'fv-has-success',
+                invalid: 'fv-has-error',
+                feedback: 'fv-has-feedback'
+            }
+        }, options);
+
+        FormValidation.Base.apply(this, [element, options]);
+    };
+
+    FormValidation.Framework.Uikit.prototype = $.extend({}, FormValidation.Base.prototype, {
+        /**
+         * Specific framework might need to adjust the icon position
+         *
+         * @param {jQuery} $field The field element
+         * @param {jQuery} $icon The icon element
+         */
+        _fixIcon: function($field, $icon) {
+            var ns      = this._namespace,
+                type    = $field.attr('type'),
+                field   = $field.attr('data-' + ns + '-field'),
+                $parent = $field.parent();
+
+            if ('checkbox' === type || 'radio' === type) {
+                if ($parent.is('label')) {
+                    $icon.insertAfter($parent);
+                }
+            }
+
+            // Support UIKit form-password component
+            // http://getuikit.com/docs/form-password.html
+            if ($parent.hasClass('uk-form-password')) {
+                $icon.insertAfter($parent);
+            }
+        },
+
+        /**
+         * Create a tooltip or popover
+         * It will be shown when focusing on the field
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} message The message
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _createTooltip: function($field, message, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                // Remove the tooltip if it's already exists
+                if ($icon.data('tooltip')) {
+                    $icon.data('tooltip').off();
+                    $icon.removeData('tooltip');
+                }
+
+                $icon
+                    .attr('title', message)
+                    .css({
+                        'cursor': 'pointer'
+                    });
+
+                new $.UIkit.tooltip($icon);
+                // UIKit auto set the 'tooltip' data for the element
+                // so I can retrieve the tooltip later via $icon.data('tooltip')
+            }
+        },
+
+        /**
+         * Destroy the tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _destroyTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                var tooltip = $icon.data('tooltip');
+                if (tooltip) {
+                    tooltip.hide();
+                    tooltip.off();
+                    $icon.off('focus mouseenter')
+                         .removeData('tooltip');
+                }
+                $icon.css({
+                    'cursor': ''
+                });
+            }
+        },
+
+        /**
+         * Hide a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _hideTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                var tooltip = $icon.data('tooltip');
+                if (tooltip) {
+                    tooltip.hide();
+                }
+                $icon.css({
+                    'cursor': ''
+                });
+            }
+        },
+
+        /**
+         * Show a tooltip or popover
+         *
+         * @param {jQuery} $field The field element
+         * @param {String} type Can be 'tooltip' or 'popover'
+         */
+        _showTooltip: function($field, type) {
+            var $icon = $field.data('fv.icon');
+            if ($icon) {
+                $icon.css({
+                    'cursor': 'pointer'
+                });
+                var tooltip = $icon.data('tooltip');
+                if (tooltip) {
+                    tooltip.show();
+                }
+            }
+        }
+    });
+}(jQuery));

+ 10 - 0
static/formvalidation/js/framework/uikit.min.js

@@ -0,0 +1,10 @@
+/*!
+ * FormValidation (http://formvalidation.io)
+ * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
+ *
+ * @version     v0.8.1, built on 2016-07-29 1:10:56 AM
+ * @author      https://twitter.com/formvalidation
+ * @copyright   (c) 2013 - 2016 Nguyen Huu Phuoc
+ * @license     http://formvalidation.io/license/
+ */
+!function(a){FormValidation.Framework.Uikit=function(b,c){c=a.extend(!0,{button:{selector:'[type="submit"]:not([formnovalidate])',disabled:"disabled"},control:{valid:"uk-form-success",invalid:"uk-form-danger"},err:{clazz:"uk-text-danger",parent:"^.*(uk-form-controls|uk-width-[\\d+]-[\\d+]).*$"},icon:{valid:null,invalid:null,validating:null,feedback:"fv-control-feedback"},row:{selector:".uk-form-row",valid:"fv-has-success",invalid:"fv-has-error",feedback:"fv-has-feedback"}},c),FormValidation.Base.apply(this,[b,c])},FormValidation.Framework.Uikit.prototype=a.extend({},FormValidation.Base.prototype,{_fixIcon:function(a,b){var c=this._namespace,d=a.attr("type"),e=(a.attr("data-"+c+"-field"),a.parent());("checkbox"===d||"radio"===d)&&e.is("label")&&b.insertAfter(e),e.hasClass("uk-form-password")&&b.insertAfter(e)},_createTooltip:function(b,c,d){var e=b.data("fv.icon");e&&(e.data("tooltip")&&(e.data("tooltip").off(),e.removeData("tooltip")),e.attr("title",c).css({cursor:"pointer"}),new a.UIkit.tooltip(e))},_destroyTooltip:function(a,b){var c=a.data("fv.icon");if(c){var d=c.data("tooltip");d&&(d.hide(),d.off(),c.off("focus mouseenter").removeData("tooltip")),c.css({cursor:""})}},_hideTooltip:function(a,b){var c=a.data("fv.icon");if(c){var d=c.data("tooltip");d&&d.hide(),c.css({cursor:""})}},_showTooltip:function(a,b){var c=a.data("fv.icon");if(c){c.css({cursor:"pointer"});var d=c.data("tooltip");d&&d.show()}}})}(jQuery);

+ 385 - 0
static/formvalidation/js/language/ar_MA.js

@@ -0,0 +1,385 @@
+(function ($) {
+    /**
+     * Arabic language package
+     * Translated by @Arkni
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'ar_MA': {
+            base64: {
+                'default': 'الرجاء إدخال قيمة مشفرة طبقا للقاعدة 64.'
+            },
+            between: {
+                'default': 'الرجاء إدخال قيمة بين %s و %s .',
+                notInclusive: 'الرجاء إدخال قيمة بين %s و %s بدقة.'
+            },
+            bic: {
+                'default': 'الرجاء إدخال رقم BIC صالح.'
+            },
+            callback: {
+                'default': 'الرجاء إدخال قيمة صالحة.'
+            },
+            choice: {
+                'default': 'الرجاء إدخال قيمة صالحة.',
+                less: 'الرجاء اختيار %s خيارات كحد أدنى.',
+                more: 'الرجاء اختيار %s خيارات كحد أقصى.',
+                between: 'الرجاء إختيار %s-%s خيارات.'
+            },
+            color: {
+                'default': 'الرجاء إدخال رمز لون صالح.'
+            },
+            creditCard: {
+                'default': 'الرجاء إدخال رقم بطاقة إئتمان صحيح.'
+            },
+            cusip: {
+                'default': 'الرجاء إدخال رقم CUSIP صالح.'
+            },
+            cvv: {
+                'default': 'الرجاء إدخال رقم CVV صالح.'
+            },
+            date: {
+                'default': 'الرجاء إدخال تاريخ صالح.',
+                min: 'الرجاء إدخال تاريخ بعد %s.',
+                max: 'الرجاء إدخال تاريخ قبل %s.',
+                range: 'الرجاء إدخال تاريخ في المجال %s - %s.'
+            },
+            different: {
+                'default': 'الرجاء إدخال قيمة مختلفة.'
+            },
+            digits: {
+                'default': 'الرجاء إدخال الأرقام فقط.'
+            },
+            ean: {
+                'default': 'الرجاء إدخال رقم EAN صالح.'
+            },
+            ein: {
+                'default': 'الرجاء إدخال رقم EIN صالح.'
+            },
+            emailAddress: {
+                'default': 'الرجاء إدخال بريد إلكتروني صحيح.'
+            },
+            file: {
+                'default': 'الرجاء إختيار ملف صالح.'
+            },
+            greaterThan: {
+                'default': 'الرجاء إدخال قيمة أكبر من أو تساوي %s.',
+                notInclusive: 'الرجاء إدخال قيمة أكبر من %s.'
+            },
+            grid: {
+                'default': 'الرجاء إدخال رقم GRid صالح.'
+            },
+            hex: {
+                'default': 'الرجاء إدخال رقم ست عشري صالح.'
+            },
+            iban: {
+                'default': 'الرجاء إدخال رقم IBAN صالح.',
+                country: 'الرجاء إدخال رقم IBAN صالح في %s.',
+                countries: {
+                    AD: 'أندورا',
+                    AE: 'الإمارات العربية المتحدة',
+                    AL: 'ألبانيا',
+                    AO: 'أنغولا',
+                    AT: 'النمسا',
+                    AZ: 'أذربيجان',
+                    BA: 'البوسنة والهرسك',
+                    BE: 'بلجيكا',
+                    BF: 'بوركينا فاسو',
+                    BG: 'بلغاريا',
+                    BH: 'البحرين',
+                    BI: 'بوروندي',
+                    BJ: 'بنين',
+                    BR: 'البرازيل',
+                    CH: 'سويسرا',
+                    CI: 'ساحل العاج',
+                    CM: 'الكاميرون',
+                    CR: 'كوستاريكا',
+                    CV: 'الرأس الأخضر',
+                    CY: 'قبرص',
+                    CZ: 'التشيك',
+                    DE: 'ألمانيا',
+                    DK: 'الدنمارك',
+                    DO: 'جمهورية الدومينيكان',
+                    DZ: 'الجزائر',
+                    EE: 'إستونيا',
+                    ES: 'إسبانيا',
+                    FI: 'فنلندا',
+                    FO: 'جزر فارو',
+                    FR: 'فرنسا',
+                    GB: 'المملكة المتحدة',
+                    GE: 'جورجيا',
+                    GI: 'جبل طارق',
+                    GL: 'جرينلاند',
+                    GR: 'اليونان',
+                    GT: 'غواتيمالا',
+                    HR: 'كرواتيا',
+                    HU: 'المجر',
+                    IE: 'أيرلندا',
+                    IL: 'إسرائيل',
+                    IR: 'إيران',
+                    IS: 'آيسلندا',
+                    IT: 'إيطاليا',
+                    JO: 'الأردن',
+                    KW: 'الكويت',
+                    KZ: 'كازاخستان',
+                    LB: 'لبنان',
+                    LI: 'ليختنشتاين',
+                    LT: 'ليتوانيا',
+                    LU: 'لوكسمبورغ',
+                    LV: 'لاتفيا',
+                    MC: 'موناكو',
+                    MD: 'مولدوفا',
+                    ME: 'الجبل الأسود',
+                    MG: 'مدغشقر',
+                    MK: 'جمهورية مقدونيا',
+                    ML: 'مالي',
+                    MR: 'موريتانيا',
+                    MT: 'مالطا',
+                    MU: 'موريشيوس',
+                    MZ: 'موزمبيق',
+                    NL: 'هولندا',
+                    NO: 'النرويج',
+                    PK: 'باكستان',
+                    PL: 'بولندا',
+                    PS: 'فلسطين',
+                    PT: 'البرتغال',
+                    QA: 'قطر',
+                    RO: 'رومانيا',
+                    RS: 'صربيا',
+                    SA: 'المملكة العربية السعودية',
+                    SE: 'السويد',
+                    SI: 'سلوفينيا',
+                    SK: 'سلوفاكيا',
+                    SM: 'سان مارينو',
+                    SN: 'السنغال',
+                    TL: 'تيمور الشرقية',
+                    TN: 'تونس',
+                    TR: 'تركيا',
+                    VG: 'جزر العذراء البريطانية',
+                    XK: 'جمهورية كوسوفو'
+                }
+            },
+            id: {
+                'default': 'الرجاء إدخال رقم هوية صالحة.',
+                country: 'الرجاء إدخال رقم تعريف صالح في %s.',
+                countries: {
+                    BA: 'البوسنة والهرسك',
+                    BG: 'بلغاريا',
+                    BR: 'البرازيل',
+                    CH: 'سويسرا',
+                    CL: 'تشيلي',
+                    CN: 'الصين',
+                    CZ: 'التشيك',
+                    DK: 'الدنمارك',
+                    EE: 'إستونيا',
+                    ES: 'إسبانيا',
+                    FI: 'فنلندا',
+                    HR: 'كرواتيا',
+                    IE: 'أيرلندا',
+                    IS: 'آيسلندا',
+                    LT: 'ليتوانيا',
+                    LV: 'لاتفيا',
+                    ME: 'الجبل الأسود',
+                    MK: 'جمهورية مقدونيا',
+                    NL: 'هولندا',
+                    PL: 'بولندا',
+                    RO: 'رومانيا',
+                    RS: 'صربيا',
+                    SE: 'السويد',
+                    SI: 'سلوفينيا',
+                    SK: 'سلوفاكيا',
+                    SM: 'سان مارينو',
+                    TH: 'تايلاند',
+                    TR: 'تركيا',
+                    ZA: 'جنوب أفريقيا'
+                }
+            },
+            identical: {
+                'default': 'الرجاء إدخال نفس القيمة.'
+            },
+            imei: {
+                'default': 'الرجاء إدخال رقم IMEI صالح.'
+            },
+            imo: {
+                'default': 'الرجاء إدخال رقم IMO صالح.'
+            },
+            integer: {
+                'default': 'الرجاء إدخال رقم صحيح.'
+            },
+            ip: {
+                'default': 'الرجاء إدخال عنوان IP صالح.',
+                ipv4: 'الرجاء إدخال عنوان IPv4 صالح.',
+                ipv6: 'الرجاء إدخال عنوان IPv6 صالح.'
+            },
+            isbn: {
+                'default': 'الرجاء إدخال رقم ISBN صالح.'
+            },
+            isin: {
+                'default': 'الرجاء إدخال رقم ISIN صالح.'
+            },
+            ismn: {
+                'default': 'الرجاء إدخال رقم ISMN صالح.'
+            },
+            issn: {
+                'default': 'الرجاء إدخال رقم ISSN صالح.'
+            },
+            lessThan: {
+                'default': 'الرجاء إدخال قيمة أصغر من أو تساوي %s.',
+                notInclusive: 'الرجاء إدخال قيمة أصغر من %s.'
+            },
+            mac: {
+                'default': 'يرجى إدخال عنوان MAC صالح.'
+            },
+            meid: {
+                'default': 'الرجاء إدخال رقم MEID صالح.'
+            },
+            notEmpty: {
+                'default': 'الرجاء إدخال قيمة.'
+            },
+            numeric: {
+                'default': 'الرجاء إدخال عدد عشري صالح.'
+            },
+            phone: {
+                'default': 'الرجاء إدخال رقم هاتف صحيح.',
+                country: 'الرجاء إدخال رقم هاتف صالح في %s.',
+                countries: {
+                    AE: 'الإمارات العربية المتحدة',
+                    BG: 'بلغاريا',
+                    BR: 'البرازيل',
+                    CN: 'الصين',
+                    CZ: 'التشيك',
+                    DE: 'ألمانيا',
+                    DK: 'الدنمارك',
+                    ES: 'إسبانيا',
+                    FR: 'فرنسا',
+                    GB: 'المملكة المتحدة',
+                    IN: 'الهند',
+                    MA: 'المغرب',
+                    NL: 'هولندا',
+                    PK: 'باكستان',
+                    RO: 'رومانيا',
+                    RU: 'روسيا',
+                    SK: 'سلوفاكيا',
+                    TH: 'تايلاند',
+                    US: 'الولايات المتحدة',
+                    VE: 'فنزويلا'
+                }
+            },
+            promise: {
+                'default': 'الرجاء إدخال قيمة صالحة.'
+            },
+            regexp: {
+                'default': 'الرجاء إدخال قيمة مطابقة للنمط.'
+            },
+            remote: {
+                'default': 'الرجاء إدخال قيمة صالحة.'
+            },
+            rtn: {
+                'default': 'الرجاء إدخال رقم RTN صالح.'
+            },
+            sedol: {
+                'default': 'الرجاء إدخال رقم SEDOL صالح.'
+            },
+            siren: {
+                'default': 'الرجاء إدخال رقم SIREN صالح.'
+            },
+            siret: {
+                'default': 'الرجاء إدخال رقم SIRET صالح.'
+            },
+            step: {
+                'default': 'الرجاء إدخال قيمة من مضاعفات %s .'
+            },
+            stringCase: {
+                'default': 'الرجاء إدخال أحرف صغيرة فقط.',
+                upper: 'الرجاء إدخال أحرف كبيرة فقط.'
+            },
+            stringLength: {
+                'default': 'الرجاء إدخال قيمة ذات طول صحيح.',
+                less: 'الرجاء إدخال أقل من %s حرفا.',
+                more: 'الرجاء إدخال أكتر من %s حرفا.',
+                between: 'الرجاء إدخال قيمة ذات عدد حروف بين %s و %s حرفا.'
+            },
+            uri: {
+                'default': 'الرجاء إدخال URI صالح.'
+            },
+            uuid: {
+                'default': 'الرجاء إدخال رقم UUID صالح.',
+                version: 'الرجاء إدخال رقم UUID صالح إصدار %s.'
+            },
+            vat: {
+                'default': 'الرجاء إدخال رقم VAT صالح.',
+                country: 'الرجاء إدخال رقم VAT صالح في %s.',
+                countries: {
+                    AT: 'النمسا',
+                    BE: 'بلجيكا',
+                    BG: 'بلغاريا',
+                    BR: 'البرازيل',
+                    CH: 'سويسرا',
+                    CY: 'قبرص',
+                    CZ: 'التشيك',
+                    DE: 'جورجيا',
+                    DK: 'الدنمارك',
+                    EE: 'إستونيا',
+                    ES: 'إسبانيا',
+                    FI: 'فنلندا',
+                    FR: 'فرنسا',
+                    GB: 'المملكة المتحدة',
+                    GR: 'اليونان',
+                    EL: 'اليونان',
+                    HR: 'كرواتيا',
+                    HU: 'المجر',
+                    IE: 'أيرلندا',
+                    IS: 'آيسلندا',
+                    IT: 'إيطاليا',
+                    LT: 'ليتوانيا',
+                    LU: 'لوكسمبورغ',
+                    LV: 'لاتفيا',
+                    MT: 'مالطا',
+                    NL: 'هولندا',
+                    NO: 'النرويج',
+                    PL: 'بولندا',
+                    PT: 'البرتغال',
+                    RO: 'رومانيا',
+                    RU: 'روسيا',
+                    RS: 'صربيا',
+                    SE: 'السويد',
+                    SI: 'سلوفينيا',
+                    SK: 'سلوفاكيا',
+                    VE: 'فنزويلا',
+                    ZA: 'جنوب أفريقيا'
+                }
+            },
+            vin: {
+                'default': 'الرجاء إدخال رقم VIN صالح.'
+            },
+            zipCode: {
+                'default': 'الرجاء إدخال رمز بريدي صالح.',
+                country: 'الرجاء إدخال رمز بريدي صالح في %s.',
+                countries: {
+                    AT: 'النمسا',
+                    BG: 'بلغاريا',
+                    BR: 'البرازيل',
+                    CA: 'كندا',
+                    CH: 'سويسرا',
+                    CZ: 'التشيك',
+                    DE: 'ألمانيا',
+                    DK: 'الدنمارك',
+                    ES: 'إسبانيا',
+                    FR: 'فرنسا',
+                    GB: 'المملكة المتحدة',
+                    IE: 'أيرلندا',
+                    IN: 'الهند',
+                    IT: 'إيطاليا',
+                    MA: 'المغرب',
+                    NL: 'هولندا',
+                    PL: 'بولندا',
+                    PT: 'البرتغال',
+                    RO: 'رومانيا',
+                    RU: 'روسيا',
+                    SE: 'السويد',
+                    SG: 'سنغافورة',
+                    SK: 'سلوفاكيا',
+                    US: 'الولايات المتحدة'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/bg_BG.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Bulgarian language package
+     * Translated by @mraiur
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'bg_BG': {
+            base64: {
+                'default': 'Моля, въведете валиден base 64 кодиран'
+            },
+            between: {
+                'default': 'Моля, въведете стойност между %s и %s',
+                notInclusive: 'Моля, въведете стойност точно между %s и %s'
+            },
+            bic: {
+                'default': 'Моля, въведете валиден BIC номер'
+            },
+            callback: {
+                'default': 'Моля, въведете валидна стойност'
+            },
+            choice: {
+                'default': 'Моля, въведете валидна стойност',
+                less: 'Моля изберете минимална стойност %s',
+                more: 'Моля изберете максимална стойност %s',
+                between: 'Моля изберете от %s до %s стойност'
+            },
+            color: {
+                'default': 'Моля, въведете валиден цвят'
+            },
+            creditCard: {
+                'default': 'Моля, въведете валиден номер на кредитна карта'
+            },
+            cusip: {
+                'default': 'Моля, въведете валиден CUSIP номер'
+            },
+            cvv: {
+                'default': 'Моля, въведете валиден CVV номер'
+            },
+            date: {
+                'default': 'Моля, въведете валидна дата',
+                min: 'Моля въведете дата след %s',
+                max: 'Моля въведете дата преди %s',
+                range: 'Моля въведете дата между %s и %s'
+            },
+            different: {
+                'default': 'Моля, въведете различна стойност'
+            },
+            digits: {
+                'default': 'Моля, въведете само цифри'
+            },
+            ean: {
+                'default': 'Моля, въведете валиден EAN номер'
+            },
+            ein: {
+                'default': 'Моля, въведете валиден EIN номер'
+            },
+            emailAddress: {
+                'default': 'Моля, въведете валиден имейл адрес'
+            },
+            file: {
+                'default': 'Моля, изберете валиден файл'
+            },
+            greaterThan: {
+                'default': 'Моля, въведете стойност по-голяма от или равна на %s',
+                notInclusive: 'Моля, въведете стойност по-голяма от %s'
+            },
+            grid: {
+                'default': 'Моля, изберете валиден GRId номер'
+            },
+            hex: {
+                'default': 'Моля, въведете валиден шестнадесетичен номер'
+            },
+            iban: {
+                'default': 'Моля, въведете валиден IBAN номер',
+                country: 'Моля, въведете валиден номер на IBAN в %s',
+                countries: {
+                    АD: 'Андора',
+                    AE: 'Обединени арабски емирства',
+                    AL: 'Албания',
+                    AO: 'Ангола',
+                    AT: 'Австрия',
+                    AZ: 'Азербайджан',
+                    BA: 'Босна и Херцеговина',
+                    BE: 'Белгия',
+                    BF: 'Буркина Фасо',
+                    BG: 'България',
+                    BH: 'Бахрейн',
+                    BI: 'Бурунди',
+                    BJ: 'Бенин',
+                    BR: 'Бразилия',
+                    CH: 'Швейцария',
+                    CI: 'Ivory Coast',
+                    CM: 'Камерун',
+                    CR: 'Коста Рика',
+                    CV: 'Cape Verde',
+                    CY: 'Кипър',
+                    CZ: 'Чешката република',
+                    DE: 'Германия',
+                    DK: 'Дания',
+                    DO: 'Доминиканска република',
+                    DZ: 'Алжир',
+                    EE: 'Естония',
+                    ES: 'Испания',
+                    FI: 'Финландия',
+                    FO: 'Фарьорските острови',
+                    FR: 'Франция',
+                    GB: 'Обединеното кралство',
+                    GE: 'Грузия',
+                    GI: 'Гибралтар',
+                    GL: 'Гренландия',
+                    GR: 'Гърция',
+                    GT: 'Гватемала',
+                    HR: 'Хърватия',
+                    HU: 'Унгария',
+                    IE: 'Ирландия',
+                    IL: 'Израел',
+                    IR: 'Иран',
+                    IS: 'Исландия',
+                    IT: 'Италия',
+                    JO: 'Йордания',
+                    KW: 'Кувейт',
+                    KZ: 'Казахстан',
+                    LB: 'Ливан',
+                    LI: 'Лихтенщайн',
+                    LT: 'Литва',
+                    LU: 'Люксембург',
+                    LV: 'Латвия',
+                    MC: 'Монако',
+                    MD: 'Молдова',
+                    ME: 'Черна гора',
+                    MG: 'Мадагаскар',
+                    MK: 'Македония',
+                    ML: 'Мали',
+                    MR: 'Мавритания',
+                    MT: 'Малта',
+                    MU: 'Мавриций',
+                    MZ: 'Мозамбик',
+                    NL: 'Нидерландия',
+                    NO: 'Норвегия',
+                    PK: 'Пакистан',
+                    PL: 'Полша',
+                    PS: 'палестинска',
+                    PT: 'Португалия',
+                    QA: 'Катар',
+                    RO: 'Румъния',
+                    RS: 'Сърбия',
+                    SA: 'Саудитска Арабия',
+                    SE: 'Швеция',
+                    SI: 'Словения',
+                    SK: 'Словакия',
+                    SM: 'San Marino',
+                    SN: 'Сенегал',
+                    TL: 'Източен Тимор',
+                    TN: 'Тунис',
+                    TR: 'Турция',
+                    VG: 'Британски Вирджински острови',
+                    XK: 'Република Косово'
+                }
+            },
+            id: {
+                'default': 'Моля, въведете валиден идентификационен номер',
+                country: 'Моля, въведете валиден идентификационен номер в %s',
+                countries: {
+                    BA: 'Босна и Херцеговина',
+                    BG: 'България',
+                    BR: 'Бразилия',
+                    СН: 'Швейцария',
+                    CL: 'Чили',
+                    CN: 'Китай',
+                    CZ: 'Чешката република',
+                    DK: 'Дания',
+                    EE: 'Естония',
+                    ES: 'Испания',
+                    FI: 'Финландия',
+                    HR: 'Хърватия',
+                    IE: 'Ирландия',
+                    IS: 'Исландия',
+                    LT: 'Литва',
+                    LV: 'Латвия',
+                    ME: 'Черна гора',
+                    MK: 'Македония',
+                    NL: 'Холандия',
+                    PL: 'Полша',
+                    RO: 'Румъния',
+                    RS: 'Сърбия',
+                    SE: 'Швеция',
+                    SI: 'Словения',
+                    SK: 'Словакия',
+                    SM: 'San Marino',
+                    TH: 'Тайланд',
+                    TR: 'Турция',
+                    ZA: 'Южна Африка'
+                }
+            },
+            identical: {
+                'default': 'Моля, въведете една и съща стойност'
+            },
+            imei: {
+                'default': 'Моля, въведете валиден IMEI номер'
+            },
+            imo: {
+                'default': 'Моля, въведете валиден IMO номер'
+            },
+            integer: {
+                'default': 'Моля, въведете валиден номер'
+            },
+            ip: {
+                'default': 'Моля, въведете валиден IP адрес',
+                ipv4: 'Моля, въведете валиден IPv4 адрес',
+                ipv6: 'Моля, въведете валиден IPv6 адрес'
+            },
+            isbn: {
+                'default': 'Моля, въведете валиден ISBN номер'
+            },
+            isin: {
+                'default': 'Моля, въведете валиден ISIN номер'
+            },
+            ismn: {
+                'default': 'Моля, въведете валиден ISMN номер'
+            },
+            issn: {
+                'default': 'Моля, въведете валиден ISSN номер'
+            },
+            lessThan: {
+                'default': 'Моля, въведете стойност по-малка или равна на %s',
+                notInclusive: 'Моля, въведете стойност по-малко от %s'
+            },
+            mac: {
+                'default': 'Моля, въведете валиден MAC адрес'
+            },
+            meid: {
+                'default': 'Моля, въведете валиден MEID номер'
+            },
+            notEmpty: {
+                'default': 'Моля, въведете стойност'
+            },
+            numeric: {
+                'default': 'Моля, въведете валидно число с плаваща запетая'
+            },
+            phone: {
+                'default': 'Моля, въведете валиден телефонен номер',
+                country: 'Моля, въведете валиден телефонен номер в %s',
+                countries: {
+                    AE: 'Обединени арабски емирства',
+                    BG: 'България',
+                    BR: 'Бразилия',
+                    CN: 'Китай',
+                    CZ: 'Чешката република',
+                    DE: 'Германия',
+                    DK: 'Дания',
+                    ES: 'Испания',
+                    FR: 'Франция',
+                    GB: 'Обединеното кралство',
+                    IN: 'Индия',
+                    MA: 'Мароко',
+                    NL: 'Нидерландия',
+                    PK: 'Пакистан',
+                    RO: 'Румъния',
+                    RU: 'Русия',
+                    SK: 'Словакия',
+                    TH: 'Тайланд',
+                    US: 'САЩ',
+                    VE: 'Венецуела'
+                }
+            },
+            promise: {
+                'default': 'Моля, въведете валидна стойност'
+            },
+            regexp: {
+                'default': 'Моля, въведете стойност, отговаряща на модела'
+            },
+            remote: {
+                'default': 'Моля, въведете валидна стойност'
+            },
+            rtn: {
+                'default': 'Моля, въведете валиде  RTN номер'
+            },
+            sedol: {
+                'default': 'Моля, въведете валиден SEDOL номер'
+            },
+            siren: {
+                'default': 'Моля, въведете валиден SIREN номер'
+            },
+            siret: {
+                'default': 'Моля, въведете валиден SIRET номер'
+            },
+            step: {
+                'default': 'Моля, въведете валиденa стъпка от %s'
+            },
+            stringCase: {
+                'default': 'Моля, въведете само с малки букви',
+                upper: 'Моля въведете само главни букви'
+            },
+            stringLength: {
+                'default': 'Моля, въведете стойност с валидни дължина',
+                less: 'Моля, въведете по-малко от %s знака',
+                more: 'Моля въведете повече от %s знака',
+                between: 'Моля, въведете стойност между %s и %s знака'
+            },
+            uri: {
+                'default': 'Моля, въведете валиден URI'
+            },
+            uuid: {
+                'default': 'Моля, въведете валиден UUID номер',
+                version: 'Моля, въведете валиден UUID номер с версия %s'
+            },
+            vat: {
+                'default': 'Моля, въведете валиден ДДС',
+                country: 'Моля, въведете валиден ДДС в %s',
+                countries: {
+                    AT: 'Австрия',
+                    BE: 'Белгия',
+                    BG: 'България',
+                    BR: 'Бразилия',
+                    СН: 'Швейцария',
+                    CY: 'Кипър',
+                    CZ: 'Чешката република',
+                    DE: 'Германия',
+                    DK: 'Дания',
+                    EE: 'Естония',
+                    ES: 'Испания',
+                    FI: 'Финландия',
+                    FR: 'Франция',
+                    GB: 'Обединеното кралство',
+                    GR: 'Гърция',
+                    EL: 'Гърция',
+                    HU: 'Унгария',
+                    HR: 'Ирландия',
+                    IE: 'Ирландски',
+                    IS: 'Исландия',
+                    IT: 'Италия',
+                    LT: 'Литва',
+                    LU: 'Люксембург',
+                    LV: 'Латвия',
+                    MT: 'Малта',
+                    NL: 'Холандия',
+                    NO: 'Норвегия',
+                    PL: 'Полша',
+                    PT: 'Португалия',
+                    RO: 'Румъния',
+                    RU: 'Русия',
+                    RS: 'Сърбия',
+                    SE: 'Швеция',
+                    SI: 'Словения',
+                    SK: 'Словакия',
+                    VE: 'Венецуела',
+                    ZA: 'Южна Африка'
+                }
+            },
+            vin: {
+                'default': 'Моля, въведете валиден номер VIN'
+            },
+            zipCode: {
+                'default': 'Моля, въведете валиден пощенски код',
+                country: 'Моля, въведете валиден пощенски код в %s',
+                countries: {
+                    AT: 'Австрия',
+                    BG: 'България',
+                    BR: 'Бразилия',
+                    CA: 'Канада',
+                    СН: 'Швейцария',
+                    CZ: 'Чешката република',
+                    DE: 'Германия',
+                    DK: 'Дания',
+                    ES: 'Испания',
+                    FR: 'Франция',
+                    GB: 'Обединеното кралство',
+                    IE: 'Ирландски',
+                    IN: 'Индия',
+                    IT: 'Италия',
+                    MA: 'Мароко',
+                    NL: 'Холандия',
+                    PL: 'Полша',
+                    PT: 'Португалия',
+                    RO: 'Румъния',
+                    RU: 'Русия',
+                    SE: 'Швеция',
+                    SG: 'Сингапур',
+                    SK: 'Словакия',
+                    US: 'САЩ'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/ca_ES.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Catalan language package
+     * Translated by @ArnauAregall
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'ca_ES': {
+            base64: {
+                'default': 'Si us plau introdueix un valor vàlid en base 64'
+            },
+            between: {
+                'default': 'Si us plau introdueix un valor entre %s i %s',
+                notInclusive: 'Si us plau introdueix un valor comprès entre %s i %s'
+            },
+            bic: {
+                'default': 'Si us plau introdueix un nombre BIC vàlid'
+            },
+            callback: {
+                'default': 'Si us plau introdueix un valor vàlid'
+            },
+            choice: {
+                'default': 'Si us plau introdueix un valor vàlid',
+                less: 'Si us plau escull %s opcions com a mínim',
+                more: 'Si us plau escull %s opcions com a màxim',
+                between: 'Si us plau escull entre %s i %s opcions'
+            },
+            color: {
+                'default': 'Si us plau introdueix un color vàlid'
+            },
+            creditCard: {
+                'default': 'Si us plau introdueix un nombre vàlid de targeta de crèdit'
+            },
+            cusip: {
+                'default': 'Si us plau introdueix un nombre CUSIP vàlid'
+            },
+            cvv: {
+                'default': 'Si us plau introdueix un nombre CVV vàlid'
+            },
+            date: {
+                'default': 'Si us plau introdueix una data vàlida',
+                min: 'Si us plau introdueix una data posterior a %s',
+                max: 'Si us plau introdueix una data anterior %s',
+                range: 'Si us plau introdueix una data compresa entre %s i %s'
+            },
+            different: {
+                'default': 'Si us plau introdueix un valor diferent'
+            },
+            digits: {
+                'default': 'Si us plau introdueix només dígits'
+            },
+            ean: {
+                'default': 'Si us plau introdueix un nombre EAN vàlid'
+            },
+            ein: {
+                'default': 'Si us plau introdueix un nombre EIN vàlid'
+            },
+            emailAddress: {
+                'default': 'Si us plau introdueix una adreça electrònica vàlida'
+            },
+            file: {
+                'default': 'Si us plau selecciona un arxiu vàlid'
+            },
+            greaterThan: {
+                'default': 'Si us plau introdueix un valor més gran o igual a %s',
+                notInclusive: 'Si us plau introdueix un valor més gran que %s'
+            },
+            grid: {
+                'default': 'Si us plau introdueix un nombre GRId vàlid'
+            },
+            hex: {
+                'default': 'Si us plau introdueix un valor hexadecimal vàlid'
+            },
+            iban: {
+                'default': 'Si us plau introdueix un nombre IBAN vàlid',
+                country: 'Si us plau introdueix un nombre IBAN vàlid a %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Emirats Àrabs Units',
+                    AL: 'Albània',
+                    AO: 'Angola',
+                    AT: 'Àustria',
+                    AZ: 'Azerbaidjan',
+                    BA: 'Bòsnia i Hercegovina',
+                    BE: 'Bèlgica',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgària',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benín',
+                    BR: 'Brasil',
+                    CH: 'Suïssa',
+                    CI: 'Costa d\'Ivori',
+                    CM: 'Camerun',
+                    CR: 'Costa Rica',
+                    CV: 'Cap Verd',
+                    CY: 'Xipre',
+                    CZ: 'República Txeca',
+                    DE: 'Alemanya',
+                    DK: 'Dinamarca',
+                    DO: 'República Dominicana',
+                    DZ: 'Algèria',
+                    EE: 'Estònia',
+                    ES: 'Espanya',
+                    FI: 'Finlàndia',
+                    FO: 'Illes Fèroe',
+                    FR: 'França',
+                    GB: 'Regne Unit',
+                    GE: 'Geòrgia',
+                    GI: 'Gibraltar',
+                    GL: 'Grenlàndia',
+                    GR: 'Grècia',
+                    GT: 'Guatemala',
+                    HR: 'Croàcia',
+                    HU: 'Hongria',
+                    IE: 'Irlanda',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Islàndia',
+                    IT: 'Itàlia',
+                    JO: 'Jordània',
+                    KW: 'Kuwait',
+                    KZ: 'Kazajistán',
+                    LB: 'Líban',
+                    LI: 'Liechtenstein',
+                    LT: 'Lituània',
+                    LU: 'Luxemburg',
+                    LV: 'Letònia',
+                    MC: 'Mònaco',
+                    MD: 'Moldàvia',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedònia',
+                    ML: 'Malo',
+                    MR: 'Mauritània',
+                    MT: 'Malta',
+                    MU: 'Maurici',
+                    MZ: 'Moçambic',
+                    NL: 'Països Baixos',
+                    NO: 'Noruega',
+                    PK: 'Pakistan',
+                    PL: 'Polònia',
+                    PS: 'Palestina',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Sèrbia',
+                    SA: 'Aràbia Saudita',
+                    SE: 'Suècia',
+                    SI: 'Eslovènia',
+                    SK: 'Eslovàquia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timor Oriental',
+                    TN: 'Tunísia',
+                    TR: 'Turquia',
+                    VG: 'Illes Verges Britàniques',
+                    XK: 'República de Kosovo'
+                }
+            },
+            id: {
+                'default': 'Si us plau introdueix un nombre d\'identificació vàlid',
+                country: 'Si us plau introdueix un nombre d\'identificació vàlid a %s',
+                countries: {
+                    BA: 'Bòsnia i Hercegovina',
+                    BG: 'Bulgària',
+                    BR: 'Brasil',
+                    CH: 'Suïssa',
+                    CL: 'Xile',
+                    CN: 'Xina',
+                    CZ: 'República Checa',
+                    DK: 'Dinamarca',
+                    EE: 'Estònia',
+                    ES: 'Espanya',
+                    FI: 'Finlpandia',
+                    HR: 'Cropàcia',
+                    IE: 'Irlanda',
+                    IS: 'Islàndia',
+                    LT: 'Lituania',
+                    LV: 'Letònia',
+                    ME: 'Montenegro',
+                    MK: 'Macedònia',
+                    NL: 'Països Baixos',
+                    PL: 'Polònia',
+                    RO: 'Romania',
+                    RS: 'Sèrbia',
+                    SE: 'Suècia',
+                    SI: 'Eslovènia',
+                    SK: 'Eslovàquia',
+                    SM: 'San Marino',
+                    TH: 'Tailàndia',
+                    TR: 'Turquia',
+                    ZA: 'Sud-àfrica'
+                }
+            },
+            identical: {
+                'default': 'Si us plau introdueix exactament el mateix valor'
+            },
+            imei: {
+                'default': 'Si us plau introdueix un nombre IMEI vàlid'
+            },
+            imo: {
+                'default': 'Si us plau introdueix un nombre IMO vàlid'
+            },
+            integer: {
+                'default': 'Si us plau introdueix un nombre vàlid'
+            },
+            ip: {
+                'default': 'Si us plau introdueix una direcció IP vàlida',
+                ipv4: 'Si us plau introdueix una direcció IPV4 vàlida',
+                ipv6: 'Si us plau introdueix una direcció IPV6 vàlida'
+            },
+            isbn: {
+                'default': 'Si us plau introdueix un nombre ISBN vàlid'
+            },
+            isin: {
+                'default': 'Si us plau introdueix un nombre ISIN vàlid'
+            },
+            ismn: {
+                'default': 'Si us plau introdueix un nombre ISMN vàlid'
+            },
+            issn: {
+                'default': 'Si us plau introdueix un nombre ISSN vàlid'
+            },
+            lessThan: {
+                'default': 'Si us plau introdueix un valor menor o igual a %s',
+                notInclusive: 'Si us plau introdueix un valor menor que %s'
+            },
+            mac: {
+                'default': 'Si us plau introdueix una adreça MAC vàlida'
+            },
+            meid: {
+                'default': 'Si us plau introdueix nombre MEID vàlid'
+            },
+            notEmpty: {
+                'default': 'Si us plau introdueix un valor'
+            },
+            numeric: {
+                'default': 'Si us plau introdueix un nombre decimal vàlid'
+            },
+            phone: {
+                'default': 'Si us plau introdueix un telèfon vàlid',
+                country: 'Si us plau introdueix un telèfon vàlid a %s',
+                countries: {
+                    AE: 'Emirats Àrabs Units',
+                    BG: 'Bulgària',
+                    BR: 'Brasil',
+                    CN: 'Xina',
+                    CZ: 'República Checa',
+                    DE: 'Alemanya',
+                    DK: 'Dinamarca',
+                    ES: 'Espanya',
+                    FR: 'França',
+                    GB: 'Regne Unit',
+                    IN: 'Índia',
+                    MA: 'Marroc',
+                    NL: 'Països Baixos',
+                    PK: 'Pakistan',
+                    RO: 'Romania',
+                    RU: 'Rússia',
+                    SK: 'Eslovàquia',
+                    TH: 'Tailàndia',
+                    US: 'Estats Units',
+                    VE: 'Veneçuela'
+                }
+            },
+            promise: {
+                'default': 'Si us plau introdueix un valor vàlid'
+            },
+            regexp: {
+                'default': 'Si us plau introdueix un valor que coincideixi amb el patró'
+            },
+            remote: {
+                'default': 'Si us plau introdueix un valor vàlid'
+            },
+            rtn: {
+                'default': 'Si us plau introdueix un nombre RTN vàlid'
+            },
+            sedol: {
+                'default': 'Si us plau introdueix un nombre SEDOL vàlid'
+            },
+            siren: {
+                'default': 'Si us plau introdueix un nombre SIREN vàlid'
+            },
+            siret: {
+                'default': 'Si us plau introdueix un nombre SIRET vàlid'
+            },
+            step: {
+                'default': 'Si us plau introdueix un pas vàlid de %s'
+            },
+            stringCase: {
+                'default': 'Si us plau introdueix només caràcters en minúscula',
+                upper: 'Si us plau introdueix només caràcters en majúscula'
+            },
+            stringLength: {
+                'default': 'Si us plau introdueix un valor amb una longitud vàlida',
+                less: 'Si us plau introdueix menys de %s caràcters',
+                more: 'Si us plau introdueix més de %s caràcters',
+                between: 'Si us plau introdueix un valor amb una longitud compresa entre %s i %s caràcters'
+            },
+            uri: {
+                'default': 'Si us plau introdueix una URI vàlida'
+            },
+            uuid: {
+                'default': 'Si us plau introdueix un nom UUID vàlid',
+                version: 'Si us plau introdueix una versió UUID vàlida per %s'
+            },
+            vat: {
+                'default': 'Si us plau introdueix una quantitat d\'IVA vàlida',
+                country: 'Si us plau introdueix una quantitat d\' IVA vàlida a %s',
+                countries: {
+                    AT: 'Àustria',
+                    BE: 'Bèlgica',
+                    BG: 'Bulgària',
+                    BR: 'Brasil',
+                    CH: 'Suïssa',
+                    CY: 'Xipre',
+                    CZ: 'República Checa',
+                    DE: 'Alemanya',
+                    DK: 'Dinamarca',
+                    EE: 'Estònia',
+                    ES: 'Espanya',
+                    FI: 'Finlàndia',
+                    FR: 'França',
+                    GB: 'Regne Unit',
+                    GR: 'Grècia',
+                    EL: 'Grècia',
+                    HU: 'Hongria',
+                    HR: 'Croàcia',
+                    IE: 'Irlanda',
+                    IS: 'Islàndia',
+                    IT: 'Itàlia',
+                    LT: 'Lituània',
+                    LU: 'Luxemburg',
+                    LV: 'Letònia',
+                    MT: 'Malta',
+                    NL: 'Països Baixos',
+                    NO: 'Noruega',
+                    PL: 'Polònia',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Rússia',
+                    RS: 'Sèrbia',
+                    SE: 'Suècia',
+                    SI: 'Eslovènia',
+                    SK: 'Eslovàquia',
+                    VE: 'Veneçuela',
+                    ZA: 'Sud-àfrica'
+                }
+            },
+            vin: {
+                'default': 'Si us plau introdueix un nombre VIN vàlid'
+            },
+            zipCode: {
+                'default': 'Si us plau introdueix un codi postal vàlid',
+                country: 'Si us plau introdueix un codi postal vàlid a %s',
+                countries: {
+                    AT: 'Àustria',
+                    BG: 'Bulgària',
+                    BR: 'Brasil',
+                    CA: 'Canadà',
+                    CH: 'Suïssa',
+                    CZ: 'República Checa',
+                    DE: 'Alemanya',
+                    DK: 'Dinamarca',
+                    ES: 'Espanya',
+                    FR: 'França',
+                    GB: 'Rege Unit',
+                    IE: 'Irlanda',
+                    IN: 'Índia',
+                    IT: 'Itàlia',
+                    MA: 'Marroc',
+                    NL: 'Països Baixos',
+                    PL: 'Polònia',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Rússia',
+                    SE: 'Suècia',
+                    SG: 'Singapur',
+                    SK: 'Eslovàquia',
+                    US: 'Estats Units'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/cs_CZ.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Czech language package
+     * Translated by @AdwinTrave. Improved by @cuchac, @budik21
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'cs_CZ': {
+            base64: {
+                'default': 'Prosím zadejte správný base64'
+            },
+            between: {
+                'default': 'Prosím zadejte hodnotu mezi %s a %s',
+                notInclusive: 'Prosím zadejte hodnotu mezi %s a %s (včetně těchto čísel)'
+            },
+            bic: {
+                'default': 'Prosím zadejte správné BIC číslo'
+            },
+            callback: {
+                'default': 'Prosím zadejte správnou hodnotu'
+            },
+            choice: {
+                'default': 'Prosím vyberte správnou hodnotu',
+                less: 'Hodnota musí být minimálně %s',
+                more: 'Hodnota nesmí být více jak %s',
+                between: 'Prosím vyberte mezi %s a %s'
+            },
+            color: {
+                'default': 'Prosím zadejte správnou barvu'
+            },
+            creditCard: {
+                'default': 'Prosím zadejte správné číslo kreditní karty'
+            },
+            cusip: {
+                'default': 'Prosím zadejte správné CUSIP číslo'
+            },
+            cvv: {
+                'default': 'Prosím zadejte správné CVV číslo'
+            },
+            date: {
+                'default': 'Prosím zadejte správné datum',
+                min: 'Prosím zadejte datum před %s',
+                max: 'Prosím zadejte datum po %s',
+                range: 'Prosím zadejte datum v rozmezí %s až %s'
+            },
+            different: {
+                'default': 'Prosím zadejte jinou hodnotu'
+            },
+            digits: {
+                'default': 'Toto pole může obsahovat pouze čísla'
+            },
+            ean: {
+                'default': 'Prosím zadejte správné EAN číslo'
+            },
+            ein: {
+                'default': 'Prosím zadejte správné EIN číslo'
+            },
+            emailAddress: {
+                'default': 'Prosím zadejte správnou emailovou adresu'
+            },
+            file: {
+                'default': 'Prosím vyberte soubor'
+            },
+            greaterThan: {
+                'default': 'Prosím zadejte hodnotu větší nebo rovnu %s',
+                notInclusive: 'Prosím zadejte hodnotu větší než %s'
+            },
+            grid: {
+                'default': 'Prosím zadejte správné GRId číslo'
+            },
+            hex: {
+                'default': 'Prosím zadejte správné hexadecimální číslo'
+            },
+            iban: {
+                'default': 'Prosím zadejte správné IBAN číslo',
+                country: 'Prosím zadejte správné IBAN číslo pro %s',
+                countries: {
+                    AD: 'Andorru',
+                    AE: 'Spojené arabské emiráty',
+                    AL: 'Albanii',
+                    AO: 'Angolu',
+                    AT: 'Rakousko',
+                    AZ: 'Ázerbajdžán',
+                    BA: 'Bosnu a Herzegovinu',
+                    BE: 'Belgii',
+                    BF: 'Burkinu Faso',
+                    BG: 'Bulharsko',
+                    BH: 'Bahrajn',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazílii',
+                    CH: 'Švýcarsko',
+                    CI: 'Pobřeží slonoviny',
+                    CM: 'Kamerun',
+                    CR: 'Kostariku',
+                    CV: 'Cape Verde',
+                    CY: 'Kypr',
+                    CZ: 'Českou republiku',
+                    DE: 'Německo',
+                    DK: 'Dánsko',
+                    DO: 'Dominikánskou republiku',
+                    DZ: 'Alžírsko',
+                    EE: 'Estonsko',
+                    ES: 'Španělsko',
+                    FI: 'Finsko',
+                    FO: 'Faerské ostrovy',
+                    FR: 'Francie',
+                    GB: 'Velkou Británii',
+                    GE: 'Gruzii',
+                    GI: 'Gibraltar',
+                    GL: 'Grónsko',
+                    GR: 'Řecko',
+                    GT: 'Guatemalu',
+                    HR: 'Chorvatsko',
+                    HU: 'Maďarsko',
+                    IE: 'Irsko',
+                    IL: 'Israel',
+                    IR: 'Irán',
+                    IS: 'Island',
+                    IT: 'Itálii',
+                    JO: 'Jordansko',
+                    KW: 'Kuwait',
+                    KZ: 'Kazachstán',
+                    LB: 'Libanon',
+                    LI: 'Lichtenštejnsko',
+                    LT: 'Litvu',
+                    LU: 'Lucembursko',
+                    LV: 'Lotyšsko',
+                    MC: 'Monaco',
+                    MD: 'Moldavsko',
+                    ME: 'Černou Horu',
+                    MG: 'Madagaskar',
+                    MK: 'Makedonii',
+                    ML: 'Mali',
+                    MR: 'Mauritánii',
+                    MT: 'Maltu',
+                    MU: 'Mauritius',
+                    MZ: 'Mosambik',
+                    NL: 'Nizozemsko',
+                    NO: 'Norsko',
+                    PK: 'Pakistán',
+                    PL: 'Polsko',
+                    PS: 'Palestinu',
+                    PT: 'Portugalsko',
+                    QA: 'Katar',
+                    RO: 'Rumunsko',
+                    RS: 'Srbsko',
+                    SA: 'Saudskou Arábii',
+                    SE: 'Švédsko',
+                    SI: 'Slovinsko',
+                    SK: 'Slovensko',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Východní Timor',
+                    TN: 'Tunisko',
+                    TR: 'Turecko',
+                    VG: 'Britské Panenské ostrovy',
+                    XK: 'Republic of Kosovo'
+                }
+            },
+            id: {
+                'default': 'Prosím zadejte správné rodné číslo',
+                country: 'Prosím zadejte správné rodné číslo pro %s',
+                countries: {
+                    BA: 'Bosnu a Hercegovinu',
+                    BG: 'Bulharsko',
+                    BR: 'Brazílii',
+                    CH: 'Švýcarsko',
+                    CL: 'Chile',
+                    CN: 'Čínu',
+                    CZ: 'Českou Republiku',
+                    DK: 'Dánsko',
+                    EE: 'Estonsko',
+                    ES: 'Španělsko',
+                    FI: 'Finsko',
+                    HR: 'Chorvatsko',
+                    IE: 'Irsko',
+                    IS: 'Island',
+                    LT: 'Litvu',
+                    LV: 'Lotyšsko',
+                    ME: 'Černou horu',
+                    MK: 'Makedonii',
+                    NL: 'Nizozemí',
+                    PL: 'Polsko',
+                    RO: 'Rumunsko',
+                    RS: 'Srbsko',
+                    SE: 'Švédsko',
+                    SI: 'Slovinsko',
+                    SK: 'Slovensko',
+                    SM: 'San Marino',
+                    TH: 'Thajsko',
+                    TR: 'Turecko',
+                    ZA: 'Jižní Afriku'
+                }
+            },
+            identical: {
+                'default': 'Prosím zadejte stejnou hodnotu'
+            },
+            imei: {
+                'default': 'Prosím zadejte správné IMEI číslo'
+            },
+            imo: {
+                'default': 'Prosím zadejte správné IMO číslo'
+            },
+            integer: {
+                'default': 'Prosím zadejte celé číslo'
+            },
+            ip: {
+                'default': 'Prosím zadejte správnou IP adresu',
+                ipv4: 'Prosím zadejte správnou IPv4 adresu',
+                ipv6: 'Prosím zadejte správnou IPv6 adresu'
+            },
+            isbn: {
+                'default': 'Prosím zadejte správné ISBN číslo'
+            },
+            isin: {
+                'default': 'Prosím zadejte správné ISIN číslo'
+            },
+            ismn: {
+                'default': 'Prosím zadejte správné ISMN číslo'
+            },
+            issn: {
+                'default': 'Prosím zadejte správné ISSN číslo'
+            },
+            lessThan: {
+                'default': 'Prosím zadejte hodnotu menší nebo rovno %s',
+                notInclusive: 'Prosím zadejte hodnotu menčí než %s'
+            },
+            mac: {
+                'default': 'Prosím zadejte správnou MAC adresu'
+            },
+            meid: {
+                'default': 'Prosím zadejte správné MEID číslo'
+            },
+            notEmpty: {
+                'default': 'Toto pole nesmí být prázdné'
+            },
+            numeric: {
+                'default': 'Prosím zadejte číselnou hodnotu'
+            },
+            phone: {
+                'default': 'Prosím zadejte správné telefoní číslo',
+                country: 'Prosím zadejte správné telefoní číslo pro %s',
+                countries: {
+                    AE: 'Spojené arabské emiráty',
+                    BG: 'Bulharsko',
+                    BR: 'Brazílii',
+                    CN: 'Čínu',
+                    CZ: 'Českou Republiku',
+                    DE: 'Německo',
+                    DK: 'Dánsko',
+                    ES: 'Španělsko',
+                    FR: 'Francii',
+                    GB: 'Velkou Británii',
+                    IN: 'Indie',
+                    MA: 'Maroko',
+                    NL: 'Nizozemsko',
+                    PK: 'Pákistán',
+                    RO: 'Rumunsko',
+                    RU: 'Rusko',
+                    SK: 'Slovensko',
+                    TH: 'Thajsko',
+                    US: 'Spojené Státy Americké',
+                    VE: 'Venezuelu'
+                }
+            },
+            promise: {
+                'default': 'Prosím zadejte správnou hodnotu'
+            },
+            regexp: {
+                'default': 'Prosím zadejte hodnotu splňující zadání'
+            },
+            remote: {
+                'default': 'Prosím zadejte správnou hodnotu'
+            },
+            rtn: {
+                'default': 'Prosím zadejte správné RTN číslo'
+            },
+            sedol: {
+                'default': 'Prosím zadejte správné SEDOL číslo'
+            },
+            siren: {
+                'default': 'Prosím zadejte správné SIREN číslo'
+            },
+            siret: {
+                'default': 'Prosím zadejte správné SIRET číslo'
+            },
+            step: {
+                'default': 'Prosím zadejte správný krok %s'
+            },
+            stringCase: {
+                'default': 'Pouze malá písmena jsou povoleny v tomto poli',
+                upper: 'Pouze velké písmena jsou povoleny v tomto poli'
+            },
+            stringLength: {
+                'default': 'Toto pole nesmí být prázdné',
+                less: 'Prosím zadejte hodnotu menší než %s znaků',
+                more: 'Prosím zadejte hodnotu %s znaků a delší',
+                between: 'Prosím zadejte hodnotu mezi %s a %s znaky'
+            },
+            uri: {
+                'default': 'Prosím zadejte správnou URI'
+            },
+            uuid: {
+                'default': 'Prosím zadejte správné UUID číslo',
+                version: 'Prosím zadejte správné UUID verze %s'
+            },
+            vat: {
+                'default': 'Prosím zadejte správné VAT číslo',
+                country: 'Prosím zadejte správné VAT číslo pro %s',
+                countries: {
+                    AT: 'Rakousko',
+                    BE: 'Belgii',
+                    BG: 'Bulharsko',
+                    BR: 'Brazílii',
+                    CH: 'Švýcarsko',
+                    CY: 'Kypr',
+                    CZ: 'Českou Republiku',
+                    DE: 'Německo',
+                    DK: 'Dánsko',
+                    EE: 'Estonsko',
+                    ES: 'Španělsko',
+                    FI: 'Finsko',
+                    FR: 'Francii',
+                    GB: 'Velkou Británii',
+                    GR: 'Řecko',
+                    EL: 'Řecko',
+                    HU: 'Maďarsko',
+                    HR: 'Chorvatsko',
+                    IE: 'Irsko',
+                    IS: 'Island',
+                    IT: 'Itálii',
+                    LT: 'Litvu',
+                    LU: 'Lucembursko',
+                    LV: 'Lotyšsko',
+                    MT: 'Maltu',
+                    NL: 'Nizozemí',
+                    NO: 'Norsko',
+                    PL: 'Polsko',
+                    PT: 'Portugalsko',
+                    RO: 'Rumunsko',
+                    RU: 'Rusko',
+                    RS: 'Srbsko',
+                    SE: 'Švédsko',
+                    SI: 'Slovinsko',
+                    SK: 'Slovensko',
+                    VE: 'Venezuelu',
+                    ZA: 'Jižní Afriku'
+                }
+            },
+            vin: {
+                'default': 'Prosím zadejte správné VIN číslo'
+            },
+            zipCode: {
+                'default': 'Prosím zadejte správné PSČ',
+                country: 'Prosím zadejte správné PSČ pro %s',
+                countries: {
+                    AT: 'Rakousko',
+                    BG: 'Bulharsko',
+                    BR: 'Brazílie',
+                    CA: 'Kanadu',
+                    CH: 'Švýcarsko',
+                    CZ: 'Českou Republiku',
+                    DE: 'Německo',
+                    DK: 'Dánsko',
+                    ES: 'Španělsko',
+                    FR: 'Francii',
+                    GB: 'Velkou Británii',
+                    IE: 'Irsko',
+                    IN: 'Indie',
+                    IT: 'Itálii',
+                    MA: 'Maroko',
+                    NL: 'Nizozemí',
+                    PL: 'Polsko',
+                    PT: 'Portugalsko',
+                    RO: 'Rumunsko',
+                    RU: 'Rusko',
+                    SE: 'Švédsko',
+                    SG: 'Singapur',
+                    SK: 'Slovensko',
+                    US: 'Spojené Státy Americké'
+                }
+            }
+        }
+    });
+}(window.jQuery));

+ 385 - 0
static/formvalidation/js/language/da_DK.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Danish language package
+     * Translated by @Djarnis
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'da_DK': {
+            base64: {
+                'default': 'Udfyld venligst dette felt med en gyldig base64-kodet værdi'
+            },
+            between: {
+                'default': 'Udfyld venligst dette felt med en værdi mellem %s og %s',
+                notInclusive: 'Indtast venligst kun en værdi mellem %s og %s'
+            },
+            bic: {
+                'default': 'Udfyld venligst dette felt med et gyldigt BIC-nummer'
+            },
+            callback: {
+                'default': 'Udfyld venligst dette felt med en gyldig værdi'
+            },
+            choice: {
+                'default': 'Udfyld venligst dette felt med en gyldig værdi',
+                less: 'Vælg venligst mindst %s valgmuligheder',
+                more: 'Vælg venligst højst %s valgmuligheder',
+                between: 'Vælg venligst %s - %s valgmuligheder'
+            },
+            color: {
+                'default': 'Udfyld venligst dette felt med en gyldig farve'
+            },
+            creditCard: {
+                'default': 'Udfyld venligst dette felt med et gyldigt kreditkort-nummer'
+            },
+            cusip: {
+                'default': 'Udfyld venligst dette felt med et gyldigt CUSIP-nummer'
+            },
+            cvv: {
+                'default': 'Udfyld venligst dette felt med et gyldigt CVV-nummer'
+            },
+            date: {
+                'default': 'Udfyld venligst dette felt med en gyldig dato',
+                min: 'Angiv venligst en dato efter %s',
+                max: 'Angiv venligst en dato før %s',
+                range: 'Angiv venligst en dato mellem %s - %s'
+            },
+            different: {
+                'default': 'Udfyld venligst dette felt med en anden værdi'
+            },
+            digits: {
+                'default': 'Indtast venligst kun cifre'
+            },
+            ean: {
+                'default': 'Udfyld venligst dette felt med et gyldigt EAN-nummer'
+            },
+            ein: {
+                'default': 'Udfyld venligst dette felt med et gyldigt EIN-nummer'
+            },
+            emailAddress: {
+                'default': 'Udfyld venligst dette felt med en gyldig e-mail-adresse'
+            },
+            file: {
+                'default': 'Vælg venligst en gyldig fil'
+            },
+            greaterThan: {
+                'default': 'Udfyld venligst dette felt med en værdi større eller lig med %s',
+                notInclusive: 'Udfyld venligst dette felt med en værdi større end %s'
+            },
+            grid: {
+                'default': 'Udfyld venligst dette felt med et gyldigt GRId-nummer'
+            },
+            hex: {
+                'default': 'Udfyld venligst dette felt med et gyldigt hexadecimal-nummer'
+            },
+            iban: {
+                'default': 'Udfyld venligst dette felt med et gyldigt IBAN-nummer',
+                country: 'Udfyld venligst dette felt med et gyldigt IBAN-nummer i %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'De Forenede Arabiske Emirater',
+                    AL: 'Albanien',
+                    AO: 'Angola',
+                    AT: 'Østrig',
+                    AZ: 'Aserbajdsjan',
+                    BA: 'Bosnien-Hercegovina',
+                    BE: 'Belgien',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgarien',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CI: 'Elfenbenskysten',
+                    CM: 'Cameroun',
+                    CR: 'Costa Rica',
+                    CV: 'Kap Verde',
+                    CY: 'Cypern',
+                    CZ: 'Tjekkiet',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    DO: 'Den Dominikanske Republik',
+                    DZ: 'Algeriet',
+                    EE: 'Estland',
+                    ES: 'Spanien',
+                    FI: 'Finland',
+                    FO: 'Færøerne',
+                    FR: 'Frankrig',
+                    GB: 'Storbritannien',
+                    GE: 'Georgien',
+                    GI: 'Gibraltar',
+                    GL: 'Grønland',
+                    GR: 'Grækenland',
+                    GT: 'Guatemala',
+                    HR: 'Kroatien',
+                    HU: 'Ungarn',
+                    IE: 'Irland',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Island',
+                    IT: 'Italien',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Kasakhstan',
+                    LB: 'Libanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Litauen',
+                    LU: 'Luxembourg',
+                    LV: 'Letland',
+                    MC: 'Monaco',
+                    MD: 'Moldova',
+                    ME: 'Montenegro',
+                    MG: 'Madagaskar',
+                    MK: 'Makedonien',
+                    ML: 'Mali',
+                    MR: 'Mauretanien',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Holland',
+                    NO: 'Norge',
+                    PK: 'Pakistan',
+                    PL: 'Polen',
+                    PS: 'Palæstina',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Rumænien',
+                    RS: 'Serbien',
+                    SA: 'Saudi-Arabien',
+                    SE: 'Sverige',
+                    SI: 'Slovenien',
+                    SK: 'Slovakiet',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Østtimor',
+                    TN: 'Tunesien',
+                    TR: 'Tyrkiet',
+                    VG: 'Britiske Jomfruøer',
+                    XK: 'Kosovo'
+                }
+            },
+            id: {
+                'default': 'Udfyld venligst dette felt med et gyldigt identifikations-nummer',
+                country: 'Udfyld venligst dette felt med et gyldigt identifikations-nummer i %s',
+                countries: {
+                    BA: 'Bosnien-Hercegovina',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CL: 'Chile',
+                    CN: 'Kina',
+                    CZ: 'Tjekkiet',
+                    DK: 'Danmark',
+                    EE: 'Estland',
+                    ES: 'Spanien',
+                    FI: 'Finland',
+                    HR: 'Kroatien',
+                    IE: 'Irland',
+                    IS: 'Island',
+                    LT: 'Litauen',
+                    LV: 'Letland',
+                    ME: 'Montenegro',
+                    MK: 'Makedonien',
+                    NL: 'Holland',
+                    PL: 'Polen',
+                    RO: 'Rumænien',
+                    RS: 'Serbien',
+                    SE: 'Sverige',
+                    SI: 'Slovenien',
+                    SK: 'Slovakiet',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Tyrkiet',
+                    ZA: 'Sydafrika'
+                }
+            },
+            identical: {
+                'default': 'Udfyld venligst dette felt med den samme værdi'
+            },
+            imei: {
+                'default': 'Udfyld venligst dette felt med et gyldigt IMEI-nummer'
+            },
+            imo: {
+                'default': 'Udfyld venligst dette felt med et gyldigt IMO-nummer'
+            },
+            integer: {
+                'default': 'Udfyld venligst dette felt med et gyldigt tal'
+            },
+            ip: {
+                'default': 'Udfyld venligst dette felt med en gyldig IP adresse',
+                ipv4: 'Udfyld venligst dette felt med en gyldig IPv4 adresse',
+                ipv6: 'Udfyld venligst dette felt med en gyldig IPv6 adresse'
+            },
+            isbn: {
+                'default': 'Udfyld venligst dette felt med et gyldigt ISBN-nummer'
+            },
+            isin: {
+                'default': 'Udfyld venligst dette felt med et gyldigt ISIN-nummer'
+            },
+            ismn: {
+                'default': 'Udfyld venligst dette felt med et gyldigt ISMN-nummer'
+            },
+            issn: {
+                'default': 'Udfyld venligst dette felt med et gyldigt ISSN-nummer'
+            },
+            lessThan: {
+                'default': 'Udfyld venligst dette felt med en værdi mindre eller lig med %s',
+                notInclusive: 'Udfyld venligst dette felt med en værdi mindre end %s'
+            },
+            mac: {
+                'default': 'Udfyld venligst dette felt med en gyldig MAC adresse'
+            },
+            meid: {
+                'default': 'Udfyld venligst dette felt med et gyldigt MEID-nummer'
+            },
+            notEmpty: {
+                'default': 'Udfyld venligst dette felt'
+            },
+            numeric: {
+                'default': 'Udfyld venligst dette felt med et gyldigt flydende decimaltal'
+            },
+            phone: {
+                'default': 'Udfyld venligst dette felt med et gyldigt telefonnummer',
+                country: 'Udfyld venligst dette felt med et gyldigt telefonnummer i %s',
+                countries: {
+                    AE: 'De Forenede Arabiske Emirater',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CN: 'Kina',
+                    CZ: 'Tjekkiet',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    ES: 'Spanien',
+                    FR: 'Frankrig',
+                    GB: 'Storbritannien',
+                    IN: 'Indien',
+                    MA: 'Marokko',
+                    NL: 'Holland',
+                    PK: 'Pakistan',
+                    RO: 'Rumænien',
+                    RU: 'Rusland',
+                    SK: 'Slovakiet',
+                    TH: 'Thailand',
+                    US: 'USA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Udfyld venligst dette felt med en gyldig værdi'
+            },
+            regexp: {
+                'default': 'Udfyld venligst dette felt med en værdi der matcher mønsteret'
+            },
+            remote: {
+                'default': 'Udfyld venligst dette felt med en gyldig værdi'
+            },
+            rtn: {
+                'default': 'Udfyld venligst dette felt med et gyldigt RTN-nummer'
+            },
+            sedol: {
+                'default': 'Udfyld venligst dette felt med et gyldigt SEDOL-nummer'
+            },
+            siren: {
+                'default': 'Udfyld venligst dette felt med et gyldigt SIREN-nummer'
+            },
+            siret: {
+                'default': 'Udfyld venligst dette felt med et gyldigt SIRET-nummer'
+            },
+            step: {
+                'default': 'Udfyld venligst dette felt med et gyldigt trin af %s'
+            },
+            stringCase: {
+                'default': 'Udfyld venligst kun dette felt med små bogstaver',
+                upper: 'Udfyld venligst kun dette felt med store bogstaver'
+            },
+            stringLength: {
+                'default': 'Udfyld venligst dette felt med en værdi af gyldig længde',
+                less: 'Udfyld venligst dette felt med mindre end %s tegn',
+                more: 'Udfyld venligst dette felt med mere end %s tegn',
+                between: 'Udfyld venligst dette felt med en værdi mellem %s og %s tegn'
+            },
+            uri: {
+                'default': 'Udfyld venligst dette felt med en gyldig URI'
+            },
+            uuid: {
+                'default': 'Udfyld venligst dette felt med et gyldigt UUID-nummer',
+                version: 'Udfyld venligst dette felt med en gyldig UUID version %s-nummer'
+            },
+            vat: {
+                'default': 'Udfyld venligst dette felt med et gyldig moms-nummer',
+                country: 'Udfyld venligst dette felt med et gyldigt moms-nummer i %s',
+                countries: {
+                    AT: 'Østrig',
+                    BE: 'Belgien',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CY: 'Cypern',
+                    CZ: 'Tjekkiet',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    EE: 'Estland',
+                    ES: 'Spanien',
+                    FI: 'Finland',
+                    FR: 'Frankrig',
+                    GB: 'Storbritannien',
+                    GR: 'Grækenland',
+                    EL: 'Grækenland',
+                    HU: 'Ungarn',
+                    HR: 'Kroatien',
+                    IE: 'Irland',
+                    IS: 'Island',
+                    IT: 'Italien',
+                    LT: 'Litauen',
+                    LU: 'Luxembourg',
+                    LV: 'Letland',
+                    MT: 'Malta',
+                    NL: 'Holland',
+                    NO: 'Norge',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Rumænien',
+                    RU: 'Rusland',
+                    RS: 'Serbien',
+                    SE: 'Sverige',
+                    SI: 'Slovenien',
+                    SK: 'Slovakiet',
+                    VE: 'Venezuela',
+                    ZA: 'Sydafrika'
+                }
+            },
+            vin: {
+                'default': 'Udfyld venligst dette felt med et gyldigt VIN-nummer'
+            },
+            zipCode: {
+                'default': 'Udfyld venligst dette felt med et gyldigt postnummer',
+                country: 'Udfyld venligst dette felt med et gyldigt postnummer i %s',
+                countries: {
+                    AT: 'Østrig',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CA: 'Canada',
+                    CH: 'Schweiz',
+                    CZ: 'Tjekkiet',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    ES: 'Spanien',
+                    FR: 'Frankrig',
+                    GB: 'Storbritannien',
+                    IE: 'Irland',
+                    IN: 'Indien',
+                    IT: 'Italien',
+                    MA: 'Marokko',
+                    NL: 'Holland',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Rumænien',
+                    RU: 'Rusland',
+                    SE: 'Sverige',
+                    SG: 'Singapore',
+                    SK: 'Slovakiet',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/de_DE.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * German language package
+     * Translated by @logemann
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'de_DE': {
+            base64: {
+                'default': 'Bitte eine Base64 Kodierung eingeben'
+            },
+            between: {
+                'default': 'Bitte einen Wert zwischen %s und %s eingeben',
+                notInclusive: 'Bitte einen Wert zwischen %s und %s (strictly) eingeben'
+            },
+            bic: {
+                'default': 'Bitte gültige BIC Nummer eingeben'
+            },
+            callback: {
+                'default': 'Bitte einen gültigen Wert eingeben'
+            },
+            choice: {
+                'default': 'Bitte einen gültigen Wert eingeben',
+                less: 'Bitte mindestens %s Werte eingeben',
+                more: 'Bitte maximal %s Werte eingeben',
+                between: 'Zwischen %s - %s Werten wählen'
+            },
+            color: {
+                'default': 'Bitte gültige Farbe eingeben'
+            },
+            creditCard: {
+                'default': 'Bitte gültige Kreditkartennr. eingeben'
+            },
+            cusip: {
+                'default': 'Bitte gültige CUSIP Nummer eingeben'
+            },
+            cvv: {
+                'default': 'Bitte gültige CVV Nummer eingeben'
+            },
+            date: {
+                'default': 'Bitte gültiges Datum eingeben',
+                min: 'Bitte gültiges Datum nach %s',
+                max: 'Bitte gültiges Datum vor %s',
+                range: 'Bitte gültiges Datum im zwischen %s - %s'
+            },
+            different: {
+                'default': 'Bitte anderen Wert eingeben'
+            },
+            digits: {
+                'default': 'Bitte Zahlen eingeben'
+            },
+            ean: {
+                'default': 'Bitte gültige EAN Nummer eingeben'
+            },
+            ein: {
+                'default': 'Bitte gültige EIN Nummer eingeben'
+            },
+            emailAddress: {
+                'default': 'Bitte gültige Emailadresse eingeben'
+            },
+            file: {
+                'default': 'Bitte gültiges File eingeben'
+            },
+            greaterThan: {
+                'default': 'Bitte Wert größer gleich %s eingeben',
+                notInclusive: 'Bitte Wert größer als %s eingeben'
+            },
+            grid: {
+                'default': 'Bitte gültige GRId Nummer eingeben'
+            },
+            hex: {
+                'default': 'Bitte gültigen Hexadezimalwert eingeben'
+            },
+            iban: {
+                'default': 'Bitte eine gültige IBAN Nummer eingeben',
+                country: 'Bitte eine gültige IBAN Nummer für %s eingeben',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Vereinigte Arabische Emirate',
+                    AL: 'Albanien',
+                    AO: 'Angola',
+                    AT: 'Österreich',
+                    AZ: 'Aserbaidschan',
+                    BA: 'Bosnien und Herzegowina',
+                    BE: 'Belgien',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgarien',
+                    BH: 'Bahrein',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CI: 'Elfenbeinküste',
+                    CM: 'Kamerun',
+                    CR: 'Costa Rica',
+                    CV: 'Kap Verde',
+                    CY: 'Zypern',
+                    CZ: 'Tschechische',
+                    DE: 'Deutschland',
+                    DK: 'Dänemark',
+                    DO: 'Dominikanische Republik',
+                    DZ: 'Algerien',
+                    EE: 'Estland',
+                    ES: 'Spanien',
+                    FI: 'Finnland',
+                    FO: 'Färöer-Inseln',
+                    FR: 'Frankreich',
+                    GB: 'Vereinigtes Königreich',
+                    GE: 'Georgien',
+                    GI: 'Gibraltar',
+                    GL: 'Grönland',
+                    GR: 'Griechenland',
+                    GT: 'Guatemala',
+                    HR: 'Croatia',
+                    HU: 'Ungarn',
+                    IE: 'Irland',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Island',
+                    IT: 'Italien',
+                    JO: 'Jordanien',
+                    KW: 'Kuwait',
+                    KZ: 'Kasachstan',
+                    LB: 'Libanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Litauen',
+                    LU: 'Luxemburg',
+                    LV: 'Lettland',
+                    MC: 'Monaco',
+                    MD: 'Moldawien',
+                    ME: 'Montenegro',
+                    MG: 'Madagaskar',
+                    MK: 'Mazedonien',
+                    ML: 'Mali',
+                    MR: 'Mauretanien',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mosambik',
+                    NL: 'Niederlande',
+                    NO: 'Norwegen',
+                    PK: 'Pakistan',
+                    PL: 'Polen',
+                    PS: 'Palästina',
+                    PT: 'Portugal',
+                    QA: 'Katar',
+                    RO: 'Rumänien',
+                    RS: 'Serbien',
+                    SA: 'Saudi-Arabien',
+                    SE: 'Schweden',
+                    SI: 'Slowenien',
+                    SK: 'Slowakei',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Ost-Timor',
+                    TN: 'Tunesien',
+                    TR: 'Türkei',
+                    VG: 'Jungferninseln',
+                    XK: 'Republik Kosovo'
+                }
+            },
+            id: {
+                'default': 'Bitte gültige Identifikationsnnummer eingeben',
+                country: 'Bitte gültige Identifikationsnummer für %s eingeben',
+                countries: {
+                    BA: 'Bosnien und Herzegowina',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CL: 'Chile',
+                    CN: 'China',
+                    CZ: 'Tschechische',
+                    DK: 'Dänemark',
+                    EE: 'Estland',
+                    ES: 'Spanien',
+                    FI: 'Finnland',
+                    HR: 'Kroatien',
+                    IE: 'Irland',
+                    IS: 'Island',
+                    LT: 'Litauen',
+                    LV: 'Lettland',
+                    ME: 'Montenegro',
+                    MK: 'Mazedonien',
+                    NL: 'Niederlande',
+                    PL: 'Polen',
+                    RO: 'Rumänien',
+                    RS: 'Serbien',
+                    SE: 'Schweden',
+                    SI: 'Slowenien',
+                    SK: 'Slowakei',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Türkei',
+                    ZA: 'Südafrika'
+                }
+            },
+            identical: {
+                'default': 'Bitte gleichen Wert eingeben'
+            },
+            imei: {
+                'default': 'Bitte gültige IMEI Nummer eingeben'
+            },
+            imo: {
+                'default': 'Bitte gültige IMO Nummer eingeben'
+            },
+            integer: {
+                'default': 'Bitte Zahl eingeben'
+            },
+            ip: {
+                'default': 'Bitte  gültige IP-Adresse eingeben',
+                ipv4: 'Bitte  gültige IPv4 Adresse eingeben',
+                ipv6: 'Bitte  gültige IPv6 Adresse eingeben'
+            },
+            isbn: {
+                'default': 'Bitte gültige ISBN Nummer eingeben'
+            },
+            isin: {
+                'default': 'Bitte gültige ISIN Nummer eingeben'
+            },
+            ismn: {
+                'default': 'Bitte gültige ISMN Nummer eingeben'
+            },
+            issn: {
+                'default': 'Bitte gültige ISSN Nummer eingeben'
+            },
+            lessThan: {
+                'default': 'Bitte Wert kleiner gleich %s eingeben',
+                notInclusive: 'Bitte Wert kleiner als %s eingeben'
+            },
+            mac: {
+                'default': 'Bitte gültige MAC Adresse eingeben'
+            },
+            meid: {
+                'default': 'Bitte gültige MEID Nummer eingeben'
+            },
+            notEmpty: {
+                'default': 'Bitte Wert eingeben'
+            },
+            numeric: {
+                'default': 'Bitte Nummer eingeben'
+            },
+            phone: {
+                'default': 'Bitte gültige Telefonnummer eingeben',
+                country: 'Bitte valide Telefonnummer für %s eingeben',
+                countries: {
+                    AE: 'Vereinigte Arabische Emirate',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CN: 'China',
+                    CZ: 'Tschechische',
+                    DE: 'Deutschland',
+                    DK: 'Dänemark',
+                    ES: 'Spanien',
+                    FR: 'Frankreich',
+                    GB: 'Vereinigtes Königreich',
+                    IN: 'Indien',
+                    MA: 'Marokko',
+                    NL: 'Niederlande',
+                    PK: 'Pakistan',
+                    RO: 'Rumänien',
+                    RU: 'Russland',
+                    SK: 'Slowakei',
+                    TH: 'Thailand',
+                    US: 'Vereinigte Staaten von Amerika',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Bitte einen gültigen Wert eingeben'
+            },
+            regexp: {
+                'default': 'Bitte Wert eingeben, der der Maske entspricht'
+            },
+            remote: {
+                'default': 'Bitte einen gültigen Wert eingeben'
+            },
+            rtn: {
+                'default': 'Bitte gültige RTN Nummer eingeben'
+            },
+            sedol: {
+                'default': 'Bitte gültige SEDOL Nummer eingeben'
+            },
+            siren: {
+                'default': 'Bitte gültige SIREN Nummer eingeben'
+            },
+            siret: {
+                'default': 'Bitte gültige SIRET Nummer eingeben'
+            },
+            step: {
+                'default': 'Bitte einen gültigen Schritt von %s eingeben'
+            },
+            stringCase: {
+                'default': 'Bitte nur Kleinbuchstaben eingeben',
+                upper: 'Bitte nur Großbuchstaben eingeben'
+            },
+            stringLength: {
+                'default': 'Bitte Wert mit gültiger Länge eingeben',
+                less: 'Bitte weniger als %s Zeichen eingeben',
+                more: 'Bitte mehr als %s Zeichen eingeben',
+                between: 'Bitte Wert zwischen %s und %s Zeichen eingeben'
+            },
+            uri: {
+                'default': 'Bitte gültige URI eingeben'
+            },
+            uuid: {
+                'default': 'Bitte gültige UUID Nummer eingeben',
+                version: 'Bitte gültige UUID Version %s eingeben'
+            },
+            vat: {
+                'default': 'Bitte gültige VAT Nummer eingeben',
+                country: 'Bitte gültige VAT Nummer für %s eingeben',
+                countries: {
+                    AT: 'Österreich',
+                    BE: 'Belgien',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CY: 'Zypern',
+                    CZ: 'Tschechische',
+                    DE: 'Deutschland',
+                    DK: 'Dänemark',
+                    EE: 'Estland',
+                    ES: 'Spanisch',
+                    FI: 'Finnland',
+                    FR: 'Frankreich',
+                    GB: 'Vereinigtes Königreich',
+                    GR: 'Griechenland',
+                    EL: 'Griechenland',
+                    HU: 'Ungarn',
+                    HR: 'Kroatien',
+                    IE: 'Irland',
+                    IS: 'Island',
+                    IT: 'Italien',
+                    LT: 'Litauen',
+                    LU: 'Luxemburg',
+                    LV: 'Lettland',
+                    MT: 'Malta',
+                    NL: 'Niederlande',
+                    NO: 'Norwegen',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Rumänien',
+                    RU: 'Russland',
+                    RS: 'Serbien',
+                    SE: 'Schweden',
+                    SI: 'Slowenien',
+                    SK: 'Slowakei',
+                    VE: 'Venezuela',
+                    ZA: 'Südafrika'
+                }
+            },
+            vin: {
+                'default': 'Bitte gültige VIN Nummer eingeben'
+            },
+            zipCode: {
+                'default': 'Bitte gültige PLZ eingeben',
+                country: 'Bitte gültige Postleitzahl für %s eingeben',
+                countries: {
+                    AT: 'Österreich',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CA: 'Kanada',
+                    CH: 'Schweiz',
+                    CZ: 'Tschechische',
+                    DE: 'Deutschland',
+                    DK: 'Dänemark',
+                    ES: 'Spanien',
+                    FR: 'Frankreich',
+                    GB: 'Vereinigtes Königreich',
+                    IE: 'Irland',
+                    IN: 'Indien',
+                    IT: 'Italien',
+                    MA: 'Marokko',
+                    NL: 'Niederlande',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Rumänien',
+                    RU: 'Russland',
+                    SE: 'Schweden',
+                    SG: 'Singapur',
+                    SK: 'Slowakei',
+                    US: 'Vereinigte Staaten von Amerika'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/el_GR.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Greek language package
+     * Translated by @pRieStaKos
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'el_GR': {
+            base64: {
+                'default': 'Παρακαλώ εισάγετε μια έγκυρη κωδικοποίηση base 64'
+            },
+            between: {
+                'default': 'Παρακαλώ εισάγετε μια τιμή μεταξύ %s και %s',
+                notInclusive: 'Παρακαλώ εισάγετε μια τιμή μεταξύ %s και %s αυστηρά'
+            },
+            bic: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό BIC'
+            },
+            callback: {
+                'default': 'Παρακαλώ εισάγετε μια έγκυρη τιμή'
+            },
+            choice: {
+                'default': 'Παρακαλώ εισάγετε μια έγκυρη τιμή',
+                less: 'Παρακαλώ επιλέξτε %s επιλογές στο ελάχιστο',
+                more: 'Παρακαλώ επιλέξτε %s επιλογές στο μέγιστο',
+                between: 'Παρακαλώ επιλέξτε %s - %s επιλογές'
+            },
+            color: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο χρώμα'
+            },
+            creditCard: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας'
+            },
+            cusip: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό CUSIP'
+            },
+            cvv: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό CVV'
+            },
+            date: {
+                'default': 'Παρακαλώ εισάγετε μια έγκυρη ημερομηνία',
+                min: 'Παρακαλώ εισάγετε ημερομηνία μετά από %s',
+                max: 'Παρακαλώ εισάγετε ημερομηνία πριν από %s',
+                range: 'Παρακαλώ εισάγετε ημερομηνία μεταξύ %s - %s'
+            },
+            different: {
+                'default': 'Παρακαλώ εισάγετε μια διαφορετική τιμή'
+            },
+            digits: {
+                'default': 'Παρακαλώ εισάγετε μόνο ψηφία'
+            },
+            ean: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό EAN'
+            },
+            ein: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό EIN'
+            },
+            emailAddress: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο email'
+            },
+            file: {
+                'default': 'Παρακαλώ επιλέξτε ένα έγκυρο αρχείο'
+            },
+            greaterThan: {
+                'default': 'Παρακαλώ εισάγετε μια τιμή μεγαλύτερη ή ίση με %s',
+                notInclusive: 'Παρακαλώ εισάγετε μια τιμή μεγαλύτερη από %s'
+            },
+            grid: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό GRId'
+            },
+            hex: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο δεκαεξαδικό αριθμό'
+            },
+            iban: {
+                'default': 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό IBAN',
+                country: 'Παρακαλώ εισάγετε έναν έγκυρο αριθμό IBAN στην %s',
+                countries: {
+                    AD: 'Ανδόρα',
+                    AE: 'Ηνωμένα Αραβικά Εμιράτα',
+                    AL: 'Αλβανία',
+                    AO: 'Αγκόλα',
+                    AT: 'Αυστρία',
+                    AZ: 'Αζερμπαϊτζάν',
+                    BA: 'Βοσνία και Ερζεγοβίνη',
+                    BE: 'Βέλγιο',
+                    BF: 'Μπουρκίνα Φάσο',
+                    BG: 'Βουλγαρία',
+                    BH: 'Μπαχρέιν',
+                    BI: 'Μπουρούντι',
+                    BJ: 'Μπενίν',
+                    BR: 'Βραζιλία',
+                    CH: 'Ελβετία',
+                    CI: 'Ακτή Ελεφαντοστού',
+                    CM: 'Καμερούν',
+                    CR: 'Κόστα Ρίκα',
+                    CV: 'Cape Verde',
+                    CY: 'Κύπρος',
+                    CZ: 'Δημοκρατία της Τσεχίας',
+                    DE: 'Γερμανία',
+                    DK: 'Δανία',
+                    DO: 'Δομινικανή Δημοκρατία',
+                    DZ: 'Αλγερία',
+                    EE: 'Εσθονία',
+                    ES: 'Ισπανία',
+                    FI: 'Φινλανδία',
+                    FO: 'Νησιά Φερόε',
+                    FR: 'Γαλλία',
+                    GB: 'Ηνωμένο Βασίλειο',
+                    GE: 'Γεωργία',
+                    GI: 'Γιβραλτάρ',
+                    GL: 'Γροιλανδία',
+                    GR: 'Ελλάδα',
+                    GT: 'Γουατεμάλα',
+                    HR: 'Κροατία',
+                    HU: 'Ουγγαρία',
+                    IE: 'Ιρλανδία',
+                    IL: 'Ισραήλ',
+                    IR: 'Ιράν',
+                    IS: 'Ισλανδία',
+                    IT: 'Ιταλία',
+                    JO: 'Ιορδανία',
+                    KW: 'Κουβέιτ',
+                    KZ: 'Καζακστάν',
+                    LB: 'Λίβανος',
+                    LI: 'Λιχτενστάιν',
+                    LT: 'Λιθουανία',
+                    LU: 'Λουξεμβούργο',
+                    LV: 'Λετονία',
+                    MC: 'Μονακό',
+                    MD: 'Μολδαβία',
+                    ME: 'Μαυροβούνιο',
+                    MG: 'Μαδαγασκάρη',
+                    MK: 'πΓΔΜ',
+                    ML: 'Μάλι',
+                    MR: 'Μαυριτανία',
+                    MT: 'Μάλτα',
+                    MU: 'Μαυρίκιος',
+                    MZ: 'Μοζαμβίκη',
+                    NL: 'Ολλανδία',
+                    NO: 'Νορβηγία',
+                    PK: 'Πακιστάν',
+                    PL: 'Πολωνία',
+                    PS: 'Παλαιστίνη',
+                    PT: 'Πορτογαλία',
+                    QA: 'Κατάρ',
+                    RO: 'Ρουμανία',
+                    RS: 'Σερβία',
+                    SA: 'Σαουδική Αραβία',
+                    SE: 'Σουηδία',
+                    SI: 'Σλοβενία',
+                    SK: 'Σλοβακία',
+                    SM: 'Σαν Μαρίνο',
+                    SN: 'Σενεγάλη',
+                    TL: 'Ανατολικό Τιμόρ',
+                    TN: 'Τυνησία',
+                    TR: 'Τουρκία',
+                    VG: 'Βρετανικές Παρθένοι Νήσοι',
+                    XK: 'Δημοκρατία του Κοσσυφοπεδίου'
+                }
+            },
+            id: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό ταυτότητας',
+                country: 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό ταυτότητας στην %s',
+                countries: {
+                    BA: 'Βοσνία και Ερζεγοβίνη',
+                    BG: 'Βουλγαρία',
+                    BR: 'Βραζιλία',
+                    CH: 'Ελβετία',
+                    CL: 'Χιλή',
+                    CN: 'Κίνα',
+                    CZ: 'Δημοκρατία της Τσεχίας',
+                    DK: 'Δανία',
+                    EE: 'Εσθονία',
+                    ES: 'Ισπανία',
+                    FI: 'Φινλανδία',
+                    HR: 'Κροατία',
+                    IE: 'Ιρλανδία',
+                    IS: 'Ισλανδία',
+                    LT: 'Λιθουανία',
+                    LV: 'Λετονία',
+                    ME: 'Μαυροβούνιο',
+                    MK: 'Μακεδονία',
+                    NL: 'Ολλανδία',
+                    PL: 'Πολωνία',
+                    RO: 'Ρουμανία',
+                    RS: 'Σερβία',
+                    SE: 'Σουηδία',
+                    SI: 'Σλοβενία',
+                    SK: 'Σλοβακία',
+                    SM: 'Σαν Μαρίνο',
+                    TH: 'Ταϊλάνδη',
+                    TR: 'Τουρκία',
+                    ZA: 'Νότια Αφρική'
+                }
+            },
+            identical: {
+                'default': 'Παρακαλώ εισάγετε την ίδια τιμή'
+            },
+            imei: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό IMEI'
+            },
+            imo: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό IMO'
+            },
+            integer: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό'
+            },
+            ip: {
+                'default': 'Παρακαλώ εισάγετε μία έγκυρη IP διεύθυνση',
+                ipv4: 'Παρακαλώ εισάγετε μία έγκυρη διεύθυνση IPv4',
+                ipv6: 'Παρακαλώ εισάγετε μία έγκυρη διεύθυνση IPv6'
+            },
+            isbn: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό ISBN'
+            },
+            isin: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό ISIN'
+            },
+            ismn: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό ISMN'
+            },
+            issn: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό ISSN'
+            },
+            lessThan: {
+                'default': 'Παρακαλώ εισάγετε μια τιμή μικρότερη ή ίση με %s',
+                notInclusive: 'Παρακαλώ εισάγετε μια τιμή μικρότερη από %s'
+            },
+            mac: {
+                'default': 'Παρακαλώ εισάγετε μία έγκυρη MAC διεύθυνση'
+            },
+            meid: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό MEID'
+            },
+            notEmpty: {
+                'default': 'Παρακαλώ εισάγετε μια τιμή'
+            },
+            numeric: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο δεκαδικό αριθμό'
+            },
+            phone: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό τηλεφώνου',
+                country: 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό τηλεφώνου στην %s',
+                countries: {
+                    AE: 'Ηνωμένα Αραβικά Εμιράτα',
+                    BG: 'Βουλγαρία',
+                    BR: 'Βραζιλία',
+                    CN: 'Κίνα',
+                    CZ: 'Δημοκρατία της Τσεχίας',
+                    DE: 'Γερμανία',
+                    DK: 'Δανία',
+                    ES: 'Ισπανία',
+                    FR: 'Γαλλία',
+                    GB: 'Ηνωμένο Βασίλειο',
+                    IN: 'Ινδία',
+                    MA: 'Μαρόκο',
+                    NL: 'Ολλανδία',
+                    PK: 'Πακιστάν',
+                    RO: 'Ρουμανία',
+                    RU: 'Ρωσία',
+                    SK: 'Σλοβακία',
+                    TH: 'Ταϊλάνδη',
+                    US: 'ΗΠΑ',
+                    VE: 'Βενεζουέλα'
+                }
+            },
+            promise: {
+                'default': 'Παρακαλώ εισάγετε μια έγκυρη τιμή'
+            },
+            regexp: {
+                'default': 'Παρακαλώ εισάγετε μια τιμή όπου ταιριάζει στο υπόδειγμα'
+            },
+            remote: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό'
+            },
+            rtn: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό RTN'
+            },
+            sedol: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό SEDOL'
+            },
+            siren: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό SIREN'
+            },
+            siret: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό SIRET'
+            },
+            step: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο βήμα από %s'
+            },
+            stringCase: {
+                'default': 'Παρακαλώ εισάγετε μόνο πεζούς χαρακτήρες',
+                upper: 'Παρακαλώ εισάγετε μόνο κεφαλαία γράμματα'
+            },
+            stringLength: {
+                'default': 'Παρακαλώ εισάγετε μια τιμή με έγκυρο μήκος',
+                less: 'Παρακαλούμε εισάγετε λιγότερο από %s χαρακτήρες',
+                more: 'Παρακαλούμε εισάγετε περισσότερο από %s χαρακτήρες',
+                between: 'Παρακαλούμε, εισάγετε τιμή μεταξύ %s και %s μήκος χαρακτήρων'
+            },
+            uri: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο URI'
+            },
+            uuid: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό UUID',
+                version: 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό έκδοσης %s'
+            },
+            vat: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό ΦΠΑ',
+                country: 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό ΦΠΑ στην %s',
+                countries: {
+                    AT: 'Αυστρία',
+                    BE: 'Βέλγιο',
+                    BG: 'Βουλγαρία',
+                    BR: 'Βραζιλία',
+                    CH: 'Ελβετία',
+                    CY: 'Κύπρος',
+                    CZ: 'Δημοκρατία της Τσεχίας',
+                    DE: 'Γερμανία',
+                    DK: 'Δανία',
+                    EE: 'Εσθονία',
+                    ES: 'Ισπανία',
+                    FI: 'Φινλανδία',
+                    FR: 'Γαλλία',
+                    GB: 'Ηνωμένο Βασίλειο',
+                    GR: 'Ελλάδα',
+                    EL: 'Ελλάδα',
+                    HU: 'Ουγγαρία',
+                    HR: 'Κροατία',
+                    IE: 'Ιρλανδία',
+                    IS: 'Ισλανδία',
+                    IT: 'Ιταλία',
+                    LT: 'Λιθουανία',
+                    LU: 'Λουξεμβούργο',
+                    LV: 'Λετονία',
+                    MT: 'Μάλτα',
+                    NL: 'Ολλανδία',
+                    NO: 'Νορβηγία',
+                    PL: 'Πολωνία',
+                    PT: 'Πορτογαλία',
+                    RO: 'Ρουμανία',
+                    RU: 'Ρωσία',
+                    RS: 'Σερβία',
+                    SE: 'Σουηδία',
+                    SI: 'Σλοβενία',
+                    SK: 'Σλοβακία',
+                    VE: 'Βενεζουέλα',
+                    ZA: 'Νότια Αφρική'
+                }
+            },
+            vin: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο αριθμό VIN'
+            },
+            zipCode: {
+                'default': 'Παρακαλώ εισάγετε ένα έγκυρο ταχυδρομικό κώδικα',
+                country: 'Παρακαλώ εισάγετε ένα έγκυρο ταχυδρομικό κώδικα στην %s',
+                countries: {
+                    AT: 'Αυστρία',
+                    BG: 'Βουλγαρία',
+                    BR: 'Βραζιλία',
+                    CA: 'Καναδάς',
+                    CH: 'Ελβετία',
+                    CZ: 'Δημοκρατία της Τσεχίας',
+                    DE: 'Γερμανία',
+                    DK: 'Δανία',
+                    ES: 'Ισπανία',
+                    FR: 'Γαλλία',
+                    GB: 'Ηνωμένο Βασίλειο',
+                    IE: 'Ιρλανδία',
+                    IN: 'Ινδία',
+                    IT: 'Ιταλία',
+                    MA: 'Μαρόκο',
+                    NL: 'Ολλανδία',
+                    PL: 'Πολωνία',
+                    PT: 'Πορτογαλία',
+                    RO: 'Ρουμανία',
+                    RU: 'Ρωσία',
+                    SE: 'Σουηδία',
+                    SG: 'Σιγκαπούρη',
+                    SK: 'Σλοβακία',
+                    US: 'ΗΠΑ'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/en_US.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Default English package. It's included in the dist, so you do NOT need to include it to your head tag
+     * The only reason I put it here is that you can clone it, and translate it into your language
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'en_US': {
+            base64: {
+                'default': 'Please enter a valid base 64 encoded'
+            },
+            between: {
+                'default': 'Please enter a value between %s and %s',
+                notInclusive: 'Please enter a value between %s and %s strictly'
+            },
+            bic: {
+                'default': 'Please enter a valid BIC number'
+            },
+            callback: {
+                'default': 'Please enter a valid value'
+            },
+            choice: {
+                'default': 'Please enter a valid value',
+                less: 'Please choose %s options at minimum',
+                more: 'Please choose %s options at maximum',
+                between: 'Please choose %s - %s options'
+            },
+            color: {
+                'default': 'Please enter a valid color'
+            },
+            creditCard: {
+                'default': 'Please enter a valid credit card number'
+            },
+            cusip: {
+                'default': 'Please enter a valid CUSIP number'
+            },
+            cvv: {
+                'default': 'Please enter a valid CVV number'
+            },
+            date: {
+                'default': 'Please enter a valid date',
+                min: 'Please enter a date after %s',
+                max: 'Please enter a date before %s',
+                range: 'Please enter a date in the range %s - %s'
+            },
+            different: {
+                'default': 'Please enter a different value'
+            },
+            digits: {
+                'default': 'Please enter only digits'
+            },
+            ean: {
+                'default': 'Please enter a valid EAN number'
+            },
+            ein: {
+                'default': 'Please enter a valid EIN number'
+            },
+            emailAddress: {
+                'default': 'Please enter a valid email address'
+            },
+            file: {
+                'default': 'Please choose a valid file'
+            },
+            greaterThan: {
+                'default': 'Please enter a value greater than or equal to %s',
+                notInclusive: 'Please enter a value greater than %s'
+            },
+            grid: {
+                'default': 'Please enter a valid GRId number'
+            },
+            hex: {
+                'default': 'Please enter a valid hexadecimal number'
+            },
+            iban: {
+                'default': 'Please enter a valid IBAN number',
+                country: 'Please enter a valid IBAN number in %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'United Arab Emirates',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbaijan',
+                    BA: 'Bosnia and Herzegovina',
+                    BE: 'Belgium',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CI: 'Ivory Coast',
+                    CM: 'Cameroon',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Cyprus',
+                    CZ: 'Czech Republic',
+                    DE: 'Germany',
+                    DK: 'Denmark',
+                    DO: 'Dominican Republic',
+                    DZ: 'Algeria',
+                    EE: 'Estonia',
+                    ES: 'Spain',
+                    FI: 'Finland',
+                    FO: 'Faroe Islands',
+                    FR: 'France',
+                    GB: 'United Kingdom',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Greenland',
+                    GR: 'Greece',
+                    GT: 'Guatemala',
+                    HR: 'Croatia',
+                    HU: 'Hungary',
+                    IE: 'Ireland',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Iceland',
+                    IT: 'Italy',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakhstan',
+                    LB: 'Lebanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MC: 'Monaco',
+                    MD: 'Moldova',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Netherlands',
+                    NO: 'Norway',
+                    PK: 'Pakistan',
+                    PL: 'Poland',
+                    PS: 'Palestine',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SA: 'Saudi Arabia',
+                    SE: 'Sweden',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'East Timor',
+                    TN: 'Tunisia',
+                    TR: 'Turkey',
+                    VG: 'Virgin Islands, British',
+                    XK: 'Republic of Kosovo'
+                }
+            },
+            id: {
+                'default': 'Please enter a valid identification number',
+                country: 'Please enter a valid identification number in %s',
+                countries: {
+                    BA: 'Bosnia and Herzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CL: 'Chile',
+                    CN: 'China',
+                    CZ: 'Czech Republic',
+                    DK: 'Denmark',
+                    EE: 'Estonia',
+                    ES: 'Spain',
+                    FI: 'Finland',
+                    HR: 'Croatia',
+                    IE: 'Ireland',
+                    IS: 'Iceland',
+                    LT: 'Lithuania',
+                    LV: 'Latvia',
+                    ME: 'Montenegro',
+                    MK: 'Macedonia',
+                    NL: 'Netherlands',
+                    PL: 'Poland',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Sweden',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Turkey',
+                    ZA: 'South Africa'
+                }
+            },
+            identical: {
+                'default': 'Please enter the same value'
+            },
+            imei: {
+                'default': 'Please enter a valid IMEI number'
+            },
+            imo: {
+                'default': 'Please enter a valid IMO number'
+            },
+            integer: {
+                'default': 'Please enter a valid number'
+            },
+            ip: {
+                'default': 'Please enter a valid IP address',
+                ipv4: 'Please enter a valid IPv4 address',
+                ipv6: 'Please enter a valid IPv6 address'
+            },
+            isbn: {
+                'default': 'Please enter a valid ISBN number'
+            },
+            isin: {
+                'default': 'Please enter a valid ISIN number'
+            },
+            ismn: {
+                'default': 'Please enter a valid ISMN number'
+            },
+            issn: {
+                'default': 'Please enter a valid ISSN number'
+            },
+            lessThan: {
+                'default': 'Please enter a value less than or equal to %s',
+                notInclusive: 'Please enter a value less than %s'
+            },
+            mac: {
+                'default': 'Please enter a valid MAC address'
+            },
+            meid: {
+                'default': 'Please enter a valid MEID number'
+            },
+            notEmpty: {
+                'default': 'Please enter a value'
+            },
+            numeric: {
+                'default': 'Please enter a valid float number'
+            },
+            phone: {
+                'default': 'Please enter a valid phone number',
+                country: 'Please enter a valid phone number in %s',
+                countries: {
+                    AE: 'United Arab Emirates',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CN: 'China',
+                    CZ: 'Czech Republic',
+                    DE: 'Germany',
+                    DK: 'Denmark',
+                    ES: 'Spain',
+                    FR: 'France',
+                    GB: 'United Kingdom',
+                    IN: 'India',
+                    MA: 'Morocco',
+                    NL: 'Netherlands',
+                    PK: 'Pakistan',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    SK: 'Slovakia',
+                    TH: 'Thailand',
+                    US: 'USA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Please enter a valid value'
+            },
+            regexp: {
+                'default': 'Please enter a value matching the pattern'
+            },
+            remote: {
+                'default': 'Please enter a valid value'
+            },
+            rtn: {
+                'default': 'Please enter a valid RTN number'
+            },
+            sedol: {
+                'default': 'Please enter a valid SEDOL number'
+            },
+            siren: {
+                'default': 'Please enter a valid SIREN number'
+            },
+            siret: {
+                'default': 'Please enter a valid SIRET number'
+            },
+            step: {
+                'default': 'Please enter a valid step of %s'
+            },
+            stringCase: {
+                'default': 'Please enter only lowercase characters',
+                upper: 'Please enter only uppercase characters'
+            },
+            stringLength: {
+                'default': 'Please enter a value with valid length',
+                less: 'Please enter less than %s characters',
+                more: 'Please enter more than %s characters',
+                between: 'Please enter value between %s and %s characters long'
+            },
+            uri: {
+                'default': 'Please enter a valid URI'
+            },
+            uuid: {
+                'default': 'Please enter a valid UUID number',
+                version: 'Please enter a valid UUID version %s number'
+            },
+            vat: {
+                'default': 'Please enter a valid VAT number',
+                country: 'Please enter a valid VAT number in %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Belgium',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CY: 'Cyprus',
+                    CZ: 'Czech Republic',
+                    DE: 'Germany',
+                    DK: 'Denmark',
+                    EE: 'Estonia',
+                    ES: 'Spain',
+                    FI: 'Finland',
+                    FR: 'France',
+                    GB: 'United Kingdom',
+                    GR: 'Greece',
+                    EL: 'Greece',
+                    HU: 'Hungary',
+                    HR: 'Croatia',
+                    IE: 'Ireland',
+                    IS: 'Iceland',
+                    IT: 'Italy',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MT: 'Malta',
+                    NL: 'Netherlands',
+                    NO: 'Norway',
+                    PL: 'Poland',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    RS: 'Serbia',
+                    SE: 'Sweden',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    VE: 'Venezuela',
+                    ZA: 'South Africa'
+                }
+            },
+            vin: {
+                'default': 'Please enter a valid VIN number'
+            },
+            zipCode: {
+                'default': 'Please enter a valid postal code',
+                country: 'Please enter a valid postal code in %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CA: 'Canada',
+                    CH: 'Switzerland',
+                    CZ: 'Czech Republic',
+                    DE: 'Germany',
+                    DK: 'Denmark',
+                    ES: 'Spain',
+                    FR: 'France',
+                    GB: 'United Kingdom',
+                    IE: 'Ireland',
+                    IN: 'India',
+                    IT: 'Italy',
+                    MA: 'Morocco',
+                    NL: 'Netherlands',
+                    PL: 'Poland',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    SE: 'Sweden',
+                    SG: 'Singapore',
+                    SK: 'Slovakia',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/es_CL.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Chilean Spanish language package
+     * Translated by @marceloampuerop6
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'es_CL': {
+            base64: {
+                'default': 'Por favor ingrese un valor válido en base 64'
+            },
+            between: {
+                'default': 'Por favor ingrese un valor entre %s y %s',
+                notInclusive: 'Por favor ingrese un valor sólo entre %s and %s'
+            },
+            bic: {
+                'default': 'Por favor ingrese un número BIC válido'
+            },
+            callback: {
+                'default': 'Por favor ingrese un valor válido'
+            },
+            choice: {
+                'default': 'Por favor ingrese un valor válido',
+                less: 'Por favor elija %s opciones como mínimo',
+                more: 'Por favor elija %s optiones como máximo',
+                between: 'Por favor elija de %s a %s opciones'
+            },
+            color: {
+                'default': 'Por favor ingrese un color válido'
+            },
+            creditCard: {
+                'default': 'Por favor ingrese un número válido de tarjeta de crédito'
+            },
+            cusip: {
+                'default': 'Por favor ingrese un número CUSIP válido'
+            },
+            cvv: {
+                'default': 'Por favor ingrese un número CVV válido'
+            },
+            date: {
+                'default': 'Por favor ingrese una fecha válida',
+                min: 'Por favor ingrese una fecha posterior a %s',
+                max: 'Por favor ingrese una fecha anterior a %s',
+                range: 'Por favor ingrese una fecha en el rango %s - %s'
+            },
+            different: {
+                'default': 'Por favor ingrese un valor distinto'
+            },
+            digits: {
+                'default': 'Por favor ingrese sólo dígitos'
+            },
+            ean: {
+                'default': 'Por favor ingrese un número EAN válido'
+            },
+            ein: {
+                'default': 'Por favor ingrese un número EIN válido'
+            },
+            emailAddress: {
+                'default': 'Por favor ingrese un email válido'
+            },
+            file: {
+                'default': 'Por favor elija un archivo válido'
+            },
+            greaterThan: {
+                'default': 'Por favor ingrese un valor mayor o igual a %s',
+                notInclusive: 'Por favor ingrese un valor mayor que %s'
+            },
+            grid: {
+                'default': 'Por favor ingrese un número GRId válido'
+            },
+            hex: {
+                'default': 'Por favor ingrese un valor hexadecimal válido'
+            },
+            iban: {
+                'default': 'Por favor ingrese un número IBAN válido',
+                country: 'Por favor ingrese un número IBAN válido en %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Emiratos Árabes Unidos',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbaiyán',
+                    BA: 'Bosnia-Herzegovina',
+                    BE: 'Bélgica',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Baréin',
+                    BI: 'Burundi',
+                    BJ: 'Benín',
+                    BR: 'Brasil',
+                    CH: 'Suiza',
+                    CI: 'Costa de Marfil',
+                    CM: 'Camerún',
+                    CR: 'Costa Rica',
+                    CV: 'Cabo Verde',
+                    CY: 'Cyprus',
+                    CZ: 'República Checa',
+                    DE: 'Alemania',
+                    DK: 'Dinamarca',
+                    DO: 'República Dominicana',
+                    DZ: 'Argelia',
+                    EE: 'Estonia',
+                    ES: 'España',
+                    FI: 'Finlandia',
+                    FO: 'Islas Feroe',
+                    FR: 'Francia',
+                    GB: 'Reino Unido',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Groenlandia',
+                    GR: 'Grecia',
+                    GT: 'Guatemala',
+                    HR: 'Croacia',
+                    HU: 'Hungría',
+                    IE: 'Irlanda',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Islandia',
+                    IT: 'Italia',
+                    JO: 'Jordania',
+                    KW: 'Kuwait',
+                    KZ: 'Kazajistán',
+                    LB: 'Líbano',
+                    LI: 'Liechtenstein',
+                    LT: 'Lituania',
+                    LU: 'Luxemburgo',
+                    LV: 'Letonia',
+                    MC: 'Mónaco',
+                    MD: 'Moldavia',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonia',
+                    ML: 'Malí',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauricio',
+                    MZ: 'Mozambique',
+                    NL: 'Países Bajos',
+                    NO: 'Noruega',
+                    PK: 'Pakistán',
+                    PL: 'Poland',
+                    PS: 'Palestina',
+                    PT: 'Portugal',
+                    QA: 'Catar',
+                    RO: 'Rumania',
+                    RS: 'Serbia',
+                    SA: 'Arabia Saudita',
+                    SE: 'Suecia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovaquia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timor Oriental',
+                    TN: 'Túnez',
+                    TR: 'Turquía',
+                    VG: 'Islas Vírgenes Británicas',
+                    XK: 'República de Kosovo'
+                }
+            },
+            id: {
+                'default': 'Por favor ingrese un número de identificación válido',
+                country: 'Por favor ingrese un número de identificación válido en %s',
+                countries: {
+                    BA: 'Bosnia Herzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CH: 'Suiza',
+                    CL: 'Chile',
+                    CN: 'China',
+                    CZ: 'República Checa',
+                    DK: 'Dinamarca',
+                    EE: 'Estonia',
+                    ES: 'España',
+                    FI: 'Finlandia',
+                    HR: 'Croacia',
+                    IE: 'Irlanda',
+                    IS: 'Islandia',
+                    LT: 'Lituania',
+                    LV: 'Letonia',
+                    ME: 'Montenegro',
+                    MK: 'Macedonia',
+                    NL: 'Países Bajos',
+                    PL: 'Poland',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Suecia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovaquia',
+                    SM: 'San Marino',
+                    TH: 'Tailandia',
+                    TR: 'Turquía',
+                    ZA: 'Sudáfrica'
+                }
+            },
+            identical: {
+                'default': 'Por favor ingrese el mismo valor'
+            },
+            imei: {
+                'default': 'Por favor ingrese un número IMEI válido'
+            },
+            imo: {
+                'default': 'Por favor ingrese un número IMO válido'
+            },
+            integer: {
+                'default': 'Por favor ingrese un número válido'
+            },
+            ip: {
+                'default': 'Por favor ingrese una dirección IP válida',
+                ipv4: 'Por favor ingrese una dirección IPv4 válida',
+                ipv6: 'Por favor ingrese una dirección IPv6 válida'
+            },
+            isbn: {
+                'default': 'Por favor ingrese un número ISBN válido'
+            },
+            isin: {
+                'default': 'Por favor ingrese un número ISIN válido'
+            },
+            ismn: {
+                'default': 'Por favor ingrese un número ISMN válido'
+            },
+            issn: {
+                'default': 'Por favor ingrese un número ISSN válido'
+            },
+            lessThan: {
+                'default': 'Por favor ingrese un valor menor o igual a %s',
+                notInclusive: 'Por favor ingrese un valor menor que %s'
+            },
+            mac: {
+                'default': 'Por favor ingrese una dirección MAC válida'
+            },
+            meid: {
+                'default': 'Por favor ingrese un número MEID válido'
+            },
+            notEmpty: {
+                'default': 'Por favor ingrese un valor'
+            },
+            numeric: {
+                'default': 'Por favor ingrese un número decimal válido'
+            },
+            phone: {
+                'default': 'Por favor ingrese un número válido de teléfono',
+                country: 'Por favor ingrese un número válido de teléfono en %s',
+                countries: {
+                    AE: 'Emiratos Árabes Unidos',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CN: 'China',
+                    CZ: 'República Checa',
+                    DE: 'Alemania',
+                    DK: 'Dinamarca',
+                    ES: 'España',
+                    FR: 'Francia',
+                    GB: 'Reino Unido',
+                    IN: 'India',
+                    MA: 'Marruecos',
+                    NL: 'Países Bajos',
+                    PK: 'Pakistán',
+                    RO: 'Rumania',
+                    RU: 'Rusa',
+                    SK: 'Eslovaquia',
+                    TH: 'Tailandia',
+                    US: 'Estados Unidos',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Por favor ingrese un valor válido'
+            },
+            regexp: {
+                'default': 'Por favor ingrese un valor que coincida con el patrón'
+            },
+            remote: {
+                'default': 'Por favor ingrese un valor válido'
+            },
+            rtn: {
+                'default': 'Por favor ingrese un número RTN válido'
+            },
+            sedol: {
+                'default': 'Por favor ingrese un número SEDOL válido'
+            },
+            siren: {
+                'default': 'Por favor ingrese un número SIREN válido'
+            },
+            siret: {
+                'default': 'Por favor ingrese un número SIRET válido'
+            },
+            step: {
+                'default': 'Por favor ingrese un paso válido de %s'
+            },
+            stringCase: {
+                'default': 'Por favor ingrese sólo caracteres en minúscula',
+                upper: 'Por favor ingrese sólo caracteres en mayúscula'
+            },
+            stringLength: {
+                'default': 'Por favor ingrese un valor con una longitud válida',
+                less: 'Por favor ingrese menos de %s caracteres',
+                more: 'Por favor ingrese más de %s caracteres',
+                between: 'Por favor ingrese un valor con una longitud entre %s y %s caracteres'
+            },
+            uri: {
+                'default': 'Por favor ingresese una URI válida'
+            },
+            uuid: {
+                'default': 'Por favor ingrese un número UUID válido',
+                version: 'Por favor ingrese una versión UUID válida para %s'
+            },
+            vat: {
+                'default': 'Por favor ingrese un número VAT válido',
+                country: 'Por favor ingrese un número VAT válido en %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Bélgica',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CH: 'Suiza',
+                    CY: 'Chipre',
+                    CZ: 'República Checa',
+                    DE: 'Alemania',
+                    DK: 'Dinamarca',
+                    EE: 'Estonia',
+                    ES: 'España',
+                    FI: 'Finlandia',
+                    FR: 'Francia',
+                    GB: 'Reino Unido',
+                    GR: 'Grecia',
+                    EL: 'Grecia',
+                    HU: 'Hungría',
+                    HR: 'Croacia',
+                    IE: 'Irlanda',
+                    IS: 'Islandia',
+                    IT: 'Italia',
+                    LT: 'Lituania',
+                    LU: 'Luxemburgo',
+                    LV: 'Letonia',
+                    MT: 'Malta',
+                    NL: 'Países Bajos',
+                    NO: 'Noruega',
+                    PL: 'Polonia',
+                    PT: 'Portugal',
+                    RO: 'Rumanía',
+                    RU: 'Rusa',
+                    RS: 'Serbia',
+                    SE: 'Suecia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovaquia',
+                    VE: 'Venezuela',
+                    ZA: 'Sudáfrica'
+                }
+            },
+            vin: {
+                'default': 'Por favor ingrese un número VIN válido'
+            },
+            zipCode: {
+                'default': 'Por favor ingrese un código postal válido',
+                country: 'Por favor ingrese un código postal válido en %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CA: 'Canadá',
+                    CH: 'Suiza',
+                    CZ: 'República Checa',
+                    DE: 'Alemania',
+                    DK: 'Dinamarca',
+                    ES: 'España',
+                    FR: 'Francia',
+                    GB: 'Reino Unido',
+                    IE: 'Irlanda',
+                    IN: 'India',
+                    IT: 'Italia',
+                    MA: 'Marruecos',
+                    NL: 'Países Bajos',
+                    PL: 'Poland',
+                    PT: 'Portugal',
+                    RO: 'Rumanía',
+                    RU: 'Rusia',
+                    SE: 'Suecia',
+                    SG: 'Singapur',
+                    SK: 'Eslovaquia',
+                    US: 'Estados Unidos'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/es_ES.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Spanish language package
+     * Translated by @vadail
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'es_ES': {
+            base64: {
+                'default': 'Por favor introduce un valor válido en base 64'
+            },
+            between: {
+                'default': 'Por favor introduce un valor entre %s y %s',
+                notInclusive: 'Por favor introduce un valor sólo entre %s and %s'
+            },
+            bic: {
+                'default': 'Por favor introduce un número BIC válido'
+            },
+            callback: {
+                'default': 'Por favor introduce un valor válido'
+            },
+            choice: {
+                'default': 'Por favor introduce un valor válido',
+                less: 'Por favor elija %s opciones como mínimo',
+                more: 'Por favor elija %s optiones como máximo',
+                between: 'Por favor elija de %s a %s opciones'
+            },
+            color: {
+                'default': 'Por favor introduce un color válido'
+            },
+            creditCard: {
+                'default': 'Por favor introduce un número válido de tarjeta de crédito'
+            },
+            cusip: {
+                'default': 'Por favor introduce un número CUSIP válido'
+            },
+            cvv: {
+                'default': 'Por favor introduce un número CVV válido'
+            },
+            date: {
+                'default': 'Por favor introduce una fecha válida',
+                min: 'Por favor introduce una fecha posterior al %s',
+                max: 'Por favor introduce una fecha previa al %s',
+                range: 'Por favor introduce una fecha entre el %s y el %s'
+            },
+            different: {
+                'default': 'Por favor introduce un valor distinto'
+            },
+            digits: {
+                'default': 'Por favor introduce sólo dígitos'
+            },
+            ean: {
+                'default': 'Por favor introduce un número EAN válido'
+            },
+            ein: {
+                'default': 'Por favor introduce un número EIN válido'
+            },
+            emailAddress: {
+                'default': 'Por favor introduce un email válido'
+            },
+            file: {
+                'default': 'Por favor elija un archivo válido'
+            },
+            greaterThan: {
+                'default': 'Por favor introduce un valor mayor o igual a %s',
+                notInclusive: 'Por favor introduce un valor mayor que %s'
+            },
+            grid: {
+                'default': 'Por favor introduce un número GRId válido'
+            },
+            hex: {
+                'default': 'Por favor introduce un valor hexadecimal válido'
+            },
+            iban: {
+                'default': 'Por favor introduce un número IBAN válido',
+                country: 'Por favor introduce un número IBAN válido en %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Emiratos Árabes Unidos',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbaiyán',
+                    BA: 'Bosnia-Herzegovina',
+                    BE: 'Bélgica',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Baréin',
+                    BI: 'Burundi',
+                    BJ: 'Benín',
+                    BR: 'Brasil',
+                    CH: 'Suiza',
+                    CI: 'Costa de Marfil',
+                    CM: 'Camerún',
+                    CR: 'Costa Rica',
+                    CV: 'Cabo Verde',
+                    CY: 'Cyprus',
+                    CZ: 'República Checa',
+                    DE: 'Alemania',
+                    DK: 'Dinamarca',
+                    DO: 'República Dominicana',
+                    DZ: 'Argelia',
+                    EE: 'Estonia',
+                    ES: 'España',
+                    FI: 'Finlandia',
+                    FO: 'Islas Feroe',
+                    FR: 'Francia',
+                    GB: 'Reino Unido',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Groenlandia',
+                    GR: 'Grecia',
+                    GT: 'Guatemala',
+                    HR: 'Croacia',
+                    HU: 'Hungría',
+                    IE: 'Irlanda',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Islandia',
+                    IT: 'Italia',
+                    JO: 'Jordania',
+                    KW: 'Kuwait',
+                    KZ: 'Kazajistán',
+                    LB: 'Líbano',
+                    LI: 'Liechtenstein',
+                    LT: 'Lituania',
+                    LU: 'Luxemburgo',
+                    LV: 'Letonia',
+                    MC: 'Mónaco',
+                    MD: 'Moldavia',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonia',
+                    ML: 'Malí',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauricio',
+                    MZ: 'Mozambique',
+                    NL: 'Países Bajos',
+                    NO: 'Noruega',
+                    PK: 'Pakistán',
+                    PL: 'Poland',
+                    PS: 'Palestina',
+                    PT: 'Portugal',
+                    QA: 'Catar',
+                    RO: 'Rumania',
+                    RS: 'Serbia',
+                    SA: 'Arabia Saudita',
+                    SE: 'Suecia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovaquia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timor Oriental',
+                    TN: 'Túnez',
+                    TR: 'Turquía',
+                    VG: 'Islas Vírgenes Británicas',
+                    XK: 'República de Kosovo'
+                }
+            },
+            id: {
+                'default': 'Por favor introduce un número de identificación válido',
+                country: 'Por favor introduce un número válido de identificación en %s',
+                countries: {
+                    BA: 'Bosnia Herzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CH: 'Suiza',
+                    CL: 'Chile',
+                    CN: 'China',
+                    CZ: 'República Checa',
+                    DK: 'Dinamarca',
+                    EE: 'Estonia',
+                    ES: 'España',
+                    FI: 'Finlandia',
+                    HR: 'Croacia',
+                    IE: 'Irlanda',
+                    IS: 'Islandia',
+                    LT: 'Lituania',
+                    LV: 'Letonia',
+                    ME: 'Montenegro',
+                    MK: 'Macedonia',
+                    NL: 'Países Bajos',
+                    PL: 'Poland',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Suecia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovaquia',
+                    SM: 'San Marino',
+                    TH: 'Tailandia',
+                    TR: 'Turquía',
+                    ZA: 'Sudáfrica'
+                }
+            },
+            identical: {
+                'default': 'Por favor introduce el mismo valor'
+            },
+            imei: {
+                'default': 'Por favor introduce un número IMEI válido'
+            },
+            imo: {
+                'default': 'Por favor introduce un número IMO válido'
+            },
+            integer: {
+                'default': 'Por favor introduce un número válido'
+            },
+            ip: {
+                'default': 'Por favor introduce una dirección IP válida',
+                ipv4: 'Por favor introduce una dirección IPv4 válida',
+                ipv6: 'Por favor introduce una dirección IPv6 válida'
+            },
+            isbn: {
+                'default': 'Por favor introduce un número ISBN válido'
+            },
+            isin: {
+                'default': 'Por favor introduce un número ISIN válido'
+            },
+            ismn: {
+                'default': 'Por favor introduce un número ISMN válido'
+            },
+            issn: {
+                'default': 'Por favor introduce un número ISSN válido'
+            },
+            lessThan: {
+                'default': 'Por favor introduce un valor menor o igual a %s',
+                notInclusive: 'Por favor introduce un valor menor que %s'
+            },
+            mac: {
+                'default': 'Por favor introduce una dirección MAC válida'
+            },
+            meid: {
+                'default': 'Por favor introduce un número MEID válido'
+            },
+            notEmpty: {
+                'default': 'Por favor introduce un valor'
+            },
+            numeric: {
+                'default': 'Por favor introduce un número decimal válido'
+            },
+            phone: {
+                'default': 'Por favor introduce un número válido de teléfono',
+                country: 'Por favor introduce un número válido de teléfono en %s',
+                countries: {
+                    AE: 'Emiratos Árabes Unidos',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CN: 'China',
+                    CZ: 'República Checa',
+                    DE: 'Alemania',
+                    DK: 'Dinamarca',
+                    ES: 'España',
+                    FR: 'Francia',
+                    GB: 'Reino Unido',
+                    IN: 'India',
+                    MA: 'Marruecos',
+                    NL: 'Países Bajos',
+                    PK: 'Pakistán',
+                    RO: 'Rumania',
+                    RU: 'Rusa',
+                    SK: 'Eslovaquia',
+                    TH: 'Tailandia',
+                    US: 'Estados Unidos',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Por favor introduce un valor válido'
+            },
+            regexp: {
+                'default': 'Por favor introduce un valor que coincida con el patrón'
+            },
+            remote: {
+                'default': 'Por favor introduce un valor válido'
+            },
+            rtn: {
+                'default': 'Por favor introduce un número RTN válido'
+            },
+            sedol: {
+                'default': 'Por favor introduce un número SEDOL válido'
+            },
+            siren: {
+                'default': 'Por favor introduce un número SIREN válido'
+            },
+            siret: {
+                'default': 'Por favor introduce un número SIRET válido'
+            },
+            step: {
+                'default': 'Por favor introduce un paso válido de %s'
+            },
+            stringCase: {
+                'default': 'Por favor introduce sólo caracteres en minúscula',
+                upper: 'Por favor introduce sólo caracteres en mayúscula'
+            },
+            stringLength: {
+                'default': 'Por favor introduce un valor con una longitud válida',
+                less: 'Por favor introduce menos de %s caracteres',
+                more: 'Por favor introduce más de %s caracteres',
+                between: 'Por favor introduce un valor con una longitud entre %s y %s caracteres'
+            },
+            uri: {
+                'default': 'Por favor introduce una URI válida'
+            },
+            uuid: {
+                'default': 'Por favor introduce un número UUID válido',
+                version: 'Por favor introduce una versión UUID válida para %s'
+            },
+            vat: {
+                'default': 'Por favor introduce un número IVA válido',
+                country: 'Por favor introduce un número IVA válido en %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Bélgica',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CH: 'Suiza',
+                    CY: 'Chipre',
+                    CZ: 'República Checa',
+                    DE: 'Alemania',
+                    DK: 'Dinamarca',
+                    EE: 'Estonia',
+                    ES: 'España',
+                    FI: 'Finlandia',
+                    FR: 'Francia',
+                    GB: 'Reino Unido',
+                    GR: 'Grecia',
+                    EL: 'Grecia',
+                    HU: 'Hungría',
+                    HR: 'Croacia',
+                    IE: 'Irlanda',
+                    IS: 'Islandia',
+                    IT: 'Italia',
+                    LT: 'Lituania',
+                    LU: 'Luxemburgo',
+                    LV: 'Letonia',
+                    MT: 'Malta',
+                    NL: 'Países Bajos',
+                    NO: 'Noruega',
+                    PL: 'Polonia',
+                    PT: 'Portugal',
+                    RO: 'Rumanía',
+                    RU: 'Rusa',
+                    RS: 'Serbia',
+                    SE: 'Suecia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovaquia',
+                    VE: 'Venezuela',
+                    ZA: 'Sudáfrica'
+                }
+            },
+            vin: {
+                'default': 'Por favor introduce un número VIN válido'
+            },
+            zipCode: {
+                'default': 'Por favor introduce un código postal válido',
+                country: 'Por favor introduce un código postal válido en %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CA: 'Canadá',
+                    CH: 'Suiza',
+                    CZ: 'República Checa',
+                    DE: 'Alemania',
+                    DK: 'Dinamarca',
+                    ES: 'España',
+                    FR: 'Francia',
+                    GB: 'Reino Unido',
+                    IE: 'Irlanda',
+                    IN: 'India',
+                    IT: 'Italia',
+                    MA: 'Marruecos',
+                    NL: 'Países Bajos',
+                    PL: 'Poland',
+                    PT: 'Portugal',
+                    RO: 'Rumanía',
+                    RU: 'Rusa',
+                    SE: 'Suecia',
+                    SG: 'Singapur',
+                    SK: 'Eslovaquia',
+                    US: 'Estados Unidos'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/eu_ES.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Basque language package
+     * Translated by @xabikip
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'eu_ES': {
+            base64: {
+                'default': 'Mesedez sartu base 64an balore egoki bat'
+            },
+            between: {
+                'default': 'Mesedez sartu %s eta %s artean balore bat',
+                notInclusive: 'Mesedez sartu %s eta %s arteko balore bat soilik'
+            },
+            bic: {
+                'default': 'Mesedez sartu BIC zenbaki egoki bat'
+            },
+            callback: {
+                'default': 'Mesedez sartu balore egoki bat'
+            },
+            choice: {
+                'default': 'Mesedez sartu balore egoki bat',
+                less: 'Mesedez aukeraru %s aukera gutxienez',
+                more: 'Mesedez aukeraru %s aukera gehienez',
+                between: 'Mesedez aukeratu %s eta %s arteko aukerak'
+            },
+            color: {
+                'default': 'Mesedezn sartu kolore egoki bat'
+            },
+            creditCard: {
+                'default': 'Mesedez sartu kerditu-txartelaren zenbaki egoki bat'
+            },
+            cusip: {
+                'default': 'Mesedez sartu CUSIP zenbaki egoki bat'
+            },
+            cvv: {
+                'default': 'Mesedez sartu CVV zenbaki egoki bat'
+            },
+            date: {
+                'default': 'Mesedez sartu data egoki bat',
+                min: 'Mesedez sartu %s baino geroagoko data bat',
+                max: 'Mesedez sartu %s baino lehenagoko data bat',
+                range: 'Mesedez sartu %s eta %s arteko data bat'
+            },
+            different: {
+                'default': 'Mesedez sartu balore ezberdin bat'
+            },
+            digits: {
+                'default': 'Mesedez sigituak soilik sartu'
+            },
+            ean: {
+                'default': 'Mesedez EAN zenbaki egoki bat sartu'
+            },
+            ein: {
+                'default': 'Mesedez EIN zenbaki egoki bat sartu'
+            },
+            emailAddress: {
+                'default': 'Mesedez e-posta egoki bat sartu'
+            },
+            file: {
+                'default': 'Mesedez artxibo egoki bat aukeratu'
+            },
+            greaterThan: {
+                'default': 'Mesedez %s baino handiagoa edo berdina den zenbaki bat sartu',
+                notInclusive: 'Mesedez %s baino handiagoa den zenbaki bat sartu'
+            },
+            grid: {
+                'default': 'Mesedez GRID zenbaki egoki bat sartu'
+            },
+            hex: {
+                'default': 'Mesedez sartu balore hamaseitar egoki bat'
+            },
+            iban: {
+                'default': 'Mesedez, sartu IBAN zenbaki egoki bat',
+                country: 'Mesedez, sartu IBAN zenbaki egoki bat honako: %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Arabiar Emirerri Batuak',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbaijan',
+                    BA: 'Bosnia-Herzegovina',
+                    BE: 'Belgika',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Baréin',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasil',
+                    CH: 'Suitza',
+                    CI: 'Boli Kosta',
+                    CM: 'Kamerun',
+                    CR: 'Costa Rica',
+                    CV: 'Cabo Verde',
+                    CY: 'Cyprus',
+                    CZ: 'Txekiar Errepublika',
+                    DE: 'Alemania',
+                    DK: 'Danimarka',
+                    DO: 'Dominikar Errepublika',
+                    DZ: 'Aljeria',
+                    EE: 'Estonia',
+                    ES: 'Espainia',
+                    FI: 'Finlandia',
+                    FO: 'Feroe Irlak',
+                    FR: 'Frantzia',
+                    GB: 'Erresuma Batua',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Groenlandia',
+                    GR: 'Grezia',
+                    GT: 'Guatemala',
+                    HR: 'Kroazia',
+                    HU: 'Hungaria',
+                    IE: 'Irlanda',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Islandia',
+                    IT: 'Italia',
+                    JO: 'Jordania',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakhstan',
+                    LB: 'Libano',
+                    LI: 'Liechtenstein',
+                    LT: 'Lituania',
+                    LU: 'Luxemburgo',
+                    LV: 'Letonia',
+                    MC: 'Monako',
+                    MD: 'Moldavia',
+                    ME: 'Montenegro',
+                    MG: 'Madagaskar',
+                    MK: 'Mazedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Maurizio',
+                    MZ: 'Mozambike',
+                    NL: 'Herbeherak',
+                    NO: 'Norvegia',
+                    PK: 'Pakistán',
+                    PL: 'Poland',
+                    PS: 'Palestina',
+                    PT: 'Portugal',
+                    QA: 'Catar',
+                    RO: 'Errumania',
+                    RS: 'Serbia',
+                    SA: 'Arabia Saudi',
+                    SE: 'Suedia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovakia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Ekialdeko Timor',
+                    TN: 'Tunisia',
+                    TR: 'Turkia',
+                    VG: 'Birjina Uharte Britainiar',
+                    XK: 'Kosovoko Errepublika'
+                }
+            },
+            id: {
+                'default': 'Mesedez baliozko identifikazio-zenbakia sartu',
+                country: 'Mesedez baliozko identifikazio-zenbakia sartu honako: %s',
+                countries: {
+                    BA: 'Bosnia Herzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CH: 'Suitza',
+                    CL: 'Txile',
+                    CN: 'Txina',
+                    CZ: 'Txekiar Errepublika',
+                    DK: 'Danimarka',
+                    EE: 'Estonia',
+                    ES: 'Espainia',
+                    FI: 'Finlandia',
+                    HR: 'Kroazia',
+                    IE: 'Irlanda',
+                    IS: 'Islandia',
+                    LT: 'Lituania',
+                    LV: 'Letonia',
+                    ME: 'Montenegro',
+                    MK: 'Mazedonia',
+                    NL: 'Herbeherak',
+                    PL: 'Poland',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Suecia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovakia',
+                    SM: 'San Marino',
+                    TH: 'Tailandia',
+                    TR: 'Turkia',
+                    ZA: 'Hegoafrika'
+                }
+            },
+            identical: {
+                'default': 'Mesedez, balio bera sartu'
+            },
+            imei: {
+                'default': 'Mesedez, IMEI baliozko zenbaki bat sartu'
+            },
+            imo: {
+                'default': 'Mesedez, IMO baliozko zenbaki bat sartu'
+            },
+            integer: {
+                'default': 'Mesedez, baliozko zenbaki bat sartu'
+            },
+            ip: {
+                'default': 'Mesedez, baliozko IP helbide bat sartu',
+                ipv4: 'Mesedez, baliozko IPv4 helbide bat sartu',
+                ipv6: 'Mesedez, baliozko IPv6 helbide bat sartu'
+            },
+            isbn: {
+                'default': 'Mesedez, ISBN baliozko zenbaki bat sartu'
+            },
+            isin: {
+                'default': 'Mesedez, ISIN baliozko zenbaki bat sartu'
+            },
+            ismn: {
+                'default': 'Mesedez, ISMM baliozko zenbaki bat sartu'
+            },
+            issn: {
+                'default': 'Mesedez, ISSN baliozko zenbaki bat sartu'
+            },
+            lessThan: {
+                'default': 'Mesedez, %s en balio txikiagoa edo berdina sartu',
+                notInclusive: 'Mesedez, %s baino balio txikiago sartu'
+            },
+            mac: {
+                'default': 'Mesedez, baliozko MAC helbide bat sartu'
+            },
+            meid: {
+                'default': 'Mesedez, MEID baliozko zenbaki bat sartu'
+            },
+            notEmpty: {
+                'default': 'Mesedez balore bat sartu'
+            },
+            numeric: {
+                'default': 'Mesedez, baliozko zenbaki hamartar bat sartu'
+            },
+            phone: {
+                'default': 'Mesedez baliozko telefono zenbaki bat sartu',
+                country: 'Mesedez baliozko telefono zenbaki bat sartu honako: %s',
+                countries: {
+                    AE: 'Arabiar Emirerri Batua',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CN: 'Txina',
+                    CZ: 'Txekiar Errepublika',
+                    DE: 'Alemania',
+                    DK: 'Danimarka',
+                    ES: 'Espainia',
+                    FR: 'Frantzia',
+                    GB: 'Erresuma Batuak',
+                    IN: 'India',
+                    MA: 'Maroko',
+                    NL: 'Herbeherak',
+                    PK: 'Pakistan',
+                    RO: 'Errumania',
+                    RU: 'Errusiarra',
+                    SK: 'Eslovakia',
+                    TH: 'Tailandia',
+                    US: 'Estatu Batuak',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Mesedez sartu balore egoki bat'
+            },
+            regexp: {
+                'default': 'Mesedez, patroiarekin bat datorren balio bat sartu'
+            },
+            remote: {
+                'default': 'Mesedez balore egoki bat sartu'
+            },
+            rtn: {
+                'default': 'Mesedez, RTN baliozko zenbaki bat sartu'
+            },
+            sedol: {
+                'default': 'Mesedez, SEDOL baliozko zenbaki bat sartu'
+            },
+            siren: {
+                'default': 'Mesedez, SIREN baliozko zenbaki bat sartu'
+            },
+            siret: {
+                'default': 'Mesedez, SIRET baliozko zenbaki bat sartu'
+            },
+            step: {
+                'default': 'Mesedez %s -ko pausu egoki bat sartu'
+            },
+            stringCase: {
+                'default': 'Mesedez, minuskulazko karaktereak bakarrik sartu',
+                upper: 'Mesedez, maiuzkulazko karaktereak bakarrik sartu'
+            },
+            stringLength: {
+                'default': 'Mesedez, luzeera egoki bateko baloreak bakarrik sartu',
+                less: 'Mesedez, %s baino karaktere gutxiago sartu',
+                more: 'Mesedez, %s baino karaktere gehiago sartu',
+                between: 'Mesedez, %s eta %s arteko luzeera duen balore bat sartu'
+            },
+            uri: {
+                'default': 'Mesedez, URI egoki bat sartu.'
+            },
+            uuid: {
+                'default': 'Mesedez, UUID baliozko zenbaki bat sartu',
+                version: 'Mesedez, UUID bertsio egoki bat sartu honendako: %s'
+            },
+            vat: {
+                'default': 'Mesedez, BEZ zenbaki egoki bat sartu',
+                country: 'Mesedez, BEZ zenbaki egoki bat sartu herrialde hontarako: %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Belgika',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CH: 'Suitza',
+                    CY: 'Txipre',
+                    CZ: 'Txekiar Errepublika',
+                    DE: 'Alemania',
+                    DK: 'Danimarka',
+                    EE: 'Estonia',
+                    ES: 'Espainia',
+                    FI: 'Finlandia',
+                    FR: 'Frantzia',
+                    GB: 'Erresuma Batuak',
+                    GR: 'Grezia',
+                    EL: 'Grezia',
+                    HU: 'Hungaria',
+                    HR: 'Kroazia',
+                    IE: 'Irlanda',
+                    IS: 'Islandia',
+                    IT: 'Italia',
+                    LT: 'Lituania',
+                    LU: 'Luxemburgo',
+                    LV: 'Letonia',
+                    MT: 'Malta',
+                    NL: 'Herbeherak',
+                    NO: 'Noruega',
+                    PL: 'Polonia',
+                    PT: 'Portugal',
+                    RO: 'Errumania',
+                    RU: 'Errusia',
+                    RS: 'Serbia',
+                    SE: 'Suedia',
+                    SI: 'Eslovenia',
+                    SK: 'Eslovakia',
+                    VE: 'Venezuela',
+                    ZA: 'Hegoafrika'
+                }
+            },
+            vin: {
+                'default': 'Mesedez, baliozko VIN zenbaki bat sartu'
+            },
+            zipCode: {
+                'default': 'Mesedez, baliozko posta kode bat sartu',
+                country: 'Mesedez, baliozko posta kode bat sartu herrialde honetarako: %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CA: 'Kanada',
+                    CH: 'Suitza',
+                    CZ: 'Txekiar Errepublika',
+                    DE: 'Alemania',
+                    DK: 'Danimarka',
+                    ES: 'Espainia',
+                    FR: 'Frantzia',
+                    GB: 'Erresuma Batuak',
+                    IE: 'Irlanda',
+                    IN: 'India',
+                    IT: 'Italia',
+                    MA: 'Maroko',
+                    NL: 'Herbeherak',
+                    PL: 'Poland',
+                    PT: 'Portugal',
+                    RO: 'Errumania',
+                    RU: 'Errusia',
+                    SE: 'Suedia',
+                    SG: 'Singapur',
+                    SK: 'Eslovakia',
+                    US: 'Estatu Batuak'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/fa_IR.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Persian (Farsi) Language package.
+     * Translated by @i0
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'fa_IR': {
+            base64: {
+                'default': 'لطفا متن کد گذاری شده base 64 صحیح وارد فرمایید'
+            },
+            between: {
+                'default': 'لطفا یک مقدار بین %s و %s وارد فرمایید',
+                notInclusive: 'لطفا یک مقدار بین فقط %s و %s وارد فرمایید'
+            },
+            bic: {
+                'default': 'لطفا یک شماره BIC معتبر وارد فرمایید'
+            },
+            callback: {
+                'default': 'لطفا یک مقدار صحیح وارد فرمایید'
+            },
+            choice: {
+                'default': 'لطفا یک مقدار صحیح وارد فرمایید',
+                less: 'لطفا حداقل %s گزینه را انتخاب فرمایید',
+                more: 'لطفا حداکثر %s گزینه را انتخاب فرمایید',
+                between: 'لطفا %s - %s گزینه انتخاب فرمایید'
+            },
+            color: {
+                'default': 'لطفا رنگ صحیح وارد فرمایید'
+            },
+            creditCard: {
+                'default': 'لطفا یک شماره کارت اعتباری معتبر وارد فرمایید'
+            },
+            cusip: {
+                'default': 'لطفا یک شماره CUSIP معتبر وارد فرمایید'
+            },
+            cvv: {
+                'default': 'لطفا یک شماره CVV معتبر وارد فرمایید'
+            },
+            date: {
+                'default': 'لطفا یک تاریخ معتبر وارد فرمایید',
+                min: 'لطفا یک تاریخ بعد از %s وارد فرمایید',
+                max: 'لطفا یک تاریخ قبل از %s وارد فرمایید',
+                range: 'لطفا یک تاریخ در بازه %s - %s وارد فرمایید'
+            },
+            different: {
+                'default': 'لطفا یک مقدار متفاوت وارد فرمایید'
+            },
+            digits: {
+                'default': 'لطفا فقط عدد وارد فرمایید'
+            },
+            ean: {
+                'default': 'لطفا یک شماره EAN معتبر وارد فرمایید'
+            },
+            ein: {
+                'default': 'لطفا یک شماره EIN معتبر وارد فرمایید'
+            },
+            emailAddress: {
+                'default': 'لطفا آدرس ایمیل معتبر وارد فرمایید'
+            },
+            file: {
+                'default': 'لطفا فایل معتبر انتخاب فرمایید'
+            },
+            greaterThan: {
+                'default': 'لطفا مقدار بزرگتر یا مساوی با %s وارد فرمایید',
+                notInclusive: 'لطفا مقدار بزرگتر از %s وارد فرمایید'
+            },
+            grid: {
+                'default': 'لطفا شماره GRId معتبر وارد فرمایید'
+            },
+            hex: {
+                'default': 'لطفا عدد هگزادسیمال صحیح وارد فرمایید'
+            },
+            iban: {
+                'default': 'لطفا شماره IBAN معتبر وارد فرمایید',
+                country: 'لطفا یک شماره IBAN صحیح در %s وارد فرمایید',
+                countries: {
+                    AD: 'آندورا',
+                    AE: 'امارات متحده عربی',
+                    AL: 'آلبانی',
+                    AO: 'آنگولا',
+                    AT: 'اتریش',
+                    AZ: 'آذربایجان',
+                    BA: 'بوسنی و هرزگوین',
+                    BE: 'بلژیک',
+                    BF: 'بورکینا فاسو',
+                    BG: 'بلغارستان',
+                    BH: 'بحرین',
+                    BI: 'بروندی',
+                    BJ: 'بنین',
+                    BR: 'برزیل',
+                    CH: 'سوئیس',
+                    CI: 'ساحل عاج',
+                    CM: 'کامرون',
+                    CR: 'کاستاریکا',
+                    CV: 'کیپ ورد',
+                    CY: 'قبرس',
+                    CZ: 'جمهوری چک',
+                    DE: 'آلمان',
+                    DK: 'دانمارک',
+                    DO: 'جمهوری دومینیکن',
+                    DZ: 'الجزایر',
+                    EE: 'استونی',
+                    ES: 'اسپانیا',
+                    FI: 'فنلاند',
+                    FO: 'جزایر فارو',
+                    FR: 'فرانسه',
+                    GB: 'بریتانیا',
+                    GE: 'گرجستان',
+                    GI: 'جبل الطارق',
+                    GL: 'گرینلند',
+                    GR: 'یونان',
+                    GT: 'گواتمالا',
+                    HR: 'کرواسی',
+                    HU: 'مجارستان',
+                    IE: 'ایرلند',
+                    IL: 'اسرائیل',
+                    IR: 'ایران',
+                    IS: 'ایسلند',
+                    IT: 'ایتالیا',
+                    JO: 'اردن',
+                    KW: 'کویت',
+                    KZ: 'قزاقستان',
+                    LB: 'لبنان',
+                    LI: 'لیختن اشتاین',
+                    LT: 'لیتوانی',
+                    LU: 'لوکزامبورگ',
+                    LV: 'لتونی',
+                    MC: 'موناکو',
+                    MD: 'مولدووا',
+                    ME: 'مونته نگرو',
+                    MG: 'ماداگاسکار',
+                    MK: 'مقدونیه',
+                    ML: 'مالی',
+                    MR: 'موریتانی',
+                    MT: 'مالت',
+                    MU: 'موریس',
+                    MZ: 'موزامبیک',
+                    NL: 'هلند',
+                    NO: 'نروژ',
+                    PK: 'پاکستان',
+                    PL: 'لهستان',
+                    PS: 'فلسطین',
+                    PT: 'پرتغال',
+                    QA: 'قطر',
+                    RO: 'رومانی',
+                    RS: 'صربستان',
+                    SA: 'عربستان سعودی',
+                    SE: 'سوئد',
+                    SI: 'اسلوونی',
+                    SK: 'اسلواکی',
+                    SM: 'سان مارینو',
+                    SN: 'سنگال',
+                    TL: 'تیمور شرق',
+                    TN: 'تونس',
+                    TR: 'ترکیه',
+                    VG: 'جزایر ویرجین، بریتانیا',
+                    XK: 'جمهوری کوزوو'
+                }
+            },
+            id: {
+                'default': 'لطفا شماره شناسایی صحیح وارد فرمایید',
+                country: 'لطفا یک شماره شناسایی معتبر در %s وارد کنید',
+                countries: {
+                    BA: 'بوسنی و هرزگوین',
+                    BG: 'بلغارستان',
+                    BR: 'برزیل',
+                    CH: 'سوئیس',
+                    CL: 'شیلی',
+                    CN: 'چین',
+                    CZ: 'چک',
+                    DK: 'دانمارک',
+                    EE: 'استونی',
+                    ES: 'اسپانیا',
+                    FI: 'فنلاند',
+                    HR: 'کرواسی',
+                    IE: 'ایرلند',
+                    IS: 'ایسلند',
+                    LT: 'لیتوانی',
+                    LV: 'لتونی',
+                    ME: 'مونته نگرو',
+                    MK: 'مقدونیه',
+                    NL: 'هلند',
+                    PL: 'لهستان',
+                    RO: 'رومانی',
+                    RS: 'صربی',
+                    SE: 'سوئد',
+                    SI: 'اسلوونی',
+                    SK: 'اسلواکی',
+                    SM: 'سان مارینو',
+                    TH: 'تایلند',
+                    TR: 'ترکیه',
+                    ZA: 'آفریقای جنوبی'
+                }
+            },
+            identical: {
+                'default': 'لطفا مقدار یکسان وارد فرمایید'
+            },
+            imei: {
+                'default': 'لطفا شماره IMEI معتبر وارد فرمایید'
+            },
+            imo: {
+                'default': 'لطفا شماره IMO معتبر وارد فرمایید'
+            },
+            integer: {
+                'default': 'لطفا یک عدد صحیح وارد فرمایید'
+            },
+            ip: {
+                'default': 'لطفا یک آدرس IP معتبر وارد فرمایید',
+                ipv4: 'لطفا یک آدرس IPv4 معتبر وارد فرمایید',
+                ipv6: 'لطفا یک آدرس IPv6 معتبر وارد فرمایید'
+            },
+            isbn: {
+                'default': 'لطفا شماره ISBN معتبر وارد فرمایید'
+            },
+            isin: {
+                'default': 'لطفا شماره ISIN معتبر وارد فرمایید'
+            },
+            ismn: {
+                'default': 'لطفا شماره ISMN معتبر وارد فرمایید'
+            },
+            issn: {
+                'default': 'لطفا شماره ISSN معتبر وارد فرمایید'
+            },
+            lessThan: {
+                'default': 'لطفا مقدار کمتر یا مساوی با %s وارد فرمایید',
+                notInclusive: 'لطفا مقدار کمتر از %s وارد فرمایید'
+            },
+            mac: {
+                'default': 'لطفا یک MAC address معتبر وارد فرمایید'
+            },
+            meid: {
+                'default': 'لطفا یک شماره MEID معتبر وارد فرمایید'
+            },
+            notEmpty: {
+                'default': 'لطفا یک مقدار وارد فرمایید'
+            },
+            numeric: {
+                'default': 'لطفا یک عدد اعشاری صحیح وارد فرمایید'
+            },
+            phone: {
+                'default': 'لطفا یک شماره تلفن صحیح وارد فرمایید',
+                country: 'لطفا یک شماره تلفن معتبر وارد کنید در %s',
+                countries: {
+                    AE: 'امارات متحده عربی',
+                    BG: 'بلغارستان',
+                    BR: 'برزیل',
+                    CN: 'کشور چین',
+                    CZ: 'چک',
+                    DE: 'آلمان',
+                    DK: 'دانمارک',
+                    ES: 'اسپانیا',
+                    FR: 'فرانسه',
+                    GB: 'بریتانیا',
+                    IN: 'هندوستان',
+                    MA: 'مراکش',
+                    NL: 'هلند',
+                    PK: 'پاکستان',
+                    RO: 'رومانی',
+                    RU: 'روسیه',
+                    SK: 'اسلواکی',
+                    TH: 'تایلند',
+                    US: 'ایالات متحده آمریکا',
+                    VE: 'ونزوئلا'
+                }
+            },
+            promise: {
+                'default': 'لطفا یک مقدار صحیح وارد فرمایید'
+            },
+            regexp: {
+                'default': 'لطفا یک مقدار مطابق با الگو وارد فرمایید'
+            },
+            remote: {
+                'default': 'لطفا یک مقدار معتبر وارد فرمایید'
+            },
+            rtn: {
+                'default': 'لطفا یک شماره RTN صحیح وارد فرمایید'
+            },
+            sedol: {
+                'default': 'لطفا یک شماره SEDOL صحیح وارد فرمایید'
+            },
+            siren: {
+                'default': 'لطفا یک شماره SIREN صحیح وارد فرمایید'
+            },
+            siret: {
+                'default': 'لطفا یک شماره SIRET صحیح وارد فرمایید'
+            },
+            step: {
+                'default': 'لطفا یک گام صحیح از %s وارد فرمایید'
+            },
+            stringCase: {
+                'default': 'لطفا فقط حروف کوچک وارد فرمایید',
+                upper: 'لطفا فقط حروف بزرگ وارد فرمایید'
+            },
+            stringLength: {
+                'default': 'لطفا یک مقدار با طول صحیح وارد فرمایید',
+                less: 'لطفا کمتر از %s حرف وارد فرمایید',
+                more: 'لطفا بیش از %s حرف وارد فرمایید',
+                between: 'لطفا مقداری بین %s و %s حرف وارد فرمایید'
+            },
+            uri: {
+                'default': 'لطفا یک آدرس URI صحیح وارد فرمایید'
+            },
+            uuid: {
+                'default': 'لطفا یک شماره UUID معتبر وارد فرمایید',
+                version: 'لطفا یک نسخه UUID صحیح %s شماره وارد فرمایید'
+            },
+            vat: {
+                'default': 'لطفا یک شماره VAT صحیح وارد فرمایید',
+                country: 'لطفا یک شماره VAT معتبر در %s وارد کنید',
+                countries: {
+                    AT: 'اتریش',
+                    BE: 'بلژیک',
+                    BG: 'بلغارستان',
+                    BR: 'برزیل',
+                    CH: 'سوئیس',
+                    CY: 'قبرس',
+                    CZ: 'چک',
+                    DE: 'آلمان',
+                    DK: 'دانمارک',
+                    EE: 'استونی',
+                    ES: 'اسپانیا',
+                    FI: 'فنلاند',
+                    FR: 'فرانسه',
+                    GB: 'بریتانیا',
+                    GR: 'یونان',
+                    EL: 'یونان',
+                    HU: 'مجارستان',
+                    HR: 'کرواسی',
+                    IE: 'ایرلند',
+                    IS: 'ایسلند',
+                    IT: 'ایتالیا',
+                    LT: 'لیتوانی',
+                    LU: 'لوکزامبورگ',
+                    LV: 'لتونی',
+                    MT: 'مالت',
+                    NL: 'هلند',
+                    NO: 'نروژ',
+                    PL: 'لهستانی',
+                    PT: 'پرتغال',
+                    RO: 'رومانی',
+                    RU: 'روسیه',
+                    RS: 'صربستان',
+                    SE: 'سوئد',
+                    SI: 'اسلوونی',
+                    SK: 'اسلواکی',
+                    VE: 'ونزوئلا',
+                    ZA: 'آفریقای جنوبی'
+                }
+            },
+            vin: {
+                'default': 'لطفا یک شماره VIN صحیح وارد فرمایید'
+            },
+            zipCode: {
+                'default': 'لطفا یک کدپستی صحیح وارد فرمایید',
+                country: 'لطفا یک کد پستی معتبر در %s وارد کنید',
+                countries: {
+                    AT: 'اتریش',
+                    BG: 'بلغارستان',
+                    BR: 'برزیل',
+                    CA: 'کانادا',
+                    CH: 'سوئیس',
+                    CZ: 'چک',
+                    DE: 'آلمان',
+                    DK: 'دانمارک',
+                    ES: 'اسپانیا',
+                    FR: 'فرانسه',
+                    GB: 'بریتانیا',
+                    IE: 'ایرلند',
+                    IN: 'هندوستان',
+                    IT: 'ایتالیا',
+                    MA: 'مراکش',
+                    NL: 'هلند',
+                    PL: 'لهستان',
+                    PT: 'پرتغال',
+                    RO: 'رومانی',
+                    RU: 'روسیه',
+                    SE: 'سوئد',
+                    SG: 'سنگاپور',
+                    SK: 'اسلواکی',
+                    US: 'ایالات متحده'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/fi_FI.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Finnish language package
+     * Translated by @traone
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'fi_FI': {
+            base64: {
+                'default': 'Ole hyvä anna kelvollinen base64 koodattu merkkijono'
+            },
+            between: {
+                'default': 'Ole hyvä anna arvo %s ja %s väliltä',
+                notInclusive: 'Ole hyvä anna arvo %s ja %s väliltä'
+            },
+            bic: {
+                'default': 'Ole hyvä anna kelvollinen BIC numero'
+            },
+            callback: {
+                'default': 'Ole hyvä anna kelvollinen arvo'
+            },
+            choice: {
+                'default': 'Ole hyvä anna kelvollinen arvo',
+                less: 'Ole hyvä valitse vähintään %s valintaa',
+                more: 'Ole hyvä valitse enintään %s valintaa',
+                between: 'Ole hyvä valitse %s - %s valintaa'
+            },
+            color: {
+                'default': 'Ole hyvä anna kelvollinen väriarvo'
+            },
+            creditCard: {
+                'default': 'Ole hyvä anna kelvollinen luottokortin numero'
+            },
+            cusip: {
+                'default': 'Ole hyvä anna kelvollinen CUSIP numero'
+            },
+            cvv: {
+                'default': 'Ole hyvä anna kelvollinen CVV numero'
+            },
+            date: {
+                'default': 'Ole hyvä anna kelvollinen päiväys',
+                min: 'Ole hyvä anna %s jälkeinen päiväys',
+                max: 'Ole hyvä anna %s edeltävä päiväys',
+                range: 'Ole hyvä anna päiväys %s - %s väliltä'
+            },
+            different: {
+                'default': 'Ole hyvä anna jokin toinen arvo'
+            },
+            digits: {
+                'default': 'Vain numerot sallittuja'
+            },
+            ean: {
+                'default': 'Ole hyvä anna kelvollinen EAN numero'
+            },
+            ein: {
+                'default': 'Ole hyvä anna kelvollinen EIN numero'
+            },
+            emailAddress: {
+                'default': 'Ole hyvä anna kelvollinen sähköpostiosoite'
+            },
+            file: {
+                'default': 'Ole hyvä valitse kelvollinen tiedosto'
+            },
+            greaterThan: {
+                'default': 'Ole hyvä anna arvoksi yhtä suuri kuin, tai suurempi kuin %s',
+                notInclusive: 'Ole hyvä anna arvoksi suurempi kuin %s'
+            },
+            grid: {
+                'default': 'Ole hyvä anna kelvollinen GRId numero'
+            },
+            hex: {
+                'default': 'Ole hyvä anna kelvollinen heksadesimaali luku'
+            },
+            iban: {
+                'default': 'Ole hyvä anna kelvollinen IBAN numero',
+                country: 'Ole hyvä anna kelvollinen IBAN numero maassa %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Yhdistyneet arabiemiirikunnat',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Itävalta',
+                    AZ: 'Azerbaidžan',
+                    BA: 'Bosnia ja Hertsegovina',
+                    BE: 'Belgia',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasilia',
+                    CH: 'Sveitsi',
+                    CI: 'Norsunluurannikko',
+                    CM: 'Kamerun',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Kypros',
+                    CZ: 'Tsekin tasavalta',
+                    DE: 'Saksa',
+                    DK: 'Tanska',
+                    DO: 'Dominikaaninen tasavalta',
+                    DZ: 'Algeria',
+                    EE: 'Viro',
+                    ES: 'Espanja',
+                    FI: 'Suomi',
+                    FO: 'Färsaaret',
+                    FR: 'Ranska',
+                    GB: 'Yhdistynyt kuningaskunta',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Grönlanti',
+                    GR: 'Kreikka',
+                    GT: 'Guatemala',
+                    HR: 'Kroatia',
+                    HU: 'Unkari',
+                    IE: 'Irlanti',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Islanti',
+                    IT: 'Italia',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakhstan',
+                    LB: 'Libanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Liettua',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MC: 'Monaco',
+                    MD: 'Moldova',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Makedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambik',
+                    NL: 'Hollanti',
+                    NO: 'Norja',
+                    PK: 'Pakistan',
+                    PL: 'Puola',
+                    PS: 'Palestiina',
+                    PT: 'Portugali',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SA: 'Saudi Arabia',
+                    SE: 'Ruotsi',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Itä-Timor',
+                    TN: 'Tunisia',
+                    TR: 'Turkki',
+                    VG: 'Neitsytsaaret, Brittien',
+                    XK: 'Kosovon tasavallan'
+                }
+            },
+            id: {
+                'default': 'Ole hyvä anna kelvollinen henkilötunnus',
+                country: 'Ole hyvä anna kelvollinen henkilötunnus maassa %s',
+                countries: {
+                    BA: 'Bosnia ja Hertsegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brasilia',
+                    CH: 'Sveitsi',
+                    CL: 'Chile',
+                    CN: 'Kiina',
+                    CZ: 'Tsekin tasavalta',
+                    DK: 'Tanska',
+                    EE: 'Viro',
+                    ES: 'Espanja',
+                    FI: 'Suomi',
+                    HR: 'Kroatia',
+                    IE: 'Irlanti',
+                    IS: 'Islanti',
+                    LT: 'Liettua',
+                    LV: 'Latvia',
+                    ME: 'Montenegro',
+                    MK: 'Makedonia',
+                    NL: 'Hollanti',
+                    PL: 'Puola',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Ruotsi',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    TH: 'Thaimaa',
+                    TR: 'Turkki',
+                    ZA: 'Etelä Afrikka'
+                }
+            },
+            identical: {
+                'default': 'Ole hyvä anna sama arvo'
+            },
+            imei: {
+                'default': 'Ole hyvä anna kelvollinen IMEI numero'
+            },
+            imo: {
+                'default': 'Ole hyvä anna kelvollinen IMO numero'
+            },
+            integer: {
+                'default': 'Ole hyvä anna kelvollinen kokonaisluku'
+            },
+            ip: {
+                'default': 'Ole hyvä anna kelvollinen IP osoite',
+                ipv4: 'Ole hyvä anna kelvollinen IPv4 osoite',
+                ipv6: 'Ole hyvä anna kelvollinen IPv6 osoite'
+            },
+            isbn: {
+                'default': 'Ole hyvä anna kelvollinen ISBN numero'
+            },
+            isin: {
+                'default': 'Ole hyvä anna kelvollinen ISIN numero'
+            },
+            ismn: {
+                'default': 'Ole hyvä anna kelvollinen ISMN numero'
+            },
+            issn: {
+                'default': 'Ole hyvä anna kelvollinen ISSN numero'
+            },
+            lessThan: {
+                'default': 'Ole hyvä anna arvo joka on vähemmän kuin tai yhtä suuri kuin %s',
+                notInclusive: 'Ole hyvä anna arvo joka on vähemmän kuin %s'
+            },
+            mac: {
+                'default': 'Ole hyvä anna kelvollinen MAC osoite'
+            },
+            meid: {
+                'default': 'Ole hyvä anna kelvollinen MEID numero'
+            },
+            notEmpty: {
+                'default': 'Pakollinen kenttä, anna jokin arvo'
+            },
+            numeric: {
+                'default': 'Ole hyvä anna kelvollinen liukuluku'
+            },
+            phone: {
+                'default': 'Ole hyvä anna kelvollinen puhelinnumero',
+                country: 'Ole hyvä anna kelvollinen puhelinnumero maassa %s',
+                countries: {
+                    AE: 'Yhdistyneet arabiemiirikunnat',
+                    BG: 'Bulgaria',
+                    BR: 'Brasilia',
+                    CN: 'Kiina',
+                    CZ: 'Tsekin tasavalta',
+                    DE: 'Saksa',
+                    DK: 'Tanska',
+                    ES: 'Espanja',
+                    FR: 'Ranska',
+                    GB: 'Yhdistynyt kuningaskunta',
+                    IN: 'Intia',
+                    MA: 'Marokko',
+                    NL: 'Hollanti',
+                    PK: 'Pakistan',
+                    RO: 'Romania',
+                    RU: 'Venäjä',
+                    SK: 'Slovakia',
+                    TH: 'Thaimaa',
+                    US: 'USA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Ole hyvä anna kelvollinen arvo'
+            },
+            regexp: {
+                'default': 'Ole hyvä anna kaavan mukainen arvo'
+            },
+            remote: {
+                'default': 'Ole hyvä anna kelvollinen arvo'
+            },
+            rtn: {
+                'default': 'Ole hyvä anna kelvollinen RTN numero'
+            },
+            sedol: {
+                'default': 'Ole hyvä anna kelvollinen SEDOL numero'
+            },
+            siren: {
+                'default': 'Ole hyvä anna kelvollinen SIREN numero'
+            },
+            siret: {
+                'default': 'Ole hyvä anna kelvollinen SIRET numero'
+            },
+            step: {
+                'default': 'Ole hyvä anna kelvollinen arvo %s porrastettuna'
+            },
+            stringCase: {
+                'default': 'Ole hyvä anna pelkästään pieniä kirjaimia',
+                upper: 'Ole hyvä anna pelkästään isoja kirjaimia'
+            },
+            stringLength: {
+                'default': 'Ole hyvä anna kelvollisen mittainen merkkijono',
+                less: 'Ole hyvä anna vähemmän kuin %s merkkiä',
+                more: 'Ole hyvä anna vähintään %s merkkiä',
+                between: 'Ole hyvä anna arvo joka on vähintään %s ja enintään %s merkkiä pitkä'
+            },
+            uri: {
+                'default': 'Ole hyvä anna kelvollinen URI'
+            },
+            uuid: {
+                'default': 'Ole hyvä anna kelvollinen UUID numero',
+                version: 'Ole hyvä anna kelvollinen UUID versio %s numero'
+            },
+            vat: {
+                'default': 'Ole hyvä anna kelvollinen VAT numero',
+                country: 'Ole hyvä anna kelvollinen VAT numero maahan: %s',
+                countries: {
+                    AT: 'Itävalta',
+                    BE: 'Belgia',
+                    BG: 'Bulgaria',
+                    BR: 'Brasilia',
+                    CH: 'Sveitsi',
+                    CY: 'Kypros',
+                    CZ: 'Tsekin tasavalta',
+                    DE: 'Saksa',
+                    DK: 'Tanska',
+                    EE: 'Viro',
+                    ES: 'Espanja',
+                    FI: 'Suomi',
+                    FR: 'Ranska',
+                    GB: 'Yhdistyneet kuningaskunnat',
+                    GR: 'Kreikka',
+                    EL: 'Kreikka',
+                    HU: 'Unkari',
+                    HR: 'Kroatia',
+                    IE: 'Irlanti',
+                    IS: 'Islanti',
+                    IT: 'Italia',
+                    LT: 'Liettua',
+                    LU: 'Luxemburg',
+                    LV: 'Latvia',
+                    MT: 'Malta',
+                    NL: 'Hollanti',
+                    NO: 'Norja',
+                    PL: 'Puola',
+                    PT: 'Portugali',
+                    RO: 'Romania',
+                    RU: 'Venäjä',
+                    RS: 'Serbia',
+                    SE: 'Ruotsi',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    VE: 'Venezuela',
+                    ZA: 'Etelä Afrikka'
+                }
+            },
+            vin: {
+                'default': 'Ole hyvä anna kelvollinen VIN numero'
+            },
+            zipCode: {
+                'default': 'Ole hyvä anna kelvollinen postinumero',
+                country: 'Ole hyvä anna kelvollinen postinumero maassa: %s',
+                countries: {
+                    AT: 'Itävalta',
+                    BG: 'Bulgaria',
+                    BR: 'Brasilia',
+                    CA: 'Kanada',
+                    CH: 'Sveitsi',
+                    CZ: 'Tsekin tasavalta',
+                    DE: 'Saksa',
+                    DK: 'Tanska',
+                    ES: 'Espanja',
+                    FR: 'Ranska',
+                    GB: 'Yhdistyneet kuningaskunnat',
+                    IE: 'Irlanti',
+                    IN: 'Intia',
+                    IT: 'Italia',
+                    MA: 'Marokko',
+                    NL: 'Hollanti',
+                    PL: 'Puola',
+                    PT: 'Portugali',
+                    RO: 'Romania',
+                    RU: 'Venäjä',
+                    SE: 'Ruotsi',
+                    SG: 'Singapore',
+                    SK: 'Slovakia',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/fr_BE.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Belgium (French) language package
+     * Translated by @neilime
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'fr_BE': {
+            base64: {
+                'default': 'Veuillez fournir une donnée correctement encodée en Base64'
+            },
+            between: {
+                'default': 'Veuillez fournir une valeur comprise entre %s et %s',
+                notInclusive: 'Veuillez fournir une valeur strictement comprise entre %s et %s'
+            },
+            bic: {
+                'default': 'Veuillez fournir un code-barre BIC valide'
+            },
+            callback: {
+                'default': 'Veuillez fournir une valeur valide'
+            },
+            choice: {
+                'default': 'Veuillez fournir une valeur valide',
+                less: 'Veuillez choisir au minimum %s options',
+                more: 'Veuillez choisir au maximum %s options',
+                between: 'Veuillez choisir de %s à %s options'
+            },
+            color: {
+                'default': 'Veuillez fournir une couleur valide'
+            },
+            creditCard: {
+                'default': 'Veuillez fournir un numéro de carte de crédit valide'
+            },
+            cusip: {
+                'default': 'Veuillez fournir un code CUSIP valide'
+            },
+            cvv: {
+                'default': 'Veuillez fournir un code CVV valide'
+            },
+            date: {
+                'default': 'Veuillez fournir une date valide',
+                'min': 'Veuillez fournir une date supérieure à %s',
+                'max': 'Veuillez fournir une date inférieure à %s',
+                'range': 'Veuillez fournir une date comprise entre %s et %s'
+            },
+            different: {
+                'default': 'Veuillez fournir une valeur différente'
+            },
+            digits: {
+                'default': 'Veuillez ne fournir que des chiffres'
+            },
+            ean: {
+                'default': 'Veuillez fournir un code-barre EAN valide'
+            },
+            ein: {
+                'default': 'Veuillez fournir un code-barre EIN valide'
+            },
+            emailAddress: {
+                'default': 'Veuillez fournir une adresse e-mail valide'
+            },
+            file: {
+                'default': 'Veuillez choisir un fichier valide'
+            },
+            greaterThan: {
+                'default': 'Veuillez fournir une valeur supérieure ou égale à %s',
+                notInclusive: 'Veuillez fournir une valeur supérieure à %s'
+            },
+            grid: {
+                'default': 'Veuillez fournir un code GRId valide'
+            },
+            hex: {
+                'default': 'Veuillez fournir un nombre hexadécimal valide'
+            },
+            iban: {
+                'default': 'Veuillez fournir un code IBAN valide',
+                country: 'Veuillez fournir un code IBAN valide pour %s',
+                countries: {
+                    AD: 'Andorre',
+                    AE: 'Émirats Arabes Unis',
+                    AL: 'Albanie',
+                    AO: 'Angola',
+                    AT: 'Autriche',
+                    AZ: 'Azerbaïdjan',
+                    BA: 'Bosnie-Herzégovine',
+                    BE: 'Belgique',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgarie',
+                    BH: 'Bahrein',
+                    BI: 'Burundi',
+                    BJ: 'Bénin',
+                    BR: 'Brésil',
+                    CH: 'Suisse',
+                    CI: 'Côte d\'ivoire',
+                    CM: 'Cameroun',
+                    CR: 'Costa Rica',
+                    CV: 'Cap Vert',
+                    CY: 'Chypre',
+                    CZ: 'Tchèque',
+                    DE: 'Allemagne',
+                    DK: 'Danemark',
+                    DO: 'République Dominicaine',
+                    DZ: 'Algérie',
+                    EE: 'Estonie',
+                    ES: 'Espagne',
+                    FI: 'Finlande',
+                    FO: 'Îles Féroé',
+                    FR: 'France',
+                    GB: 'Royaume Uni',
+                    GE: 'Géorgie',
+                    GI: 'Gibraltar',
+                    GL: 'Groënland',
+                    GR: 'Gréce',
+                    GT: 'Guatemala',
+                    HR: 'Croatie',
+                    HU: 'Hongrie',
+                    IE: 'Irlande',
+                    IL: 'Israël',
+                    IR: 'Iran',
+                    IS: 'Islande',
+                    IT: 'Italie',
+                    JO: 'Jordanie',
+                    KW: 'Koweït',
+                    KZ: 'Kazakhstan',
+                    LB: 'Liban',
+                    LI: 'Liechtenstein',
+                    LT: 'Lithuanie',
+                    LU: 'Luxembourg',
+                    LV: 'Lettonie',
+                    MC: 'Monaco',
+                    MD: 'Moldavie',
+                    ME: 'Monténégro',
+                    MG: 'Madagascar',
+                    MK: 'Macédoine',
+                    ML: 'Mali',
+                    MR: 'Mauritanie',
+                    MT: 'Malte',
+                    MU: 'Maurice',
+                    MZ: 'Mozambique',
+                    NL: 'Pays-Bas',
+                    NO: 'Norvège',
+                    PK: 'Pakistan',
+                    PL: 'Pologne',
+                    PS: 'Palestine',
+                    PT: 'Portugal',
+                    QA: 'Quatar',
+                    RO: 'Roumanie',
+                    RS: 'Serbie',
+                    SA: 'Arabie Saoudite',
+                    SE: 'Suède',
+                    SI: 'Slovènie',
+                    SK: 'Slovaquie',
+                    SM: 'Saint-Marin',
+                    SN: 'Sénégal',
+                    TL: 'Timor oriental',
+                    TN: 'Tunisie',
+                    TR: 'Turquie',
+                    VG: 'Îles Vierges britanniques',
+                    XK: 'République du Kosovo'
+                }
+            },
+            id: {
+                'default': 'Veuillez fournir un numéro d\'identification valide',
+                country: 'Veuillez fournir un numéro d\'identification valide pour %s',
+                countries: {
+                    BA: 'Bosnie-Herzégovine',
+                    BG: 'Bulgarie',
+                    BR: 'Brésil',
+                    CH: 'Suisse',
+                    CL: 'Chili',
+                    CN: 'Chine',
+                    CZ: 'Tchèque',
+                    DK: 'Danemark',
+                    EE: 'Estonie',
+                    ES: 'Espagne',
+                    FI: 'Finlande',
+                    HR: 'Croatie',
+                    IE: 'Irlande',
+                    IS: 'Islande',
+                    LT: 'Lituanie',
+                    LV: 'Lettonie',
+                    ME: 'Monténégro',
+                    MK: 'Macédoine',
+                    NL: 'Pays-Bas',
+                    PL: 'Pologne',
+                    RO: 'Roumanie',
+                    RS: 'Serbie',
+                    SE: 'Suède',
+                    SI: 'Slovénie',
+                    SK: 'Slovaquie',
+                    SM: 'Saint-Marin',
+                    TH: 'Thaïlande',
+                    TR: 'Turquie',
+                    ZA: 'Afrique du Sud'
+                }
+            },
+            identical: {
+                'default': 'Veuillez fournir la même valeur'
+            },
+            imei: {
+                'default': 'Veuillez fournir un code IMEI valide'
+            },
+            imo: {
+                'default': 'Veuillez fournir un code IMO valide'
+            },
+            integer: {
+                'default': 'Veuillez fournir un nombre valide'
+            },
+            ip: {
+                'default': 'Veuillez fournir une adresse IP valide',
+                ipv4: 'Veuillez fournir une adresse IPv4 valide',
+                ipv6: 'Veuillez fournir une adresse IPv6 valide'
+            },
+            isbn: {
+                'default': 'Veuillez fournir un code ISBN valide'
+            },
+            isin: {
+                'default': 'Veuillez fournir un code ISIN valide'
+            },
+            ismn: {
+                'default': 'Veuillez fournir un code ISMN valide'
+            },
+            issn: {
+                'default': 'Veuillez fournir un code ISSN valide'
+            },
+            lessThan: {
+                'default': 'Veuillez fournir une valeur inférieure ou égale à %s',
+                notInclusive: 'Veuillez fournir une valeur inférieure à %s'
+            },
+            mac: {
+                'default': 'Veuillez fournir une adresse MAC valide'
+            },
+            meid: {
+                'default': 'Veuillez fournir un code MEID valide'
+            },
+            notEmpty: {
+                'default': 'Veuillez fournir une valeur'
+            },
+            numeric: {
+                'default': 'Veuillez fournir une valeur décimale valide'
+            },
+            phone: {
+                'default': 'Veuillez fournir un numéro de téléphone valide',
+                country: 'Veuillez fournir un numéro de téléphone valide pour %s',
+                countries: {
+                    AE: 'Émirats Arabes Unis',
+                    BG: 'Bulgarie',
+                    BR: 'Brésil',
+                    CN: 'Chine',
+                    CZ: 'Tchèque',
+                    DE: 'Allemagne',
+                    DK: 'Danemark',
+                    ES: 'Espagne',
+                    FR: 'France',
+                    GB: 'Royaume-Uni',
+                    IN: 'Inde',
+                    MA: 'Maroc',
+                    NL: 'Pays-Bas',
+                    PK: 'Pakistan',
+                    RO: 'Roumanie',
+                    RU: 'Russie',
+                    SK: 'Slovaquie',
+                    TH: 'Thaïlande',
+                    US: 'USA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Veuillez fournir une valeur valide'
+            },
+            regexp: {
+                'default': 'Veuillez fournir une valeur correspondant au modèle'
+            },
+            remote: {
+                'default': 'Veuillez fournir une valeur valide'
+            },
+            rtn: {
+                'default': 'Veuillez fournir un code RTN valide'
+            },
+            sedol: {
+                'default': 'Veuillez fournir a valid SEDOL number'
+            },
+            siren: {
+                'default': 'Veuillez fournir un numéro SIREN valide'
+            },
+            siret: {
+                'default': 'Veuillez fournir un numéro SIRET valide'
+            },
+            step: {
+                'default': 'Veuillez fournir un écart valide de %s'
+            },
+            stringCase: {
+                'default': 'Veuillez ne fournir que des caractères minuscules',
+                upper: 'Veuillez ne fournir que des caractères majuscules'
+            },
+            stringLength: {
+                'default': 'Veuillez fournir une valeur de longueur valide',
+                less: 'Veuillez fournir moins de %s caractères',
+                more: 'Veuillez fournir plus de %s caractères',
+                between: 'Veuillez fournir entre %s et %s caractères'
+            },
+            uri: {
+                'default': 'Veuillez fournir un URI valide'
+            },
+            uuid: {
+                'default': 'Veuillez fournir un UUID valide',
+                version: 'Veuillez fournir un UUID version %s number'
+            },
+            vat: {
+                'default': 'Veuillez fournir un code VAT valide',
+                country: 'Veuillez fournir un code VAT valide pour %s',
+                countries: {
+                    AT: 'Autriche',
+                    BE: 'Belgique',
+                    BG: 'Bulgarie',
+                    BR: 'Brésil',
+                    CH: 'Suisse',
+                    CY: 'Chypre',
+                    CZ: 'Tchèque',
+                    DE: 'Allemagne',
+                    DK: 'Danemark',
+                    EE: 'Estonie',
+                    ES: 'Espagne',
+                    FI: 'Finlande',
+                    FR: 'France',
+                    GB: 'Royaume-Uni',
+                    GR: 'Grèce',
+                    EL: 'Grèce',
+                    HU: 'Hongrie',
+                    HR: 'Croatie',
+                    IE: 'Irlande',
+                    IS: 'Islande',
+                    IT: 'Italie',
+                    LT: 'Lituanie',
+                    LU: 'Luxembourg',
+                    LV: 'Lettonie',
+                    MT: 'Malte',
+                    NL: 'Pays-Bas',
+                    NO: 'Norvège',
+                    PL: 'Pologne',
+                    PT: 'Portugal',
+                    RO: 'Roumanie',
+                    RU: 'Russie',
+                    RS: 'Serbie',
+                    SE: 'Suède',
+                    SI: 'Slovénie',
+                    SK: 'Slovaquie',
+                    VE: 'Venezuela',
+                    ZA: 'Afrique du Sud'
+                }
+            },
+            vin: {
+                'default': 'Veuillez fournir un code VIN valide'
+            },
+            zipCode: {
+                'default': 'Veuillez fournir un code postal valide',
+                country: 'Veuillez fournir un code postal valide pour %s',
+                countries: {
+                    AT: 'Autriche',
+                    BG: 'Bulgarie',
+                    BR: 'Brésil',
+                    CA: 'Canada',
+                    CH: 'Suisse',
+                    CZ: 'Tchèque',
+                    DE: 'Allemagne',
+                    DK: 'Danemark',
+                    ES: 'Espagne',
+                    FR: 'France',
+                    GB: 'Royaume-Uni',
+                    IE: 'Irlande',
+                    IN: 'Inde',
+                    IT: 'Italie',
+                    MA: 'Maroc',
+                    NL: 'Pays-Bas',
+                    PL: 'Pologne',
+                    PT: 'Portugal',
+                    RO: 'Roumanie',
+                    RU: 'Russie',
+                    SE: 'Suède',
+                    SG: 'Singapour',
+                    SK: 'Slovaquie',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/fr_FR.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * French language package
+     * Translated by @dlucazeau. Updated by @neilime, @jazzzz
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'fr_FR': {
+            base64: {
+                'default': 'Veuillez fournir une donnée correctement encodée en Base64'
+            },
+            between: {
+                'default': 'Veuillez fournir une valeur comprise entre %s et %s',
+                notInclusive: 'Veuillez fournir une valeur strictement comprise entre %s et %s'
+            },
+            bic: {
+                'default': 'Veuillez fournir un code-barre BIC valide'
+            },
+            callback: {
+                'default': 'Veuillez fournir une valeur valide'
+            },
+            choice: {
+                'default': 'Veuillez fournir une valeur valide',
+                less: 'Veuillez choisir au minimum %s options',
+                more: 'Veuillez choisir au maximum %s options',
+                between: 'Veuillez choisir de %s à %s options'
+            },
+            color: {
+                'default': 'Veuillez fournir une couleur valide'
+            },
+            creditCard: {
+                'default': 'Veuillez fournir un numéro de carte de crédit valide'
+            },
+            cusip: {
+                'default': 'Veuillez fournir un code CUSIP valide'
+            },
+            cvv: {
+                'default': 'Veuillez fournir un code CVV valide'
+            },
+            date: {
+                'default': 'Veuillez fournir une date valide',
+                'min': 'Veuillez fournir une date supérieure à %s',
+                'max': 'Veuillez fournir une date inférieure à %s',
+                'range': 'Veuillez fournir une date comprise entre %s et %s'
+            },
+            different: {
+                'default': 'Veuillez fournir une valeur différente'
+            },
+            digits: {
+                'default': 'Veuillez ne fournir que des chiffres'
+            },
+            ean: {
+                'default': 'Veuillez fournir un code-barre EAN valide'
+            },
+            ein: {
+                'default': 'Veuillez fournir un code-barre EIN valide'
+            },
+            emailAddress: {
+                'default': 'Veuillez fournir une adresse e-mail valide'
+            },
+            file: {
+                'default': 'Veuillez choisir un fichier valide'
+            },
+            greaterThan: {
+                'default': 'Veuillez fournir une valeur supérieure ou égale à %s',
+                notInclusive: 'Veuillez fournir une valeur supérieure à %s'
+            },
+            grid: {
+                'default': 'Veuillez fournir un code GRId valide'
+            },
+            hex: {
+                'default': 'Veuillez fournir un nombre hexadécimal valide'
+            },
+            iban: {
+                'default': 'Veuillez fournir un code IBAN valide',
+                country: 'Veuillez fournir un code IBAN valide pour %s',
+                countries: {
+                    AD: 'Andorre',
+                    AE: 'Émirats Arabes Unis',
+                    AL: 'Albanie',
+                    AO: 'Angola',
+                    AT: 'Autriche',
+                    AZ: 'Azerbaïdjan',
+                    BA: 'Bosnie-Herzégovine',
+                    BE: 'Belgique',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgarie',
+                    BH: 'Bahrein',
+                    BI: 'Burundi',
+                    BJ: 'Bénin',
+                    BR: 'Brésil',
+                    CH: 'Suisse',
+                    CI: 'Côte d\'ivoire',
+                    CM: 'Cameroun',
+                    CR: 'Costa Rica',
+                    CV: 'Cap Vert',
+                    CY: 'Chypre',
+                    CZ: 'République Tchèque',
+                    DE: 'Allemagne',
+                    DK: 'Danemark',
+                    DO: 'République Dominicaine',
+                    DZ: 'Algérie',
+                    EE: 'Estonie',
+                    ES: 'Espagne',
+                    FI: 'Finlande',
+                    FO: 'Îles Féroé',
+                    FR: 'France',
+                    GB: 'Royaume Uni',
+                    GE: 'Géorgie',
+                    GI: 'Gibraltar',
+                    GL: 'Groënland',
+                    GR: 'Gréce',
+                    GT: 'Guatemala',
+                    HR: 'Croatie',
+                    HU: 'Hongrie',
+                    IE: 'Irlande',
+                    IL: 'Israël',
+                    IR: 'Iran',
+                    IS: 'Islande',
+                    IT: 'Italie',
+                    JO: 'Jordanie',
+                    KW: 'Koweït',
+                    KZ: 'Kazakhstan',
+                    LB: 'Liban',
+                    LI: 'Liechtenstein',
+                    LT: 'Lithuanie',
+                    LU: 'Luxembourg',
+                    LV: 'Lettonie',
+                    MC: 'Monaco',
+                    MD: 'Moldavie',
+                    ME: 'Monténégro',
+                    MG: 'Madagascar',
+                    MK: 'Macédoine',
+                    ML: 'Mali',
+                    MR: 'Mauritanie',
+                    MT: 'Malte',
+                    MU: 'Maurice',
+                    MZ: 'Mozambique',
+                    NL: 'Pays-Bas',
+                    NO: 'Norvège',
+                    PK: 'Pakistan',
+                    PL: 'Pologne',
+                    PS: 'Palestine',
+                    PT: 'Portugal',
+                    QA: 'Quatar',
+                    RO: 'Roumanie',
+                    RS: 'Serbie',
+                    SA: 'Arabie Saoudite',
+                    SE: 'Suède',
+                    SI: 'Slovènie',
+                    SK: 'Slovaquie',
+                    SM: 'Saint-Marin',
+                    SN: 'Sénégal',
+                    TL: 'Timor oriental',
+                    TN: 'Tunisie',
+                    TR: 'Turquie',
+                    VG: 'Îles Vierges britanniques',
+                    XK: 'République du Kosovo'
+                }
+            },
+            id: {
+                'default': 'Veuillez fournir un numéro d\'identification valide',
+                country: 'Veuillez fournir un numéro d\'identification valide pour %s',
+                countries: {
+                    BA: 'Bosnie-Herzégovine',
+                    BG: 'Bulgarie',
+                    BR: 'Brésil',
+                    CH: 'Suisse',
+                    CL: 'Chili',
+                    CN: 'Chine',
+                    CZ: 'République Tchèque',
+                    DK: 'Danemark',
+                    EE: 'Estonie',
+                    ES: 'Espagne',
+                    FI: 'Finlande',
+                    HR: 'Croatie',
+                    IE: 'Irlande',
+                    IS: 'Islande',
+                    LT: 'Lituanie',
+                    LV: 'Lettonie',
+                    ME: 'Monténégro',
+                    MK: 'Macédoine',
+                    NL: 'Pays-Bas',
+                    PL: 'Pologne',
+                    RO: 'Roumanie',
+                    RS: 'Serbie',
+                    SE: 'Suède',
+                    SI: 'Slovénie',
+                    SK: 'Slovaquie',
+                    SM: 'Saint-Marin',
+                    TH: 'Thaïlande',
+                    TR: 'Turquie',
+                    ZA: 'Afrique du Sud'
+                }
+            },
+            identical: {
+                'default': 'Veuillez fournir la même valeur'
+            },
+            imei: {
+                'default': 'Veuillez fournir un code IMEI valide'
+            },
+            imo: {
+                'default': 'Veuillez fournir un code IMO valide'
+            },
+            integer: {
+                'default': 'Veuillez fournir un nombre valide'
+            },
+            ip: {
+                'default': 'Veuillez fournir une adresse IP valide',
+                ipv4: 'Veuillez fournir une adresse IPv4 valide',
+                ipv6: 'Veuillez fournir une adresse IPv6 valide'
+            },
+            isbn: {
+                'default': 'Veuillez fournir un code ISBN valide'
+            },
+            isin: {
+                'default': 'Veuillez fournir un code ISIN valide'
+            },
+            ismn: {
+                'default': 'Veuillez fournir un code ISMN valide'
+            },
+            issn: {
+                'default': 'Veuillez fournir un code ISSN valide'
+            },
+            lessThan: {
+                'default': 'Veuillez fournir une valeur inférieure ou égale à %s',
+                notInclusive: 'Veuillez fournir une valeur inférieure à %s'
+            },
+            mac: {
+                'default': 'Veuillez fournir une adresse MAC valide'
+            },
+            meid: {
+                'default': 'Veuillez fournir un code MEID valide'
+            },
+            notEmpty: {
+                'default': 'Veuillez fournir une valeur'
+            },
+            numeric: {
+                'default': 'Veuillez fournir une valeur décimale valide'
+            },
+            phone: {
+                'default': 'Veuillez fournir un numéro de téléphone valide',
+                country: 'Veuillez fournir un numéro de téléphone valide pour %s',
+                countries: {
+                    AE: 'Émirats Arabes Unis',
+                    BG: 'Bulgarie',
+                    BR: 'Brésil',
+                    CN: 'Chine',
+                    CZ: 'République Tchèque',
+                    DE: 'Allemagne',
+                    DK: 'Danemark',
+                    ES: 'Espagne',
+                    FR: 'France',
+                    GB: 'Royaume-Uni',
+                    IN: 'Inde',
+                    MA: 'Maroc',
+                    NL: 'Pays-Bas',
+                    PK: 'Pakistan',
+                    RO: 'Roumanie',
+                    RU: 'Russie',
+                    SK: 'Slovaquie',
+                    TH: 'Thaïlande',
+                    US: 'USA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Veuillez fournir une valeur valide'
+            },
+            regexp: {
+                'default': 'Veuillez fournir une valeur correspondant au modèle'
+            },
+            remote: {
+                'default': 'Veuillez fournir une valeur valide'
+            },
+            rtn: {
+                'default': 'Veuillez fournir un code RTN valide'
+            },
+            sedol: {
+                'default': 'Veuillez fournir a valid SEDOL number'
+            },
+            siren: {
+                'default': 'Veuillez fournir un numéro SIREN valide'
+            },
+            siret: {
+                'default': 'Veuillez fournir un numéro SIRET valide'
+            },
+            step: {
+                'default': 'Veuillez fournir un écart valide de %s'
+            },
+            stringCase: {
+                'default': 'Veuillez ne fournir que des caractères minuscules',
+                upper: 'Veuillez ne fournir que des caractères majuscules'
+            },
+            stringLength: {
+                'default': 'Veuillez fournir une valeur de longueur valide',
+                less: 'Veuillez fournir moins de %s caractères',
+                more: 'Veuillez fournir plus de %s caractères',
+                between: 'Veuillez fournir entre %s et %s caractères'
+            },
+            uri: {
+                'default': 'Veuillez fournir un URI valide'
+            },
+            uuid: {
+                'default': 'Veuillez fournir un UUID valide',
+                version: 'Veuillez fournir un UUID version %s number'
+            },
+            vat: {
+                'default': 'Veuillez fournir un code VAT valide',
+                country: 'Veuillez fournir un code VAT valide pour %s',
+                countries: {
+                    AT: 'Autriche',
+                    BE: 'Belgique',
+                    BG: 'Bulgarie',
+                    BR: 'Brésil',
+                    CH: 'Suisse',
+                    CY: 'Chypre',
+                    CZ: 'République Tchèque',
+                    DE: 'Allemagne',
+                    DK: 'Danemark',
+                    EE: 'Estonie',
+                    ES: 'Espagne',
+                    FI: 'Finlande',
+                    FR: 'France',
+                    GB: 'Royaume-Uni',
+                    GR: 'Grèce',
+                    EL: 'Grèce',
+                    HU: 'Hongrie',
+                    HR: 'Croatie',
+                    IE: 'Irlande',
+                    IS: 'Islande',
+                    IT: 'Italie',
+                    LT: 'Lituanie',
+                    LU: 'Luxembourg',
+                    LV: 'Lettonie',
+                    MT: 'Malte',
+                    NL: 'Pays-Bas',
+                    NO: 'Norvège',
+                    PL: 'Pologne',
+                    PT: 'Portugal',
+                    RO: 'Roumanie',
+                    RU: 'Russie',
+                    RS: 'Serbie',
+                    SE: 'Suède',
+                    SI: 'Slovénie',
+                    SK: 'Slovaquie',
+                    VE: 'Venezuela',
+                    ZA: 'Afrique du Sud'
+                }
+            },
+            vin: {
+                'default': 'Veuillez fournir un code VIN valide'
+            },
+            zipCode: {
+                'default': 'Veuillez fournir un code postal valide',
+                country: 'Veuillez fournir un code postal valide pour %s',
+                countries: {
+                    AT: 'Autriche',
+                    BG: 'Bulgarie',
+                    BR: 'Brésil',
+                    CA: 'Canada',
+                    CH: 'Suisse',
+                    CZ: 'République Tchèque',
+                    DE: 'Allemagne',
+                    DK: 'Danemark',
+                    ES: 'Espagne',
+                    FR: 'France',
+                    GB: 'Royaume-Uni',
+                    IE: 'Irlande',
+                    IN: 'Inde',
+                    IT: 'Italie',
+                    MA: 'Maroc',
+                    NL: 'Pays-Bas',
+                    PL: 'Pologne',
+                    PT: 'Portugal',
+                    RO: 'Roumanie',
+                    RU: 'Russie',
+                    SE: 'Suède',
+                    SG: 'Singapour',
+                    SK: 'Slovaquie',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/he_IL.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Hebrew language package
+     * Translated by @yakidahan
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'he_IL': {
+            base64: {
+                'default': 'נא להזין ערך המקודד בבסיס 64'
+            },
+            between: {
+                'default': 'נא להזין ערך בין %s ל-%s',
+                notInclusive: 'נא להזין ערך בין %s ל-%s בדיוק'
+            },
+            bic: {
+                'default': 'נא להזין מספר BIC תקין'
+            },
+            callback: {
+                'default': 'נא להזין ערך תקין'
+            },
+            choice: {
+                'default': 'נא להזין ערך תקין',
+                less: 'נא לבחור מינימום %s אפשרויות',
+                more: 'נא לבחור מקסימום %s אפשרויות',
+                between: 'נא לבחור  %s-%s אפשרויות'
+            },
+            color: {
+                'default': 'נא להזין קוד צבע תקין'
+            },
+            creditCard: {
+                'default': 'נא להזין מספר כרטיס אשראי תקין'
+            },
+            cusip: {
+                'default': 'נא להזין מספר CUSIP תקין'
+            },
+            cvv: {
+                'default': 'נא להזין מספר CVV תקין'
+            },
+            date: {
+                'default': 'נא להזין תאריך תקין',
+                min: 'נא להזין תאריך אחרי %s',
+                max: 'נא להזין תאריך לפני %s',
+                range: 'נא להזין תאריך בטווח %s - %s'
+            },
+            different: {
+                'default': 'נא להזין ערך שונה'
+            },
+            digits: {
+                'default': 'נא להזין ספרות בלבד'
+            },
+            ean: {
+                'default': 'נא להזין מספר EAN תקין'
+            },
+            ein: {
+                'default': 'נא להזין מספר EIN תקין'
+            },
+            emailAddress: {
+                'default': 'נא להזין כתובת דוא"ל תקינה'
+            },
+            file: {
+                'default': 'נא לבחור קובץ חוקי'
+            },
+            greaterThan: {
+                'default': 'נא להזין ערך גדול או שווה ל-%s',
+                notInclusive: 'נא להזין ערך גדול מ-%s'
+            },
+            grid: {
+                'default': 'נא להזין מספר GRId תקין'
+            },
+            hex: {
+                'default': 'נא להזין מספר הקסדצימלי תקין'
+            },
+            iban: {
+                'default': 'נא להזין מספר IBAN תקין',
+                country: 'נא להזין מספר IBAN תקני ב%s',
+                countries: {
+                    AD: 'אנדורה',
+                    AE: 'איחוד האמירויות הערבי',
+                    AL: 'אלבניה',
+                    AO: 'אנגולה',
+                    AT: 'אוסטריה',
+                    AZ: 'אזרבייגאן',
+                    BA: 'בוסניה והרצגובינה',
+                    BE: 'בלגיה',
+                    BF: 'בורקינה פאסו',
+                    BG: 'בולגריה',
+                    BH: 'בחריין',
+                    BI: 'בורונדי',
+                    BJ: 'בנין',
+                    BR: 'ברזיל',
+                    CH: 'שווייץ',
+                    CI: 'חוף השנהב',
+                    CM: 'קמרון',
+                    CR: 'קוסטה ריקה',
+                    CV: 'קייפ ורדה',
+                    CY: 'קפריסין',
+                    CZ: 'צכיה',
+                    DE: 'גרמניה',
+                    DK: 'דנמרק',
+                    DO: 'דומיניקה',
+                    DZ: 'אלגיריה',
+                    EE: 'אסטוניה',
+                    ES: 'ספרד',
+                    FI: 'פינלנד',
+                    FO: 'איי פארו',
+                    FR: 'צרפת',
+                    GB: 'בריטניה',
+                    GE: 'גאורגיה',
+                    GI: 'גיברלטר',
+                    GL: 'גרינלנד',
+                    GR: 'יוון',
+                    GT: 'גואטמלה',
+                    HR: 'קרואטיה',
+                    HU: 'הונגריה',
+                    IE: 'אירלנד',
+                    IL: 'ישראל',
+                    IR: 'איראן',
+                    IS: 'איסלנד',
+                    IT: 'איטליה',
+                    JO: 'ירדן',
+                    KW: 'כווית',
+                    KZ: 'קזחסטן',
+                    LB: 'לבנון',
+                    LI: 'ליכטנשטיין',
+                    LT: 'ליטא',
+                    LU: 'לוקסמבורג',
+                    LV: 'לטביה',
+                    MC: 'מונקו',
+                    MD: 'מולדובה',
+                    ME: 'מונטנגרו',
+                    MG: 'מדגסקר',
+                    MK: 'מקדוניה',
+                    ML: 'מאלי',
+                    MR: 'מאוריטניה',
+                    MT: 'מלטה',
+                    MU: 'מאוריציוס',
+                    MZ: 'מוזמביק',
+                    NL: 'הולנד',
+                    NO: 'נורווגיה',
+                    PK: 'פקיסטן',
+                    PL: 'פולין',
+                    PS: 'פלסטין',
+                    PT: 'פורטוגל',
+                    QA: 'קטאר',
+                    RO: 'רומניה',
+                    RS: 'סרביה',
+                    SA: 'ערב הסעודית',
+                    SE: 'שוודיה',
+                    SI: 'סלובניה',
+                    SK: 'סלובקיה',
+                    SM: 'סן מרינו',
+                    SN: 'סנגל',
+                    TL: 'מזרח טימור',
+                    TN: 'תוניסיה',
+                    TR: 'טורקיה',
+                    VG: 'איי הבתולה, בריטניה',
+                    XK: 'רפובליקה של קוסובו'
+                }
+            },
+            id: {
+                'default': 'נא להזין מספר זהות תקין',
+                country: 'נא להזין מספר זהות תקני ב%s',
+                countries: {
+                    BA: 'בוסניה והרצגובינה',
+                    BG: 'בולגריה',
+                    BR: 'ברזיל',
+                    CH: 'שווייץ',
+                    CL: 'צילה',
+                    CN: 'סין',
+                    CZ: 'צכיה',
+                    DK: 'דנמרק',
+                    EE: 'אסטוניה',
+                    ES: 'ספרד',
+                    FI: 'פינלנד',
+                    HR: 'קרואטיה',
+                    IE: 'אירלנד',
+                    IS: 'איסלנד',
+                    LT: 'ליטא',
+                    LV: 'לטביה',
+                    ME: 'מונטנגרו',
+                    MK: 'מקדוניה',
+                    NL: 'הולנד',
+                    PL: 'פולין',
+                    RO: 'רומניה',
+                    RS: 'סרביה',
+                    SE: 'שוודיה',
+                    SI: 'סלובניה',
+                    SK: 'סלובקיה',
+                    SM: 'סן מרינו',
+                    TH: 'תאילנד',
+                    TR: 'טורקיה',
+                    ZA: 'דרום אפריקה'
+                }
+            },
+            identical: {
+                'default': 'נא להזין את הערך שנית'
+            },
+            imei: {
+                'default': 'נא להזין מספר IMEI תקין'
+            },
+            imo: {
+                'default': 'נא להזין מספר IMO תקין'
+            },
+            integer: {
+                'default': 'נא להזין מספר תקין'
+            },
+            ip: {
+                'default': 'נא להזין כתובת IP תקינה',
+                ipv4: 'נא להזין כתובת IPv4 תקינה',
+                ipv6: 'נא להזין כתובת IPv6 תקינה'
+            },
+            isbn: {
+                'default': 'נא להזין מספר ISBN תקין'
+            },
+            isin: {
+                'default': 'נא להזין מספר ISIN תקין'
+            },
+            ismn: {
+                'default': 'נא להזין מספר ISMN תקין'
+            },
+            issn: {
+                'default': 'נא להזין מספר ISSN תקין'
+            },
+            lessThan: {
+                'default': 'נא להזין ערך קטן או שווה ל-%s',
+                notInclusive: 'נא להזין ערך קטן מ-%s'
+            },
+            mac: {
+                'default': 'נא להזין מספר MAC תקין'
+            },
+            meid: {
+                'default': 'נא להזין מספר MEID תקין'
+            },
+            notEmpty: {
+                'default': 'נא להזין ערך'
+            },
+            numeric: {
+                'default': 'נא להזין מספר עשרוני חוקי'
+            },
+            phone: {
+                'default': 'נא להין מספר טלפון תקין',
+                country: 'נא להזין מספר טלפון תקין ב%s',
+                countries: {
+                    AE: 'איחוד האמירויות הערבי',
+                    BG: 'בולגריה',
+                    BR: 'ברזיל',
+                    CN: 'סין',
+                    CZ: 'צכיה',
+                    DE: 'גרמניה',
+                    DK: 'דנמרק',
+                    ES: 'ספרד',
+                    FR: 'צרפת',
+                    GB: 'בריטניה',
+                    IN: 'הודו',
+                    MA: 'מרוקו',
+                    NL: 'הולנד',
+                    PK: 'פקיסטן',
+                    RO: 'רומניה',
+                    RU: 'רוסיה',
+                    SK: 'סלובקיה',
+                    TH: 'תאילנד',
+                    US: 'ארצות הברית',
+                    VE: 'ונצואלה'
+                }
+            },
+            promise: {
+                'default': 'נא להזין ערך תקין'
+            },
+            regexp: {
+                'default': 'נא להזין ערך תואם לתבנית'
+            },
+            remote: {
+                'default': 'נא להזין ערך תקין'
+            },
+            rtn: {
+                'default': 'נא להזין מספר RTN תקין'
+            },
+            sedol: {
+                'default': 'נא להזין מספר SEDOL תקין'
+            },
+            siren: {
+                'default': 'נא להזין מספר SIREN תקין'
+            },
+            siret: {
+                'default': 'נא להזין מספר SIRET תקין'
+            },
+            step: {
+                'default': 'נא להזין שלב תקין מתוך %s'
+            },
+            stringCase: {
+                'default': 'נא להזין אותיות קטנות בלבד',
+                upper: 'נא להזין אותיות גדולות בלבד'
+            },
+            stringLength: {
+                'default': 'נא להזין ערך באורך חוקי',
+                less: 'נא להזין ערך קטן מ-%s תווים',
+                more: 'נא להזין ערך גדול מ- %s תווים',
+                between: 'נא להזין ערך בין %s עד %s תווים'
+            },
+            uri: {
+                'default': 'נא להזין URI תקין'
+            },
+            uuid: {
+                'default': 'נא להזין מספר UUID תקין',
+                version: 'נא להזין מספר UUID גרסה %s תקין'
+            },
+            vat: {
+                'default': 'נא להזין מספר VAT תקין',
+                country: 'נא להזין מספר VAT תקין ב%s',
+                countries: {
+                    AT: 'אוסטריה',
+                    BE: 'בלגיה',
+                    BG: 'בולגריה',
+                    BR: 'ברזיל',
+                    CH: 'שווייץ',
+                    CY: 'קפריסין',
+                    CZ: 'צכיה',
+                    DE: 'גרמניה',
+                    DK: 'דנמרק',
+                    EE: 'אסטוניה',
+                    ES: 'ספרד',
+                    FI: 'פינלנד',
+                    FR: 'צרפת',
+                    GB: 'בריטניה',
+                    GR: 'יוון',
+                    EL: 'יוון',
+                    HU: 'הונגריה',
+                    HR: 'קרואטיה',
+                    IE: 'אירלנד',
+                    IS: 'איסלנד',
+                    IT: 'איטליה',
+                    LT: 'ליטא',
+                    LU: 'לוקסמבורג',
+                    LV: 'לטביה',
+                    MT: 'מלטה',
+                    NL: 'הולנד',
+                    NO: 'נורווגיה',
+                    PL: 'פולין',
+                    PT: 'פורטוגל',
+                    RO: 'רומניה',
+                    RU: 'רוסיה',
+                    RS: 'סרביה',
+                    SE: 'שוודיה',
+                    SI: 'סלובניה',
+                    SK: 'סלובקיה',
+                    VE: 'ונצואלה',
+                    ZA: 'דרום אפריקה'
+                }
+            },
+            vin: {
+                'default': 'נא להזין מספר VIN תקין'
+            },
+            zipCode: {
+                'default': 'נא להזין מיקוד תקין',
+                country: 'נא להזין מיקוד תקין ב%s',
+                countries: {
+                    AT: 'אוסטריה',
+                    BG: 'בולגריה',
+                    BR: 'ברזיל',
+                    CA: 'קנדה',
+                    CH: 'שווייץ',
+                    CZ: 'צכיה',
+                    DE: 'גרמניה',
+                    DK: 'דנמרק',
+                    ES: 'ספרד',
+                    FR: 'צרפת',
+                    GB: 'בריטניה',
+                    IE: 'אירלנד',
+                    IN: 'הודו',
+                    IT: 'איטליה',
+                    MA: 'מרוקו',
+                    NL: 'הולנד',
+                    PL: 'פולין',
+                    PT: 'פורטוגל',
+                    RO: 'רומניה',
+                    RU: 'רוסיה',
+                    SE: 'שוודיה',
+                    SG: 'סינגפור',
+                    SK: 'סלובקיה',
+                    US: 'ארצות הברית'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/hi_IN.js

@@ -0,0 +1,385 @@
+(function ($) {
+    /**
+     * Hindi (India) language package
+     * Translated by @gladiatorAsh
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'hi_IN': {
+            base64: {
+                'default': 'कृपया एक वैध 64 इनकोडिंग मूल्यांक प्रविष्ट करें'
+            },
+            between: {
+                'default': 'कृपया %s और %s के बीच एक मूल्यांक प्रविष्ट करें',
+                notInclusive: 'कृपया सिर्फ़ %s और %s के बीच मूल्यांक प्रविष्ट करें'
+            },
+            bic: {
+                'default': 'कृपया एक वैध BIC संख्या प्रविष्ट करें'
+            },
+            callback: {
+                'default': 'कृपया एक वैध मूल्यांक प्रविष्ट करें'
+            },
+            choice: {
+                'default': 'कृपया एक वैध मूल्यांक प्रविष्ट करें',
+                less: 'कृपया कम से कम %s विकल्पों का चयन करें',
+                more: 'कृपया अधिकतम %s विकल्पों का चयन करें',
+                between: 'कृपया %s और %s के बीच विकल्पों का चयन करें'
+            },
+            color: {
+                'default': 'कृपया एक वैध रंग प्रविष्ट करें'
+            },
+            creditCard: {
+                'default': 'कृपया एक वैध क्रेडिट कार्ड संख्या प्रविष्ट करें'
+            },
+            cusip: {
+                'default': 'कृपया एक वैध CUSIP संख्या प्रविष्ट करें'
+            },
+            cvv: {
+                'default': 'कृपया एक वैध CVV संख्या प्रविष्ट करें'
+            },
+            date: {
+                'default': 'कृपया एक वैध दिनांक प्रविष्ट करें',
+                min: 'कृपया %s के बाद एक वैध दिनांक प्रविष्ट करें',
+                max: 'कृपया %s के पहले एक वैध दिनांक प्रविष्ट करें',
+                range: 'कृपया %s से %s के बीच एक वैध दिनांक प्रविष्ट करें'
+            },
+            different: {
+                'default': 'कृपया एक अलग मूल्यांक प्रविष्ट करें'
+            },
+            digits: {
+                'default': 'कृपया केवल अंक प्रविष्ट करें'
+            },
+            ean: {
+                'default': 'कृपया एक वैध EAN संख्या प्रविष्ट करें'
+            },
+            ein: {
+                'default': 'कृपया एक वैध EIN संख्या प्रविष्ट करें'
+            },
+            emailAddress: {
+                'default': 'कृपया एक वैध ईमेल पता प्रविष्ट करें'
+            },
+            file: {
+                'default': 'कृपया एक वैध फ़ाइल का चयन करें'
+            },
+            greaterThan: {
+                'default': 'कृपया %s से अधिक या बराबर एक मूल्यांक प्रविष्ट करें',
+                notInclusive: 'कृपया %s से अधिक एक मूल्यांक प्रविष्ट करें'
+            },
+            grid: {
+                'default': 'कृपया एक वैध GRID संख्या प्रविष्ट करें'
+            },
+            hex: {
+                'default': 'कृपया एक वैध हेक्साडेसिमल संख्या प्रविष्ट करें'
+            },
+            iban: {
+                'default': 'कृपया एक वैध IBAN संख्या प्रविष्ट करें',
+                country: 'कृपया %s में एक वैध IBAN संख्या प्रविष्ट करें',
+                countries: {
+                    AD: 'अंडोरा',
+                    AE: 'संयुक्त अरब अमीरात',
+                    AL: 'अल्बानिया',
+                    AO: 'अंगोला',
+                    AT: 'ऑस्ट्रिया',
+                    AZ: 'अज़रबैजान',
+                    BA: 'बोस्निया और हर्जेगोविना',
+                    BE: 'बेल्जियम',
+                    BF: 'बुर्किना फासो',
+                    BG: 'बुल्गारिया',
+                    BH: 'बहरीन',
+                    BI: 'बुस्र्न्दी',
+                    BJ: 'बेनिन',
+                    BR: 'ब्राज़िल',
+                    CH: 'स्विट्जरलैंड',
+                    CI: 'आइवरी कोस्ट',
+                    CM: 'कैमरून',
+                    CR: 'कोस्टा रिका',
+                    CV: 'केप वर्डे',
+                    CY: 'साइप्रस',
+                    CZ: 'चेक रिपब्लिक',
+                    DE: 'जर्मनी',
+                    DK: 'डेनमार्क',
+                    DO: 'डोमिनिकन गणराज्य',
+                    DZ: 'एलजीरिया',
+                    EE: 'एस्तोनिया',
+                    ES: 'स्पेन',
+                    FI: 'फिनलैंड',
+                    FO: 'फरो आइलैंड्स',
+                    FR: 'फ्रांस',
+                    GB: 'यूनाइटेड किंगडम',
+                    GE: 'जॉर्जिया',
+                    GI: 'जिब्राल्टर',
+                    GL: 'ग्रीनलैंड',
+                    GR: 'ग्रीस',
+                    GT: 'ग्वाटेमाला',
+                    HR: 'क्रोएशिया',
+                    HU: 'हंगरी',
+                    IE: 'आयरलैंड',
+                    IL: 'इज़राइल',
+                    IR: 'ईरान',
+                    IS: 'आइसलैंड',
+                    IT: 'इटली',
+                    JO: 'जॉर्डन',
+                    KW: 'कुवैत',
+                    KZ: 'कजाखस्तान',
+                    LB: 'लेबनान',
+                    LI: 'लिकटेंस्टीन',
+                    LT: 'लिथुआनिया',
+                    LU: 'लक्समबर्ग',
+                    LV: 'लाटविया',
+                    MC: 'मोनाको',
+                    MD: 'माल्डोवा',
+                    ME: 'मॉन्टेंगरो',
+                    MG: 'मेडागास्कर',
+                    MK: 'मैसेडोनिया',
+                    ML: 'माली',
+                    MR: 'मॉरिटानिया',
+                    MT: 'माल्टा',
+                    MU: 'मॉरीशस',
+                    MZ: 'मोज़ाम्बिक',
+                    NL: 'नीदरलैंड',
+                    NO: 'नॉर्वे',
+                    PK: 'पाकिस्तान',
+                    PL: 'पोलैंड',
+                    PS: 'फिलिस्तीन',
+                    PT: 'पुर्तगाल',
+                    QA: 'क़तर',
+                    RO: 'रोमानिया',
+                    RS: 'सर्बिया',
+                    SA: 'सऊदी अरब',
+                    SE: 'स्वीडन',
+                    SI: 'स्लोवेनिया',
+                    SK: 'स्लोवाकिया',
+                    SM: 'सैन मैरिनो',
+                    SN: 'सेनेगल',
+                    TL: 'पूर्वी तिमोर',
+                    TN: 'ट्यूनीशिया',
+                    TR: 'तुर्की',
+                    VG: 'वर्जिन आइलैंड्स, ब्रिटिश',
+                    XK: 'कोसोवो गणराज्य'
+                }
+            },
+            id: {
+                'default': 'कृपया एक वैध पहचान संख्या प्रविष्ट करें',
+                country: 'कृपया %s में एक वैध पहचान संख्या प्रविष्ट करें',
+                countries: {
+                    BA: 'बोस्निया और हर्जेगोविना',
+                    BG: 'बुल्गारिया',
+                    BR: 'ब्राज़िल',
+                    CH: 'स्विट्जरलैंड',
+                    CL: 'चिली',
+                    CN: 'चीन',
+                    CZ: 'चेक रिपब्लिक',
+                    DK: 'डेनमार्क',
+                    EE: 'एस्तोनिया',
+                    ES: 'स्पेन',
+                    FI: 'फिनलैंड',
+                    HR: 'क्रोएशिया',
+                    IE: 'आयरलैंड',
+                    IS: 'आइसलैंड',
+                    LT: 'लिथुआनिया',
+                    LV: 'लाटविया',
+                    ME: 'मोंटेनेग्रो',
+                    MK: 'मैसेडोनिया',
+                    NL: 'नीदरलैंड',
+                    PL: 'पोलैंड',
+                    RO: 'रोमानिया',
+                    RS: 'सर्बिया',
+                    SE: 'स्वीडन',
+                    SI: 'स्लोवेनिया',
+                    SK: 'स्लोवाकिया',
+                    SM: 'सैन मैरिनो',
+                    TH: 'थाईलैंड',
+                    TR: 'तुर्की',
+                    ZA: 'दक्षिण अफ्रीका'
+                }
+            },
+            identical: {
+                'default': 'कृपया वही मूल्यांक दोबारा प्रविष्ट करें'
+            },
+            imei: {
+                'default': 'कृपया एक वैध IMEI संख्या प्रविष्ट करें'
+            },
+            imo: {
+                'default': 'कृपया एक वैध IMO संख्या प्रविष्ट करें'
+            },
+            integer: {
+                'default': 'कृपया एक वैध संख्या प्रविष्ट करें'
+            },
+            ip: {
+                'default': 'कृपया एक वैध IP पता प्रविष्ट करें',
+                ipv4: 'कृपया एक वैध IPv4 पता प्रविष्ट करें',
+                ipv6: 'कृपया एक वैध IPv6 पता प्रविष्ट करें'
+            },
+            isbn: {
+                'default': 'कृपया एक वैध ISBN संख्या दर्ज करें'
+            },
+            isin: {
+                'default': 'कृपया एक वैध ISIN संख्या दर्ज करें'
+            },
+            ismn: {
+                'default': 'कृपया एक वैध ISMN संख्या दर्ज करें'
+            },
+            issn: {
+                'default': 'कृपया एक वैध ISSN संख्या दर्ज करें'
+            },
+            lessThan: {
+                'default': 'कृपया %s से कम या बराबर एक मूल्यांक प्रविष्ट करें',
+                notInclusive: 'कृपया %s से कम एक मूल्यांक प्रविष्ट करें'
+            },
+            mac: {
+                'default': 'कृपया एक वैध MAC पता प्रविष्ट करें'
+            },
+            meid: {
+                'default': 'कृपया एक वैध MEID संख्या प्रविष्ट करें'
+            },
+            notEmpty: {
+                'default': 'कृपया एक मूल्यांक प्रविष्ट करें'
+            },
+            numeric: {
+                'default': 'कृपया एक वैध दशमलव संख्या प्रविष्ट करें'
+            },
+            phone: {
+                'default': 'कृपया एक वैध फ़ोन नंबर प्रविष्ट करें',
+                country: 'कृपया %s में एक वैध फ़ोन नंबर प्रविष्ट करें',
+                countries: {
+                    AE: 'संयुक्त अरब अमीरात',
+                    BG: 'बुल्गारिया',
+                    BR: 'ब्राज़िल',
+                    CN: 'चीन',
+                    CZ: 'चेक रिपब्लिक',
+                    DE: 'जर्मनी',
+                    DK: 'डेनमार्क',
+                    ES: 'स्पेन',
+                    FR: 'फ्रांस',
+                    GB: 'यूनाइटेड किंगडम',
+                    IN: 'भारत',
+                    MA: 'मोरक्को',
+                    NL: 'नीदरलैंड',
+                    PK: 'पाकिस्तान',
+                    RO: 'रोमानिया',
+                    RU: 'रुस',
+                    SK: 'स्लोवाकिया',
+                    TH: 'थाईलैंड',
+                    US: 'अमेरीका',
+                    VE: 'वेनेजुएला'
+                }
+            },
+            promise: {
+                'default': 'कृपया एक वैध मूल्यांक प्रविष्ट करें'
+            },
+            regexp: {
+                'default': 'कृपया पैटर्न से मेल खाते एक मूल्यांक प्रविष्ट करें'
+            },
+            remote: {
+                'default': 'कृपया एक वैध मूल्यांक प्रविष्ट करें'
+            },
+            rtn: {
+                'default': 'कृपया एक वैध RTN संख्या प्रविष्ट करें'
+            },
+            sedol: {
+                'default': 'कृपया एक वैध SEDOL संख्या प्रविष्ट करें'
+            },
+            siren: {
+                'default': 'कृपया एक वैध SIREN संख्या प्रविष्ट करें'
+            },
+            siret: {
+                'default': 'कृपया एक वैध SIRET संख्या प्रविष्ट करें'
+            },
+            step: {
+                'default': '%s के एक गुणज मूल्यांक प्रविष्ट करें'
+            },
+            stringCase: {
+                'default': 'कृपया केवल छोटे पात्रों का प्रविष्ट करें',
+                upper: 'कृपया केवल बड़े पात्रों का प्रविष्ट करें'
+            },
+            stringLength: {
+                'default': 'कृपया वैध लंबाई का एक मूल्यांक प्रविष्ट करें',
+                less: 'कृपया %s से कम पात्रों को प्रविष्ट करें',
+                more: 'कृपया %s से अधिक पात्रों को प्रविष्ट करें',
+                between: 'कृपया %s से %s के बीच लंबाई का एक मूल्यांक प्रविष्ट करें'
+            },
+            uri: {
+                'default': 'कृपया एक वैध URI प्रविष्ट करें'
+            },
+            uuid: {
+                'default': 'कृपया एक वैध UUID संख्या प्रविष्ट करें',
+                version: 'कृपया एक वैध UUID संस्करण %s संख्या प्रविष्ट करें'
+            },
+            vat: {
+                'default': 'कृपया एक वैध VAT संख्या प्रविष्ट करें',
+                country: 'कृपया एक वैध VAT संख्या %s मे प्रविष्ट करें',
+                countries: {
+                    AT: 'ऑस्ट्रिया',
+                    BE: 'बेल्जियम',
+                    BG: 'बुल्गारिया',
+                    BR: 'ब्राज़िल',
+                    CH: 'स्विट्जरलैंड',
+                    CY: 'साइप्रस',
+                    CZ: 'चेक रिपब्लिक',
+                    DE: 'जर्मनी',
+                    DK: 'डेनमार्क',
+                    EE: 'एस्तोनिया',
+                    ES: 'स्पेन',
+                    FI: 'फिनलैंड',
+                    FR: 'फ्रांस',
+                    GB: 'यूनाइटेड किंगडम',
+                    GR: 'ग्रीस',
+                    EL: 'ग्रीस',
+                    HU: 'हंगरी',
+                    HR: 'क्रोएशिया',
+                    IE: 'आयरलैंड',
+                    IS: 'आइसलैंड',
+                    IT: 'इटली',
+                    LT: 'लिथुआनिया',
+                    LU: 'लक्समबर्ग',
+                    LV: 'लाटविया',
+                    MT: 'माल्टा',
+                    NL: 'नीदरलैंड',
+                    NO: 'नॉर्वे',
+                    PL: 'पोलैंड',
+                    PT: 'पुर्तगाल',
+                    RO: 'रोमानिया',
+                    RU: 'रुस',
+                    RS: 'सर्बिया',
+                    SE: 'स्वीडन',
+                    SI: 'स्लोवेनिया',
+                    SK: 'स्लोवाकिया',
+                    VE: 'वेनेजुएला',
+                    ZA: 'दक्षिण अफ्रीका'
+                }
+            },
+            vin: {
+                'default': 'कृपया एक वैध VIN संख्या प्रविष्ट करें'
+            },
+            zipCode: {
+                'default': 'कृपया एक वैध डाक कोड प्रविष्ट करें',
+                country: 'कृपया एक वैध डाक कोड %s मे प्रविष्ट करें',
+                countries: {
+                    AT: 'ऑस्ट्रिया',
+                    BG: 'बुल्गारिया',
+                    BR: 'ब्राज़िल',
+                    CA: 'कनाडा',
+                    CH: 'स्विट्जरलैंड',
+                    CZ: 'चेक रिपब्लिक',
+                    DE: 'जर्मनी',
+                    DK: 'डेनमार्क',
+                    ES: 'स्पेन',
+                    FR: 'फ्रांस',
+                    GB: 'यूनाइटेड किंगडम',
+                    IE: 'आयरलैंड',
+                    IN: 'भारत',
+                    IT: 'इटली',
+                    MA: 'मोरक्को',
+                    NL: 'नीदरलैंड',
+                    PL: 'पोलैंड',
+                    PT: 'पुर्तगाल',
+                    RO: 'रोमानिया',
+                    RU: 'रुस',
+                    SE: 'स्वीडन',
+                    SG: 'सिंगापुर',
+                    SK: 'स्लोवाकिया',
+                    US: 'अमेरीका'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/hu_HU.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Hungarian language package
+     * Translated by @blackfyre
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'hu_HU': {
+            base64: {
+                'default': 'Kérlek, hogy érvényes base 64 karakter láncot adj meg'
+            },
+            between: {
+                'default': 'Kérlek, hogy %s és %s között adj meg értéket',
+                notInclusive: 'Kérlek, hogy %s és %s között adj meg értéket'
+            },
+            bic: {
+                'default': 'Kérlek, hogy érvényes BIC számot adj meg'
+            },
+            callback: {
+                'default': 'Kérlek, hogy érvényes értéket adj meg'
+            },
+            choice: {
+                'default': 'Kérlek, hogy érvényes értéket adj meg',
+                less: 'Kérlek, hogy legalább %s lehetőséget válassz ki',
+                more: 'Kérlek, hogy maximum %s lehetőséget válassz ki',
+                between: 'Kérlek, hogy válassz %s - %s lehetőséget'
+            },
+            color: {
+                'default': 'Kérlek, hogy érvényes színt adj meg'
+            },
+            creditCard: {
+                'default': 'Kérlek, hogy érvényes bankkártya számot adj meg'
+            },
+            cusip: {
+                'default': 'Kérlek, hogy érvényes CUSIP számot adj meg'
+            },
+            cvv: {
+                'default': 'Kérlek, hogy érvényes CVV számot adj meg'
+            },
+            date: {
+                'default': 'Kérlek, hogy érvényes dátumot adj meg',
+                min: 'Kérlek, hogy %s -nál későbbi dátumot adj meg',
+                max: 'Kérlek, hogy %s -nál korábbi dátumot adj meg',
+                range: 'Kérlek, hogy %s - %s között adj meg dátumot'
+            },
+            different: {
+                'default': 'Kérlek, hogy egy másik értéket adj meg'
+            },
+            digits: {
+                'default': 'Kérlek, hogy csak számot adj meg'
+            },
+            ean: {
+                'default': 'Kérlek, hogy érvényes EAN számot adj meg'
+            },
+            ein: {
+                'default': 'Kérlek, hogy érvényes EIN számot adj meg'
+            },
+            emailAddress: {
+                'default': 'Kérlek, hogy érvényes email címet adj meg'
+            },
+            file: {
+                'default': 'Kérlek, hogy érvényes fájlt válassz'
+            },
+            greaterThan: {
+                'default': 'Kérlek, hogy ezzel (%s) egyenlő vagy nagyobb számot adj meg',
+                notInclusive: 'Kérlek, hogy ennél (%s) nagyobb számot adj meg'
+            },
+            grid: {
+                'default': 'Kérlek, hogy érvényes GRId számot adj meg'
+            },
+            hex: {
+                'default': 'Kérlek, hogy érvényes hexadecimális számot adj meg'
+            },
+            iban: {
+                'default': 'Kérlek, hogy érvényes IBAN számot adj meg',
+                country: 'Kérlek, hogy %s érvényes  IBAN számot adj meg',
+                countries: {
+                    AD: 'az Andorrai Fejedelemségben', /* Special case */
+                    AE: 'az Egyesült Arab Emírségekben', /* Special case */
+                    AL: 'Albániában',
+                    AO: 'Angolában',
+                    AT: 'Ausztriában',
+                    AZ: 'Azerbadjzsánban',
+                    BA: 'Bosznia-Hercegovinában', /* Special case */
+                    BE: 'Belgiumban',
+                    BF: 'Burkina Fasoban',
+                    BG: 'Bulgáriában',
+                    BH: 'Bahreinben',
+                    BI: 'Burundiban',
+                    BJ: 'Beninben',
+                    BR: 'Brazíliában',
+                    CH: 'Svájcban',
+                    CI: 'az Elefántcsontparton', /* Special case */
+                    CM: 'Kamerunban',
+                    CR: 'Costa Ricán', /* Special case */
+                    CV: 'Zöld-foki Köztársaságban',
+                    CY: 'Cypruson',
+                    CZ: 'Csehországban',
+                    DE: 'Németországban',
+                    DK: 'Dániában',
+                    DO: 'Dominikán', /* Special case */
+                    DZ: 'Algériában',
+                    EE: 'Észtországban',
+                    ES: 'Spanyolországban',
+                    FI: 'Finnországban',
+                    FO: 'a Feröer-szigeteken', /* Special case */
+                    FR: 'Franciaországban',
+                    GB: 'az Egyesült Királyságban', /* Special case */
+                    GE: 'Grúziában',
+                    GI: 'Gibraltáron', /* Special case */
+                    GL: 'Grönlandon', /* Special case */
+                    GR: 'Görögországban',
+                    GT: 'Guatemalában',
+                    HR: 'Horvátországban',
+                    HU: 'Magyarországon',
+                    IE: 'Írországban', /* Special case */
+                    IL: 'Izraelben',
+                    IR: 'Iránban', /* Special case */
+                    IS: 'Izlandon',
+                    IT: 'Olaszországban',
+                    JO: 'Jordániában',
+                    KW: 'Kuvaitban', /* Special case */
+                    KZ: 'Kazahsztánban',
+                    LB: 'Libanonban',
+                    LI: 'Liechtensteinben',
+                    LT: 'Litvániában',
+                    LU: 'Luxemburgban',
+                    LV: 'Lettországban',
+                    MC: 'Monacóban', /* Special case */
+                    MD: 'Moldovában', /* Special case */
+                    ME: 'Montenegróban',
+                    MG: 'Madagaszkáron',
+                    MK: 'Macedóniában',
+                    ML: 'Malin',
+                    MR: 'Mauritániában',
+                    MT: 'Máltán',
+                    MU: 'Mauritiuson',
+                    MZ: 'Mozambikban',
+                    NL: 'Hollandiában',
+                    NO: 'Norvégiában',
+                    PK: 'Pakisztánban',
+                    PL: 'Lengyelországban',
+                    PS: 'Palesztinában',
+                    PT: 'Portugáliában',
+                    QA: 'Katarban', /* Special case */
+                    RO: 'Romániában',
+                    RS: 'Szerbiában',
+                    SA: 'Szaúd-Arábiában',
+                    SE: 'Svédországban',
+                    SI: 'Szlovéniában',
+                    SK: 'Szlovákiában',
+                    SM: 'San Marinoban',
+                    SN: 'Szenegálban', /* Special case */
+                    TL: 'Kelet-Timor',
+                    TN: 'Tunéziában', /* Special case */
+                    TR: 'Törökországban',
+                    VG: 'Britt Virgin szigeteken', /* Special case */
+                    XK: 'Koszovói Köztársaság'
+                }
+            },
+            id: {
+                'default': 'Kérlek, hogy érvényes személy azonosító számot adj meg',
+                country: 'Kérlek, hogy %s érvényes személy azonosító számot adj meg',
+                countries: {
+                    BA: 'Bosznia-Hercegovinában',
+                    BG: 'Bulgáriában',
+                    BR: 'Brazíliában',
+                    CH: 'Svájcban',
+                    CL: 'Chilében',
+                    CN: 'Kínában',
+                    CZ: 'Csehországban',
+                    DK: 'Dániában',
+                    EE: 'Észtországban',
+                    ES: 'Spanyolországban',
+                    FI: 'Finnországban',
+                    HR: 'Horvátországban',
+                    IE: 'Írországban',
+                    IS: 'Izlandon',
+                    LT: 'Litvániában',
+                    LV: 'Lettországban',
+                    ME: 'Montenegróban',
+                    MK: 'Macedóniában',
+                    NL: 'Hollandiában',
+                    PL: 'Lengyelországban',
+                    RO: 'Romániában',
+                    RS: 'Szerbiában',
+                    SE: 'Svédországban',
+                    SI: 'Szlovéniában',
+                    SK: 'Szlovákiában',
+                    SM: 'San Marinoban',
+                    TH: 'Thaiföldön',
+                    TR: 'Törökországban',
+                    ZA: 'Dél-Afrikában'
+                }
+            },
+            identical: {
+                'default': 'Kérlek, hogy ugyan azt az értéket add meg'
+            },
+            imei: {
+                'default': 'Kérlek, hogy érvényes IMEI számot adj meg'
+            },
+            imo: {
+                'default': 'Kérlek, hogy érvényes IMO számot adj meg'
+            },
+            integer: {
+                'default': 'Kérlek, hogy számot adj meg'
+            },
+            ip: {
+                'default': 'Kérlek, hogy IP címet adj meg',
+                ipv4: 'Kérlek, hogy érvényes IPv4 címet adj meg',
+                ipv6: 'Kérlek, hogy érvényes IPv6 címet adj meg'
+            },
+            isbn: {
+                'default': 'Kérlek, hogy érvényes ISBN számot adj meg'
+            },
+            isin: {
+                'default': 'Kérlek, hogy érvényes ISIN számot adj meg'
+            },
+            ismn: {
+                'default': 'Kérlek, hogy érvényes ISMN számot adj meg'
+            },
+            issn: {
+                'default': 'Kérlek, hogy érvényes ISSN számot adj meg'
+            },
+            lessThan: {
+                'default': 'Kérlek, hogy adj meg egy számot ami kisebb vagy egyenlő mint %s',
+                notInclusive: 'Kérlek, hogy adj meg egy számot ami kisebb mint %s'
+            },
+            mac: {
+                'default': 'Kérlek, hogy érvényes MAC címet adj meg'
+            },
+            meid: {
+                'default': 'Kérlek, hogy érvényes MEID számot adj meg'
+            },
+            notEmpty: {
+                'default': 'Kérlek, hogy adj értéket a mezőnek'
+            },
+            numeric: {
+                'default': 'Please enter a valid float number'
+            },
+            phone: {
+                'default': 'Kérlek, hogy érvényes telefonszámot adj meg',
+                country: 'Kérlek, hogy %s érvényes telefonszámot adj meg',
+                countries: {
+                    AE: 'az Egyesült Arab Emírségekben', /* Special case */
+                    BG: 'Bulgáriában',
+                    BR: 'Brazíliában',
+                    CN: 'Kínában',
+                    CZ: 'Csehországban',
+                    DE: 'Németországban',
+                    DK: 'Dániában',
+                    ES: 'Spanyolországban',
+                    FR: 'Franciaországban',
+                    GB: 'az Egyesült Királyságban',
+                    IN: 'India',
+                    MA: 'Marokkóban',
+                    NL: 'Hollandiában',
+                    PK: 'Pakisztánban',
+                    RO: 'Romániában',
+                    RU: 'Oroszországban',
+                    SK: 'Szlovákiában',
+                    TH: 'Thaiföldön',
+                    US: 'az Egyesült Államokban',
+                    VE: 'Venezuelában' /* Sepcial case */
+                }
+            },
+            promise: {
+                'default': 'Kérlek, hogy érvényes értéket adj meg'
+            },
+            regexp: {
+                'default': 'Kérlek, hogy a mintának megfelelő értéket adj meg'
+            },
+            remote: {
+                'default': 'Kérlek, hogy érvényes értéket adj meg'
+            },
+            rtn: {
+                'default': 'Kérlek, hogy érvényes RTN számot adj meg'
+            },
+            sedol: {
+                'default': 'Kérlek, hogy érvényes SEDOL számot adj meg'
+            },
+            siren: {
+                'default': 'Kérlek, hogy érvényes SIREN számot adj meg'
+            },
+            siret: {
+                'default': 'Kérlek, hogy érvényes SIRET számot adj meg'
+            },
+            step: {
+                'default': 'Kérlek, hogy érvényes lépteket adj meg (%s)'
+            },
+            stringCase: {
+                'default': 'Kérlek, hogy csak kisbetüket adj meg',
+                upper: 'Kérlek, hogy csak nagy betüket adj meg'
+            },
+            stringLength: {
+                'default': 'Kérlek, hogy érvényes karakter hosszúsággal adj meg értéket',
+                less: 'Kérlek, hogy kevesebb mint %s karaktert adj meg',
+                more: 'Kérlek, hogy több mint %s karaktert adj meg',
+                between: 'Kérlek, hogy legalább %s, de maximum %s karaktert adj meg'
+            },
+            uri: {
+                'default': 'Kérlek, hogy helyes URI -t adj meg'
+            },
+            uuid: {
+                'default': 'Kérlek, hogy érvényes UUID számot adj meg',
+                version: 'Kérlek, hogy érvényes UUID verzió %s számot adj meg'
+            },
+            vat: {
+                'default': 'Kérlek, hogy helyes adó számot adj meg',
+                country: 'Kérlek, hogy %s helyes  adószámot adj meg',
+                countries: {
+                    AT: 'Ausztriában',
+                    BE: 'Belgiumban',
+                    BG: 'Bulgáriában',
+                    BR: 'Brazíliában',
+                    CH: 'Svájcban',
+                    CY: 'Cipruson',
+                    CZ: 'Csehországban',
+                    DE: 'Németországban',
+                    DK: 'Dániában',
+                    EE: 'Észtországban',
+                    ES: 'Spanyolországban',
+                    FI: 'Finnországban',
+                    FR: 'Franciaországban',
+                    GB: 'az Egyesült Királyságban',
+                    GR: 'Görögországban',
+                    EL: 'Görögországban',
+                    HU: 'Magyarországon',
+                    HR: 'Horvátországban',
+                    IE: 'Írországban',
+                    IS: 'Izlandon',
+                    IT: 'Olaszországban',
+                    LT: 'Litvániában',
+                    LU: 'Luxemburgban',
+                    LV: 'Lettországban',
+                    MT: 'Máltán',
+                    NL: 'Hollandiában',
+                    NO: 'Norvégiában',
+                    PL: 'Lengyelországban',
+                    PT: 'Portugáliában',
+                    RO: 'Romániában',
+                    RU: 'Oroszországban',
+                    RS: 'Szerbiában',
+                    SE: 'Svédországban',
+                    SI: 'Szlovéniában',
+                    SK: 'Szlovákiában',
+                    VE: 'Venezuelában',
+                    ZA: 'Dél-Afrikában'
+                }
+            },
+            vin: {
+                'default': 'Kérlek, hogy érvényes VIN számot adj meg'
+            },
+            zipCode: {
+                'default': 'Kérlek, hogy érvényes irányítószámot adj meg',
+                country: 'Kérlek, hogy %s érvényes irányítószámot adj meg',
+                countries: {
+                    AT: 'Ausztriában',
+                    BG: 'Bulgáriában',
+                    BR: 'Brazíliában',
+                    CA: 'Kanadában',
+                    CH: 'Svájcban',
+                    CZ: 'Csehországban',
+                    DE: 'Németországban',
+                    DK: 'Dániában',
+                    ES: 'Spanyolországban',
+                    FR: 'Franciaországban',
+                    GB: 'az Egyesült Királyságban',
+                    IE: 'Írországban',
+                    IN: 'India',
+                    IT: 'Olaszországban',
+                    MA: 'Marokkóban',
+                    NL: 'Hollandiában',
+                    PL: 'Lengyelországban',
+                    PT: 'Portugáliában',
+                    RO: 'Romániában',
+                    RU: 'Oroszországban',
+                    SE: 'Svájcban',
+                    SG: 'Szingapúrban',
+                    SK: 'Szlovákiában',
+                    US: 'Egyesült Államok beli'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/id_ID.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Indonesian language package
+     * Translated by @egig
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'id_ID': {
+            base64: {
+                'default': 'Silahkan isi karakter base 64 tersandi yang valid'
+            },
+            between: {
+                'default': 'Silahkan isi nilai antara %s dan %s',
+                notInclusive: 'Silahkan isi nilai antara %s dan %s, strictly'
+            },
+            bic: {
+                'default': 'Silahkan isi nomor BIC yang valid'
+            },
+            callback: {
+                'default': 'Silahkan isi nilai yang valid'
+            },
+            choice: {
+                'default': 'Silahkan isi nilai yang valid',
+                less: 'Silahkan pilih pilihan %s pada minimum',
+                more: 'Silahkan pilih pilihan %s pada maksimum',
+                between: 'Silahkan pilih pilihan %s - %s'
+            },
+            color: {
+                'default': 'Silahkan isi karakter warna yang valid'
+            },
+            creditCard: {
+                'default': 'Silahkan isi nomor kartu kredit yang valid'
+            },
+            cusip: {
+                'default': 'Silahkan isi nomor CUSIP yang valid'
+            },
+            cvv: {
+                'default': 'Silahkan isi nomor CVV yang valid'
+            },
+            date: {
+                'default': 'Silahkan isi tanggal yang benar',
+                min: 'Silahkan isi tanggal setelah tanggal %s',
+                max: 'Silahkan isi tanggal sebelum tanggal %s',
+                range: 'Silahkan isi tanggal antara %s - %s'
+            },
+            different: {
+                'default': 'Silahkan isi nilai yang berbeda'
+            },
+            digits: {
+                'default': 'Silahkan isi dengan hanya digit'
+            },
+            ean: {
+                'default': 'Silahkan isi nomor EAN yang valid'
+            },
+            ein: {
+                'default': 'Silahkan isi nomor EIN yang valid'
+            },
+            emailAddress: {
+                'default': 'Silahkan isi alamat email yang valid'
+            },
+            file: {
+                'default': 'Silahkan pilih file yang valid'
+            },
+            greaterThan: {
+                'default': 'Silahkan isi nilai yang lebih besar atau sama dengan %s',
+                notInclusive: 'Silahkan is nilai yang lebih besar dari %s'
+            },
+            grid: {
+                'default': 'Silahkan nomor GRId yang valid'
+            },
+            hex: {
+                'default': 'Silahkan isi karakter hexadecimal yang valid'
+            },
+            iban: {
+                'default': 'silahkan isi nomor IBAN yang valid',
+                country: 'Silahkan isi nomor IBAN yang valid dalam %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Uni Emirat Arab',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbaijan',
+                    BA: 'Bosnia and Herzegovina',
+                    BE: 'Belgia',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CI: 'Pantai Gading',
+                    CM: 'Kamerun',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Cyprus',
+                    CZ: 'Czech',
+                    DE: 'Jerman',
+                    DK: 'Denmark',
+                    DO: 'Republik Dominika',
+                    DZ: 'Algeria',
+                    EE: 'Estonia',
+                    ES: 'Spanyol',
+                    FI: 'Finlandia',
+                    FO: 'Faroe Islands',
+                    FR: 'Francis',
+                    GB: 'Inggris',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Greenland',
+                    GR: 'Yunani',
+                    GT: 'Guatemala',
+                    HR: 'Kroasia',
+                    HU: 'Hungary',
+                    IE: 'Irlandia',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Iceland',
+                    IT: 'Italia',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakhstan',
+                    LB: 'Libanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MC: 'Monaco',
+                    MD: 'Moldova',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Netherlands',
+                    NO: 'Norway',
+                    PK: 'Pakistan',
+                    PL: 'Polandia',
+                    PS: 'Palestina',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SA: 'Saudi Arabia',
+                    SE: 'Swedia',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timor Leste',
+                    TN: 'Tunisia',
+                    TR: 'Turki',
+                    VG: 'Virgin Islands, British',
+                    XK: 'Kosovo'
+                }
+            },
+            id: {
+                'default': 'Silahkan isi nomor identitas yang valid',
+                country: 'Silahkan isi nomor identitas yang valid dalam %s',
+                countries: {
+                    BA: 'Bosnia and Herzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CL: 'Chile',
+                    CN: 'Cina',
+                    CZ: 'Czech',
+                    DK: 'Denmark',
+                    EE: 'Estonia',
+                    ES: 'Spanyol',
+                    FI: 'Finlandia',
+                    HR: 'Kroasia',
+                    IE: 'Irlandia',
+                    IS: 'Iceland',
+                    LT: 'Lithuania',
+                    LV: 'Latvia',
+                    ME: 'Montenegro',
+                    MK: 'Macedonia',
+                    NL: 'Netherlands',
+                    PL: 'Polandia',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Sweden',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Turki',
+                    ZA: 'Africa Selatan'
+                }
+            },
+            identical: {
+                'default': 'Silahkan isi nilai yang sama'
+            },
+            imei: {
+                'default': 'Silahkan isi nomor IMEI yang valid'
+            },
+            imo: {
+                'default': 'Silahkan isi nomor IMO yang valid'
+            },
+            integer: {
+                'default': 'Silahkan isi angka yang valid'
+            },
+            ip: {
+                'default': 'Silahkan isi alamat IP yang valid',
+                ipv4: 'Silahkan isi alamat IPv4 yang valid',
+                ipv6: 'Silahkan isi alamat IPv6 yang valid'
+            },
+            isbn: {
+                'default': 'Slilahkan isi nomor ISBN yang valid'
+            },
+            isin: {
+                'default': 'Silahkan isi ISIN yang valid'
+            },
+            ismn: {
+                'default': 'Silahkan isi nomor ISMN yang valid'
+            },
+            issn: {
+                'default': 'Silahkan isi nomor ISSN yang valid'
+            },
+            lessThan: {
+                'default': 'Silahkan isi nilai kurang dari atau sama dengan %s',
+                notInclusive: 'Silahkan isi nilai kurang dari %s'
+            },
+            mac: {
+                'default': 'Silahkan isi MAC address yang valid'
+            },
+            meid: {
+                'default': 'Silahkan isi nomor MEID yang valid'
+            },
+            notEmpty: {
+                'default': 'Silahkan isi'
+            },
+            numeric: {
+                'default': 'Silahkan isi nomor yang valid'
+            },
+            phone: {
+                'default': 'Silahkan isi nomor telepon yang valid',
+                country: 'Silahkan isi nomor telepon yang valid dalam %s',
+                countries: {
+                    AE: 'Uni Emirat Arab',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CN: 'Cina',
+                    CZ: 'Czech',
+                    DE: 'Jerman',
+                    DK: 'Denmark',
+                    ES: 'Spanyol',
+                    FR: 'Francis',
+                    GB: 'Inggris',
+                    IN: 'India',
+                    MA: 'Maroko',
+                    NL: 'Netherlands',
+                    PK: 'Pakistan',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    SK: 'Slovakia',
+                    TH: 'Thailand',
+                    US: 'Amerika Serikat',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Silahkan isi nilai yang valid'
+            },
+            regexp: {
+                'default': 'Silahkan isi nilai yang cocok dengan pola'
+            },
+            remote: {
+                'default': 'Silahkan isi nilai yang valid'
+            },
+            rtn: {
+                'default': 'Silahkan isi nomor RTN yang valid'
+            },
+            sedol: {
+                'default': 'Silahkan isi nomor SEDOL yang valid'
+            },
+            siren: {
+                'default': 'Silahkan isi nomor SIREN yang valid'
+            },
+            siret: {
+                'default': 'Silahkan isi nomor SIRET yang valid'
+            },
+            step: {
+                'default': 'Silahkan isi langkah yang benar pada %s'
+            },
+            stringCase: {
+                'default': 'Silahkan isi hanya huruf kecil',
+                upper: 'Silahkan isi hanya huruf besar'
+            },
+            stringLength: {
+                'default': 'Silahkan isi nilai dengan panjang karakter yang benar',
+                less: 'Silahkan isi kurang dari %s karakter',
+                more: 'Silahkan isi lebih dari %s karakter',
+                between: 'Silahkan isi antara %s dan %s panjang karakter'
+            },
+            uri: {
+                'default': 'Silahkan isi URI yang valid'
+            },
+            uuid: {
+                'default': 'Silahkan isi nomor UUID yang valid',
+                version: 'Silahkan si nomor versi %s UUID yang valid'
+            },
+            vat: {
+                'default': 'Silahkan isi nomor VAT yang valid',
+                country: 'Silahkan nomor VAT yang valid dalam %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Belgium',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CH: 'Switzerland',
+                    CY: 'Cyprus',
+                    CZ: 'Czech',
+                    DE: 'Jerman',
+                    DK: 'Denmark',
+                    EE: 'Estonia',
+                    ES: 'Spanyol',
+                    FI: 'Finlandia',
+                    FR: 'Francis',
+                    GB: 'Inggris',
+                    GR: 'Yunani',
+                    EL: 'Yunani',
+                    HU: 'Hungaria',
+                    HR: 'Kroasia',
+                    IE: 'Irlandia',
+                    IS: 'Iceland',
+                    IT: 'Italy',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MT: 'Malta',
+                    NL: 'Belanda',
+                    NO: 'Norway',
+                    PL: 'Polandia',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    RS: 'Serbia',
+                    SE: 'Sweden',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    VE: 'Venezuela',
+                    ZA: 'Afrika Selatan'
+                }
+            },
+            vin: {
+                'default': 'Silahkan isi nomor VIN yang valid'
+            },
+            zipCode: {
+                'default': 'Silahkan isi kode pos yang valid',
+                country: 'Silahkan isi kode pos yang valid di %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CA: 'Kanada',
+                    CH: 'Switzerland',
+                    CZ: 'Czech',
+                    DE: 'Jerman',
+                    DK: 'Denmark',
+                    ES: 'Spanyol',
+                    FR: 'Francis',
+                    GB: 'Inggris',
+                    IE: 'Irlandia',
+                    IN: 'India',
+                    IT: 'Italia',
+                    MA: 'Maroko',
+                    NL: 'Belanda',
+                    PL: 'Polandia',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    SE: 'Sweden',
+                    SG: 'Singapura',
+                    SK: 'Slovakia',
+                    US: 'Amerika Serikat'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/it_IT.js

@@ -0,0 +1,385 @@
+(function ($) {
+    /**
+     * Italian language package
+     * Translated by @maramazza
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'it_IT': {
+            base64: {
+                'default': 'Si prega di inserire un valore codificato in Base 64'
+            },
+            between: {
+                'default': 'Si prega di inserire un valore tra %s e %s',
+                notInclusive: 'Si prega di scegliere rigorosamente un valore tra %s e %s'
+            },
+            bic: {
+                'default': 'Si prega di inserire un numero BIC valido'
+            },
+            callback: {
+                'default': 'Si prega di inserire un valore valido'
+            },
+            choice: {
+                'default': 'Si prega di inserire un valore valido',
+                less: 'Si prega di scegliere come minimo l\'opzione %s',
+                more: 'Si prega di scegliere al massimo l\'opzione %s',
+                between: 'Si prega di scegliere l\'opzione tra %s e %s'
+            },
+            color: {
+                'default': 'Si prega di inserire un colore valido'
+            },
+            creditCard: {
+                'default': 'Si prega di inserire un numero di carta di credito valido'
+            },
+            cusip: {
+                'default': 'Si prega di inserire un numero CUSIP valido'
+            },
+            cvv: {
+                'default': 'Si prega di inserire un numero CVV valido'
+            },
+            date: {
+                'default': 'Si prega di inserire una data valida',
+                min: 'Si prega di inserire una data successiva al %s',
+                max: 'Si prega di inserire una data antecedente il %s',
+                range: 'Si prega di inserire una data compresa tra %s - %s'
+            },
+            different: {
+                'default': 'Si prega di inserire un valore differente'
+            },
+            digits: {
+                'default': 'Si prega di inserire solo numeri'
+            },
+            ean: {
+                'default': 'Si prega di inserire un numero EAN valido'
+            },
+            ein: {
+                'default': 'Si prega di inserire un numero EIN valido'
+            },
+            emailAddress: {
+                'default': 'Si prega di inserire un indirizzo email valido'
+            },
+            file: {
+                'default': 'Si prega di scegliere un file valido'
+            },
+            greaterThan: {
+                'default': 'Si prega di inserire un numero maggiore o uguale a %s',
+                notInclusive: 'Si prega di inserire un numero maggiore di %s'
+            },
+            grid: {
+                'default': 'Si prega di inserire un numero GRId valido'
+            },
+            hex: {
+                'default': 'Si prega di inserire un numero esadecimale valido'
+            },
+            iban: {
+                'default': 'Si prega di inserire un numero IBAN valido',
+                country: 'Si prega di inserire un numero IBAN valido per %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Emirati Arabi Uniti',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbaijan',
+                    BA: 'Bosnia-Erzegovina',
+                    BE: 'Belgio',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasile',
+                    CH: 'Svizzera',
+                    CI: 'Costa d\'Avorio',
+                    CM: 'Cameron',
+                    CR: 'Costa Rica',
+                    CV: 'Capo Verde',
+                    CY: 'Cipro',
+                    CZ: 'Republica Ceca',
+                    DE: 'Germania',
+                    DK: 'Danimarca',
+                    DO: 'Repubblica Domenicana',
+                    DZ: 'Algeria',
+                    EE: 'Estonia',
+                    ES: 'Spagna',
+                    FI: 'Finlandia',
+                    FO: 'Isole Faroe',
+                    FR: 'Francia',
+                    GB: 'Regno Unito',
+                    GE: 'Georgia',
+                    GI: 'Gibilterra',
+                    GL: 'Groenlandia',
+                    GR: 'Grecia',
+                    GT: 'Guatemala',
+                    HR: 'Croazia',
+                    HU: 'Ungheria',
+                    IE: 'Irlanda',
+                    IL: 'Israele',
+                    IR: 'Iran',
+                    IS: 'Islanda',
+                    IT: 'Italia',
+                    JO: 'Giordania',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakhstan',
+                    LB: 'Libano',
+                    LI: 'Liechtenstein',
+                    LT: 'Lituania',
+                    LU: 'Lussemburgo',
+                    LV: 'Lettonia',
+                    MC: 'Monaco',
+                    MD: 'Moldavia',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambico',
+                    NL: 'Olanda',
+                    NO: 'Norvegia',
+                    PK: 'Pachistan',
+                    PL: 'Polonia',
+                    PS: 'Palestina',
+                    PT: 'Portogallo',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SA: 'Arabia Saudita',
+                    SE: 'Svezia',
+                    SI: 'Slovenia',
+                    SK: 'Slovacchia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timor Est',
+                    TN: 'Tunisia',
+                    TR: 'Turchia',
+                    VG: 'Isole Vergini, Inghilterra',
+                    XK: 'Repubblica del Kosovo'
+                }
+            },
+            id: {
+                'default': 'Si prega di inserire un numero di identificazione valido',
+                country: 'Si prega di inserire un numero di identificazione valido per %s',
+                countries: {
+                    BA: 'Bosnia-Erzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brasile',
+                    CH: 'Svizzera',
+                    CL: 'Chile',
+                    CN: 'Cina',
+                    CZ: 'Republica Ceca',
+                    DK: 'Danimarca',
+                    EE: 'Estonia',
+                    ES: 'Spagna',
+                    FI: 'Finlandia',
+                    HR: 'Croazia',
+                    IE: 'Irlanda',
+                    IS: 'Islanda',
+                    LT: 'Lituania',
+                    LV: 'Lettonia',
+                    ME: 'Montenegro',
+                    MK: 'Macedonia',
+                    NL: 'Paesi Bassi',
+                    PL: 'Polonia',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Svezia',
+                    SI: 'Slovenia',
+                    SK: 'Slovacchia',
+                    SM: 'San Marino',
+                    TH: 'Thailandia',
+                    TR: 'Turchia',
+                    ZA: 'Sudafrica'
+                }
+            },
+            identical: {
+                'default': 'Si prega di inserire un valore identico'
+            },
+            imei: {
+                'default': 'Si prega di inserire un numero IMEI valido'
+            },
+            imo: {
+                'default': 'Si prega di inserire un numero IMO valido'
+            },
+            integer: {
+                'default': 'Si prega di inserire un numero valido'
+            },
+            ip: {
+                'default': 'Please enter a valid IP address',
+                ipv4: 'Si prega di inserire un indirizzo IPv4 valido',
+                ipv6: 'Si prega di inserire un indirizzo IPv6 valido'
+            },
+            isbn: {
+                'default': 'Si prega di inserire un numero ISBN valido'
+            },
+            isin: {
+                'default': 'Si prega di inserire un numero ISIN valido'
+            },
+            ismn: {
+                'default': 'Si prega di inserire un numero ISMN valido'
+            },
+            issn: {
+                'default': 'Si prega di inserire un numero ISSN valido'
+            },
+            lessThan: {
+                'default': 'Si prega di inserire un valore minore o uguale a %s',
+                notInclusive: 'Si prega di inserire un valore minore di %s'
+            },
+            mac: {
+                'default': 'Si prega di inserire un valido MAC address'
+            },
+            meid: {
+                'default': 'Si prega di inserire un numero MEID valido'
+            },
+            notEmpty: {
+                'default': 'Si prega di non lasciare il campo vuoto'
+            },
+            numeric: {
+                'default': 'Si prega di inserire un numero con decimali valido'
+            },
+            phone: {
+                'default': 'Si prega di inserire un numero di telefono valido',
+                country: 'Si prega di inserire un numero di telefono valido per %s',
+                countries: {
+                    AE: 'Emirati Arabi Uniti',
+                    BG: 'Bulgaria',
+                    BR: 'Brasile',
+                    CN: 'Cina',
+                    CZ: 'Republica Ceca',
+                    DE: 'Germania',
+                    DK: 'Danimarca',
+                    ES: 'Spagna',
+                    FR: 'Francia',
+                    GB: 'Regno Unito',
+                    IN: 'India',
+                    MA: 'Marocco',
+                    NL: 'Olanda',
+                    PK: 'Pakistan',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    SK: 'Slovacchia',
+                    TH: 'Thailandia',
+                    US: 'Stati Uniti d\'America',
+                    VE: 'Venezuelano'
+                }
+            },
+            promise: {
+                'default': 'Si prega di inserire un valore valido'
+            },
+            regexp: {
+                'default': 'Inserisci un valore che corrisponde al modello'
+            },
+            remote: {
+                'default': 'Si prega di inserire un valore valido'
+            },
+            rtn: {
+                'default': 'Si prega di inserire un numero RTN valido'
+            },
+            sedol: {
+                'default': 'Si prega di inserire un numero SEDOL valido'
+            },
+            siren: {
+                'default': 'Si prega di inserire un numero SIREN valido'
+            },
+            siret: {
+                'default': 'Si prega di inserire un numero SIRET valido'
+            },
+            step: {
+                'default': 'Si prega di inserire uno step valido di %s'
+            },
+            stringCase: {
+                'default': 'Si prega di inserire solo caratteri minuscoli',
+                upper: 'Si prega di inserire solo caratteri maiuscoli'
+            },
+            stringLength: {
+                'default': 'Si prega di inserire un valore con lunghezza valida',
+                less: 'Si prega di inserire meno di %s caratteri',
+                more: 'Si prega di inserire piu di %s caratteri',
+                between: 'Si prega di inserire un numero di caratteri compreso tra  %s e %s'
+            },
+            uri: {
+                'default': 'Si prega di inserire un URI valido'
+            },
+            uuid: {
+                'default': 'Si prega di inserire un numero UUID valido',
+                version: 'Si prega di inserire un numero di versione UUID %s valido'
+            },
+            vat: {
+                'default': 'Si prega di inserire un valore di IVA valido',
+                country: 'Si prega di inserire un valore di IVA valido per %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Belgio',
+                    BG: 'Bulgaria',
+                    BR: 'Brasiliano',
+                    CH: 'Svizzera',
+                    CY: 'Cipro',
+                    CZ: 'Republica Ceca',
+                    DE: 'Germania',
+                    DK: 'Danimarca',
+                    EE: 'Estonia',
+                    ES: 'Spagna',
+                    FI: 'Finlandia',
+                    FR: 'Francia',
+                    GB: 'Regno Unito',
+                    GR: 'Grecia',
+                    EL: 'Grecia',
+                    HU: 'Ungheria',
+                    HR: 'Croazia',
+                    IE: 'Irlanda',
+                    IS: 'Islanda',
+                    IT: 'Italia',
+                    LT: 'Lituania',
+                    LU: 'Lussemburgo',
+                    LV: 'Lettonia',
+                    MT: 'Malta',
+                    NL: 'Olanda',
+                    NO: 'Norvegia',
+                    PL: 'Polonia',
+                    PT: 'Portogallo',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    RS: 'Serbia',
+                    SE: 'Svezia',
+                    SI: 'Slovenia',
+                    SK: 'Slovacchia',
+                    VE: 'Venezuelano',
+                    ZA: 'Sud Africano'
+                }
+            },
+            vin: {
+                'default': 'Si prega di inserire un numero VIN valido'
+            },
+            zipCode: {
+                'default': 'Si prega di inserire un codice postale valido',
+                country: 'Si prega di inserire un codice postale valido per %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bulgaria',
+                    BR: 'Brasile',
+                    CA: 'Canada',
+                    CH: 'Svizzera',
+                    CZ: 'Republica Ceca',
+                    DE: 'Germania',
+                    DK: 'Danimarca',
+                    ES: 'Spagna',
+                    FR: 'Francia',
+                    GB: 'Regno Unito',
+                    IE: 'Irlanda',
+                    IN: 'India',
+                    IT: 'Italia',
+                    MA: 'Marocco',
+                    NL: 'Paesi Bassi',
+                    PL: 'Polonia',
+                    PT: 'Portogallo',
+                    RO: 'Romania',
+                    RU: 'Russia',
+                    SE: 'Svezia',
+                    SG: 'Singapore',
+                    SK: 'Slovacchia',
+                    US: 'Stati Uniti d\'America'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/ja_JP.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Japanese language package
+     * Translated by @tsuyoshifujii
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'ja_JP': {
+            base64: {
+                'default': '有効なBase64エンコードを入力してください'
+            },
+            between: {
+                'default': '%sから%sの間で入力してください',
+                notInclusive: '厳密に%sから%sの間で入力してください'
+            },
+            bic: {
+                'default': '有効なBICコードを入力してください'
+            },
+            callback: {
+                'default': '有効な値を入力してください'
+            },
+            choice: {
+                'default': '有効な値を入力してください',
+                less: '最低でも%sを選択してください',
+                more: '最大でも%sを選択してください',
+                between: '%s - %s で選択してください'
+            },
+            color: {
+                'default': '有効なカラーコードを入力してください'
+            },
+            creditCard: {
+                'default': '有効なクレジットカード番号を入力してください'
+            },
+            cusip: {
+                'default': '有効なCUSIP番号を入力してください'
+            },
+            cvv: {
+                'default': '有効なCVV番号を入力してください'
+            },
+            date: {
+                'default': '有効な日付を入力してください',
+                min: '%s 後に有効な日付を入力してください',
+                max: '%s の前に有効な日付を入力してください',
+                range: '%s - %s の間に有効な日付を入力してください'
+            },
+            different: {
+                'default': '異なる値を入力してください'
+            },
+            digits: {
+                'default': '数字のみで入力してください'
+            },
+            ean: {
+                'default': '有効なEANコードを入力してください'
+            },
+            ein: {
+                'default': '有効なEINコードを入力してください'
+            },
+            emailAddress: {
+                'default': '有効なメールアドレスを入力してください'
+            },
+            file: {
+                'default': '有効なファイルを選択してください'
+            },
+            greaterThan: {
+                'default': '%sより大きい値を入力してください',
+                notInclusive: '%sより大きい値を入力してください'
+            },
+            grid: {
+                'default': '有効なGRIdコードを入力してください'
+            },
+            hex: {
+                'default': '有効な16進数を入力してください。'
+            },
+            iban: {
+                'default': '有効なIBANコードを入力してください',
+                country: '有効な%sのIBANコードを入力してください',
+                countries: {
+                    AD: 'アンドラ',
+                    AE: 'アラブ首長国連邦',
+                    AL: 'アルバニア',
+                    AO: 'アンゴラ',
+                    AT: 'オーストリア',
+                    AZ: 'アゼルバイジャン',
+                    BA: 'ボスニア·ヘルツェゴビナ',
+                    BE: 'ベルギー',
+                    BF: 'ブルキナファソ',
+                    BG: 'ブルガリア',
+                    BH: 'バーレーン',
+                    BI: 'ブルンジ',
+                    BJ: 'ベナン',
+                    BR: 'ブラジル',
+                    CH: 'スイス',
+                    CI: '象牙海岸',
+                    CM: 'カメルーン',
+                    CR: 'コスタリカ',
+                    CV: 'カーボベルデ',
+                    CY: 'キプロス',
+                    CZ: 'チェコ共和国',
+                    DE: 'ドイツ',
+                    DK: 'デンマーク',
+                    DO: 'ドミニカ共和国',
+                    DZ: 'アルジェリア',
+                    EE: 'エストニア',
+                    ES: 'スペイン',
+                    FI: 'フィンランド',
+                    FO: 'フェロー諸島',
+                    FR: 'フランス',
+                    GB: 'イギリス',
+                    GE: 'グルジア',
+                    GI: 'ジブラルタル',
+                    GL: 'グリーンランド',
+                    GR: 'ギリシャ',
+                    GT: 'グアテマラ',
+                    HR: 'クロアチア',
+                    HU: 'ハンガリー',
+                    IE: 'アイルランド',
+                    IL: 'イスラエル',
+                    IR: 'イラン',
+                    IS: 'アイスランド',
+                    IT: 'イタリア',
+                    JO: 'ヨルダン',
+                    KW: 'クウェート',
+                    KZ: 'カザフスタン',
+                    LB: 'レバノン',
+                    LI: 'リヒテンシュタイン',
+                    LT: 'リトアニア',
+                    LU: 'ルクセンブルグ',
+                    LV: 'ラトビア',
+                    MC: 'モナコ',
+                    MD: 'モルドバ',
+                    ME: 'モンテネグロ',
+                    MG: 'マダガスカル',
+                    MK: 'マケドニア',
+                    ML: 'マリ',
+                    MR: 'モーリタニア',
+                    MT: 'マルタ',
+                    MU: 'モーリシャス',
+                    MZ: 'モザンビーク',
+                    NL: 'オランダ',
+                    NO: 'ノルウェー',
+                    PK: 'パキスタン',
+                    PL: 'ポーランド',
+                    PS: 'パレスチナ',
+                    PT: 'ポルトガル',
+                    QA: 'カタール',
+                    RO: 'ルーマニア',
+                    RS: 'セルビア',
+                    SA: 'サウジアラビア',
+                    SE: 'スウェーデン',
+                    SI: 'スロベニア',
+                    SK: 'スロバキア',
+                    SM: 'サン·マリノ',
+                    SN: 'セネガル',
+                    TL: '東チモール',
+                    TN: 'チュニジア',
+                    TR: 'トルコ',
+                    VG: '英領バージン諸島',
+                    XK: 'コソボ共和国'
+                }
+            },
+            id: {
+                'default': '有効なIDを入力してください',
+                country: '有効な%sのIDを入力してください',
+                countries: {
+                    BA: 'スニア·ヘルツェゴビナ',
+                    BG: 'ブルガリア',
+                    BR: 'ブラジル',
+                    CH: 'スイス',
+                    CL: 'チリ',
+                    CN: 'チャイナ',
+                    CZ: 'チェコ共和国',
+                    DK: 'デンマーク',
+                    EE: 'エストニア',
+                    ES: 'スペイン',
+                    FI: 'フィンランド',
+                    HR: 'クロアチア',
+                    IE: 'アイルランド',
+                    IS: 'アイスランド',
+                    LT: 'リトアニア',
+                    LV: 'ラトビア',
+                    ME: 'モンテネグロ',
+                    MK: 'マケドニア',
+                    NL: 'オランダ',
+                    PL: 'ポーランド',
+                    RO: 'ルーマニア',
+                    RS: 'セルビア',
+                    SE: 'スウェーデン',
+                    SI: 'スロベニア',
+                    SK: 'スロバキア',
+                    SM: 'サン·マリノ',
+                    TH: 'タイ国',
+                    TR: 'トルコ',
+                    ZA: '南アフリカ'
+                }
+            },
+            identical: {
+                'default': '同じ値を入力してください'
+            },
+            imei: {
+                'default': '有効なIMEIを入力してください'
+            },
+            imo: {
+                'default': '有効なIMOを入力してください'
+            },
+            integer: {
+                'default': '有効な数値を入力してください'
+            },
+            ip: {
+                'default': '有効なIPアドレスを入力してください',
+                ipv4: '有効なIPv4アドレスを入力してください',
+                ipv6: '有効なIPv6アドレスを入力してください'
+            },
+            isbn: {
+                'default': '有効なISBN番号を入力してください'
+            },
+            isin: {
+                'default': '有効なISIN番号を入力してください'
+            },
+            ismn: {
+                'default': '有効なISMN番号を入力してください'
+            },
+            issn: {
+                'default': '有効なISSN番号を入力してください'
+            },
+            lessThan: {
+                'default': '%s未満の値を入力してください',
+                notInclusive: '%s未満の値を入力してください'
+            },
+            mac: {
+                'default': '有効なMACアドレスを入力してください'
+            },
+            meid: {
+                'default': '有効なMEID番号を入力してください'
+            },
+            notEmpty: {
+                'default': '値を入力してください'
+            },
+            numeric: {
+                'default': '有効な浮動小数点数値を入力してください。'
+            },
+            phone: {
+                'default': '有効な電話番号を入力してください',
+                country: '有効な%sの電話番号を入力してください',
+                countries: {
+                    AE: 'アラブ首長国連邦',
+                    BG: 'ブルガリア',
+                    BR: 'ブラジル',
+                    CN: 'チャイナ',
+                    CZ: 'チェコ共和国',
+                    DE: 'ドイツ',
+                    DK: 'デンマーク',
+                    ES: 'スペイン',
+                    FR: 'フランス',
+                    GB: 'イギリス',
+                    IN: 'インド',
+                    MA: 'モロッコ',
+                    NL: 'オランダ',
+                    PK: 'パキスタン',
+                    RO: 'ルーマニア',
+                    RU: 'ロシア',
+                    SK: 'スロバキア',
+                    TH: 'タイ国',
+                    US: 'アメリカ',
+                    VE: 'ベネズエラ'
+                }
+            },
+            promise: {
+                'default': '有効な値を入力してください'
+            },
+            regexp: {
+                'default': '正規表現に一致する値を入力してください'
+            },
+            remote: {
+                'default': '有効な値を入力してください。'
+            },
+            rtn: {
+                'default': '有効なRTN番号を入力してください'
+            },
+            sedol: {
+                'default': '有効なSEDOL番号を入力してください'
+            },
+            siren: {
+                'default': '有効なSIREN番号を入力してください'
+            },
+            siret: {
+                'default': '有効なSIRET番号を入力してください'
+            },
+            step: {
+                'default': '%sの有効なステップを入力してください'
+            },
+            stringCase: {
+                'default': '小文字のみで入力してください',
+                upper: '大文字のみで入力してください'
+            },
+            stringLength: {
+                'default': '有効な長さの値を入力してください',
+                less: '%s文字未満で入力してください',
+                more: '%s文字より大きく入力してください',
+                between: '%s文字から%s文字の間で入力してください'
+            },
+            uri: {
+                'default': '有効なURIを入力してください。'
+            },
+            uuid: {
+                'default': '有効なUUIDを入力してください',
+                version: '有効なバージョン%s UUIDを入力してください'
+            },
+            vat: {
+                'default': '有効なVAT番号を入力してください',
+                country: '有効な%sのVAT番号を入力してください',
+                countries: {
+                    AT: 'オーストリア',
+                    BE: 'ベルギー',
+                    BG: 'ブルガリア',
+                    BR: 'ブラジル',
+                    CH: 'スイス',
+                    CY: 'キプロス等',
+                    CZ: 'チェコ共和国',
+                    DE: 'ドイツ',
+                    DK: 'デンマーク',
+                    EE: 'エストニア',
+                    ES: 'スペイン',
+                    FI: 'フィンランド',
+                    FR: 'フランス',
+                    GB: 'イギリス',
+                    GR: 'ギリシャ',
+                    EL: 'ギリシャ',
+                    HU: 'ハンガリー',
+                    HR: 'クロアチア',
+                    IE: 'アイルランド',
+                    IS: 'アイスランド',
+                    IT: 'イタリア',
+                    LT: 'リトアニア',
+                    LU: 'ルクセンブルグ',
+                    LV: 'ラトビア',
+                    MT: 'マルタ',
+                    NL: 'オランダ',
+                    NO: 'ノルウェー',
+                    PL: 'ポーランド',
+                    PT: 'ポルトガル',
+                    RO: 'ルーマニア',
+                    RU: 'ロシア',
+                    RS: 'セルビア',
+                    SE: 'スウェーデン',
+                    SI: 'スロベニア',
+                    SK: 'スロバキア',
+                    VE: 'ベネズエラ',
+                    ZA: '南アフリカ'
+                }
+            },
+            vin: {
+                'default': '有効なVIN番号を入力してください'
+            },
+            zipCode: {
+                'default': '有効な郵便番号を入力してください',
+                country: '有効な%sの郵便番号を入力してください',
+                countries: {
+                    AT: 'オーストリア',
+                    BG: 'ブルガリア',
+                    BR: 'ブラジル',
+                    CA: 'カナダ',
+                    CH: 'スイス',
+                    CZ: 'チェコ共和国',
+                    DE: 'ドイツ',
+                    DK: 'デンマーク',
+                    ES: 'スペイン',
+                    FR: 'フランス',
+                    GB: 'イギリス',
+                    IE: 'アイルランド',
+                    IN: 'インド',
+                    IT: 'イタリア',
+                    MA: 'モロッコ',
+                    NL: 'オランダ',
+                    PL: 'ポーランド',
+                    PT: 'ポルトガル',
+                    RO: 'ルーマニア',
+                    RU: 'ロシア',
+                    SE: 'スウェーデン',
+                    SG: 'シンガポール',
+                    SK: 'スロバキア',
+                    US: 'アメリカ'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/nl_BE.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Belgium (Dutch) language package
+     * Translated by @dokterpasta. Improved by @jdt
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'nl_BE': {
+            base64: {
+                'default': 'Geef een geldige base 64 geëncodeerde tekst in'
+            },
+            between: {
+                'default': 'Geef een waarde in van %s tot en met %s',
+                notInclusive: 'Geef een waarde in van %s tot %s'
+            },
+            bic: {
+                'default': 'Geef een geldig BIC-nummer in'
+            },
+            callback: {
+                'default': 'Geef een geldige waarde in'
+            },
+            choice: {
+                'default': 'Geef een geldige waarde in',
+                less: 'Kies minimaal %s opties',
+                more: 'Kies maximaal %s opties',
+                between: 'Kies tussen de %s en %s opties'
+            },
+            color: {
+                'default': 'Geef een geldige kleurcode in'
+            },
+            creditCard: {
+                'default': 'Geef een geldig kredietkaartnummer in'
+            },
+            cusip: {
+                'default': 'Geef een geldig CUSIP-nummer in'
+            },
+            cvv: {
+                'default': 'Geef een geldig CVV-nummer in'
+            },
+            date: {
+                'default': 'Geef een geldige datum in',
+                min: 'Geef een datum in die na %s ligt',
+                max: 'Geef een datum in die voor %s ligt',
+                range: 'Geef een datum in die tussen %s en %s ligt'
+            },
+            different: {
+                'default': 'Geef een andere waarde in'
+            },
+            digits: {
+                'default': 'Geef alleen cijfers in'
+            },
+            ean: {
+                'default': 'Geef een geldig EAN-nummer in'
+            },
+            ein: {
+                'default': 'Geef een geldig EIN-nummer in'
+            },
+            emailAddress: {
+                'default': 'Geef een geldig emailadres op'
+            },
+            file: {
+                'default': 'Kies een geldig bestand'
+            },
+            greaterThan: {
+                'default': 'Geef een waarde in die gelijk is aan of groter is dan %s',
+                notInclusive: 'Geef een waarde in die groter is dan %s'
+            },
+            grid: {
+                'default': 'Geef een geldig GRID-nummer in'
+            },
+            hex: {
+                'default': 'Geef een geldig hexadecimaal nummer in'
+            },
+            iban: {
+                'default': 'Geef een geldig IBAN-nummer in',
+                country: 'Geef een geldig IBAN-nummer in uit %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Verenigde Arabische Emiraten',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Oostenrijk',
+                    AZ: 'Azerbeidzjan',
+                    BA: 'Bosnië en Herzegovina',
+                    BE: 'België',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgarije"',
+                    BH: 'Bahrein',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazilië',
+                    CH: 'Zwitserland',
+                    CI: 'Ivoorkust',
+                    CM: 'Kameroen',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Cyprus',
+                    CZ: 'Tsjechische',
+                    DE: 'Duitsland',
+                    DK: 'Denemarken',
+                    DO: 'Dominicaanse Republiek',
+                    DZ: 'Algerije',
+                    EE: 'Estland',
+                    ES: 'Spanje',
+                    FI: 'Finland',
+                    FO: 'Faeröer',
+                    FR: 'Frankrijk',
+                    GB: 'Verenigd Koninkrijk',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Groenland',
+                    GR: 'Griekenland',
+                    GT: 'Guatemala',
+                    HR: 'Kroatië',
+                    HU: 'Hongarije',
+                    IE: 'Ierland',
+                    IL: 'Israël',
+                    IR: 'Iran',
+                    IS: 'IJsland',
+                    IT: 'Italië',
+                    JO: 'Jordan',
+                    KW: 'Koeweit',
+                    KZ: 'Kazachstan',
+                    LB: 'Libanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Litouwen',
+                    LU: 'Luxemburg',
+                    LV: 'Letland',
+                    MC: 'Monaco',
+                    MD: 'Moldavië',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonië',
+                    ML: 'Mali',
+                    MR: 'Mauretanië',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Nederland',
+                    NO: 'Noorwegen',
+                    PK: 'Pakistan',
+                    PL: 'Polen',
+                    PS: 'Palestijnse',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Roemenië',
+                    RS: 'Servië',
+                    SA: 'Saudi-Arabië',
+                    SE: 'Zweden',
+                    SI: 'Slovenië',
+                    SK: 'Slowakije',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Oost-Timor',
+                    TN: 'Tunesië',
+                    TR: 'Turkije',
+                    VG: 'Britse Maagdeneilanden',
+                    XK: 'Republiek Kosovo'
+                }
+            },
+            id: {
+                'default': 'Geef een geldig identificatienummer in',
+                country: 'Geef een geldig identificatienummer in uit %s',
+                countries: {
+                    BA: 'Bosnië en Herzegovina',
+                    BG: 'Bulgarije',
+                    BR: 'Brazilië',
+                    CH: 'Zwitserland',
+                    CL: 'Chili',
+                    CN: 'China',
+                    CZ: 'Tsjechische',
+                    DK: 'Denemarken',
+                    EE: 'Estland',
+                    ES: 'Spanje',
+                    FI: 'Finland',
+                    HR: 'Kroatië',
+                    IE: 'Ierland',
+                    IS: 'IJsland',
+                    LT: 'Litouwen',
+                    LV: 'Letland',
+                    ME: 'Montenegro',
+                    MK: 'Macedonië',
+                    NL: 'Nederland',
+                    PL: 'Polen',
+                    RO: 'Roemenië',
+                    RS: 'Servië',
+                    SE: 'Zweden',
+                    SI: 'Slovenië',
+                    SK: 'Slowakije',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Turkije',
+                    ZA: 'Zuid-Afrika'
+                }
+            },
+            identical: {
+                'default': 'Geef dezelfde waarde in'
+            },
+            imei: {
+                'default': 'Geef een geldig IMEI-nummer in'
+            },
+            imo: {
+                'default': 'Geef een geldig IMO-nummer in'
+            },
+            integer: {
+                'default': 'Geef een geldig nummer in'
+            },
+            ip: {
+                'default': 'Geef een geldig IP-adres in',
+                ipv4: 'Geef een geldig IPv4-adres in',
+                ipv6: 'Geef een geldig IPv6-adres in'
+            },
+            isbn: {
+                'default': 'Geef een geldig ISBN-nummer in'
+            },
+            isin: {
+                'default': 'Geef een geldig ISIN-nummer in'
+            },
+            ismn: {
+                'default': 'Geef een geldig ISMN-nummer in'
+            },
+            issn: {
+                'default': 'Geef een geldig ISSN-nummer in'
+            },
+            lessThan: {
+                'default': 'Geef een waarde in die gelijk is aan of kleiner is dan %s',
+                notInclusive: 'Geef een waarde in die kleiner is dan %s'
+            },
+            mac: {
+                'default': 'Geef een geldig MAC-adres in'
+            },
+            meid: {
+                'default': 'Geef een geldig MEID-nummer in'
+            },
+            notEmpty: {
+                'default': 'Geef een waarde in'
+            },
+            numeric: {
+                'default': 'Geef een geldig kommagetal in'
+            },
+            phone: {
+                'default': 'Geef een geldig telefoonnummer in',
+                country: 'Geef een geldig telefoonnummer in uit %s',
+                countries: {
+                    AE: 'Verenigde Arabische Emiraten',
+                    BG: 'Bulgarije',
+                    BR: 'Brazilië',
+                    CN: 'China',
+                    CZ: 'Tsjechische',
+                    DE: 'Duitsland',
+                    DK: 'Denemarken',
+                    ES: 'Spanje',
+                    FR: 'Frankrijk',
+                    GB: 'Verenigd Koninkrijk',
+                    IN: 'Indië',
+                    MA: 'Marokko',
+                    NL: 'Nederland',
+                    PK: 'Pakistan',
+                    RO: 'Roemenië',
+                    RU: 'Rusland',
+                    SK: 'Slowakije',
+                    TH: 'Thailand',
+                    US: 'VS',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Geef een geldige waarde in'
+            },
+            regexp: {
+                'default': 'Geef een waarde in die overeenkomt met het patroon'
+            },
+            remote: {
+                'default': 'Geef een geldige waarde in'
+            },
+            rtn: {
+                'default': 'Geef een geldig RTN-nummer in'
+            },
+            sedol: {
+                'default': 'Geef een geldig SEDOL-nummer in'
+            },
+            siren: {
+                'default': 'Geef een geldig SIREN-nummer in'
+            },
+            siret: {
+                'default': 'Geef een geldig SIRET-nummer in'
+            },
+            step: {
+                'default': 'Geef een geldig meervoud in van %s'
+            },
+            stringCase: {
+                'default': 'Geef enkel kleine letters in',
+                upper: 'Geef enkel hoofdletters in'
+            },
+            stringLength: {
+                'default': 'Geef een waarde in met de juiste lengte',
+                less: 'Geef minder dan %s karakters in',
+                more: 'Geef meer dan %s karakters in',
+                between: 'Geef tussen %s en %s karakters in'
+            },
+            uri: {
+                'default': 'Geef een geldige URI in'
+            },
+            uuid: {
+                'default': 'Geef een geldig UUID-nummer in',
+                version: 'Geef een geldig UUID-nummer (versie %s) in'
+            },
+            vat: {
+                'default': 'Geef een geldig BTW-nummer in',
+                country: 'Geef een geldig BTW-nummer in uit %s',
+                countries: {
+                    AT: 'Oostenrijk',
+                    BE: 'België',
+                    BG: 'Bulgarije',
+                    BR: 'Brazilië',
+                    CH: 'Zwitserland',
+                    CY: 'Cyprus',
+                    CZ: 'Tsjechische',
+                    DE: 'Duitsland',
+                    DK: 'Denemarken',
+                    EE: 'Estland',
+                    ES: 'Spanje',
+                    FI: 'Finland',
+                    FR: 'Frankrijk',
+                    GB: 'Verenigd Koninkrijk',
+                    GR: 'Griekenland',
+                    EL: 'Griekenland',
+                    HU: 'Hongarije',
+                    HR: 'Kroatië',
+                    IE: 'Ierland',
+                    IS: 'IJsland',
+                    IT: 'Italië',
+                    LT: 'Litouwen',
+                    LU: 'Luxemburg',
+                    LV: 'Letland',
+                    MT: 'Malta',
+                    NL: 'Nederland',
+                    NO: 'Noorwegen',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Roemenië',
+                    RU: 'Rusland',
+                    RS: 'Servië',
+                    SE: 'Zweden',
+                    SI: 'Slovenië',
+                    SK: 'Slowakije',
+                    VE: 'Venezuela',
+                    ZA: 'Zuid-Afrika'
+                }
+            },
+            vin: {
+                'default': 'Geef een geldig VIN-nummer in'
+            },
+            zipCode: {
+                'default': 'Geef een geldige postcode in',
+                country: 'Geef een geldige postcode in uit %s',
+                countries: {
+                    AT: 'Oostenrijk',
+                    BG: 'Bulgarije',
+                    BR: 'Brazilië',
+                    CA: 'Canada',
+                    CH: 'Zwitserland',
+                    CZ: 'Tsjechische',
+                    DE: 'Duitsland',
+                    DK: 'Denemarken',
+                    ES: 'Spanje',
+                    FR: 'Frankrijk',
+                    GB: 'Verenigd Koninkrijk',
+                    IE: 'Ierland',
+                    IN: 'Indië',
+                    IT: 'Italië',
+                    MA: 'Marokko',
+                    NL: 'Nederland',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Roemenië',
+                    RU: 'Rusland',
+                    SE: 'Zweden',
+                    SG: 'Singapore',
+                    SK: 'Slowakije',
+                    US: 'VS'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/nl_NL.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * The Dutch language package
+     * Translated by @jvanderheide
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'nl_NL': {
+            base64: {
+                'default': 'Voer een geldige Base64 geëncodeerde tekst in'
+            },
+            between: {
+                'default': 'Voer een waarde in van %s tot en met %s',
+                notInclusive: 'Voer een waarde die tussen %s en %s ligt'
+            },
+            bic: {
+                'default': 'Voer een geldige BIC-code in'
+            },
+            callback: {
+                'default': 'Voer een geldige waarde in'
+            },
+            choice: {
+                'default': 'Voer een geldige waarde in',
+                less: 'Kies minimaal %s optie(s)',
+                more: 'Kies maximaal %s opties',
+                between: 'Kies tussen de %s - %s opties'
+            },
+            color: {
+                'default': 'Voer een geldige kleurcode in'
+            },
+            creditCard: {
+                'default': 'Voer een geldig creditcardnummer in'
+            },
+            cusip: {
+                'default': 'Voer een geldig CUSIP-nummer in'
+            },
+            cvv: {
+                'default': 'Voer een geldig CVV-nummer in'
+            },
+            date: {
+                'default': 'Voer een geldige datum in',
+                min: 'Voer een datum in die na %s ligt',
+                max: 'Voer een datum in die vóór %s ligt',
+                range: 'Voer een datum in die tussen %s en %s ligt'
+            },
+            different: {
+                'default': 'Voer een andere waarde in'
+            },
+            digits: {
+                'default': 'Voer enkel cijfers in'
+            },
+            ean: {
+                'default': 'Voer een geldige EAN-code in'
+            },
+            ein: {
+                'default': 'Voer een geldige EIN-code in'
+            },
+            emailAddress: {
+                'default': 'Voer een geldig e-mailadres in'
+            },
+            file: {
+                'default': 'Kies een geldig bestand'
+            },
+            greaterThan: {
+                'default': 'Voer een waarde in die gelijk is aan of groter is dan %s',
+                notInclusive: 'Voer een waarde in die is groter dan %s'
+            },
+            grid: {
+                'default': 'Voer een geldig GRId-nummer in'
+            },
+            hex: {
+                'default': 'Voer een geldig hexadecimaal nummer in'
+            },
+            iban: {
+                'default': 'Voer een geldig IBAN nummer in',
+                country: 'Voer een geldig IBAN nummer in uit %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Verenigde Arabische Emiraten',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Oostenrijk',
+                    AZ: 'Azerbeidzjan',
+                    BA: 'Bosnië en Herzegovina',
+                    BE: 'België',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgarije"',
+                    BH: 'Bahrein',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazilië',
+                    CH: 'Zwitserland',
+                    CI: 'Ivoorkust',
+                    CM: 'Kameroen',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Cyprus',
+                    CZ: 'Tsjechische Republiek',
+                    DE: 'Duitsland',
+                    DK: 'Denemarken',
+                    DO: 'Dominicaanse Republiek',
+                    DZ: 'Algerije',
+                    EE: 'Estland',
+                    ES: 'Spanje',
+                    FI: 'Finland',
+                    FO: 'Faeröer',
+                    FR: 'Frankrijk',
+                    GB: 'Verenigd Koninkrijk',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Groenland',
+                    GR: 'Griekenland',
+                    GT: 'Guatemala',
+                    HR: 'Kroatië',
+                    HU: 'Hongarije',
+                    IE: 'Ierland',
+                    IL: 'Israël',
+                    IR: 'Iran',
+                    IS: 'IJsland',
+                    IT: 'Italië',
+                    JO: 'Jordan',
+                    KW: 'Koeweit',
+                    KZ: 'Kazachstan',
+                    LB: 'Libanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Litouwen',
+                    LU: 'Luxemburg',
+                    LV: 'Letland',
+                    MC: 'Monaco',
+                    MD: 'Moldavië',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonië',
+                    ML: 'Mali',
+                    MR: 'Mauretanië',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Nederland',
+                    NO: 'Noorwegen',
+                    PK: 'Pakistan',
+                    PL: 'Polen',
+                    PS: 'Palestijnse',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Roemenië',
+                    RS: 'Servië',
+                    SA: 'Saudi-Arabië',
+                    SE: 'Zweden',
+                    SI: 'Slovenië',
+                    SK: 'Slowakije',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Oost-Timor',
+                    TN: 'Tunesië',
+                    TR: 'Turkije',
+                    VG: 'Britse Maagdeneilanden',
+                    XK: 'Republiek Kosovo'
+                }
+            },
+            id: {
+                'default': 'Voer een geldig identificatie nummer in',
+                country: 'Voer een geldig identificatie nummer in uit %s',
+                countries: {
+                    BA: 'Bosnië en Herzegovina',
+                    BG: 'Bulgarije',
+                    BR: 'Brazilië',
+                    CH: 'Zwitserland',
+                    CL: 'Chili',
+                    CN: 'China',
+                    CZ: 'Tsjechische Republiek',
+                    DK: 'Denemarken',
+                    EE: 'Estland',
+                    ES: 'Spanje',
+                    FI: 'Finland',
+                    HR: 'Kroatië',
+                    IE: 'Ierland',
+                    IS: 'IJsland',
+                    LT: 'Litouwen',
+                    LV: 'Letland',
+                    ME: 'Montenegro',
+                    MK: 'Macedonië',
+                    NL: 'Nederland',
+                    PL: 'Polen',
+                    RO: 'Roemenië',
+                    RS: 'Servië',
+                    SE: 'Zweden',
+                    SI: 'Slovenië',
+                    SK: 'Slowakije',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Turkije',
+                    ZA: 'Zuid-Afrika'
+                }
+            },
+            identical: {
+                'default': 'Voer dezelfde waarde in'
+            },
+            imei: {
+                'default': 'Voer een geldig IMEI-nummer in'
+            },
+            imo: {
+                'default': 'Voer een geldig IMO-nummer in'
+            },
+            integer: {
+                'default': 'Voer een geldig getal in'
+            },
+            ip: {
+                'default': 'Voer een geldig IP adres in',
+                ipv4: 'Voer een geldig IPv4 adres in',
+                ipv6: 'Voer een geldig IPv6 adres in'
+            },
+            isbn: {
+                'default': 'Voer een geldig ISBN-nummer in'
+            },
+            isin: {
+                'default': 'Voer een geldig ISIN-nummer in'
+            },
+            ismn: {
+                'default': 'Voer een geldig ISMN-nummer in'
+            },
+            issn: {
+                'default': 'Voer een geldig ISSN-nummer in'
+            },
+            lessThan: {
+                'default': 'Voer een waarde in gelijk aan of kleiner dan %s',
+                notInclusive: 'Voer een waarde in kleiner dan %s'
+            },
+            mac: {
+                'default': 'Voer een geldig MAC adres in'
+            },
+            meid: {
+                'default': 'Voer een geldig MEID-nummer in'
+            },
+            notEmpty: {
+                'default': 'Voer een waarde in'
+            },
+            numeric: {
+                'default': 'Voer een geldig kommagetal in'
+            },
+            phone: {
+                'default': 'Voer een geldig telefoonnummer in',
+                country: 'Voer een geldig telefoonnummer in uit %s',
+                countries: {
+                    AE: 'Verenigde Arabische Emiraten',
+                    BG: 'Bulgarije',
+                    BR: 'Brazilië',
+                    CN: 'China',
+                    CZ: 'Tsjechische Republiek',
+                    DE: 'Duitsland',
+                    DK: 'Denemarken',
+                    ES: 'Spanje',
+                    FR: 'Frankrijk',
+                    GB: 'Verenigd Koninkrijk',
+                    IN: 'Indië',
+                    MA: 'Marokko',
+                    NL: 'Nederland',
+                    PK: 'Pakistan',
+                    RO: 'Roemenië',
+                    RU: 'Rusland',
+                    SK: 'Slowakije',
+                    TH: 'Thailand',
+                    US: 'VS',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Voer een geldige waarde in'
+            },
+            regexp: {
+                'default': 'Voer een waarde in die overeenkomt met het patroon'
+            },
+            remote: {
+                'default': 'Voer een geldige waarde in'
+            },
+            rtn: {
+                'default': 'Voer een geldig RTN-nummer in'
+            },
+            sedol: {
+                'default': 'Voer een geldig SEDOL-nummer in'
+            },
+            siren: {
+                'default': 'Voer een geldig SIREN-nummer in'
+            },
+            siret: {
+                'default': 'Voer een geldig SIRET-nummer in'
+            },
+            step: {
+                'default': 'Voer een meervoud van %s in'
+            },
+            stringCase: {
+                'default': 'Voer enkel kleine letters in',
+                upper: 'Voer enkel hoofdletters in'
+            },
+            stringLength: {
+                'default': 'Voer een waarde met de juiste lengte in',
+                less: 'Voer minder dan %s karakters in',
+                more: 'Voer meer dan %s karakters in',
+                between: 'Voer tussen tussen %s en %s karakters in'
+            },
+            uri: {
+                'default': 'Voer een geldige link in'
+            },
+            uuid: {
+                'default': 'Voer een geldige UUID in',
+                version: 'Voer een geldige UUID (versie %s) in'
+            },
+            vat: {
+                'default': 'Voer een geldig BTW-nummer in',
+                country: 'Voer een geldig BTW-nummer in uit %s',
+                countries: {
+                    AT: 'Oostenrijk',
+                    BE: 'België',
+                    BG: 'Bulgarije',
+                    BR: 'Brazilië',
+                    CH: 'Zwitserland',
+                    CY: 'Cyprus',
+                    CZ: 'Tsjechische Republiek',
+                    DE: 'Duitsland',
+                    DK: 'Denemarken',
+                    EE: 'Estland',
+                    ES: 'Spanje',
+                    FI: 'Finland',
+                    FR: 'Frankrijk',
+                    GB: 'Verenigd Koninkrijk',
+                    GR: 'Griekenland',
+                    EL: 'Griekenland',
+                    HU: 'Hongarije',
+                    HR: 'Kroatië',
+                    IE: 'Ierland',
+                    IS: 'IJsland',
+                    IT: 'Italië',
+                    LT: 'Litouwen',
+                    LU: 'Luxemburg',
+                    LV: 'Letland',
+                    MT: 'Malta',
+                    NL: 'Nederland',
+                    NO: 'Noorwegen',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Roemenië',
+                    RU: 'Rusland',
+                    RS: 'Servië',
+                    SE: 'Zweden',
+                    SI: 'Slovenië',
+                    SK: 'Slowakije',
+                    VE: 'Venezuela',
+                    ZA: 'Zuid-Afrika'
+                }
+            },
+            vin: {
+                'default': 'Voer een geldig VIN-nummer in'
+            },
+            zipCode: {
+                'default': 'Voer een geldige postcode in',
+                country: 'Voer een geldige postcode in uit %s',
+                countries: {
+                    AT: 'Oostenrijk',
+                    BG: 'Bulgarije',
+                    BR: 'Brazilië',
+                    CA: 'Canada',
+                    CH: 'Zwitserland',
+                    CZ: 'Tsjechische Republiek',
+                    DE: 'Duitsland',
+                    DK: 'Denemarken',
+                    ES: 'Spanje',
+                    FR: 'Frankrijk',
+                    GB: 'Verenigd Koninkrijk',
+                    IE: 'Ierland',
+                    IN: 'Indië',
+                    IT: 'Italië',
+                    MA: 'Marokko',
+                    NL: 'Nederland',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Roemenië',
+                    RU: 'Rusland',
+                    SE: 'Zweden',
+                    SG: 'Singapore',
+                    SK: 'Slowakije',
+                    US: 'VS'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/no_NO.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Norwegian language package
+     * Translated by @trondulseth
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'no_NO': {
+            base64: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig base64-kodet verdi'
+            },
+            between: {
+                'default': 'Vennligst fyll ut dette feltet med en verdi mellom %s og %s',
+                notInclusive: 'Vennligst tast inn kun en verdi mellom %s og %s'
+            },
+            bic: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig BIC-nummer'
+            },
+            callback: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig verdi'
+            },
+            choice: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig verdi',
+                less: 'Vennligst velg minst %s valgmuligheter',
+                more: 'Vennligst velg maks %s valgmuligheter',
+                between: 'Vennligst velg %s - %s valgmuligheter'
+            },
+            color: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig'
+            },
+            creditCard: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig kreditkortnummer'
+            },
+            cusip: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig CUSIP-nummer'
+            },
+            cvv: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig CVV-nummer'
+            },
+            date: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig dato',
+                min: 'Vennligst fyll ut dette feltet med en gyldig dato etter %s',
+                max: 'Vennligst fyll ut dette feltet med en gyldig dato før %s',
+                range: 'Vennligst fyll ut dette feltet med en gyldig dato mellom %s - %s'
+            },
+            different: {
+                'default': 'Vennligst fyll ut dette feltet med en annen verdi'
+            },
+            digits: {
+                'default': 'Vennligst tast inn kun sifre'
+            },
+            ean: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig EAN-nummer'
+            },
+            ein: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig EIN-nummer'
+            },
+            emailAddress: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig epostadresse'
+            },
+            file: {
+                'default': 'Velg vennligst en gyldig fil'
+            },
+            greaterThan: {
+                'default': 'Vennligst fyll ut dette feltet med en verdi større eller lik %s',
+                notInclusive: 'Vennligst fyll ut dette feltet med en verdi større enn %s'
+            },
+            grid: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig GRIDnummer'
+            },
+            hex: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig hexadecimalt nummer'
+            },
+            iban: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig IBAN-nummer',
+                country: 'Vennligst fyll ut dette feltet med et gyldig IBAN-nummer i %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'De Forente Arabiske Emirater',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Østerrike',
+                    AZ: 'Aserbajdsjan',
+                    BA: 'Bosnia-Hercegovina',
+                    BE: 'Belgia',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasil',
+                    CH: 'Sveits',
+                    CI: 'Elfenbenskysten',
+                    CM: 'Kamerun',
+                    CR: 'Costa Rica',
+                    CV: 'Kapp Verde',
+                    CY: 'Kypros',
+                    CZ: 'Tsjekkia',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    DO: 'Den dominikanske republikk',
+                    DZ: 'Algerie',
+                    EE: 'Estland',
+                    ES: 'Spania',
+                    FI: 'Finland',
+                    FO: 'Færøyene',
+                    FR: 'Frankrike',
+                    GB: 'Storbritannia',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Grønland',
+                    GR: 'Hellas',
+                    GT: 'Guatemala',
+                    HR: 'Kroatia',
+                    HU: 'Ungarn',
+                    IE: 'Irland',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Island',
+                    IT: 'Italia',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Kasakhstan',
+                    LB: 'Libanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Litauen',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MC: 'Monaco',
+                    MD: 'Moldova',
+                    ME: 'Montenegro',
+                    MG: 'Madagaskar',
+                    MK: 'Makedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mosambik',
+                    NL: 'Nederland',
+                    NO: 'Norge',
+                    PK: 'Pakistan',
+                    PL: 'Polen',
+                    PS: 'Palestina',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SA: 'Saudi-Arabia',
+                    SE: 'Sverige',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'øst-Timor',
+                    TN: 'Tunisia',
+                    TR: 'Tyrkia',
+                    VG: 'De Britiske Jomfruøyene',
+                    XK: 'Republikken Kosovo'
+                }
+            },
+            id: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig identifikasjons-nummer',
+                country: 'Vennligst fyll ut dette feltet med et gyldig identifikasjons-nummer i %s',
+                countries: {
+                    BA: 'Bosnien-Hercegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CH: 'Sveits',
+                    CL: 'Chile',
+                    CN: 'Kina',
+                    CZ: 'Tsjekkia',
+                    DK: 'Danmark',
+                    EE: 'Estland',
+                    ES: 'Spania',
+                    FI: 'Finland',
+                    HR: 'Kroatia',
+                    IE: 'Irland',
+                    IS: 'Island',
+                    LT: 'Litauen',
+                    LV: 'Latvia',
+                    ME: 'Montenegro',
+                    MK: 'Makedonia',
+                    NL: 'Nederland',
+                    PL: 'Polen',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Sverige',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Tyrkia',
+                    ZA: 'Sør-Afrika'
+                }
+            },
+            identical: {
+                'default': 'Vennligst fyll ut dette feltet med den samme verdi'
+            },
+            imei: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig IMEI-nummer'
+            },
+            imo: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig IMO-nummer'
+            },
+            integer: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig tall'
+            },
+            ip: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig IP adresse',
+                ipv4: 'Vennligst fyll ut dette feltet med en gyldig IPv4 adresse',
+                ipv6: 'Vennligst fyll ut dette feltet med en gyldig IPv6 adresse'
+            },
+            isbn: {
+                'default': 'Vennligst fyll ut dette feltet med ett gyldig ISBN-nummer'
+            },
+            isin: {
+                'default': 'Vennligst fyll ut dette feltet med ett gyldig ISIN-nummer'
+            },
+            ismn: {
+                'default': 'Vennligst fyll ut dette feltet med ett gyldig ISMN-nummer'
+            },
+            issn: {
+                'default': 'Vennligst fyll ut dette feltet med ett gyldig ISSN-nummer'
+            },
+            lessThan: {
+                'default': 'Vennligst fyll ut dette feltet med en verdi mindre eller lik %s',
+                notInclusive: 'Vennligst fyll ut dette feltet med en verdi mindre enn %s'
+            },
+            mac: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig MAC adresse'
+            },
+            meid: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig MEID-nummer'
+            },
+            notEmpty: {
+                'default': 'Vennligst fyll ut dette feltet'
+            },
+            numeric: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig flytende desimaltall'
+            },
+            phone: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig telefonnummer',
+                country: 'Vennligst fyll ut dette feltet med et gyldig telefonnummer i %s',
+                countries: {
+                    AE: 'De Forente Arabiske Emirater',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CN: 'Kina',
+                    CZ: 'Tsjekkia',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    ES: 'Spania',
+                    FR: 'Frankrike',
+                    GB: 'Storbritannia',
+                    IN: 'India',
+                    MA: 'Marokko',
+                    NL: 'Nederland',
+                    PK: 'Pakistan',
+                    RO: 'Rumenia',
+                    RU: 'Russland',
+                    SK: 'Slovakia',
+                    TH: 'Thailand',
+                    US: 'USA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig verdi'
+            },
+            regexp: {
+                'default': 'Vennligst fyll ut dette feltet med en verdi som matcher mønsteret'
+            },
+            remote: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig verdi'
+            },
+            rtn: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig RTN-nummer'
+            },
+            sedol: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig SEDOL-nummer'
+            },
+            siren: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig SIREN-nummer'
+            },
+            siret: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig SIRET-nummer'
+            },
+            step: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig trinn av %s'
+            },
+            stringCase: {
+                'default': 'Venligst fyll inn dette feltet kun med små bokstaver',
+                upper: 'Venligst fyll inn dette feltet kun med store bokstaver'
+            },
+            stringLength: {
+                'default': 'Vennligst fyll ut dette feltet med en verdi av gyldig lengde',
+                less: 'Vennligst fyll ut dette feltet med mindre enn %s tegn',
+                more: 'Vennligst fyll ut dette feltet med mer enn %s tegn',
+                between: 'Vennligst fyll ut dette feltet med en verdi mellom %s og %s tegn'
+            },
+            uri: {
+                'default': 'Vennligst fyll ut dette feltet med en gyldig URI'
+            },
+            uuid: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig UUID-nummer',
+                version: 'Vennligst fyll ut dette feltet med en gyldig UUID version %s-nummer'
+            },
+            vat: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig MVA nummer',
+                country: 'Vennligst fyll ut dette feltet med et gyldig MVA nummer i %s',
+                countries: {
+                    AT: 'Østerrike',
+                    BE: 'Belgia',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CH: 'Schweiz',
+                    CY: 'Cypern',
+                    CZ: 'Tsjekkia',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    EE: 'Estland',
+                    ES: 'Spania',
+                    FI: 'Finland',
+                    FR: 'Frankrike',
+                    GB: 'Storbritania',
+                    GR: 'Hellas',
+                    EL: 'Hellas',
+                    HU: 'Ungarn',
+                    HR: 'Kroatia',
+                    IE: 'Irland',
+                    IS: 'Island',
+                    IT: 'Italia',
+                    LT: 'Litauen',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MT: 'Malta',
+                    NL: 'Nederland',
+                    NO: 'Norge',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Russland',
+                    RS: 'Serbia',
+                    SE: 'Sverige',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    VE: 'Venezuela',
+                    ZA: 'Sør-Afrika'
+                }
+            },
+            vin: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig VIN-nummer'
+            },
+            zipCode: {
+                'default': 'Vennligst fyll ut dette feltet med et gyldig postnummer',
+                country: 'Vennligst fyll ut dette feltet med et gyldig postnummer i %s',
+                countries: {
+                    AT: 'Østerrike',
+                    BG: 'Bulgaria',
+                    BR: 'Brasil',
+                    CA: 'Canada',
+                    CH: 'Schweiz',
+                    CZ: 'Tsjekkia',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    ES: 'Spania',
+                    FR: 'Frankrike',
+                    GB: 'Storbritannia',
+                    IE: 'Irland',
+                    IN: 'India',
+                    IT: 'Italia',
+                    MA: 'Marokko',
+                    NL: 'Nederland',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Romania',
+                    RU: 'Russland',
+                    SE: 'Sverige',
+                    SG: 'Singapore',
+                    SK: 'Slovakia',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/pl_PL.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Polish language package
+     * Translated by @grzesiek
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'pl_PL': {
+            base64: {
+                'default': 'Wpisz poprawny ciąg znaków zakodowany w base 64'
+            },
+            between: {
+                'default': 'Wprowadź wartość pomiędzy %s i %s',
+                notInclusive: 'Wprowadź wartość pomiędzy %s i %s (zbiór otwarty)'
+            },
+            bic: {
+                'default': 'Wprowadź poprawny numer BIC'
+            },
+            callback: {
+                'default': 'Wprowadź poprawną wartość'
+            },
+            choice: {
+                'default': 'Wprowadź poprawną wartość',
+                less: 'Wybierz przynajmniej %s opcji',
+                more: 'Wybierz maksymalnie %s opcji',
+                between: 'Wybierz przynajmniej %s i maksymalnie %s opcji'
+            },
+            color: {
+                'default': 'Wprowadź poprawny kolor w formacie'
+            },
+            creditCard: {
+                'default': 'Wprowadź poprawny numer karty kredytowej'
+            },
+            cusip: {
+                'default': 'Wprowadź poprawny numer CUSIP'
+            },
+            cvv: {
+                'default': 'Wprowadź poprawny numer CVV'
+            },
+            date: {
+                'default': 'Wprowadź poprawną datę',
+                min: 'Wprowadź datę po %s',
+                max: 'Wprowadź datę przed  %s',
+                range: 'Wprowadź datę pomiędzy %s i %s'
+            },
+            different: {
+                'default': 'Wprowadź inną wartość'
+            },
+            digits: {
+                'default': 'Wprowadź tylko cyfry'
+            },
+            ean: {
+                'default': 'Wprowadź poprawny numer EAN'
+            },
+            ein: {
+                'default': 'Wprowadź poprawny numer EIN'
+            },
+            emailAddress: {
+                'default': 'Wprowadź poprawny adres e-mail'
+            },
+            file: {
+                'default': 'Wybierz prawidłowy plik'
+            },
+            greaterThan: {
+                'default': 'Wprowadź wartość większą bądź równą %s',
+                notInclusive: 'Wprowadź wartość większą niż %s'
+            },
+            grid: {
+                'default': 'Wprowadź poprawny numer GRId'
+            },
+            hex: {
+                'default': 'Wprowadź poprawną liczbę w formacie heksadecymalnym'
+            },
+            iban: {
+                'default': 'Wprowadź poprawny numer IBAN',
+                country: 'Wprowadź poprawny numer IBAN w kraju %s',
+                countries: {
+                    AD: 'Andora',
+                    AE: 'Zjednoczone Emiraty Arabskie',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbejdżan',
+                    BA: 'Bośnia i Hercegowina',
+                    BE: 'Belgia',
+                    BF: 'Burkina Faso',
+                    BG: 'Bułgaria',
+                    BH: 'Bahrajn',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazylia',
+                    CH: 'Szwajcaria',
+                    CI: 'Wybrzeże Kości Słoniowej',
+                    CM: 'Kamerun',
+                    CR: 'Kostaryka',
+                    CV: 'Republika Zielonego Przylądka',
+                    CY: 'Cypr',
+                    CZ: 'Czechy',
+                    DE: 'Niemcy',
+                    DK: 'Dania',
+                    DO: 'Dominikana',
+                    DZ: 'Algeria',
+                    EE: 'Estonia',
+                    ES: 'Hiszpania',
+                    FI: 'Finlandia',
+                    FO: 'Wyspy Owcze',
+                    FR: 'Francja',
+                    GB: 'Wielka Brytania',
+                    GE: 'Gruzja',
+                    GI: 'Gibraltar',
+                    GL: 'Grenlandia',
+                    GR: 'Grecja',
+                    GT: 'Gwatemala',
+                    HR: 'Chorwacja',
+                    HU: 'Węgry',
+                    IE: 'Irlandia',
+                    IL: 'Izrael',
+                    IR: 'Iran',
+                    IS: 'Islandia',
+                    IT: 'Włochy',
+                    JO: 'Jordania',
+                    KW: 'Kuwejt',
+                    KZ: 'Kazahstan',
+                    LB: 'Liban',
+                    LI: 'Liechtenstein',
+                    LT: 'Litwa',
+                    LU: 'Luksemburg',
+                    LV: 'Łotwa',
+                    MC: 'Monako',
+                    MD: 'Mołdawia',
+                    ME: 'Czarnogóra',
+                    MG: 'Madagaskar',
+                    MK: 'Macedonia',
+                    ML: 'Mali',
+                    MR: 'Mauretania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambik',
+                    NL: 'Holandia',
+                    NO: 'Norwegia',
+                    PK: 'Pakistan',
+                    PL: 'Polska',
+                    PS: 'Palestyna',
+                    PT: 'Portugalia',
+                    QA: 'Katar',
+                    RO: 'Rumunia',
+                    RS: 'Serbia',
+                    SA: 'Arabia Saudyjska',
+                    SE: 'Szwecja',
+                    SI: 'Słowenia',
+                    SK: 'Słowacja',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timor Wschodni',
+                    TN: 'Tunezja',
+                    TR: 'Turcja',
+                    VG: 'Brytyjskie Wyspy Dziewicze',
+                    XK: 'Republika Kosowa'
+                }
+            },
+            id: {
+                'default': 'Wprowadź poprawny numer identyfikacyjny',
+                country: 'Wprowadź poprawny numer identyfikacyjny w kraju %s',
+                countries: {
+                    BA: 'Bośnia i Hercegowina',
+                    BG: 'Bułgaria',
+                    BR: 'Brazylia',
+                    CH: 'Szwajcaria',
+                    CL: 'Chile',
+                    CN: 'Chiny',
+                    CZ: 'Czechy',
+                    DK: 'Dania',
+                    EE: 'Estonia',
+                    ES: 'Hiszpania',
+                    FI: 'Finlandia',
+                    HR: 'Chorwacja',
+                    IE: 'Irlandia',
+                    IS: 'Islandia',
+                    LT: 'Litwa',
+                    LV: 'Łotwa',
+                    ME: 'Czarnogóra',
+                    MK: 'Macedonia',
+                    NL: 'Holandia',
+                    PL: 'Polska',
+                    RO: 'Rumunia',
+                    RS: 'Serbia',
+                    SE: 'Szwecja',
+                    SI: 'Słowenia',
+                    SK: 'Słowacja',
+                    SM: 'San Marino',
+                    TH: 'Tajlandia',
+                    TR: 'Turcja',
+                    ZA: 'Republika Południowej Afryki'
+                }
+            },
+            identical: {
+                'default': 'Wprowadź taką samą wartość'
+            },
+            imei: {
+                'default': 'Wprowadź poprawny numer IMEI'
+            },
+            imo: {
+                'default': 'Wprowadź poprawny numer IMO'
+            },
+            integer: {
+                'default': 'Wprowadź poprawną liczbę całkowitą'
+            },
+            ip: {
+                'default': 'Wprowadź poprawny adres IP',
+                ipv4: 'Wprowadź poprawny adres IPv4',
+                ipv6: 'Wprowadź poprawny adres IPv6'
+            },
+            isbn: {
+                'default': 'Wprowadź poprawny numer ISBN'
+            },
+            isin: {
+                'default': 'Wprowadź poprawny numer ISIN'
+            },
+            ismn: {
+                'default': 'Wprowadź poprawny numer ISMN'
+            },
+            issn: {
+                'default': 'Wprowadź poprawny numer ISSN'
+            },
+            lessThan: {
+                'default': 'Wprowadź wartość mniejszą bądź równą %s',
+                notInclusive: 'Wprowadź wartość mniejszą niż %s'
+            },
+            mac: {
+                'default': 'Wprowadź poprawny adres MAC'
+            },
+            meid: {
+                'default': 'Wprowadź poprawny numer MEID'
+            },
+            notEmpty: {
+                'default': 'Wprowadź wartość, pole nie może być puste'
+            },
+            numeric: {
+                'default': 'Wprowadź poprawną liczbę zmiennoprzecinkową'
+            },
+            phone: {
+                'default': 'Wprowadź poprawny numer telefonu',
+                country: 'Wprowadź poprawny numer telefonu w kraju %s',
+                countries: {
+                    AE: 'Zjednoczone Emiraty Arabskie',
+                    BG: 'Bułgaria',
+                    BR: 'Brazylia',
+                    CN: 'Chiny',
+                    CZ: 'Czechy',
+                    DE: 'Niemcy',
+                    DK: 'Dania',
+                    ES: 'Hiszpania',
+                    FR: 'Francja',
+                    GB: 'Wielka Brytania',
+                    IN: 'Indie',
+                    MA: 'Maroko',
+                    NL: 'Holandia',
+                    PK: 'Pakistan',
+                    RO: 'Rumunia',
+                    RU: 'Rosja',
+                    SK: 'Słowacja',
+                    TH: 'Tajlandia',
+                    US: 'USA',
+                    VE: 'Wenezuela'
+                }
+            },
+            promise: {
+                'default': 'Wprowadź poprawną wartość'
+            },
+            regexp: {
+                'default': 'Wprowadź wartość pasującą do wzoru'
+            },
+            remote: {
+                'default': 'Wprowadź poprawną wartość'
+            },
+            rtn: {
+                'default': 'Wprowadź poprawny numer RTN'
+            },
+            sedol: {
+                'default': 'Wprowadź poprawny numer SEDOL'
+            },
+            siren: {
+                'default': 'Wprowadź poprawny numer SIREN'
+            },
+            siret: {
+                'default': 'Wprowadź poprawny numer SIRET'
+            },
+            step: {
+                'default': 'Wprowadź wielokrotność %s'
+            },
+            stringCase: {
+                'default': 'Wprowadź tekst składającą się tylko z małych liter',
+                upper: 'Wprowadź tekst składający się tylko z dużych liter'
+            },
+            stringLength: {
+                'default': 'Wprowadź wartość o poprawnej długości',
+                less: 'Wprowadź mniej niż %s znaków',
+                more: 'Wprowadź więcej niż %s znaków',
+                between: 'Wprowadź wartość składająca się z min %s i max %s znaków'
+            },
+            uri: {
+                'default': 'Wprowadź poprawny URI'
+            },
+            uuid: {
+                'default': 'Wprowadź poprawny numer UUID',
+                version: 'Wprowadź poprawny numer UUID w wersji %s'
+            },
+            vat: {
+                'default': 'Wprowadź poprawny numer VAT',
+                country: 'Wprowadź poprawny numer VAT w kraju %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Belgia',
+                    BG: 'Bułgaria',
+                    BR: 'Brazylia',
+                    CH: 'Szwajcaria',
+                    CY: 'Cypr',
+                    CZ: 'Czechy',
+                    DE: 'Niemcy',
+                    DK: 'Dania',
+                    EE: 'Estonia',
+                    ES: 'Hiszpania',
+                    FI: 'Finlandia',
+                    FR: 'Francja',
+                    GB: 'Wielka Brytania',
+                    GR: 'Grecja',
+                    EL: 'Grecja',
+                    HU: 'Węgry',
+                    HR: 'Chorwacja',
+                    IE: 'Irlandia',
+                    IS: 'Islandia',
+                    IT: 'Włochy',
+                    LT: 'Litwa',
+                    LU: 'Luksemburg',
+                    LV: 'Łotwa',
+                    MT: 'Malta',
+                    NL: 'Holandia',
+                    NO: 'Norwegia',
+                    PL: 'Polska',
+                    PT: 'Portugalia',
+                    RO: 'Rumunia',
+                    RU: 'Rosja',
+                    RS: 'Serbia',
+                    SE: 'Szwecja',
+                    SI: 'Słowenia',
+                    SK: 'Słowacja',
+                    VE: 'Wenezuela',
+                    ZA: 'Republika Południowej Afryki'
+                }
+            },
+            vin: {
+                'default': 'Wprowadź poprawny numer VIN'
+            },
+            zipCode: {
+                'default': 'Wprowadź poprawny kod pocztowy',
+                country: 'Wprowadź poprawny kod pocztowy w kraju %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bułgaria',
+                    BR: 'Brazylia',
+                    CA: 'Kanada',
+                    CH: 'Szwajcaria',
+                    CZ: 'Czechy',
+                    DE: 'Niemcy',
+                    DK: 'Dania',
+                    ES: 'Hiszpania',
+                    FR: 'Francja',
+                    GB: 'Wielka Brytania',
+                    IE: 'Irlandia',
+                    IN: 'Indie',
+                    IT: 'Włochy',
+                    MA: 'Maroko',
+                    NL: 'Holandia',
+                    PL: 'Polska',
+                    PT: 'Portugalia',
+                    RO: 'Rumunia',
+                    RU: 'Rosja',
+                    SE: 'Szwecja',
+                    SG: 'Singapur',
+                    SK: 'Słowacja',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/pt_BR.js

@@ -0,0 +1,385 @@
+(function ($) {
+    /**
+     * Portuguese (Brazil) language package
+     * Translated by @marcuscarvalho6. Improved by @dgmike
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'pt_BR': {
+            base64: {
+                'default': 'Por favor insira um código base 64 válido'
+            },
+            between: {
+                'default': 'Por favor insira um valor entre %s e %s',
+                notInclusive: 'Por favor insira um valor estritamente entre %s e %s'
+            },
+            bic: {
+                'default': 'Por favor insira um número BIC válido'
+            },
+            callback: {
+                'default': 'Por favor insira um valor válido'
+            },
+            choice: {
+                'default': 'Por favor insira um valor válido',
+                less: 'Por favor escolha %s opções no mínimo',
+                more: 'Por favor escolha %s opções no máximo',
+                between: 'Por favor escolha de %s a %s opções'
+            },
+            color: {
+                'default': 'Por favor insira uma cor válida'
+            },
+            creditCard: {
+                'default': 'Por favor insira um número de cartão de crédito válido'
+            },
+            cusip: {
+                'default': 'Por favor insira um número CUSIP válido'
+            },
+            cvv: {
+                'default': 'Por favor insira um número CVV válido'
+            },
+            date: {
+                'default': 'Por favor insira uma data válida',
+                min: 'Por favor insira uma data posterior a %s',
+                max: 'Por favor insira uma data anterior a %s',
+                range: 'Por favor insira uma data entre %s e %s'
+            },
+            different: {
+                'default': 'Por favor insira valores diferentes'
+            },
+            digits: {
+                'default': 'Por favor insira somente dígitos'
+            },
+            ean: {
+                'default': 'Por favor insira um número EAN válido'
+            },
+            ein: {
+                'default': 'Por favor insira um número EIN válido'
+            },
+            emailAddress: {
+                'default': 'Por favor insira um email válido'
+            },
+            file: {
+                'default': 'Por favor escolha um arquivo válido'
+            },
+            greaterThan: {
+                'default': 'Por favor insira um valor maior ou igual a %s',
+                notInclusive: 'Por favor insira um valor maior do que %s'
+            },
+            grid: {
+                'default': 'Por favor insira uma GRID válida'
+            },
+            hex: {
+                'default': 'Por favor insira um hexadecimal válido'
+            },
+            iban: {
+                'default': 'Por favor insira um número IBAN válido',
+                country: 'Por favor insira um número IBAN válido em %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Emirados Árabes',
+                    AL: 'Albânia',
+                    AO: 'Angola',
+                    AT: 'Áustria',
+                    AZ: 'Azerbaijão',
+                    BA: 'Bósnia-Herzegovina',
+                    BE: 'Bélgica',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgária',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasil',
+                    CH: 'Suíça',
+                    IC: 'Costa do Marfim',
+                    CM: 'Camarões',
+                    CR: 'Costa Rica',
+                    CV: 'Cabo Verde',
+                    CY: 'Chipre',
+                    CZ: 'República Checa',
+                    DE: 'Alemanha',
+                    DK: 'Dinamarca',
+                    DO: 'República Dominicana',
+                    DZ: 'Argélia',
+                    EE: 'Estónia',
+                    ES: 'Espanha',
+                    FI: 'Finlândia',
+                    FO: 'Ilhas Faroé',
+                    FR: 'França',
+                    GB: 'Reino Unido',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Groenlândia',
+                    GR: 'Grécia',
+                    GT: 'Guatemala',
+                    HR: 'Croácia',
+                    HU: 'Hungria',
+                    IE: 'Ireland',
+                    IL: 'Israel',
+                    IR: 'Irão',
+                    IS: 'Islândia',
+                    TI: 'Itália',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Cazaquistão',
+                    LB: 'Líbano',
+                    LI: 'Liechtenstein',
+                    LT: 'Lituânia',
+                    LU: 'Luxemburgo',
+                    LV: 'Letónia',
+                    MC: 'Mônaco',
+                    MD: 'Moldávia',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedónia',
+                    ML: 'Mali',
+                    MR: 'Mauritânia',
+                    MT: 'Malta',
+                    MU: 'Maurício',
+                    MZ: 'Moçambique',
+                    NL: 'Países Baixos',
+                    NO: 'Noruega',
+                    PK: 'Paquistão',
+                    PL: 'Polônia',
+                    PS: 'Palestino',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Roménia',
+                    RS: 'Sérvia',
+                    SA: 'Arábia Saudita',
+                    SE: 'Suécia',
+                    SI: 'Eslovénia',
+                    SK: 'Eslováquia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timor Leste',
+                    TN: 'Tunísia',
+                    TR: 'Turquia',
+                    VG: 'Ilhas Virgens Britânicas',
+                    XK: 'República do Kosovo'
+                }
+            },
+            id: {
+                'default': 'Por favor insira um código de identificação válido',
+                country: 'Por favor insira um número de indentificação válido em %s',
+                countries: {
+                    BA: 'Bósnia e Herzegovina',
+                    BG: 'Bulgária',
+                    BR: 'Brasil',
+                    CH: 'Suíça',
+                    CL: 'Chile',
+                    CN: 'China',
+                    CZ: 'República Checa',
+                    DK: 'Dinamarca',
+                    EE: 'Estônia',
+                    ES: 'Espanha',
+                    FI: 'Finlândia',
+                    HR: 'Croácia',
+                    IE: 'Irlanda',
+                    IS: 'Islândia',
+                    LT: 'Lituânia',
+                    LV: 'Letónia',
+                    ME: 'Montenegro',
+                    MK: 'Macedónia',
+                    NL: 'Holanda',
+                    PL: 'Polônia',
+                    RO: 'Roménia',
+                    RS: 'Sérvia',
+                    SE: 'Suécia',
+                    SI: 'Eslovênia',
+                    SK: 'Eslováquia',
+                    SM: 'San Marino',
+                    TH: 'Tailândia',
+                    TR: 'Turquia',
+                    ZA: 'África do Sul'
+                }
+            },
+            identical: {
+                'default': 'Por favor, insira o mesmo valor'
+            },
+            imei: {
+                'default': 'Por favor insira um IMEI válido'
+            },
+            imo: {
+                'default': 'Por favor insira um IMO válido'
+            },
+            integer: {
+                'default': 'Por favor insira um número inteiro válido'
+            },
+            ip: {
+                'default': 'Por favor insira um IP válido',
+                ipv4: 'Por favor insira um endereço de IPv4 válido',
+                ipv6: 'Por favor insira um endereço de IPv6 válido'
+            },
+            isbn: {
+                'default': 'Por favor insira um ISBN válido'
+            },
+            isin: {
+                'default': 'Por favor insira um ISIN válido'
+            },
+            ismn: {
+                'default': 'Por favor insira um ISMN válido'
+            },
+            issn: {
+                'default': 'Por favor insira um ISSN válido'
+            },
+            lessThan: {
+                'default': 'Por favor insira um valor menor ou igual a %s',
+                notInclusive: 'Por favor insira um valor menor do que %s'
+            },
+            mac: {
+                'default': 'Por favor insira um endereço MAC válido'
+            },
+            meid: {
+                'default': 'Por favor insira um MEID válido'
+            },
+            notEmpty: {
+                'default': 'Por favor insira um valor'
+            },
+            numeric: {
+                'default': 'Por favor insira um número real válido'
+            },
+            phone: {
+                'default': 'Por favor insira um número de telefone válido',
+                country: 'Por favor insira um número de telefone válido em %s',
+                countries: {
+                    AE: 'Emirados Árabes',
+                    BG: 'Bulgária',
+                    BR: 'Brasil',
+                    CN: 'China',
+                    CZ: 'República Checa',
+                    DE: 'Alemanha',
+                    DK: 'Dinamarca',
+                    ES: 'Espanha',
+                    FR: 'França',
+                    GB: 'Reino Unido',
+                    IN: 'Índia',
+                    MA: 'Marrocos',
+                    NL: 'Países Baixos',
+                    PK: 'Paquistão',
+                    RO: 'Roménia',
+                    RU: 'Rússia',
+                    SK: 'Eslováquia',
+                    TH: 'Tailândia',
+                    US: 'EUA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Por favor insira um valor válido'
+            },
+            regexp: {
+                'default': 'Por favor insira um valor correspondente ao padrão'
+            },
+            remote: {
+                'default': 'Por favor insira um valor válido'
+            },
+            rtn: {
+                'default': 'Por favor insira um número válido RTN'
+            },
+            sedol: {
+                'default': 'Por favor insira um número válido SEDOL'
+            },
+            siren: {
+                'default': 'Por favor insira um número válido SIREN'
+            },
+            siret: {
+                'default': 'Por favor insira um número válido SIRET'
+            },
+            step: {
+                'default': 'Por favor insira um passo válido %s'
+            },
+            stringCase: {
+                'default': 'Por favor, digite apenas caracteres minúsculos',
+                upper: 'Por favor, digite apenas caracteres maiúsculos'
+            },
+            stringLength: {
+                'default': 'Por favor insira um valor com comprimento válido',
+                less: 'Por favor insira menos de %s caracteres',
+                more: 'Por favor insira mais de %s caracteres',
+                between: 'Por favor insira um valor entre %s e %s caracteres'
+            },
+            uri: {
+                'default': 'Por favor insira um URI válido'
+            },
+            uuid: {
+                'default': 'Por favor insira um número válido UUID',
+                version: 'Por favor insira uma versão %s  UUID válida'
+            },
+            vat: {
+                'default': 'Por favor insira um VAT válido',
+                country: 'Por favor insira um número VAT válido em %s',
+                countries: {
+                    AT: 'Áustria',
+                    BE: 'Bélgica',
+                    BG: 'Bulgária',
+                    BR: 'Brasil',
+                    CH: 'Suíça',
+                    CY: 'Chipre',
+                    CZ: 'República Checa',
+                    DE: 'Alemanha',
+                    DK: 'Dinamarca',
+                    EE: 'Estônia',
+                    ES: 'Espanha',
+                    FI: 'Finlândia',
+                    FR: 'França',
+                    GB: 'Reino Unido',
+                    GR: 'Grécia',
+                    EL: 'Grécia',
+                    HU: 'Hungria',
+                    HR: 'Croácia',
+                    IE: 'Irlanda',
+                    IS: 'Islândia',
+                    IT: 'Itália',
+                    LT: 'Lituânia',
+                    LU: 'Luxemburgo',
+                    LV: 'Letónia',
+                    MT: 'Malta',
+                    NL: 'Holanda',
+                    NO: 'Norway',
+                    PL: 'Polônia',
+                    PT: 'Portugal',
+                    RO: 'Roménia',
+                    RU: 'Rússia',
+                    RS: 'Sérvia',
+                    SE: 'Suécia',
+                    SI: 'Eslovênia',
+                    SK: 'Eslováquia',
+                    VE: 'Venezuela',
+                    ZA: 'África do Sul'
+                }
+            },
+            vin: {
+                'default': 'Por favor insira um VIN válido'
+            },
+            zipCode: {
+                'default': 'Por favor insira um código postal válido',
+                country: 'Por favor insira um código postal válido em %s',
+                countries: {
+                    AT: 'Áustria',
+                    BG: 'Bulgária',
+                    BR: 'Brasil',
+                    CA: 'Canadá',
+                    CH: 'Suíça',
+                    CZ: 'República Checa',
+                    DE: 'Alemanha',
+                    DK: 'Dinamarca',
+                    ES: 'Espanha',
+                    FR: 'França',
+                    GB: 'Reino Unido',
+                    IE: 'Irlanda',
+                    IN: 'Índia',
+                    IT: 'Itália',
+                    MA: 'Marrocos',
+                    NL: 'Holanda',
+                    PL: 'Polônia',
+                    PT: 'Portugal',
+                    RO: 'Roménia',
+                    RU: 'Rússia',
+                    SE: 'Suécia',
+                    SG: 'Cingapura',
+                    SK: 'Eslováquia',
+                    US: 'EUA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/pt_PT.js

@@ -0,0 +1,385 @@
+(function ($) {
+    /**
+     * Portuguese (Portugal) language package
+     * Translated by @rtbfreitas
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'pt_PT': {
+            base64: {
+                'default': 'Por favor insira um código base 64 válido'
+            },
+            between: {
+                'default': 'Por favor insira um valor entre %s e %s',
+                notInclusive: 'Por favor insira um valor estritamente entre %s e %s'
+            },
+            bic: {
+                'default': 'Por favor insira um número BIC válido'
+            },
+            callback: {
+                'default': 'Por favor insira um valor válido'
+            },
+            choice: {
+                'default': 'Por favor insira um valor válido',
+                less: 'Por favor escolha %s opções no mínimo',
+                more: 'Por favor escolha %s opções no máximo',
+                between: 'Por favor escolha de %s a %s opções'
+            },
+            color: {
+                'default': 'Por favor insira uma cor válida'
+            },
+            creditCard: {
+                'default': 'Por favor insira um número de cartão de crédito válido'
+            },
+            cusip: {
+                'default': 'Por favor insira um número CUSIP válido'
+            },
+            cvv: {
+                'default': 'Por favor insira um número CVV válido'
+            },
+            date: {
+                'default': 'Por favor insira uma data válida',
+                min: 'Por favor insira uma data posterior a %s',
+                max: 'Por favor insira uma data anterior a %s',
+                range: 'Por favor insira uma data entre %s e %s'
+            },
+            different: {
+                'default': 'Por favor insira valores diferentes'
+            },
+            digits: {
+                'default': 'Por favor insira somente dígitos'
+            },
+            ean: {
+                'default': 'Por favor insira um número EAN válido'
+            },
+            ein: {
+                'default': 'Por favor insira um número EIN válido'
+            },
+            emailAddress: {
+                'default': 'Por favor insira um email válido'
+            },
+            file: {
+                'default': 'Por favor escolha um arquivo válido'
+            },
+            greaterThan: {
+                'default': 'Por favor insira um valor maior ou igual a %s',
+                notInclusive: 'Por favor insira um valor maior do que %s'
+            },
+            grid: {
+                'default': 'Por favor insira uma GRID válida'
+            },
+            hex: {
+                'default': 'Por favor insira um hexadecimal válido'
+            },
+            iban: {
+                'default': 'Por favor insira um número IBAN válido',
+                country: 'Por favor insira um número IBAN válido em %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Emirados Árabes',
+                    AL: 'Albânia',
+                    AO: 'Angola',
+                    AT: 'Áustria',
+                    AZ: 'Azerbaijão',
+                    BA: 'Bósnia-Herzegovina',
+                    BE: 'Bélgica',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgária',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasil',
+                    CH: 'Suíça',
+                    IC: 'Costa do Marfim',
+                    CM: 'Camarões',
+                    CR: 'Costa Rica',
+                    CV: 'Cabo Verde',
+                    CY: 'Chipre',
+                    CZ: 'República Checa',
+                    DE: 'Alemanha',
+                    DK: 'Dinamarca',
+                    DO: 'República Dominicana',
+                    DZ: 'Argélia',
+                    EE: 'Estónia',
+                    ES: 'Espanha',
+                    FI: 'Finlândia',
+                    FO: 'Ilhas Faroé',
+                    FR: 'França',
+                    GB: 'Reino Unido',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Groenlândia',
+                    GR: 'Grécia',
+                    GT: 'Guatemala',
+                    HR: 'Croácia',
+                    HU: 'Hungria',
+                    IE: 'Ireland',
+                    IL: 'Israel',
+                    IR: 'Irão',
+                    IS: 'Islândia',
+                    TI: 'Itália',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Cazaquistão',
+                    LB: 'Líbano',
+                    LI: 'Liechtenstein',
+                    LT: 'Lituânia',
+                    LU: 'Luxemburgo',
+                    LV: 'Letónia',
+                    MC: 'Mônaco',
+                    MD: 'Moldávia',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedónia',
+                    ML: 'Mali',
+                    MR: 'Mauritânia',
+                    MT: 'Malta',
+                    MU: 'Maurício',
+                    MZ: 'Moçambique',
+                    NL: 'Países Baixos',
+                    NO: 'Noruega',
+                    PK: 'Paquistão',
+                    PL: 'Polônia',
+                    PS: 'Palestino',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Roménia',
+                    RS: 'Sérvia',
+                    SA: 'Arábia Saudita',
+                    SE: 'Suécia',
+                    SI: 'Eslovénia',
+                    SK: 'Eslováquia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timor Leste',
+                    TN: 'Tunísia',
+                    TR: 'Turquia',
+                    VG: 'Ilhas Virgens Britânicas',
+                    XK: 'República do Kosovo'
+                }
+            },
+            id: {
+                'default': 'Por favor insira um código de identificação válido',
+                country: 'Por favor insira um número de indentificação válido em %s',
+                countries: {
+                    BA: 'Bósnia e Herzegovina',
+                    BG: 'Bulgária',
+                    BR: 'Brasil',
+                    CH: 'Suíça',
+                    CL: 'Chile',
+                    CN: 'China',
+                    CZ: 'República Checa',
+                    DK: 'Dinamarca',
+                    EE: 'Estônia',
+                    ES: 'Espanha',
+                    FI: 'Finlândia',
+                    HR: 'Croácia',
+                    IE: 'Irlanda',
+                    IS: 'Islândia',
+                    LT: 'Lituânia',
+                    LV: 'Letónia',
+                    ME: 'Montenegro',
+                    MK: 'Macedónia',
+                    NL: 'Holanda',
+                    PL: 'Polônia',
+                    RO: 'Roménia',
+                    RS: 'Sérvia',
+                    SE: 'Suécia',
+                    SI: 'Eslovênia',
+                    SK: 'Eslováquia',
+                    SM: 'San Marino',
+                    TH: 'Tailândia',
+                    TR: 'Turquia',
+                    ZA: 'África do Sul'
+                }
+            },
+            identical: {
+                'default': 'Por favor, insira o mesmo valor'
+            },
+            imei: {
+                'default': 'Por favor insira um IMEI válido'
+            },
+            imo: {
+                'default': 'Por favor insira um IMO válido'
+            },
+            integer: {
+                'default': 'Por favor insira um número inteiro válido'
+            },
+            ip: {
+                'default': 'Por favor insira um IP válido',
+                ipv4: 'Por favor insira um endereço de IPv4 válido',
+                ipv6: 'Por favor insira um endereço de IPv6 válido'
+            },
+            isbn: {
+                'default': 'Por favor insira um ISBN válido'
+            },
+            isin: {
+                'default': 'Por favor insira um ISIN válido'
+            },
+            ismn: {
+                'default': 'Por favor insira um ISMN válido'
+            },
+            issn: {
+                'default': 'Por favor insira um ISSN válido'
+            },
+            lessThan: {
+                'default': 'Por favor insira um valor menor ou igual a %s',
+                notInclusive: 'Por favor insira um valor menor do que %s'
+            },
+            mac: {
+                'default': 'Por favor insira um endereço MAC válido'
+            },
+            meid: {
+                'default': 'Por favor insira um MEID válido'
+            },
+            notEmpty: {
+                'default': 'Por favor insira um valor'
+            },
+            numeric: {
+                'default': 'Por favor insira um número real válido'
+            },
+            phone: {
+                'default': 'Por favor insira um número de telefone válido',
+                country: 'Por favor insira um número de telefone válido em %s',
+                countries: {
+                    AE: 'Emirados Árabes',
+                    BG: 'Bulgária',
+                    BR: 'Brasil',
+                    CN: 'China',
+                    CZ: 'República Checa',
+                    DE: 'Alemanha',
+                    DK: 'Dinamarca',
+                    ES: 'Espanha',
+                    FR: 'França',
+                    GB: 'Reino Unido',
+                    IN: 'Índia',
+                    MA: 'Marrocos',
+                    NL: 'Países Baixos',
+                    PK: 'Paquistão',
+                    RO: 'Roménia',
+                    RU: 'Rússia',
+                    SK: 'Eslováquia',
+                    TH: 'Tailândia',
+                    US: 'EUA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Por favor insira um valor válido'
+            },
+            regexp: {
+                'default': 'Por favor insira um valor correspondente ao padrão'
+            },
+            remote: {
+                'default': 'Por favor insira um valor válido'
+            },
+            rtn: {
+                'default': 'Por favor insira um número válido RTN'
+            },
+            sedol: {
+                'default': 'Por favor insira um número válido SEDOL'
+            },
+            siren: {
+                'default': 'Por favor insira um número válido SIREN'
+            },
+            siret: {
+                'default': 'Por favor insira um número válido SIRET'
+            },
+            step: {
+                'default': 'Por favor insira um passo válido %s'
+            },
+            stringCase: {
+                'default': 'Por favor, digite apenas caracteres minúsculos',
+                upper: 'Por favor, digite apenas caracteres maiúsculos'
+            },
+            stringLength: {
+                'default': 'Por favor insira um valor com comprimento válido',
+                less: 'Por favor insira menos de %s caracteres',
+                more: 'Por favor insira mais de %s caracteres',
+                between: 'Por favor insira um valor entre %s e %s caracteres'
+            },
+            uri: {
+                'default': 'Por favor insira um URI válido'
+            },
+            uuid: {
+                'default': 'Por favor insira um número válido UUID',
+                version: 'Por favor insira uma versão %s  UUID válida'
+            },
+            vat: {
+                'default': 'Por favor insira um VAT válido',
+                country: 'Por favor insira um número VAT válido em %s',
+                countries: {
+                    AT: 'Áustria',
+                    BE: 'Bélgica',
+                    BG: 'Bulgária',
+                    BR: 'Brasil',
+                    CH: 'Suíça',
+                    CY: 'Chipre',
+                    CZ: 'República Checa',
+                    DE: 'Alemanha',
+                    DK: 'Dinamarca',
+                    EE: 'Estônia',
+                    ES: 'Espanha',
+                    FI: 'Finlândia',
+                    FR: 'França',
+                    GB: 'Reino Unido',
+                    GR: 'Grécia',
+                    EL: 'Grécia',
+                    HU: 'Hungria',
+                    HR: 'Croácia',
+                    IE: 'Irlanda',
+                    IS: 'Islândia',
+                    IT: 'Itália',
+                    LT: 'Lituânia',
+                    LU: 'Luxemburgo',
+                    LV: 'Letónia',
+                    MT: 'Malta',
+                    NL: 'Holanda',
+                    NO: 'Norway',
+                    PL: 'Polônia',
+                    PT: 'Portugal',
+                    RO: 'Roménia',
+                    RU: 'Rússia',
+                    RS: 'Sérvia',
+                    SE: 'Suécia',
+                    SI: 'Eslovênia',
+                    SK: 'Eslováquia',
+                    VE: 'Venezuela',
+                    ZA: 'África do Sul'
+                }
+            },
+            vin: {
+                'default': 'Por favor insira um VIN válido'
+            },
+            zipCode: {
+                'default': 'Por favor insira um código postal válido',
+                country: 'Por favor insira um código postal válido em %s',
+                countries: {
+                    AT: 'Áustria',
+                    BG: 'Bulgária',
+                    BR: 'Brasil',
+                    CA: 'Canadá',
+                    CH: 'Suíça',
+                    CZ: 'República Checa',
+                    DE: 'Alemanha',
+                    DK: 'Dinamarca',
+                    ES: 'Espanha',
+                    FR: 'França',
+                    GB: 'Reino Unido',
+                    IE: 'Irlanda',
+                    IN: 'Índia',
+                    IT: 'Itália',
+                    MA: 'Marrocos',
+                    NL: 'Holanda',
+                    PL: 'Polônia',
+                    PT: 'Portugal',
+                    RO: 'Roménia',
+                    RU: 'Rússia',
+                    SE: 'Suécia',
+                    SG: 'Cingapura',
+                    SK: 'Eslováquia',
+                    US: 'EUA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/ro_RO.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Romanian language package
+     * Translated by @filipac
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'ro_RO': {
+            base64: {
+                'default': 'Te rog introdu un base64 valid'
+            },
+            between: {
+                'default': 'Te rog introdu o valoare intre %s si %s',
+                notInclusive: 'Te rog introdu o valoare doar intre %s si %s'
+            },
+            bic: {
+                'default': 'Te rog sa introduci un numar BIC valid'
+            },
+            callback: {
+                'default': 'Te rog introdu o valoare valida'
+            },
+            choice: {
+                'default': 'Te rog introdu o valoare valida',
+                less: 'Te rog alege minim %s optiuni',
+                more: 'Te rog alege maxim %s optiuni',
+                between: 'Te rog alege %s - %s optiuni'
+            },
+            color: {
+                'default': 'Te rog sa introduci o culoare valida'
+            },
+            creditCard: {
+                'default': 'Te rog introdu un numar de card valid'
+            },
+            cusip: {
+                'default': 'Te rog introdu un numar CUSIP valid'
+            },
+            cvv: {
+                'default': 'Te rog introdu un numar CVV valid'
+            },
+            date: {
+                'default': 'Te rog introdu o data valida',
+                min: 'Te rog sa introduci o data dupa %s',
+                max: 'Te rog sa introduci o data inainte de %s',
+                range: 'Te rog sa introduci o data in intervalul %s - %s'
+            },
+            different: {
+                'default': 'Te rog sa introduci o valoare diferita'
+            },
+            digits: {
+                'default': 'Te rog sa introduci doar cifre'
+            },
+            ean: {
+                'default': 'Te rog sa introduci un numar EAN valid'
+            },
+            ein: {
+                'default': 'Te rog sa introduci un numar EIN valid'
+            },
+            emailAddress: {
+                'default': 'Te rog sa introduci o adresa de email valide'
+            },
+            file: {
+                'default': 'Te rog sa introduci un fisier valid'
+            },
+            greaterThan: {
+                'default': 'Te rog sa introduci o valoare mai mare sau egala cu %s',
+                notInclusive: 'Te rog sa introduci  o valoare mai mare ca %s'
+            },
+            grid: {
+                'default': 'Te rog sa introduci un numar GRId valid'
+            },
+            hex: {
+                'default': 'Te rog sa introduci un numar hexadecimal valid'
+            },
+            iban: {
+                'default': 'Te rog sa introduci un IBAN valid',
+                country: 'Te rog sa introduci un IBAN valid din %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Emiratele Arabe unite',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Austria',
+                    AZ: 'Azerbaijan',
+                    BA: 'Bosnia si Herzegovina',
+                    BE: 'Belgia',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazilia',
+                    CH: 'Elvetia',
+                    CI: 'Coasta de Fildes',
+                    CM: 'Cameroon',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Cipru',
+                    CZ: 'Republica Cehia',
+                    DE: 'Germania',
+                    DK: 'Danemarca',
+                    DO: 'Republica Dominicană',
+                    DZ: 'Algeria',
+                    EE: 'Estonia',
+                    ES: 'Spania',
+                    FI: 'Finlanda',
+                    FO: 'Insulele Faroe',
+                    FR: 'Franta',
+                    GB: 'Regatul Unit',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Groenlanda',
+                    GR: 'Grecia',
+                    GT: 'Guatemala',
+                    HR: 'Croatia',
+                    HU: 'Ungaria',
+                    IE: 'Irlanda',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Islanda',
+                    IT: 'Italia',
+                    JO: 'Iordania',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakhstan',
+                    LB: 'Lebanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MC: 'Monaco',
+                    MD: 'Moldova',
+                    ME: 'Muntenegru',
+                    MG: 'Madagascar',
+                    MK: 'Macedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Olanda',
+                    NO: 'Norvegia',
+                    PK: 'Pakistan',
+                    PL: 'Polanda',
+                    PS: 'Palestina',
+                    PT: 'Portugalia',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SA: 'Arabia Saudita',
+                    SE: 'Suedia',
+                    SI: 'Slovenia',
+                    SK: 'Slovacia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timorul de Est',
+                    TN: 'Tunisia',
+                    TR: 'Turkey',
+                    VG: 'Insulele Virgin',
+                    XK: 'Republica Kosovo'
+                }
+            },
+            id: {
+                'default': 'Te rog sa introduci un numar de identificare valid',
+                country: 'Te rog sa introduci un numar de identificare valid din %s',
+                countries: {
+                    BA: 'Bosnia si Herzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brazilia',
+                    CH: 'Elvetia',
+                    CL: 'Chile',
+                    CN: 'China',
+                    CZ: 'Republica Cehia',
+                    DK: 'Danemarca',
+                    EE: 'Estonia',
+                    ES: 'Spania',
+                    FI: 'Finlanda',
+                    HR: 'Croatia',
+                    IE: 'Irlanda',
+                    IS: 'Islanda',
+                    LT: 'Lithuania',
+                    LV: 'Latvia',
+                    ME: 'Muntenegru',
+                    MK: 'Macedonia',
+                    NL: 'Olanda',
+                    PL: 'Polanda',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Suedia',
+                    SI: 'Slovenia',
+                    SK: 'Slovacia',
+                    SM: 'San Marino',
+                    TH: 'Thailanda',
+                    TR: 'Turkey',
+                    ZA: 'Africa de Sud'
+                }
+            },
+            identical: {
+                'default': 'Te rog sa introduci aceeasi valoare'
+            },
+            imei: {
+                'default': 'Te rog sa introduci un numar IMEI valid'
+            },
+            imo: {
+                'default': 'Te rog sa introduci un numar IMO valid'
+            },
+            integer: {
+                'default': 'Te rog sa introduci un numar valid'
+            },
+            ip: {
+                'default': 'Te rog sa introduci o adresa IP valida',
+                ipv4: 'Te rog sa introduci o adresa IPv4 valida',
+                ipv6: 'Te rog sa introduci o adresa IPv6 valida'
+            },
+            isbn: {
+                'default': 'Te rog sa introduci un numar ISBN valid'
+            },
+            isin: {
+                'default': 'Te rog sa introduci un numar ISIN valid'
+            },
+            ismn: {
+                'default': 'Te rog sa introduci un numar ISMN valid'
+            },
+            issn: {
+                'default': 'Te rog sa introduci un numar ISSN valid'
+            },
+            lessThan: {
+                'default': 'Te rog sa introduci o valoare mai mica sau egala cu %s',
+                notInclusive: 'Te rog sa introduci o valoare mai mica decat %s'
+            },
+            mac: {
+                'default': 'Te rog sa introduci o adresa MAC valida'
+            },
+            meid: {
+                'default': 'Te rog sa introduci un numar MEID valid'
+            },
+            notEmpty: {
+                'default': 'Te rog sa introduci o valoare'
+            },
+            numeric: {
+                'default': 'Te rog sa introduci un numar'
+            },
+            phone: {
+                'default': 'Te rog sa introduci un numar de telefon valid',
+                country: 'Te rog sa introduci un numar de telefon valid din %s',
+                countries: {
+                    AE: 'Emiratele Arabe unite',
+                    BG: 'Bulgaria',
+                    BR: 'Brazilia',
+                    CN: 'China',
+                    CZ: 'Republica Cehia',
+                    DE: 'Germania',
+                    DK: 'Danemarca',
+                    ES: 'Spania',
+                    FR: 'Franta',
+                    GB: 'Regatul Unit',
+                    IN: 'India',
+                    MA: 'Maroc',
+                    NL: 'Olanda',
+                    PK: 'Pakistan',
+                    RO: 'Romania',
+                    RU: 'Rusia',
+                    SK: 'Slovacia',
+                    TH: 'Thailanda',
+                    US: 'SUA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Te rog introdu o valoare valida'
+            },
+            regexp: {
+                'default': 'Te rog sa introduci o valoare in formatul'
+            },
+            remote: {
+                'default': 'Te rog sa introduci o valoare valida'
+            },
+            rtn: {
+                'default': 'Te rog sa introduci un numar RTN valid'
+            },
+            sedol: {
+                'default': 'Te rog sa introduci un numar SEDOL valid'
+            },
+            siren: {
+                'default': 'Te rog sa introduci un numar SIREN valid'
+            },
+            siret: {
+                'default': 'Te rog sa introduci un numar SIRET valid'
+            },
+            step: {
+                'default': 'Te rog introdu un pas de %s'
+            },
+            stringCase: {
+                'default': 'Te rog sa introduci doar litere mici',
+                upper: 'Te rog sa introduci doar litere mari'
+            },
+            stringLength: {
+                'default': 'Te rog sa introduci o valoare cu lungimea valida',
+                less: 'Te rog sa introduci mai putin de %s caractere',
+                more: 'Te rog sa introduci mai mult de %s caractere',
+                between: 'Te rog sa introduci o valoare cu lungimea intre %s si %s caractere'
+            },
+            uri: {
+                'default': 'Te rog sa introduci un URI valid'
+            },
+            uuid: {
+                'default': 'Te rog sa introduci un numar UUID valid',
+                version: 'Te rog sa introduci un numar UUID versiunea %s valid'
+            },
+            vat: {
+                'default': 'Te rog sa introduci un numar TVA valid',
+                country: 'Te rog sa introduci un numar TVA valid din %s',
+                countries: {
+                    AT: 'Austria',
+                    BE: 'Belgia',
+                    BG: 'Bulgaria',
+                    BR: 'Brazilia',
+                    CH: 'Elvetia',
+                    CY: 'Cipru',
+                    CZ: 'Republica Cehia',
+                    DE: 'Germania',
+                    DK: 'Danemarca',
+                    EE: 'Estonia',
+                    ES: 'Spania',
+                    FI: 'Finlanda',
+                    FR: 'Franta',
+                    GB: 'Regatul Unit',
+                    GR: 'Grecia',
+                    EL: 'Grecia',
+                    HU: 'Ungaria',
+                    HR: 'Croatia',
+                    IE: 'Irlanda',
+                    IS: 'Islanda',
+                    IT: 'Italia',
+                    LT: 'Lituania',
+                    LU: 'Luxemburg',
+                    LV: 'Latvia',
+                    MT: 'Malta',
+                    NL: 'Olanda',
+                    NO: 'Norvegia',
+                    PL: 'Polanda',
+                    PT: 'Portugalia',
+                    RO: 'Romania',
+                    RU: 'Rusia',
+                    RS: 'Serbia',
+                    SE: 'Suedia',
+                    SI: 'Slovenia',
+                    SK: 'Slovacia',
+                    VE: 'Venezuela',
+                    ZA: 'Africa de Sud'
+                }
+            },
+            vin: {
+                'default': 'Te rog sa introduci un numar VIN valid'
+            },
+            zipCode: {
+                'default': 'Te rog sa introduci un cod postal valid',
+                country: 'Te rog sa introduci un cod postal valid din %s',
+                countries: {
+                    AT: 'Austria',
+                    BG: 'Bulgaria',
+                    BR: 'Brazilia',
+                    CA: 'Canada',
+                    CH: 'Elvetia',
+                    CZ: 'Republica Cehia',
+                    DE: 'Germania',
+                    DK: 'Danemarca',
+                    ES: 'Spania',
+                    FR: 'Franta',
+                    GB: 'Regatul Unit',
+                    IE: 'Irlanda',
+                    IN: 'India',
+                    IT: 'Italia',
+                    MA: 'Maroc',
+                    NL: 'Olanda',
+                    PL: 'Polanda',
+                    PT: 'Portugalia',
+                    RO: 'Romania',
+                    RU: 'Rusia',
+                    SE: 'Suedia',
+                    SG: 'Singapore',
+                    SK: 'Slovacia',
+                    US: 'SUA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/ru_RU.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Russian language package
+     * Translated by @cylon-v. Improved by @stepin, @oleg-voloshyn
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'ru_RU': {
+            base64: {
+                'default': 'Пожалуйста, введите корректную строку base64'
+            },
+            between: {
+                'default': 'Пожалуйста, введите значение от %s до %s',
+                notInclusive: 'Пожалуйста, введите значение между %s и %s'
+            },
+            bic: {
+                'default': 'Пожалуйста, введите правильный номер BIC'
+            },
+            callback: {
+                'default': 'Пожалуйста, введите корректное значение'
+            },
+            choice: {
+                'default': 'Пожалуйста, введите корректное значение',
+                less: 'Пожалуйста, выберите хотя бы %s опций',
+                more: 'Пожалуйста, выберите не больше %s опций',
+                between: 'Пожалуйста, выберите %s-%s опций'
+            },
+            color: {
+                'default': 'Пожалуйста, введите правильный номер цвета'
+            },
+            creditCard: {
+                'default': 'Пожалуйста, введите правильный номер кредитной карты'
+            },
+            cusip: {
+                'default': 'Пожалуйста, введите правильный номер CUSIP'
+            },
+            cvv: {
+                'default': 'Пожалуйста, введите правильный номер CVV'
+            },
+            date: {
+                'default': 'Пожалуйста, введите правильную дату',
+                min: 'Пожалуйста, введите дату после %s',
+                max: 'Пожалуйста, введите дату перед %s',
+                range: 'Пожалуйста, введите дату в диапазоне %s - %s'
+            },
+            different: {
+                'default': 'Пожалуйста, введите другое значение'
+            },
+            digits: {
+                'default': 'Пожалуйста, введите только цифры'
+            },
+            ean: {
+                'default': 'Пожалуйста, введите правильный номер EAN'
+            },
+            ein: {
+                'default': 'Пожалуйста, введите правильный номер EIN'
+            },
+            emailAddress: {
+                'default': 'Пожалуйста, введите правильный адрес эл. почты'
+            },
+            file: {
+                'default': 'Пожалуйста, выберите файл'
+            },
+            greaterThan: {
+                'default': 'Пожалуйста, введите значение большее или равное %s',
+                notInclusive: 'Пожалуйста, введите значение больше %s'
+            },
+            grid: {
+                'default': 'Пожалуйста, введите правильный номер GRId'
+            },
+            hex: {
+                'default': 'Пожалуйста, введите правильное шестнадцатиричное число'
+            },
+            iban: {
+                'default': 'Пожалуйста, введите правильный номер IBAN',
+                country: 'Пожалуйста, введите правильный номер IBAN в %s',
+                countries: {
+                    AD: 'Андорре',
+                    AE: 'Объединённых Арабских Эмиратах',
+                    AL: 'Албании',
+                    AO: 'Анголе',
+                    AT: 'Австрии',
+                    AZ: 'Азербайджане',
+                    BA: 'Боснии и Герцеговине',
+                    BE: 'Бельгии',
+                    BF: 'Буркина-Фасо',
+                    BG: 'Болгарии',
+                    BH: 'Бахрейне',
+                    BI: 'Бурунди',
+                    BJ: 'Бенине',
+                    BR: 'Бразилии',
+                    CH: 'Швейцарии',
+                    CI: "Кот-д'Ивуаре",
+                    CM: 'Камеруне',
+                    CR: 'Коста-Рике',
+                    CV: 'Кабо-Верде',
+                    CY: 'Кипре',
+                    CZ: 'Чешская республика',
+                    DE: 'Германии',
+                    DK: 'Дании',
+                    DO: 'Доминикане Республика',
+                    DZ: 'Алжире',
+                    EE: 'Эстонии',
+                    ES: 'Испании',
+                    FI: 'Финляндии',
+                    FO: 'Фарерских островах',
+                    FR: 'Франции',
+                    GB: 'Великобритании',
+                    GE: 'Грузии',
+                    GI: 'Гибралтаре',
+                    GL: 'Гренландии',
+                    GR: 'Греции',
+                    GT: 'Гватемале',
+                    HR: 'Хорватии',
+                    HU: 'Венгрии',
+                    IE: 'Ирландии',
+                    IL: 'Израиле',
+                    IR: 'Иране',
+                    IS: 'Исландии',
+                    IT: 'Италии',
+                    JO: 'Иордании',
+                    KW: 'Кувейте',
+                    KZ: 'Казахстане',
+                    LB: 'Ливане',
+                    LI: 'Лихтенштейне',
+                    LT: 'Литве',
+                    LU: 'Люксембурге',
+                    LV: 'Латвии',
+                    MC: 'Монако',
+                    MD: 'Молдове',
+                    ME: 'Черногории',
+                    MG: 'Мадагаскаре',
+                    MK: 'Македонии',
+                    ML: 'Мали',
+                    MR: 'Мавритании',
+                    MT: 'Мальте',
+                    MU: 'Маврикии',
+                    MZ: 'Мозамбике',
+                    NL: 'Нидерландах',
+                    NO: 'Норвегии',
+                    PK: 'Пакистане',
+                    PL: 'Польше',
+                    PS: 'Палестине',
+                    PT: 'Португалии',
+                    QA: 'Катаре',
+                    RO: 'Румынии',
+                    RS: 'Сербии',
+                    SA: 'Саудовской Аравии',
+                    SE: 'Швеции',
+                    SI: 'Словении',
+                    SK: 'Словакии',
+                    SM: 'Сан-Марино',
+                    SN: 'Сенегале',
+                    TL: 'Восточный Тимор',
+                    TN: 'Тунисе',
+                    TR: 'Турции',
+                    VG: 'Британских Виргинских островах',
+                    XK: 'Республика Косово'
+                }
+            },
+            id: {
+                'default': 'Пожалуйста, введите правильный идентификационный номер',
+                country: 'Пожалуйста, введите правильный идентификационный номер в %s',
+                countries: {
+                    BA: 'Боснии и Герцеговине',
+                    BG: 'Болгарии',
+                    BR: 'Бразилии',
+                    CH: 'Швейцарии',
+                    CL: 'Чили',
+                    CN: 'Китае',
+                    CZ: 'Чешская республика',
+                    DK: 'Дании',
+                    EE: 'Эстонии',
+                    ES: 'Испании',
+                    FI: 'Финляндии',
+                    HR: 'Хорватии',
+                    IE: 'Ирландии',
+                    IS: 'Исландии',
+                    LT: 'Литве',
+                    LV: 'Латвии',
+                    ME: 'Черногории',
+                    MK: 'Македонии',
+                    NL: 'Нидерландах',
+                    PL: 'Польше',
+                    RO: 'Румынии',
+                    RS: 'Сербии',
+                    SE: 'Швеции',
+                    SI: 'Словении',
+                    SK: 'Словакии',
+                    SM: 'Сан-Марино',
+                    TH: 'Тайланде',
+                    TR: 'Турции',
+                    ZA: 'ЮАР'
+                }
+            },
+            identical: {
+                'default': 'Пожалуйста, введите такое же значение'
+            },
+            imei: {
+                'default': 'Пожалуйста, введите правильный номер IMEI'
+            },
+            imo: {
+                'default': 'Пожалуйста, введите правильный номер IMO'
+            },
+            integer: {
+                'default': 'Пожалуйста, введите правильное целое число'
+            },
+            ip: {
+                'default': 'Пожалуйста, введите правильный IP-адрес',
+                ipv4: 'Пожалуйста, введите правильный IPv4-адрес',
+                ipv6: 'Пожалуйста, введите правильный IPv6-адрес'
+            },
+            isbn: {
+                'default': 'Пожалуйста, введите правильный номер ISBN'
+            },
+            isin: {
+                'default': 'Пожалуйста, введите правильный номер ISIN'
+            },
+            ismn: {
+                'default': 'Пожалуйста, введите правильный номер ISMN'
+            },
+            issn: {
+                'default': 'Пожалуйста, введите правильный номер ISSN'
+            },
+            lessThan: {
+                'default': 'Пожалуйста, введите значение меньшее или равное %s',
+                notInclusive: 'Пожалуйста, введите значение меньше %s'
+            },
+            mac: {
+                'default': 'Пожалуйста, введите правильный MAC-адрес'
+            },
+            meid: {
+                'default': 'Пожалуйста, введите правильный номер MEID'
+            },
+            notEmpty: {
+                'default': 'Пожалуйста, введите значение'
+            },
+            numeric: {
+                'default': 'Пожалуйста, введите корректное действительное число'
+            },
+            phone: {
+                'default': 'Пожалуйста, введите правильный номер телефона',
+                country: 'Пожалуйста, введите правильный номер телефона в %s',
+                countries: {
+                    AE: 'Объединённых Арабских Эмиратах',
+                    BG: 'Болгарии',
+                    BR: 'Бразилии',
+                    CN: 'Китае',
+                    CZ: 'Чешская республика',
+                    DE: 'Германии',
+                    DK: 'Дании',
+                    ES: 'Испании',
+                    FR: 'Франции',
+                    GB: 'Великобритании',
+                    IN: 'Индия',
+                    MA: 'Марокко',
+                    NL: 'Нидерландах',
+                    PK: 'Пакистане',
+                    RO: 'Румынии',
+                    RU: 'России',
+                    SK: 'Словакии',
+                    TH: 'Тайланде',
+                    US: 'США',
+                    VE: 'Венесуэле'
+                }
+            },
+            promise: {
+                'default': 'Пожалуйста, введите корректное значение'
+            },
+            regexp: {
+                'default': 'Пожалуйста, введите значение соответствующее шаблону'
+            },
+            remote: {
+                'default': 'Пожалуйста, введите правильное значение'
+            },
+            rtn: {
+                'default': 'Пожалуйста, введите правильный номер RTN'
+            },
+            sedol: {
+                'default': 'Пожалуйста, введите правильный номер SEDOL'
+            },
+            siren: {
+                'default': 'Пожалуйста, введите правильный номер SIREN'
+            },
+            siret: {
+                'default': 'Пожалуйста, введите правильный номер SIRET'
+            },
+            step: {
+                'default': 'Пожалуйста, введите правильный шаг %s'
+            },
+            stringCase: {
+                'default': 'Пожалуйста, вводите только строчные буквы',
+                upper: 'Пожалуйста, вводите только заглавные буквы'
+            },
+            stringLength: {
+                'default': 'Пожалуйста, введите значение корректной длины',
+                less: 'Пожалуйста, введите не больше %s символов',
+                more: 'Пожалуйста, введите не меньше %s символов',
+                between: 'Пожалуйста, введите строку длиной от %s до %s символов'
+            },
+            uri: {
+                'default': 'Пожалуйста, введите правильный URI'
+            },
+            uuid: {
+                'default': 'Пожалуйста, введите правильный номер UUID',
+                version: 'Пожалуйста, введите правильный номер UUID версии %s'
+            },
+            vat: {
+                'default': 'Пожалуйста, введите правильный номер ИНН',
+                country: 'Пожалуйста, введите правильный номер ИНН (VAT) в %s',
+                countries: {
+                    AT: 'Австрии',
+                    BE: 'Бельгии',
+                    BG: 'Болгарии',
+                    BR: 'Бразилии',
+                    CH: 'Швейцарии',
+                    CY: 'Кипре',
+                    CZ: 'Чешская республика',
+                    DE: 'Германии',
+                    DK: 'Дании',
+                    EE: 'Эстонии',
+                    ES: 'Испании',
+                    FI: 'Финляндии',
+                    FR: 'Франции',
+                    GB: 'Великобритании',
+                    GR: 'Греции',
+                    EL: 'Греции',
+                    HU: 'Венгрии',
+                    HR: 'Хорватии',
+                    IE: 'Ирландии',
+                    IS: 'Исландии',
+                    IT: 'Италии',
+                    LT: 'Литве',
+                    LU: 'Люксембурге',
+                    LV: 'Латвии',
+                    MT: 'Мальте',
+                    NL: 'Нидерландах',
+                    NO: 'Норвегии',
+                    PL: 'Польше',
+                    PT: 'Португалии',
+                    RO: 'Румынии',
+                    RU: 'России',
+                    RS: 'Сербии',
+                    SE: 'Швеции',
+                    SI: 'Словении',
+                    SK: 'Словакии',
+                    VE: 'Венесуэле',
+                    ZA: 'ЮАР'
+                }
+            },
+            vin: {
+                'default': 'Пожалуйста, введите правильный номер VIN'
+            },
+            zipCode: {
+                'default': 'Пожалуйста, введите правильный почтовый индекс',
+                country: 'Пожалуйста, введите правильный почтовый индекс в %s',
+                countries: {
+                    AT: 'Австрии',
+                    BG: 'Болгарии',
+                    BR: 'Бразилии',
+                    CA: 'Канаде',
+                    CH: 'Швейцарии',
+                    CZ: 'Чешская республика',
+                    DE: 'Германии',
+                    DK: 'Дании',
+                    ES: 'Испании',
+                    FR: 'Франции',
+                    GB: 'Великобритании',
+                    IE: 'Ирландии',
+                    IN: 'Индия',
+                    IT: 'Италии',
+                    MA: 'Марокко',
+                    NL: 'Нидерландах',
+                    PL: 'Польше',
+                    PT: 'Португалии',
+                    RO: 'Румынии',
+                    RU: 'России',
+                    SE: 'Швеции',
+                    SG: 'Сингапуре',
+                    SK: 'Словакии',
+                    US: 'США'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/sk_SK.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Slovak language package
+     * Translated by @budik21. Improved by @PatrikGallik
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'sk_SK': {
+            base64: {
+                'default': 'Prosím zadajte správny base64'
+            },
+            between: {
+                'default': 'Prosím zadajte hodnotu medzi %s a %s',
+                notInclusive: 'Prosím zadajte hodnotu medzi %s a %s (vrátane týchto čísel)'
+            },
+            bic: {
+                'default': 'Prosím zadajte správne BIC číslo'
+            },
+            callback: {
+                'default': 'Prosím zadajte správnu hodnotu'
+            },
+            choice: {
+                'default': 'Prosím vyberte správnu hodnotu',
+                less: 'Hodnota musí byť minimálne %s',
+                more: 'Hodnota nesmie byť viac ako %s',
+                between: 'Prosím vyberte medzi %s a %s'
+            },
+            color: {
+                'default': 'Prosím zadajte správnu farbu'
+            },
+            creditCard: {
+                'default': 'Prosím zadajte správne číslo kreditnej karty'
+            },
+            cusip: {
+                'default': 'Prosím zadajte správne CUSIP číslo'
+            },
+            cvv: {
+                'default': 'Prosím zadajte správne CVV číslo'
+            },
+            date: {
+                'default': 'Prosím zadajte správny dátum',
+                min: 'Prosím zadajte dátum pred %s',
+                max: 'Prosím zadajte dátum po %s',
+                range: 'Prosím zadajte dátum v rozmedzí %s až %s'
+            },
+            different: {
+                'default': 'Prosím zadajte inú hodnotu'
+            },
+            digits: {
+                'default': 'Toto pole môže obsahovať len čísla'
+            },
+            ean: {
+                'default': 'Prosím zadajte správne EAN číslo'
+            },
+            ein: {
+                'default': 'Prosím zadajte správne EIN číslo'
+            },
+            emailAddress: {
+                'default': 'Prosím zadajte správnu emailovú adresu'
+            },
+            file: {
+                'default': 'Prosím vyberte súbor'
+            },
+            greaterThan: {
+                'default': 'Prosím zadajte hodnotu väčšiu alebo rovnú %s',
+                notInclusive: 'Prosím zadajte hodnotu väčšiu ako %s'
+            },
+            grid: {
+                'default': 'Prosím zadajte správné GRId číslo'
+            },
+            hex: {
+                'default': 'Prosím zadajte správne hexadecimálne číslo'
+            },
+            iban: {
+                'default': 'Prosím zadajte správne IBAN číslo',
+                country: 'Prosím zadajte správne IBAN číslo pre %s',
+                countries: {
+                    AD: 'Andorru',
+                    AE: 'Spojené arabské emiráty',
+                    AL: 'Albánsko',
+                    AO: 'Angolu',
+                    AT: 'Rakúsko',
+                    AZ: 'Ázerbajdžán',
+                    BA: 'Bosnu a Herzegovinu',
+                    BE: 'Belgicko',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulharsko',
+                    BH: 'Bahrajn',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazíliu',
+                    CH: 'Švajčiarsko',
+                    CI: 'Pobrežie Slonoviny',
+                    CM: 'Kamerun',
+                    CR: 'Kostariku',
+                    CV: 'Cape Verde',
+                    CY: 'Cyprus',
+                    CZ: 'Českú Republiku',
+                    DE: 'Nemecko',
+                    DK: 'Dánsko',
+                    DO: 'Dominikánsku republiku',
+                    DZ: 'Alžírsko',
+                    EE: 'Estónsko',
+                    ES: 'Španielsko',
+                    FI: 'Fínsko',
+                    FO: 'Faerské ostrovy',
+                    FR: 'Francúzsko',
+                    GB: 'Veľkú Britániu',
+                    GE: 'Gruzínsko',
+                    GI: 'Gibraltár',
+                    GL: 'Grónsko',
+                    GR: 'Grécko',
+                    GT: 'Guatemalu',
+                    HR: 'Chorvátsko',
+                    HU: 'Maďarsko',
+                    IE: 'Írsko',
+                    IL: 'Izrael',
+                    IR: 'Irán',
+                    IS: 'Island',
+                    IT: 'Taliansko',
+                    JO: 'Jordánsko',
+                    KW: 'Kuwait',
+                    KZ: 'Kazachstan',
+                    LB: 'Libanon',
+                    LI: 'Lichtenštajnsko',
+                    LT: 'Litvu',
+                    LU: 'Luxemburgsko',
+                    LV: 'Lotyšsko',
+                    MC: 'Monako',
+                    MD: 'Moldavsko',
+                    ME: 'Čiernu horu',
+                    MG: 'Madagaskar',
+                    MK: 'Macedónsko',
+                    ML: 'Mali',
+                    MR: 'Mauritániu',
+                    MT: 'Maltu',
+                    MU: 'Mauritius',
+                    MZ: 'Mosambik',
+                    NL: 'Holandsko',
+                    NO: 'Nórsko',
+                    PK: 'Pakistan',
+                    PL: 'Poľsko',
+                    PS: 'Palestínu',
+                    PT: 'Portugalsko',
+                    QA: 'Katar',
+                    RO: 'Rumunsko',
+                    RS: 'Srbsko',
+                    SA: 'Saudskú Arábiu',
+                    SE: 'Švédsko',
+                    SI: 'Slovinsko',
+                    SK: 'Slovensko',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Východný Timor',
+                    TN: 'Tunisko',
+                    TR: 'Turecko',
+                    VG: 'Britské Panenské ostrovy',
+                    XK: 'Republic of Kosovo'
+                }
+            },
+            id: {
+                'default': 'Prosím zadajte správne rodné číslo',
+                country: 'Prosím zadajte správne rodné číslo pre %s',
+                countries: {
+                    BA: 'Bosnu a Hercegovinu',
+                    BG: 'Bulharsko',
+                    BR: 'Brazíliu',
+                    CH: 'Švajčiarsko',
+                    CL: 'Chile',
+                    CN: 'Čínu',
+                    CZ: 'Českú Republiku',
+                    DK: 'Dánsko',
+                    EE: 'Estónsko',
+                    ES: 'Španielsko',
+                    FI: 'Fínsko',
+                    HR: 'Chorvátsko',
+                    IE: 'Írsko',
+                    IS: 'Island',
+                    LT: 'Litvu',
+                    LV: 'Lotyšsko',
+                    ME: 'Čiernu horu',
+                    MK: 'Macedónsko',
+                    NL: 'Holandsko',
+                    PL: 'Poľsko',
+                    RO: 'Rumunsko',
+                    RS: 'Srbsko',
+                    SE: 'Švédsko',
+                    SI: 'Slovinsko',
+                    SK: 'Slovensko',
+                    SM: 'San Marino',
+                    TH: 'Thajsko',
+                    TR: 'Turecko',
+                    ZA: 'Južnú Afriku'
+                }
+            },
+            identical: {
+                'default': 'Prosím zadajte rovnakú hodnotu'
+            },
+            imei: {
+                'default': 'Prosím zadajte správne IMEI číslo'
+            },
+            imo: {
+                'default': 'Prosím zadajte správne IMO číslo'
+            },
+            integer: {
+                'default': 'Prosím zadajte celé číslo'
+            },
+            ip: {
+                'default': 'Prosím zadajte správnu IP adresu',
+                ipv4: 'Prosím zadajte správnu IPv4 adresu',
+                ipv6: 'Prosím zadajte správnu IPv6 adresu'
+            },
+            isbn: {
+                'default': 'Prosím zadajte správne ISBN číslo'
+            },
+            isin: {
+                'default': 'Prosím zadajte správne ISIN číslo'
+            },
+            ismn: {
+                'default': 'Prosím zadajte správne ISMN číslo'
+            },
+            issn: {
+                'default': 'Prosím zadajte správne ISSN číslo'
+            },
+            lessThan: {
+                'default': 'Prosím zadajte hodnotu menšiu alebo rovnú %s',
+                notInclusive: 'Prosím zadajte hodnotu menšiu ako %s'
+            },
+            mac: {
+                'default': 'Prosím zadajte správnu MAC adresu'
+            },
+            meid: {
+                'default': 'Prosím zadajte správne MEID číslo'
+            },
+            notEmpty: {
+                'default': 'Toto pole nesmie byť prázdne'
+            },
+            numeric: {
+                'default': 'Prosím zadajte číselnú hodnotu'
+            },
+            phone: {
+                'default': 'Prosím zadajte správne telefónne číslo',
+                country: 'Prosím zadajte správne telefónne číslo pre %s',
+                countries: {
+                    AE: 'Spojené arabské emiráty',
+                    BG: 'Bulharsko',
+                    BR: 'Brazíliu',
+                    CN: 'Čínu',
+                    CZ: 'Českú Republiku',
+                    DE: 'Nemecko',
+                    DK: 'Dánsko',
+                    ES: 'Španielsko',
+                    FR: 'Francúzsko',
+                    GB: 'Veľkú Britániu',
+                    IN: 'Indiu',
+                    MA: 'Maroko',
+                    NL: 'Holandsko',
+                    PK: 'Pakistan',
+                    RO: 'Rumunsko',
+                    RU: 'Rusko',
+                    SK: 'Slovensko',
+                    TH: 'Thajsko',
+                    US: 'Spojené Štáty Americké',
+                    VE: 'Venezuelu'
+                }
+            },
+            promise: {
+                'default': 'Prosím zadajte správnu hodnotu'
+            },
+            regexp: {
+                'default': 'Prosím zadajte hodnotu spĺňajúcu zadanie'
+            },
+            remote: {
+                'default': 'Prosím zadajte správnu hodnotu'
+            },
+            rtn: {
+                'default': 'Prosím zadajte správne RTN číslo'
+            },
+            sedol: {
+                'default': 'Prosím zadajte správne SEDOL číslo'
+            },
+            siren: {
+                'default': 'Prosím zadajte správne SIREN číslo'
+            },
+            siret: {
+                'default': 'Prosím zadajte správne SIRET číslo'
+            },
+            step: {
+                'default': 'Prosím zadajte správny krok %s'
+            },
+            stringCase: {
+                'default': 'Len malé písmená sú povolené v tomto poli',
+                upper: 'Len veľké písmená sú povolené v tomto poli'
+            },
+            stringLength: {
+                'default': 'Toto pole nesmie byť prázdne',
+                less: 'Prosím zadajte hodnotu kratšiu ako %s znakov',
+                more: 'Prosím zadajte hodnotu dlhú %s znakov a viacej',
+                between: 'Prosím zadajte hodnotu medzi %s a %s znakov'
+            },
+            uri: {
+                'default': 'Prosím zadajte správnu URI'
+            },
+            uuid: {
+                'default': 'Prosím zadajte správne UUID číslo',
+                version: 'Prosím zadajte správne UUID vo verzii %s'
+            },
+            vat: {
+                'default': 'Prosím zadajte správne VAT číslo',
+                country: 'Prosím zadajte správne VAT číslo pre %s',
+                countries: {
+                    AT: 'Rakúsko',
+                    BE: 'Belgicko',
+                    BG: 'Bulharsko',
+                    BR: 'Brazíliu',
+                    CH: 'Švajčiarsko',
+                    CY: 'Cyprus',
+                    CZ: 'Českú Republiku',
+                    DE: 'Nemecko',
+                    DK: 'Dánsko',
+                    EE: 'Estónsko',
+                    ES: 'Španielsko',
+                    FI: 'Fínsko',
+                    FR: 'Francúzsko',
+                    GB: 'Veľkú Britániu',
+                    GR: 'Grécko',
+                    EL: 'Grécko',
+                    HU: 'Maďarsko',
+                    HR: 'Chorvátsko',
+                    IE: 'Írsko',
+                    IS: 'Island',
+                    IT: 'Taliansko',
+                    LT: 'Litvu',
+                    LU: 'Luxemburgsko',
+                    LV: 'Lotyšsko',
+                    MT: 'Maltu',
+                    NL: 'Holandsko',
+                    NO: 'Norsko',
+                    PL: 'Poľsko',
+                    PT: 'Portugalsko',
+                    RO: 'Rumunsko',
+                    RU: 'Rusko',
+                    RS: 'Srbsko',
+                    SE: 'Švédsko',
+                    SI: 'Slovinsko',
+                    SK: 'Slovensko',
+                    VE: 'Venezuelu',
+                    ZA: 'Južnú Afriku'
+                }
+            },
+            vin: {
+                'default': 'Prosím zadajte správne VIN číslo'
+            },
+            zipCode: {
+                'default': 'Prosím zadajte správne PSČ',
+                country: 'Prosím zadajte správne PSČ pre %s',
+                countries: {
+                    AT: 'Rakúsko',
+                    BG: 'Bulharsko',
+                    BR: 'Brazíliu',
+                    CA: 'Kanadu',
+                    CH: 'Švajčiarsko',
+                    CZ: 'Českú Republiku',
+                    DE: 'Nemecko',
+                    DK: 'Dánsko',
+                    ES: 'Španielsko',
+                    FR: 'Francúzsko',
+                    GB: 'Veľkú Britániu',
+                    IE: 'Írsko',
+                    IN: 'Indiu',
+                    IT: 'Taliansko',
+                    MA: 'Maroko',
+                    NL: 'Holandsko',
+                    PL: 'Poľsko',
+                    PT: 'Portugalsko',
+                    RO: 'Rumunsko',
+                    RU: 'Rusko',
+                    SE: 'Švédsko',
+                    SG: 'Singapur',
+                    SK: 'Slovensko',
+                    US: 'Spojené Štáty Americké'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/sq_AL.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Albanian language package
+     * Translated by @desaretiuss
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'sq_AL': {
+            base64: {
+                'default': 'Ju lutem përdorni sistemin e kodimit Base64'
+            },
+            between: {
+                'default': 'Ju lutem vendosni një vlerë midis %s dhe %s',
+                notInclusive: 'Ju lutem vendosni një vlerë rreptësisht midis %s dhe %s'
+            },
+            bic: {
+                'default': 'Ju lutem vendosni një numër BIC të vlefshëm'
+            },
+            callback: {
+                'default': 'Ju lutem vendosni një vlerë të vlefshme'
+            },
+            choice: {
+                'default': 'Ju lutem vendosni një vlerë të vlefshme',
+                less: 'Ju lutem përzgjidhni së paku %s mundësi',
+                more: 'Ju lutem përzgjidhni së shumti %s mundësi ',
+                between: 'Ju lutem përzgjidhni %s - %s mundësi'
+            },
+            color: {
+                'default': 'Ju lutem vendosni një ngjyrë të vlefshme'
+            },
+            creditCard: {
+                'default': 'Ju lutem vendosni një numër karte krediti të vlefshëm'
+            },
+            cusip: {
+                'default': 'Ju lutem vendosni një numër CUSIP të vlefshëm'
+            },
+            cvv: {
+                'default': 'Ju lutem vendosni një numër CVV të vlefshëm'
+            },
+            date: {
+                'default': 'Ju lutem vendosni një datë të saktë',
+                min: 'Ju lutem vendosni një datë pas %s',
+                max: 'Ju lutem vendosni një datë para %s',
+                range: 'Ju lutem vendosni një datë midis %s - %s'
+            },
+            different: {
+                'default': 'Ju lutem vendosni një vlerë tjetër'
+            },
+            digits: {
+                'default': 'Ju lutem vendosni vetëm numra'
+            },
+            ean: {
+                'default': 'Ju lutem vendosni një numër EAN të vlefshëm'
+            },
+            ein: {
+                'default': 'Ju lutem vendosni një numër EIN të vlefshëm'
+            },
+            emailAddress: {
+                'default': 'Ju lutem vendosni një adresë email të vlefshme'
+            },
+            file: {
+                'default': 'Ju lutem përzgjidhni një skedar të vlefshëm'
+            },
+            greaterThan: {
+                'default': 'Ju lutem vendosni një vlerë më të madhe ose të barabartë me %s',
+                notInclusive: 'Ju lutem vendosni një vlerë më të madhe se %s'
+            },
+            grid: {
+                'default': 'Ju lutem vendosni një numër GRId të vlefshëm'
+            },
+            hex: {
+                'default': 'Ju lutem vendosni një numër të saktë heksadecimal'
+            },
+            iban: {
+                'default': 'Ju lutem vendosni një numër IBAN të vlefshëm',
+                country: 'Ju lutem vendosni një numër IBAN të vlefshëm në %s',
+                countries: {
+                    AD: 'Andora',
+                    AE: 'Emiratet e Bashkuara Arabe',
+                    AL: 'Shqipëri',
+                    AO: 'Angola',
+                    AT: 'Austri',
+                    AZ: 'Azerbajxhan',
+                    BA: 'Bosnjë dhe Hercegovinë',
+                    BE: 'Belgjikë',
+                    BF: 'Burkina Faso',
+                    BG: 'Bullgari',
+                    BH: 'Bahrein',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazil',
+                    CH: 'Zvicër',
+                    CI: 'Bregu i fildishtë',
+                    CM: 'Kamerun',
+                    CR: 'Kosta Rika',
+                    CV: 'Kepi i Gjelbër',
+                    CY: 'Qipro',
+                    CZ: 'Republika Çeke',
+                    DE: 'Gjermani',
+                    DK: 'Danimarkë',
+                    DO: 'Dominika',
+                    DZ: 'Algjeri',
+                    EE: 'Estoni',
+                    ES: 'Spanjë',
+                    FI: 'Finlandë',
+                    FO: 'Ishujt Faroe',
+                    FR: 'Francë',
+                    GB: 'Mbretëria e Bashkuar',
+                    GE: 'Gjeorgji',
+                    GI: 'Gjibraltar',
+                    GL: 'Groenlandë',
+                    GR: 'Greqi',
+                    GT: 'Guatemalë',
+                    HR: 'Kroaci',
+                    HU: 'Hungari',
+                    IE: 'Irlandë',
+                    IL: 'Izrael',
+                    IR: 'Iran',
+                    IS: 'Islandë',
+                    IT: 'Itali',
+                    JO: 'Jordani',
+                    KW: 'Kuvajt',
+                    KZ: 'Kazakistan',
+                    LB: 'Liban',
+                    LI: 'Lihtenshtejn',
+                    LT: 'Lituani',
+                    LU: 'Luksemburg',
+                    LV: 'Letoni',
+                    MC: 'Monako',
+                    MD: 'Moldavi',
+                    ME: 'Mal i Zi',
+                    MG: 'Madagaskar',
+                    MK: 'Maqedoni',
+                    ML: 'Mali',
+                    MR: 'Mauritani',
+                    MT: 'Maltë',
+                    MU: 'Mauricius',
+                    MZ: 'Mozambik',
+                    NL: 'Hollandë',
+                    NO: 'Norvegji',
+                    PK: 'Pakistan',
+                    PL: 'Poloni',
+                    PS: 'Palestinë',
+                    PT: 'Portugali',
+                    QA: 'Katar',
+                    RO: 'Rumani',
+                    RS: 'Serbi',
+                    SA: 'Arabi Saudite',
+                    SE: 'Suedi',
+                    SI: 'Slloveni',
+                    SK: 'Sllovaki',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Timori Lindor',
+                    TN: 'Tunizi',
+                    TR: 'Turqi',
+                    VG: 'Ishujt Virxhin Britanikë',
+                    XK: 'Republika e Kosovës'
+                }
+            },
+            id: {
+                'default': 'Ju lutem vendosni një numër identifikimi të vlefshëm ',
+                country: 'Ju lutem vendosni një numër identifikimi të vlefshëm në %s',
+                countries: {
+                    BA: 'Bosnjë dhe Hercegovinë',
+                    BG: 'Bullgari',
+                    BR: 'Brazil',
+                    CH: 'Zvicër',
+                    CL: 'Kili',
+                    CN: 'Kinë',
+                    CZ: 'Republika Çeke',
+                    DK: 'Danimarkë',
+                    EE: 'Estoni',
+                    ES: 'Spanjë',
+                    FI: 'Finlandë',
+                    HR: 'Kroaci',
+                    IE: 'Irlandë',
+                    IS: 'Islandë',
+                    LT: 'Lituani',
+                    LV: 'Letoni',
+                    ME: 'Mal i Zi',
+                    MK: 'Maqedoni',
+                    NL: 'Hollandë',
+                    PL: 'Poloni',
+                    RO: 'Rumani',
+                    RS: 'Serbi',
+                    SE: 'Suedi',
+                    SI: 'Slloveni',
+                    SK: 'Slovaki',
+                    SM: 'San Marino',
+                    TH: 'Tajlandë',
+                    TR: 'Turqi',
+                    ZA: 'Afrikë e Jugut'
+                }
+            },
+            identical: {
+                'default': 'Ju lutem vendosni të njëjtën vlerë'
+            },
+            imei: {
+                'default': 'Ju lutem vendosni numër IMEI të njëjtë'
+            },
+            imo: {
+                'default': 'Ju lutem vendosni numër IMO të vlefshëm'
+            },
+            integer: {
+                'default': 'Ju lutem vendosni një numër të vlefshëm'
+            },
+            ip: {
+                'default': 'Ju lutem vendosni një adresë IP të vlefshme',
+                ipv4: 'Ju lutem vendosni një adresë IPv4 të vlefshme',
+                ipv6: 'Ju lutem vendosni një adresë IPv6 të vlefshme'
+            },
+            isbn: {
+                'default': 'Ju lutem vendosni një numër ISBN të vlefshëm'
+            },
+            isin: {
+                'default': 'Ju lutem vendosni një numër ISIN të vlefshëm'
+            },
+            ismn: {
+                'default': 'Ju lutem vendosni një numër ISMN të vlefshëm'
+            },
+            issn: {
+                'default': 'Ju lutem vendosni një numër ISSN të vlefshëm'
+            },
+            lessThan: {
+                'default': 'Ju lutem vendosni një vlerë më të madhe ose të barabartë me %s',
+                notInclusive: 'Ju lutem vendosni një vlerë më të vogël se %s'
+            },
+            mac: {
+                'default': 'Ju lutem vendosni një adresë MAC të vlefshme'
+            },
+            meid: {
+                'default': 'Ju lutem vendosni një numër MEID të vlefshëm'
+            },
+            notEmpty: {
+                'default': 'Ju lutem vendosni një vlerë'
+            },
+            numeric: {
+                'default': 'Ju lutem vendosni një numër me presje notuese të saktë'
+            },
+            phone: {
+                'default': 'Ju lutem vendosni një numër telefoni të vlefshëm',
+                country: 'Ju lutem vendosni një numër telefoni të vlefshëm në %s',
+                countries: {
+                    AE: 'Emiratet e Bashkuara Arabe',
+                    BG: 'Bullgari',
+                    BR: 'Brazil',
+                    CN: 'Kinë',
+                    CZ: 'Republika Çeke',
+                    DE: 'Gjermani',
+                    DK: 'Danimarkë',
+                    ES: 'Spanjë',
+                    FR: 'Francë',
+                    GB: 'Mbretëria e Bashkuar',
+                    IN: 'Indi',
+                    MA: 'Marok',
+                    NL: 'Hollandë',
+                    PK: 'Pakistan',
+                    RO: 'Rumani',
+                    RU: 'Rusi',
+                    SK: 'Sllovaki',
+                    TH: 'Tajlandë',
+                    US: 'SHBA',
+                    VE: 'Venezuelë'
+                }
+            },
+            promise: {
+                'default': 'Ju lutem vendosni një vlerë të vlefshme'
+            },
+            regexp: {
+                'default': 'Ju lutem vendosni një vlerë që përputhet me modelin'
+            },
+            remote: {
+                'default': 'Ju lutem vendosni një vlerë të vlefshme'
+            },
+            rtn: {
+                'default': 'Ju lutem vendosni një numër RTN të vlefshëm'
+            },
+            sedol: {
+                'default': 'Ju lutem vendosni një numër SEDOL të vlefshëm'
+            },
+            siren: {
+                'default': 'Ju lutem vendosni një numër SIREN të vlefshëm'
+            },
+            siret: {
+                'default': 'Ju lutem vendosni një numër SIRET të vlefshëm'
+            },
+            step: {
+                'default': 'Ju lutem vendosni një hap të vlefshëm të %s'
+            },
+            stringCase: {
+                'default': 'Ju lutem përdorni vetëm shenja të vogla të shtypit',
+                upper: 'Ju lutem përdorni vetëm shenja të mëdha të shtypit'
+            },
+            stringLength: {
+                'default': 'Ju lutem vendosni një vlerë me gjatësinë e duhur',
+                less: 'Ju lutem vendosni më pak se %s simbole',
+                more: 'Ju lutem vendosni më shumë se %s simbole',
+                between: 'Ju lutem vendosni një vlerë me gjatësi midis %s dhe %s simbole'
+            },
+            uri: {
+                'default': 'Ju lutem vendosni një URI të vlefshme'
+            },
+            uuid: {
+                'default': 'Ju lutem vendosni një numër UUID të vlefshëm',
+                version: 'Ju lutem vendosni një numër UUID version %s të vlefshëm'
+            },
+            vat: {
+                'default': 'Ju lutem vendosni një numër VAT të vlefshëm',
+                country: 'Ju lutem vendosni një numër VAT të vlefshëm në %s',
+                countries: {
+                    AT: 'Austri',
+                    BE: 'Belgjikë',
+                    BG: 'Bullgari',
+                    BR: 'Brazil',
+                    CH: 'Zvicër',
+                    CY: 'Qipro',
+                    CZ: 'Republika Çeke',
+                    DE: 'Gjermani',
+                    DK: 'Danimarkë',
+                    EE: 'Estoni',
+                    ES: 'Spanjë',
+                    FI: 'Finlandë',
+                    FR: 'Francë',
+                    GB: 'Mbretëria e Bashkuar',
+                    GR: 'Greqi',
+                    EL: 'Greqi',
+                    HU: 'Hungari',
+                    HR: 'Kroaci',
+                    IE: 'Irlandë',
+                    IS: 'Iclandë',
+                    IT: 'Itali',
+                    LT: 'Lituani',
+                    LU: 'Luksemburg',
+                    LV: 'Letoni',
+                    MT: 'Maltë',
+                    NL: 'Hollandë',
+                    NO: 'Norvegji',
+                    PL: 'Poloni',
+                    PT: 'Portugali',
+                    RO: 'Rumani',
+                    RU: 'Rusi',
+                    RS: 'Serbi',
+                    SE: 'Suedi',
+                    SI: 'Slloveni',
+                    SK: 'Sllovaki',
+                    VE: 'Venezuelë',
+                    ZA: 'Afrikë e Jugut'
+                }
+            },
+            vin: {
+                'default': 'Ju lutem vendosni një numër VIN të vlefshëm'
+            },
+            zipCode: {
+                'default': 'Ju lutem vendosni një kod postar të vlefshëm',
+                country: 'Ju lutem vendosni një kod postar të vlefshëm në %s',
+                countries: {
+                    AT: 'Austri',
+                    BG: 'Bullgari',
+                    BR: 'Brazil',
+                    CA: 'Kanada',
+                    CH: 'Zvicër',
+                    CZ: 'Republika Çeke',
+                    DE: 'Gjermani',
+                    DK: 'Danimarkë',
+                    ES: 'Spanjë',
+                    FR: 'Francë',
+                    GB: 'Mbretëria e Bashkuar',
+                    IE: 'Irlandë',
+                    IN: 'Indi',
+                    IT: 'Itali',
+                    MA: 'Marok',
+                    NL: 'Hollandë',
+                    PL: 'Poloni',
+                    PT: 'Portugali',
+                    RO: 'Rumani',
+                    RU: 'Rusi',
+                    SE: 'Suedi',
+                    SG: 'Singapor',
+                    SK: 'Sllovaki',
+                    US: 'SHBA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/sr_RS.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Serbian Latin language package
+     * Translated by @markocrni
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'sr_RS': {
+            base64: {
+                'default': 'Molimo da unesete važeći base 64 enkodovan'
+            },
+            between: {
+                'default': 'Molimo da unesete vrednost između %s i %s',
+                notInclusive: 'Molimo da unesete vrednost strogo između %s i %s'
+            },
+            bic: {
+                'default': 'Molimo da unesete ispravan BIC broj'
+            },
+            callback: {
+                'default': 'Molimo da unesete važeću vrednost'
+            },
+            choice: {
+                'default': 'Molimo da unesete važeću vrednost',
+                less: 'Molimo da odaberete minimalno %s opciju(a)',
+                more: 'Molimo da odaberete maksimalno %s opciju(a)',
+                between: 'Molimo odaberite %s - %s opcije(a)'
+            },
+            color: {
+                'default': 'Molimo da unesete ispravnu boju'
+            },
+            creditCard: {
+                'default': 'Molimo da unesete ispravan broj kreditne kartice'
+            },
+            cusip: {
+                'default': 'Molimo da unesete ispravan CUSIP broj'
+            },
+            cvv: {
+                'default': 'Molimo da unesete ispravan CVV broj'
+            },
+            date: {
+                'default': 'Molimo da unesete ispravan datum',
+                min: 'Molimo da unesete datum posle %s',
+                max: 'Molimo da unesete datum pre %s',
+                range: 'Molimo da unesete datum od %s do %s'
+            },
+            different: {
+                'default': 'Molimo da unesete drugu vrednost'
+            },
+            digits: {
+                'default': 'Molimo da unesete samo cifre'
+            },
+            ean: {
+                'default': 'Molimo da unesete ispravan EAN broj'
+            },
+            ein: {
+                'default': 'Molimo da unesete ispravan EIN broj'
+            },
+            emailAddress: {
+                'default': 'Molimo da unesete važeću e-mail adresu'
+            },
+            file: {
+                'default': 'Molimo da unesete ispravan fajl'
+            },
+            greaterThan: {
+                'default': 'Molimo da unesete vrednost veću ili jednaku od %s',
+                notInclusive: 'Molimo da unesete vrednost veću od %s'
+            },
+            grid: {
+                'default': 'Molimo da unesete ispravan GRId broj'
+            },
+            hex: {
+                'default': 'Molimo da unesete ispravan heksadecimalan broj'
+            },
+            iban: {
+                'default': 'Molimo da unesete ispravan IBAN broj',
+                country: 'Molimo da unesete ispravan IBAN broj %s',
+                countries: {
+                    AD: 'Andore',
+                    AE: 'Ujedinjenih Arapskih Emirata',
+                    AL: 'Albanije',
+                    AO: 'Angole',
+                    AT: 'Austrije',
+                    AZ: 'Azerbejdžana',
+                    BA: 'Bosne i Hercegovine',
+                    BE: 'Belgije',
+                    BF: 'Burkina Fasa',
+                    BG: 'Bugarske',
+                    BH: 'Bahraina',
+                    BI: 'Burundija',
+                    BJ: 'Benina',
+                    BR: 'Brazila',
+                    CH: 'Švajcarske',
+                    CI: 'Obale slonovače',
+                    CM: 'Kameruna',
+                    CR: 'Kostarike',
+                    CV: 'Zelenorotskih Ostrva',
+                    CY: 'Kipra',
+                    CZ: 'Češke',
+                    DE: 'Nemačke',
+                    DK: 'Danske',
+                    DO: 'Dominike',
+                    DZ: 'Alžira',
+                    EE: 'Estonije',
+                    ES: 'Španije',
+                    FI: 'Finske',
+                    FO: 'Farskih Ostrva',
+                    FR: 'Francuske',
+                    GB: 'Engleske',
+                    GE: 'Džordžije',
+                    GI: 'Giblartara',
+                    GL: 'Grenlanda',
+                    GR: 'Grčke',
+                    GT: 'Gvatemale',
+                    HR: 'Hrvatske',
+                    HU: 'Mađarske',
+                    IE: 'Irske',
+                    IL: 'Izraela',
+                    IR: 'Irana',
+                    IS: 'Islanda',
+                    IT: 'Italije',
+                    JO: 'Jordana',
+                    KW: 'Kuvajta',
+                    KZ: 'Kazahstana',
+                    LB: 'Libana',
+                    LI: 'Lihtenštajna',
+                    LT: 'Litvanije',
+                    LU: 'Luksemburga',
+                    LV: 'Latvije',
+                    MC: 'Monaka',
+                    MD: 'Moldove',
+                    ME: 'Crne Gore',
+                    MG: 'Madagaskara',
+                    MK: 'Makedonije',
+                    ML: 'Malija',
+                    MR: 'Mauritanije',
+                    MT: 'Malte',
+                    MU: 'Mauricijusa',
+                    MZ: 'Mozambika',
+                    NL: 'Holandije',
+                    NO: 'Norveške',
+                    PK: 'Pakistana',
+                    PL: 'Poljske',
+                    PS: 'Palestine',
+                    PT: 'Portugala',
+                    QA: 'Katara',
+                    RO: 'Rumunije',
+                    RS: 'Srbije',
+                    SA: 'Saudijske Arabije',
+                    SE: 'Švedske',
+                    SI: 'Slovenije',
+                    SK: 'Slovačke',
+                    SM: 'San Marina',
+                    SN: 'Senegala',
+                    TL: 'Источни Тимор',
+                    TN: 'Tunisa',
+                    TR: 'Turske',
+                    VG: 'Britanskih Devičanskih Ostrva',
+                    XK: 'Република Косово'
+                }
+            },
+            id: {
+                'default': 'Molimo da unesete ispravan identifikacioni broj',
+                country: 'Molimo da unesete ispravan identifikacioni broj %s',
+                countries: {
+                    BA: 'Bosne i Herzegovine',
+                    BG: 'Bugarske',
+                    BR: 'Brazila',
+                    CH: 'Švajcarske',
+                    CL: 'Čilea',
+                    CN: 'Kine',
+                    CZ: 'Češke',
+                    DK: 'Danske',
+                    EE: 'Estonije',
+                    ES: 'Španije',
+                    FI: 'Finske',
+                    HR: 'Hrvatske',
+                    IE: 'Irske',
+                    IS: 'Islanda',
+                    LT: 'Litvanije',
+                    LV: 'Letonije',
+                    ME: 'Crne Gore',
+                    MK: 'Makedonije',
+                    NL: 'Holandije',
+                    PL: 'Poljske',
+                    RO: 'Rumunije',
+                    RS: 'Srbije',
+                    SE: 'Švedske',
+                    SI: 'Slovenije',
+                    SK: 'Slovačke',
+                    SM: 'San Marina',
+                    TH: 'Tajlanda',
+                    TR: 'Turske',
+                    ZA: 'Južne Afrike'
+                }
+            },
+            identical: {
+                'default': 'Molimo da unesete istu vrednost'
+            },
+            imei: {
+                'default': 'Molimo da unesete ispravan IMEI broj'
+            },
+            imo: {
+                'default': 'Molimo da unesete ispravan IMO broj'
+            },
+            integer: {
+                'default': 'Molimo da unesete ispravan broj'
+            },
+            ip: {
+                'default': 'Molimo da unesete ispravnu IP adresu',
+                ipv4: 'Molimo da unesete ispravnu IPv4 adresu',
+                ipv6: 'Molimo da unesete ispravnu IPv6 adresu'
+            },
+            isbn: {
+                'default': 'Molimo da unesete ispravan ISBN broj'
+            },
+            isin: {
+                'default': 'Molimo da unesete ispravan ISIN broj'
+            },
+            ismn: {
+                'default': 'Molimo da unesete ispravan ISMN broj'
+            },
+            issn: {
+                'default': 'Molimo da unesete ispravan ISSN broj'
+            },
+            lessThan: {
+                'default': 'Molimo da unesete vrednost manju ili jednaku od %s',
+                notInclusive: 'Molimo da unesete vrednost manju od %s'
+            },
+            mac: {
+                'default': 'Molimo da unesete ispravnu MAC adresu'
+            },
+            meid: {
+                'default': 'Molimo da unesete ispravan MEID broj'
+            },
+            notEmpty: {
+                'default': 'Molimo da unesete vrednost'
+            },
+            numeric: {
+                'default': 'Molimo da unesete ispravan decimalni broj'
+            },
+            phone: {
+                'default': 'Molimo da unesete ispravan broj telefona',
+                country: 'Molimo da unesete ispravan broj telefona %s',
+                countries: {
+                    AE: 'Ujedinjenih Arapskih Emirata',
+                    BG: 'Bugarske',
+                    BR: 'Brazila',
+                    CN: 'Kine',
+                    CZ: 'Češke',
+                    DE: 'Nemačke',
+                    DK: 'Danske',
+                    ES: 'Španije',
+                    FR: 'Francuske',
+                    GB: 'Engleske',
+                    IN: 'Индија',
+                    MA: 'Maroka',
+                    NL: 'Holandije',
+                    PK: 'Pakistana',
+                    RO: 'Rumunije',
+                    RU: 'Rusije',
+                    SK: 'Slovačke',
+                    TH: 'Tajlanda',
+                    US: 'Amerike',
+                    VE: 'Venecuele'
+                }
+            },
+            promise: {
+                'default': 'Molimo da unesete važeću vrednost'
+            },
+            regexp: {
+                'default': 'Molimo da unesete vrednost koja se poklapa sa paternom'
+            },
+            remote: {
+                'default': 'Molimo da unesete ispravnu vrednost'
+            },
+            rtn: {
+                'default': 'Molimo da unesete ispravan RTN broj'
+            },
+            sedol: {
+                'default': 'Molimo da unesete ispravan SEDOL broj'
+            },
+            siren: {
+                'default': 'Molimo da unesete ispravan SIREN broj'
+            },
+            siret: {
+                'default': 'Molimo da unesete ispravan SIRET broj'
+            },
+            step: {
+                'default': 'Molimo da unesete ispravan korak od %s'
+            },
+            stringCase: {
+                'default': 'Molimo da unesete samo mala slova',
+                upper: 'Molimo da unesete samo velika slova'
+            },
+            stringLength: {
+                'default': 'Molimo da unesete vrednost sa ispravnom dužinom',
+                less: 'Molimo da unesete manje od %s karaktera',
+                more: 'Molimo da unesete više od %s karaktera',
+                between: 'Molimo da unesete vrednost dužine između %s i %s karaktera'
+            },
+            uri: {
+                'default': 'Molimo da unesete ispravan URI'
+            },
+            uuid: {
+                'default': 'Molimo da unesete ispravan UUID broj',
+                version: 'Molimo da unesete ispravnu verziju UUID %s broja'
+            },
+            vat: {
+                'default': 'Molimo da unesete ispravan VAT broj',
+                country: 'Molimo da unesete ispravan VAT broj %s',
+                countries: {
+                    AT: 'Austrije',
+                    BE: 'Belgije',
+                    BG: 'Bugarske',
+                    BR: 'Brazila',
+                    CH: 'Švajcarske',
+                    CY: 'Kipra',
+                    CZ: 'Češke',
+                    DE: 'Nemačke',
+                    DK: 'Danske',
+                    EE: 'Estonije',
+                    ES: 'Španije',
+                    FI: 'Finske',
+                    FR: 'Francuske',
+                    GB: 'Engleske',
+                    GR: 'Grčke',
+                    EL: 'Grčke',
+                    HU: 'Mađarske',
+                    HR: 'Hrvatske',
+                    IE: 'Irske',
+                    IS: 'Islanda',
+                    IT: 'Italije',
+                    LT: 'Litvanije',
+                    LU: 'Luksemburga',
+                    LV: 'Letonije',
+                    MT: 'Malte',
+                    NL: 'Holandije',
+                    NO: 'Norveške',
+                    PL: 'Poljske',
+                    PT: 'Portugala',
+                    RO: 'Romunje',
+                    RU: 'Rusije',
+                    RS: 'Srbije',
+                    SE: 'Švedske',
+                    SI: 'Slovenije',
+                    SK: 'Slovačke',
+                    VE: 'Venecuele',
+                    ZA: 'Južne Afrike'
+                }
+            },
+            vin: {
+                'default': 'Molimo da unesete ispravan VIN broj'
+            },
+            zipCode: {
+                'default': 'Molimo da unesete ispravan poštanski broj',
+                country: 'Molimo da unesete ispravan poštanski broj %s',
+                countries: {
+                    AT: 'Austrije',
+                    BG: 'Bugarske',
+                    BR: 'Brazila',
+                    CA: 'Kanade',
+                    CH: 'Švajcarske',
+                    CZ: 'Češke',
+                    DE: 'Nemačke',
+                    DK: 'Danske',
+                    ES: 'Španije',
+                    FR: 'Francuske',
+                    GB: 'Engleske',
+                    IE: 'Irske',
+                    IN: 'Индија',
+                    IT: 'Italije',
+                    MA: 'Maroka',
+                    NL: 'Holandije',
+                    PL: 'Poljske',
+                    PT: 'Portugala',
+                    RO: 'Rumunije',
+                    RU: 'Rusije',
+                    SE: 'Švedske',
+                    SG: 'Singapura',
+                    SK: 'Slovačke',
+                    US: 'Amerike'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/sv_SE.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Swedish language package
+     * Translated by @ulsa
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'sv_SE': {
+            base64: {
+                'default': 'Vänligen mata in ett giltigt Base64-kodat värde'
+            },
+            between: {
+                'default': 'Vänligen mata in ett värde mellan %s och %s',
+                notInclusive: 'Vänligen mata in ett värde strikt mellan %s och %s'
+            },
+            bic: {
+                'default': 'Vänligen mata in ett giltigt BIC-nummer'
+            },
+            callback: {
+                'default': 'Vänligen mata in ett giltigt värde'
+            },
+            choice: {
+                'default': 'Vänligen mata in ett giltigt värde',
+                less: 'Vänligen välj minst %s alternativ',
+                more: 'Vänligen välj max %s alternativ',
+                between: 'Vänligen välj %s - %s alternativ'
+            },
+            color: {
+                'default': 'Vänligen mata in en giltig färg'
+            },
+            creditCard: {
+                'default': 'Vänligen mata in ett giltigt kredikortsnummer'
+            },
+            cusip: {
+                'default': 'Vänligen mata in ett giltigt CUSIP-nummer'
+            },
+            cvv: {
+                'default': 'Vänligen mata in ett giltigt CVV-nummer'
+            },
+            date: {
+                'default': 'Vänligen mata in ett giltigt datum',
+                min: 'Vänligen mata in ett datum efter %s',
+                max: 'Vänligen mata in ett datum före %s',
+                range: 'Vänligen mata in ett datum i intervallet %s - %s'
+            },
+            different: {
+                'default': 'Vänligen mata in ett annat värde'
+            },
+            digits: {
+                'default': 'Vänligen mata in endast siffror'
+            },
+            ean: {
+                'default': 'Vänligen mata in ett giltigt EAN-nummer'
+            },
+            ein: {
+                'default': 'Vänligen mata in ett giltigt EIN-nummer'
+            },
+            emailAddress: {
+                'default': 'Vänligen mata in en giltig emailadress'
+            },
+            file: {
+                'default': 'Vänligen välj en giltig fil'
+            },
+            greaterThan: {
+                'default': 'Vänligen mata in ett värde större än eller lika med %s',
+                notInclusive: 'Vänligen mata in ett värde större än %s'
+            },
+            grid: {
+                'default': 'Vänligen mata in ett giltigt GRID-nummer'
+            },
+            hex: {
+                'default': 'Vänligen mata in ett giltigt hexadecimalt tal'
+            },
+            iban: {
+                'default': 'Vänligen mata in ett giltigt IBAN-nummer',
+                country: 'Vänligen mata in ett giltigt IBAN-nummer i %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Förenade Arabemiraten',
+                    AL: 'Albanien',
+                    AO: 'Angola',
+                    AT: 'Österrike',
+                    AZ: 'Azerbadjan',
+                    BA: 'Bosnien och Herzegovina',
+                    BE: 'Belgien',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgarien',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CI: 'Elfenbenskusten',
+                    CM: 'Kamerun',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Cypern',
+                    CZ: 'Tjeckien',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    DO: 'Dominikanska Republiken',
+                    DZ: 'Algeriet',
+                    EE: 'Estland',
+                    ES: 'Spanien',
+                    FI: 'Finland',
+                    FO: 'Färöarna',
+                    FR: 'Frankrike',
+                    GB: 'Storbritannien',
+                    GE: 'Georgien',
+                    GI: 'Gibraltar',
+                    GL: 'Grönland',
+                    GR: 'Greekland',
+                    GT: 'Guatemala',
+                    HR: 'Kroatien',
+                    HU: 'Ungern',
+                    IE: 'Irland',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Island',
+                    IT: 'Italien',
+                    JO: 'Jordanien',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakstan',
+                    LB: 'Libanon',
+                    LI: 'Lichtenstein',
+                    LT: 'Litauen',
+                    LU: 'Luxemburg',
+                    LV: 'Lettland',
+                    MC: 'Monaco',
+                    MD: 'Moldovien',
+                    ME: 'Montenegro',
+                    MG: 'Madagaskar',
+                    MK: 'Makedonien',
+                    ML: 'Mali',
+                    MR: 'Mauretanien',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Holland',
+                    NO: 'Norge',
+                    PK: 'Pakistan',
+                    PL: 'Polen',
+                    PS: 'Palestina',
+                    PT: 'Portugal',
+                    QA: 'Qatar',
+                    RO: 'Rumänien',
+                    RS: 'Serbien',
+                    SA: 'Saudiarabien',
+                    SE: 'Sverige',
+                    SI: 'Slovenien',
+                    SK: 'Slovakien',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Östtimor',
+                    TN: 'Tunisien',
+                    TR: 'Turkiet',
+                    VG: 'Brittiska Jungfruöarna',
+                    XK: 'Republiken Kosovo'
+                }
+            },
+            id: {
+                'default': 'Vänligen mata in ett giltigt identifikationsnummer',
+                country: 'Vänligen mata in ett giltigt identifikationsnummer i %s',
+                countries: {
+                    BA: 'Bosnien och Hercegovina',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CL: 'Chile',
+                    CN: 'Kina',
+                    CZ: 'Tjeckien',
+                    DK: 'Danmark',
+                    EE: 'Estland',
+                    ES: 'Spanien',
+                    FI: 'Finland',
+                    HR: 'Kroatien',
+                    IE: 'Irland',
+                    IS: 'Island',
+                    LT: 'Litauen',
+                    LV: 'Lettland',
+                    ME: 'Montenegro',
+                    MK: 'Makedonien',
+                    NL: 'Nederländerna',
+                    PL: 'Polen',
+                    RO: 'Rumänien',
+                    RS: 'Serbien',
+                    SE: 'Sverige',
+                    SI: 'Slovenien',
+                    SK: 'Slovakien',
+                    SM: 'San Marino',
+                    TH: 'Thailand',
+                    TR: 'Turkiet',
+                    ZA: 'Sydafrika'
+                }
+            },
+            identical: {
+                'default': 'Vänligen mata in samma värde'
+            },
+            imei: {
+                'default': 'Vänligen mata in ett giltigt IMEI-nummer'
+            },
+            imo: {
+                'default': 'Vänligen mata in ett giltigt IMO-nummer'
+            },
+            integer: {
+                'default': 'Vänligen mata in ett giltigt heltal'
+            },
+            ip: {
+                'default': 'Vänligen mata in en giltig IP-adress',
+                ipv4: 'Vänligen mata in en giltig IPv4-adress',
+                ipv6: 'Vänligen mata in en giltig IPv6-adress'
+            },
+            isbn: {
+                'default': 'Vänligen mata in ett giltigt ISBN-nummer'
+            },
+            isin: {
+                'default': 'Vänligen mata in ett giltigt ISIN-nummer'
+            },
+            ismn: {
+                'default': 'Vänligen mata in ett giltigt ISMN-nummer'
+            },
+            issn: {
+                'default': 'Vänligen mata in ett giltigt ISSN-nummer'
+            },
+            lessThan: {
+                'default': 'Vänligen mata in ett värde mindre än eller lika med %s',
+                notInclusive: 'Vänligen mata in ett värde mindre än %s'
+            },
+            mac: {
+                'default': 'Vänligen mata in en giltig MAC-adress'
+            },
+            meid: {
+                'default': 'Vänligen mata in ett giltigt MEID-nummer'
+            },
+            notEmpty: {
+                'default': 'Vänligen mata in ett värde'
+            },
+            numeric: {
+                'default': 'Vänligen mata in ett giltigt flyttal'
+            },
+            phone: {
+                'default': 'Vänligen mata in ett giltigt telefonnummer',
+                country: 'Vänligen mata in ett giltigt telefonnummer i %s',
+                countries: {
+                    AE: 'Förenade Arabemiraten',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CN: 'Kina',
+                    CZ: 'Tjeckien',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    ES: 'Spanien',
+                    FR: 'Frankrike',
+                    GB: 'Storbritannien',
+                    IN: 'Indien',
+                    MA: 'Marocko',
+                    NL: 'Holland',
+                    PK: 'Pakistan',
+                    RO: 'Rumänien',
+                    RU: 'Ryssland',
+                    SK: 'Slovakien',
+                    TH: 'Thailand',
+                    US: 'USA',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Vänligen mata in ett giltigt värde'
+            },
+            regexp: {
+                'default': 'Vänligen mata in ett värde som matchar uttrycket'
+            },
+            remote: {
+                'default': 'Vänligen mata in ett giltigt värde'
+            },
+            rtn: {
+                'default': 'Vänligen mata in ett giltigt RTN-nummer'
+            },
+            sedol: {
+                'default': 'Vänligen mata in ett giltigt SEDOL-nummer'
+            },
+            siren: {
+                'default': 'Vänligen mata in ett giltigt SIREN-nummer'
+            },
+            siret: {
+                'default': 'Vänligen mata in ett giltigt SIRET-nummer'
+            },
+            step: {
+                'default': 'Vänligen mata in ett giltigt steg av %s'
+            },
+            stringCase: {
+                'default': 'Vänligen mata in endast små bokstäver',
+                upper: 'Vänligen mata in endast stora bokstäver'
+            },
+            stringLength: {
+                'default': 'Vänligen mata in ett värde med giltig längd',
+                less: 'Vänligen mata in färre än %s tecken',
+                more: 'Vänligen mata in fler än %s tecken',
+                between: 'Vänligen mata in ett värde mellan %s och %s tecken långt'
+            },
+            uri: {
+                'default': 'Vänligen mata in en giltig URI'
+            },
+            uuid: {
+                'default': 'Vänligen mata in ett giltigt UUID-nummer',
+                version: 'Vänligen mata in ett giltigt UUID-nummer av version %s'
+            },
+            vat: {
+                'default': 'Vänligen mata in ett giltigt momsregistreringsnummer',
+                country: 'Vänligen mata in ett giltigt momsregistreringsnummer i %s',
+                countries: {
+                    AT: 'Österrike',
+                    BE: 'Belgien',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CH: 'Schweiz',
+                    CY: 'Cypern',
+                    CZ: 'Tjeckien',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    EE: 'Estland',
+                    ES: 'Spanien',
+                    FI: 'Finland',
+                    FR: 'Frankrike',
+                    GB: 'Förenade Kungariket',
+                    GR: 'Grekland',
+                    EL: 'Grekland',
+                    HU: 'Ungern',
+                    HR: 'Kroatien',
+                    IE: 'Irland',
+                    IS: 'Island',
+                    IT: 'Italien',
+                    LT: 'Litauen',
+                    LU: 'Luxemburg',
+                    LV: 'Lettland',
+                    MT: 'Malta',
+                    NL: 'Nederländerna',
+                    NO: 'Norge',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Rumänien',
+                    RU: 'Ryssland',
+                    RS: 'Serbien',
+                    SE: 'Sverige',
+                    SI: 'Slovenien',
+                    SK: 'Slovakien',
+                    VE: 'Venezuela',
+                    ZA: 'Sydafrika'
+                }
+            },
+            vin: {
+                'default': 'Vänligen mata in ett giltigt VIN-nummer'
+            },
+            zipCode: {
+                'default': 'Vänligen mata in ett giltigt postnummer',
+                country: 'Vänligen mata in ett giltigt postnummer i %s',
+                countries: {
+                    AT: 'Österrike',
+                    BG: 'Bulgarien',
+                    BR: 'Brasilien',
+                    CA: 'Kanada',
+                    CH: 'Schweiz',
+                    CZ: 'Tjeckien',
+                    DE: 'Tyskland',
+                    DK: 'Danmark',
+                    ES: 'Spanien',
+                    FR: 'Frankrike',
+                    GB: 'Förenade Kungariket',
+                    IE: 'Irland',
+                    IN: 'Indien',
+                    IT: 'Italien',
+                    MA: 'Marocko',
+                    NL: 'Nederländerna',
+                    PL: 'Polen',
+                    PT: 'Portugal',
+                    RO: 'Rumänien',
+                    RU: 'Ryssland',
+                    SE: 'Sverige',
+                    SG: 'Singapore',
+                    SK: 'Slovakien',
+                    US: 'USA'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/th_TH.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Thai language package
+     * Translated by @figgaro
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'th_TH': {
+            base64: {
+                'default': 'กรุณาระบุ base 64 encoded ให้ถูกต้อง'
+            },
+            between: {
+                'default': 'กรุณาระบุค่าระหว่าง %s และ %s',
+                notInclusive: 'กรุณาระบุค่าระหว่าง %s และ %s เท่านั้น'
+            },
+            bic: {
+                'default': 'กรุณาระบุหมายเลข BIC ให้ถูกต้อง'
+            },
+            callback: {
+                'default': 'กรุณาระบุค่าให้ถูก'
+            },
+            choice: {
+                'default': 'กรุณาระบุค่าให้ถูกต้อง',
+                less: 'โปรดเลือกตัวเลือก %s ที่ต่ำสุด',
+                more: 'โปรดเลือกตัวเลือก %s ที่สูงสุด',
+                between: 'กรุณาเลือก %s - %s ที่มีอยู่'
+            },
+            color: {
+                'default': 'กรุณาระบุค่าสี color ให้ถูกต้อง'
+            },
+            creditCard: {
+                'default': 'กรุณาระบุเลขที่บัตรเครดิตให้ถูกต้อง'
+            },
+            cusip: {
+                'default': 'กรุณาระบุหมายเลข CUSIP ให้ถูกต้อง'
+            },
+            cvv: {
+                'default': 'กรุณาระบุ CVV ให้ถูกต้อง'
+            },
+            date: {
+                'default': 'กรุณาระบุวันที่ให้ถูกต้อง',
+                min: 'ไม่สามารถระบุวันที่ได้ก่อน %s',
+                max: 'ไม่สามารถระบุวันที่ได้หลังจาก %s',
+                range: 'โปรดระบุวันที่ระหว่าง %s - %s'
+            },
+            different: {
+                'default': 'กรุณาระบุค่าอื่นที่แตกต่าง'
+            },
+            digits: {
+                'default': 'กรุณาระบุตัวเลขเท่านั้น'
+            },
+            ean: {
+                'default': 'กรุณาระบุหมายเลข EAN ให้ถูกต้อง'
+            },
+            ein: {
+                'default': 'กรุณาระบุหมายเลข EIN ให้ถูกต้อง'
+            },
+            emailAddress: {
+                'default': 'กรุณาระบุอีเมล์ให้ถูกต้อง'
+            },
+            file: {
+                'default': 'กรุณาเลือกไฟล์'
+            },
+            greaterThan: {
+                'default': 'กรุณาระบุค่ามากกว่าหรือเท่ากับ %s',
+                notInclusive: 'กรุณาระบุค่ามากกว่า %s'
+            },
+            grid: {
+                'default': 'กรุณาระบุหมายลข GRId ให้ถูกต้อง'
+            },
+            hex: {
+                'default': 'กรุณาระบุเลขฐานสิบหกให้ถูกต้อง'
+            },
+            iban: {
+                'default': 'กรุณาระบุหมายเลข IBAN ให้ถูกต้อง',
+                country: 'กรุณาระบุหมายเลข IBAN ใน %s',
+                countries: {
+                    AD: 'อันดอร์รา',
+                    AE: 'สหรัฐอาหรับเอมิเรตส์',
+                    AL: 'แอลเบเนีย',
+                    AO: 'แองโกลา',
+                    AT: 'ออสเตรีย',
+                    AZ: 'อาเซอร์ไบจาน',
+                    BA: 'บอสเนียและเฮอร์เซโก',
+                    BE: 'ประเทศเบลเยียม',
+                    BF: 'บูร์กินาฟาโซ',
+                    BG: 'บัลแกเรีย',
+                    BH: 'บาห์เรน',
+                    BI: 'บุรุนดี',
+                    BJ: 'เบนิน',
+                    BR: 'บราซิล',
+                    CH: 'สวิตเซอร์แลนด์',
+                    CI: 'ไอวอรี่โคสต์',
+                    CM: 'แคเมอรูน',
+                    CR: 'คอสตาริกา',
+                    CV: 'เคปเวิร์ด',
+                    CY: 'ไซปรัส',
+                    CZ: 'สาธารณรัฐเชค',
+                    DE: 'เยอรมนี',
+                    DK: 'เดนมาร์ก',
+                    DO: 'สาธารณรัฐโดมินิกัน',
+                    DZ: 'แอลจีเรีย',
+                    EE: 'เอสโตเนีย',
+                    ES: 'สเปน',
+                    FI: 'ฟินแลนด์',
+                    FO: 'หมู่เกาะแฟโร',
+                    FR: 'ฝรั่งเศส',
+                    GB: 'สหราชอาณาจักร',
+                    GE: 'จอร์เจีย',
+                    GI: 'ยิบรอลตา',
+                    GL: 'กรีนแลนด์',
+                    GR: 'กรีซ',
+                    GT: 'กัวเตมาลา',
+                    HR: 'โครเอเชีย',
+                    HU: 'ฮังการี',
+                    IE: 'ไอร์แลนด์',
+                    IL: 'อิสราเอล',
+                    IR: 'อิหร่าน',
+                    IS: 'ไอซ์',
+                    IT: 'อิตาลี',
+                    JO: 'จอร์แดน',
+                    KW: 'คูเวต',
+                    KZ: 'คาซัคสถาน',
+                    LB: 'เลบานอน',
+                    LI: 'Liechtenstein',
+                    LT: 'ลิทัวเนีย',
+                    LU: 'ลักเซมเบิร์ก',
+                    LV: 'ลัตเวีย',
+                    MC: 'โมนาโก',
+                    MD: 'มอลโดวา',
+                    ME: 'มอนเตเนโก',
+                    MG: 'มาดากัสการ์',
+                    MK: 'มาซิโดเนีย',
+                    ML: 'มาลี',
+                    MR: 'มอริเตเนีย',
+                    MT: 'มอลตา',
+                    MU: 'มอริเชียส',
+                    MZ: 'โมซัมบิก',
+                    NL: 'เนเธอร์แลนด์',
+                    NO: 'นอร์เวย์',
+                    PK: 'ปากีสถาน',
+                    PL: 'โปแลนด์',
+                    PS: 'ปาเลสไตน์',
+                    PT: 'โปรตุเกส',
+                    QA: 'กาตาร์',
+                    RO: 'โรมาเนีย',
+                    RS: 'เซอร์เบีย',
+                    SA: 'ซาอุดิอารเบีย',
+                    SE: 'สวีเดน',
+                    SI: 'สโลวีเนีย',
+                    SK: 'สโลวาเกีย',
+                    SM: 'ซานมาริโน',
+                    SN: 'เซเนกัล',
+                    TL: 'ติมอร์ตะวันออก',
+                    TN: 'ตูนิเซีย',
+                    TR: 'ตุรกี',
+                    VG: 'หมู่เกาะบริติชเวอร์จิน',
+                    XK: 'สาธารณรัฐโคโซโว'
+                }
+            },
+            id: {
+                'default': 'โปรดระบุเลขบัตรประจำตัวประชาชนให้ถูกต้อง',
+                country: 'โปรดระบุเลขบัตรประจำตัวประชาชนใน %s ให้ถูกต้อง',
+                countries: {
+                    BA: 'บอสเนียและเฮอร์เซโก',
+                    BG: 'บัลแกเรีย',
+                    BR: 'บราซิล',
+                    CH: 'วิตเซอร์แลนด์',
+                    CL: 'ชิลี',
+                    CN: 'จีน',
+                    CZ: 'สาธารณรัฐเชค',
+                    DK: 'เดนมาร์ก',
+                    EE: 'เอสโตเนีย',
+                    ES: 'สเปน',
+                    FI: 'ฟินแลนด์',
+                    HR: 'โครเอเชีย',
+                    IE: 'ไอร์แลนด์',
+                    IS: 'ไอซ์',
+                    LT: 'ลิทัวเนีย',
+                    LV: 'ลัตเวีย',
+                    ME: 'มอนเตเนโก',
+                    MK: 'มาซิโดเนีย',
+                    NL: 'เนเธอร์แลนด์',
+                    PL: 'โปแลนด์',
+                    RO: 'โรมาเนีย',
+                    RS: 'เซอร์เบีย',
+                    SE: 'สวีเดน',
+                    SI: 'สโลวีเนีย',
+                    SK: 'สโลวาเกีย',
+                    SM: 'ซานมาริโน',
+                    TH: 'ไทย',
+                    TR: 'ตุรกี',
+                    ZA: 'แอฟริกาใต้'
+                }
+            },
+            identical: {
+                'default': 'โปรดระบุค่าให้ตรง'
+            },
+            imei: {
+                'default': 'โปรดระบุหมายเลข IMEI ให้ถูกต้อง'
+            },
+            imo: {
+                'default': 'โปรดระบุหมายเลข IMO ให้ถูกต้อง'
+            },
+            integer: {
+                'default': 'โปรดระบุตัวเลขให้ถูกต้อง'
+            },
+            ip: {
+                'default': 'โปรดระบุ IP address ให้ถูกต้อง',
+                ipv4: 'โปรดระบุ IPv4 address ให้ถูกต้อง',
+                ipv6: 'โปรดระบุ IPv6 address ให้ถูกต้อง'
+            },
+            isbn: {
+                'default': 'โปรดระบุหมายเลข ISBN ให้ถูกต้อง'
+            },
+            isin: {
+                'default': 'โปรดระบุหมายเลข ISIN ให้ถูกต้อง'
+            },
+            ismn: {
+                'default': 'โปรดระบุหมายเลข ISMN ให้ถูกต้อง'
+            },
+            issn: {
+                'default': 'โปรดระบุหมายเลข ISSN ให้ถูกต้อง'
+            },
+            lessThan: {
+                'default': 'โปรดระบุค่าน้อยกว่าหรือเท่ากับ %s',
+                notInclusive: 'โปรดระบุค่าน้อยกว่า %s'
+            },
+            mac: {
+                'default': 'โปรดระบุหมายเลข MAC address ให้ถูกต้อง'
+            },
+            meid: {
+                'default': 'โปรดระบุหมายเลข MEID ให้ถูกต้อง'
+            },
+            notEmpty: {
+                'default': 'โปรดระบุค่า'
+            },
+            numeric: {
+                'default': 'โปรดระบุเลขหน่วยหรือจำนวนทศนิยม ให้ถูกต้อง'
+            },
+            phone: {
+                'default': 'โปรดระบุหมายเลขโทรศัพท์ให้ถูกต้อง',
+                country: 'โปรดระบุหมายเลขโทรศัพท์ใน %s ให้ถูกต้อง',
+                countries: {
+                    AE: 'สหรัฐอาหรับเอมิเรตส์',
+                    BG: 'บัลแกเรีย',
+                    BR: 'บราซิล',
+                    CN: 'จีน',
+                    CZ: 'สาธารณรัฐเชค',
+                    DE: 'เยอรมนี',
+                    DK: 'เดนมาร์ก',
+                    ES: 'สเปน',
+                    FR: 'ฝรั่งเศส',
+                    GB: 'สหราชอาณาจักร',
+                    IN: 'อินเดีย',
+                    MA: 'โมร็อกโก',
+                    NL: 'เนเธอร์แลนด์',
+                    PK: 'ปากีสถาน',
+                    RO: 'โรมาเนีย',
+                    RU: 'รัสเซีย',
+                    SK: 'สโลวาเกีย',
+                    TH: 'ไทย',
+                    US: 'สหรัฐอเมริกา',
+                    VE: 'เวเนซูเอลา'
+                }
+            },
+            promise: {
+                'default': 'กรุณาระบุค่าให้ถูก'
+            },
+            regexp: {
+                'default': 'โปรดระบุค่าให้ตรงกับรูปแบบที่กำหนด'
+            },
+            remote: {
+                'default': 'โปรดระบุค่าให้ถูกต้อง'
+            },
+            rtn: {
+                'default': 'โปรดระบุหมายเลข RTN ให้ถูกต้อง'
+            },
+            sedol: {
+                'default': 'โปรดระบุหมายเลข SEDOL ให้ถูกต้อง'
+            },
+            siren: {
+                'default': 'โปรดระบุหมายเลข SIREN ให้ถูกต้อง'
+            },
+            siret: {
+                'default': 'โปรดระบุหมายเลข SIRET ให้ถูกต้อง'
+            },
+            step: {
+                'default': 'โปรดระบุลำดับของ %s'
+            },
+            stringCase: {
+                'default': 'โปรดระบุตัวอักษรพิมพ์เล็กเท่านั้น',
+                upper: 'โปรดระบุตัวอักษรพิมพ์ใหญ่เท่านั้น'
+            },
+            stringLength: {
+                'default': 'ค่าที่ระบุยังไม่ครบตามจำนวนที่กำหนด',
+                less: 'โปรดระบุค่าตัวอักษรน้อยกว่า %s ตัว',
+                more: 'โปรดระบุค่าตัวอักษรมากกว่า %s ตัว',
+                between: 'โปรดระบุค่าตัวอักษรระหว่าง %s ถึง %s ตัวอักษร'
+            },
+            uri: {
+                'default': 'โปรดระบุค่า URI ให้ถูกต้อง'
+            },
+            uuid: {
+                'default': 'โปรดระบุหมายเลข UUID ให้ถูกต้อง',
+                version: 'โปรดระบุหมายเลข UUID ในเวอร์ชั่น %s'
+            },
+            vat: {
+                'default': 'โปรดระบุจำนวนภาษีมูลค่าเพิ่ม',
+                country: 'โปรดระบุจำนวนภาษีมูลค่าเพิ่มใน %s',
+                countries: {
+                    AT: 'ออสเตรีย',
+                    BE: 'เบลเยี่ยม',
+                    BG: 'บัลแกเรีย',
+                    BR: 'บราซิล',
+                    CH: 'วิตเซอร์แลนด์',
+                    CY: 'ไซปรัส',
+                    CZ: 'สาธารณรัฐเชค',
+                    DE: 'เยอรมัน',
+                    DK: 'เดนมาร์ก',
+                    EE: 'เอสโตเนีย',
+                    ES: 'สเปน',
+                    FI: 'ฟินแลนด์',
+                    FR: 'ฝรั่งเศส',
+                    GB: 'สหราชอาณาจักร',
+                    GR: 'กรีซ',
+                    EL: 'กรีซ',
+                    HU: 'ฮังการี',
+                    HR: 'โครเอเชีย',
+                    IE: 'ไอร์แลนด์',
+                    IS: 'ไอซ์',
+                    IT: 'อิตาลี',
+                    LT: 'ลิทัวเนีย',
+                    LU: 'ลักเซมเบิร์ก',
+                    LV: 'ลัตเวีย',
+                    MT: 'มอลตา',
+                    NL: 'เนเธอร์แลนด์',
+                    NO: 'นอร์เวย์',
+                    PL: 'โปแลนด์',
+                    PT: 'โปรตุเกส',
+                    RO: 'โรมาเนีย',
+                    RU: 'รัสเซีย',
+                    RS: 'เซอร์เบีย',
+                    SE: 'สวีเดน',
+                    SI: 'สโลวีเนีย',
+                    SK: 'สโลวาเกีย',
+                    VE: 'เวเนซูเอลา',
+                    ZA: 'แอฟริกาใต้'
+                }
+            },
+            vin: {
+                'default': 'โปรดระบุหมายเลข VIN ให้ถูกต้อง'
+            },
+            zipCode: {
+                'default': 'โปรดระบุรหัสไปรษณีย์ให้ถูกต้อง',
+                country: 'โปรดระบุรหัสไปรษณีย์ให้ถูกต้องใน %s',
+                countries: {
+                    AT: 'ออสเตรีย',
+                    BG: 'บัลแกเรีย',
+                    BR: 'บราซิล',
+                    CA: 'แคนาดา',
+                    CH: 'วิตเซอร์แลนด์',
+                    CZ: 'สาธารณรัฐเชค',
+                    DE: 'เยอรมนี',
+                    DK: 'เดนมาร์ก',
+                    ES: 'สเปน',
+                    FR: 'ฝรั่งเศส',
+                    GB: 'สหราชอาณาจักร',
+                    IE: 'ไอร์แลนด์',
+                    IN: 'อินเดีย',
+                    IT: 'อิตาลี',
+                    MA: 'โมร็อกโก',
+                    NL: 'เนเธอร์แลนด์',
+                    PL: 'โปแลนด์',
+                    PT: 'โปรตุเกส',
+                    RO: 'โรมาเนีย',
+                    RU: 'รัสเซีย',
+                    SE: 'สวีเดน',
+                    SG: 'สิงคโปร์',
+                    SK: 'สโลวาเกีย',
+                    US: 'สหรัฐอเมริกา'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/tr_TR.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Turkish language package
+     * Translated By @CeRBeR666
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'tr_TR': {
+            base64: {
+                'default': 'Lütfen 64 bit tabanına uygun bir giriş yapınız'
+            },
+            between: {
+                'default': 'Lütfen %s ile %s arasında bir değer giriniz',
+                notInclusive: 'Lütfen sadece %s ile %s arasında bir değer giriniz'
+            },
+            bic: {
+                'default': 'Lütfen geçerli bir BIC numarası giriniz'
+            },
+            callback: {
+                'default': 'Lütfen geçerli bir değer giriniz'
+            },
+            choice: {
+                'default': 'Lütfen geçerli bir değer giriniz',
+                less: 'Lütfen minimum %s kadar değer giriniz',
+                more: 'Lütfen maksimum %s kadar değer giriniz',
+                between: 'Lütfen %s - %s arası seçiniz'
+            },
+            color: {
+                'default': 'Lütfen geçerli bir codu giriniz'
+            },
+            creditCard: {
+                'default': 'Lütfen geçerli bir kredi kartı numarası giriniz'
+            },
+            cusip: {
+                'default': 'Lütfen geçerli bir CUSIP numarası giriniz'
+            },
+            cvv: {
+                'default': 'Lütfen geçerli bir CCV numarası giriniz'
+            },
+            date: {
+                'default': 'Lütfen geçerli bir tarih giriniz',
+                min: 'Lütfen %s tarihinden sonra bir tarih giriniz',
+                max: 'Lütfen %s tarihinden önce bir tarih giriniz',
+                range: 'Lütfen %s - %s aralığında bir tarih giriniz'
+            },
+            different: {
+                'default': 'Lütfen farklı bir değer giriniz'
+            },
+            digits: {
+                'default': 'Lütfen sadece sayı giriniz'
+            },
+            ean: {
+                'default': 'Lütfen geçerli bir EAN numarası giriniz'
+            },
+            ein: {
+                'default': 'Lütfen geçerli bir EIN numarası giriniz'
+            },
+            emailAddress: {
+                'default': 'Lütfen geçerli bir E-Mail adresi giriniz'
+            },
+            file: {
+                'default': 'Lütfen geçerli bir dosya seçiniz'
+            },
+            greaterThan: {
+                'default': 'Lütfen %s ye eşit veya daha büyük bir değer giriniz',
+                notInclusive: 'Lütfen %s den büyük bir değer giriniz'
+            },
+            grid: {
+                'default': 'Lütfen geçerli bir GRId numarası giriniz'
+            },
+            hex: {
+                'default': 'Lütfen geçerli bir Hexadecimal sayı giriniz'
+            },
+            iban: {
+                'default': 'Lütfen geçerli bir IBAN numarası giriniz',
+                country: 'Lütfen geçerli bir IBAN numarası giriniz içinde %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Birleşik Arap Emirlikleri',
+                    AL: 'Arnavutluk',
+                    AO: 'Angola',
+                    AT: 'Avusturya',
+                    AZ: 'Azerbaycan',
+                    BA: 'Bosna Hersek',
+                    BE: 'Belçika',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaristan',
+                    BH: 'Bahreyn',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brezilya',
+                    CH: 'İsviçre',
+                    CI: 'Fildişi Sahili',
+                    CM: 'Kamerun',
+                    CR: 'Kosta Rika',
+                    CV: 'Cape Verde',
+                    CY: 'Kıbrıs',
+                    CZ: 'Çek Cumhuriyeti',
+                    DE: 'Almanya',
+                    DK: 'Danimarka',
+                    DO: 'Dominik Cumhuriyeti',
+                    DZ: 'Cezayir',
+                    EE: 'Estonya',
+                    ES: 'İspanya',
+                    FI: 'Finlandiya',
+                    FO: 'Faroe Adaları',
+                    FR: 'Fransa',
+                    GB: 'İngiltere',
+                    GE: 'Georgia',
+                    GI: 'Cebelitarık',
+                    GL: 'Grönland',
+                    GR: 'Yunansitan',
+                    GT: 'Guatemala',
+                    HR: 'Hırvatistan',
+                    HU: 'Macaristan',
+                    IE: 'İrlanda',
+                    IL: 'İsrail',
+                    IR: 'İran',
+                    IS: 'İzlanda',
+                    IT: 'İtalya',
+                    JO: 'Ürdün',
+                    KW: 'Kuveit',
+                    KZ: 'Kazakistan',
+                    LB: 'Lübnan',
+                    LI: 'Lihtenştayn',
+                    LT: 'Litvanya',
+                    LU: 'Lüksemburg',
+                    LV: 'Letonya',
+                    MC: 'Monako',
+                    MD: 'Moldova',
+                    ME: 'Karadağ',
+                    MG: 'Madagaskar',
+                    MK: 'Makedonya',
+                    ML: 'Mali',
+                    MR: 'Moritanya',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambik',
+                    NL: 'Hollanda',
+                    NO: 'Norveç',
+                    PK: 'Pakistan',
+                    PL: 'Polanya',
+                    PS: 'Filistin',
+                    PT: 'Portekiz',
+                    QA: 'Katar',
+                    RO: 'Romanya',
+                    RS: 'Serbistan',
+                    SA: 'Suudi Arabistan',
+                    SE: 'İsveç',
+                    SI: 'Slovenya',
+                    SK: 'Slovakya',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Doğu Timor',
+                    TN: 'Tunus',
+                    TR: 'Turkiye',
+                    VG: 'Virgin Adaları, İngiliz',
+                    XK: 'Kosova Cumhuriyeti'
+                }
+            },
+            id: {
+                'default': 'Lütfen geçerli bir tanımlama numarası giriniz',
+                country: 'Lütfen geçerli bir kimlik numarası giriniz içinde %s',
+                countries: {
+                    BA: 'Bosna Hersek',
+                    BG: 'Bulgaristan',
+                    BR: 'Brezilya',
+                    CH: 'İsviçre',
+                    CL: 'Şili',
+                    CN: 'Çin',
+                    CZ: 'Çek Cumhuriyeti',
+                    DK: 'Danimarka',
+                    EE: 'Estonya',
+                    ES: 'İspanya',
+                    FI: 'Finlandiya',
+                    HR: 'Hırvatistan',
+                    IE: 'İrlanda',
+                    IS: 'İzlanda',
+                    LT: 'Litvanya',
+                    LV: 'Letonya',
+                    ME: 'Karadağ',
+                    MK: 'Makedonya',
+                    NL: 'Hollanda',
+                    PL: 'Polanya',
+                    RO: 'Romanya',
+                    RS: 'Sırbistan',
+                    SE: 'İsveç',
+                    SI: 'Slovenya',
+                    SK: 'Slovakya',
+                    SM: 'San Marino',
+                    TH: 'Tayland',
+                    TR: 'Turkiye',
+                    ZA: 'Güney Afrika'
+                }
+            },
+            identical: {
+                'default': 'Lütfen aynı değeri giriniz'
+            },
+            imei: {
+                'default': 'Lütfen geçerli bir IMEI numarası giriniz'
+            },
+            imo: {
+                'default': 'Lütfen geçerli bir IMO numarası giriniz'
+            },
+            integer: {
+                'default': 'Lütfen geçerli bir numara giriniz'
+            },
+            ip: {
+                'default': 'Lütfen geçerli bir IP adresi giriniz',
+                ipv4: 'Lütfen geçerli bir IPv4 adresi giriniz',
+                ipv6: 'Lütfen geçerli bri IPv6 adresi giriniz'
+            },
+            isbn: {
+                'default': 'Lütfen geçerli bir ISBN numarası giriniz'
+            },
+            isin: {
+                'default': 'Lütfen geçerli bir ISIN numarası giriniz'
+            },
+            ismn: {
+                'default': 'Lütfen geçerli bir ISMN numarası giriniz'
+            },
+            issn: {
+                'default': 'Lütfen geçerli bir ISSN numarası giriniz'
+            },
+            lessThan: {
+                'default': 'Lütfen %s den düşük veya eşit bir değer giriniz',
+                notInclusive: 'Lütfen %s den büyük bir değer giriniz'
+            },
+            mac: {
+                'default': 'Lütfen geçerli bir MAC Adresi giriniz'
+            },
+            meid: {
+                'default': 'Lütfen geçerli bir MEID numarası giriniz'
+            },
+            notEmpty: {
+                'default': 'Bir değer giriniz'
+            },
+            numeric: {
+                'default': 'Lütfen geçerli bir float değer giriniz'
+            },
+            phone: {
+                'default': 'Lütfen geçerli bir telefon numarası giriniz',
+                country: 'Lütfen geçerli bir telefon numarası giriniz içinde %s',
+                countries: {
+                    AE: 'Birleşik Arap Emirlikleri',
+                    BG: 'Bulgaristan',
+                    BR: 'Brezilya',
+                    CN: 'Çin',
+                    CZ: 'Çek Cumhuriyeti',
+                    DE: 'Almanya',
+                    DK: 'Danimarka',
+                    ES: 'İspanya',
+                    FR: 'Fransa',
+                    GB: 'İngiltere',
+                    IN: 'Hindistan',
+                    MA: 'Fas',
+                    NL: 'Hollanda',
+                    PK: 'Pakistan',
+                    RO: 'Romanya',
+                    RU: 'Rusya',
+                    SK: 'Slovakya',
+                    TH: 'Tayland',
+                    US: 'Amerika',
+                    VE: 'Venezüella'
+                }
+            },
+            promise: {
+                'default': 'Lütfen geçerli bir değer giriniz'
+            },
+            regexp: {
+                'default': 'Lütfen uyumlu bir değer giriniz'
+            },
+            remote: {
+                'default': 'Lütfen geçerli bir numara giriniz'
+            },
+            rtn: {
+                'default': 'Lütfen geçerli bir RTN numarası giriniz'
+            },
+            sedol: {
+                'default': 'Lütfen geçerli bir SEDOL numarası giriniz'
+            },
+            siren: {
+                'default': 'Lütfen geçerli bir SIREN numarası giriniz'
+            },
+            siret: {
+                'default': 'Lütfen geçerli bir SIRET numarası giriniz'
+            },
+            step: {
+                'default': 'Lütfen geçerli bir %s adımı giriniz'
+            },
+            stringCase: {
+                'default': 'Lütfen sadece küçük harf giriniz',
+                upper: 'Lütfen sadece büyük harf giriniz'
+            },
+            stringLength: {
+                'default': 'Lütfen geçerli uzunluktaki bir değer giriniz',
+                less: 'Lütfen %s karakterden az değer giriniz',
+                more: 'Lütfen %s karakterden fazla değer giriniz',
+                between: 'Lütfen %s ile %s arası uzunlukta bir değer giriniz'
+            },
+            uri: {
+                'default': 'Lütfen geçerli bir URL giriniz'
+            },
+            uuid: {
+                'default': 'Lütfen geçerli bir UUID numarası giriniz',
+                version: 'Lütfen geçerli bir UUID versiyon %s numarası giriniz'
+            },
+            vat: {
+                'default': 'Lütfen geçerli bir VAT kodu giriniz',
+                country: 'Lütfen geçerli bir vergi numarası giriniz içinde %s',
+                countries: {
+                    AT: 'Avustralya',
+                    BE: 'Belçika',
+                    BG: 'Bulgaristan',
+                    BR: 'Brezilya',
+                    CH: 'İsviçre',
+                    CY: 'Kıbrıs',
+                    CZ: 'Çek Cumhuriyeti',
+                    DE: 'Almanya',
+                    DK: 'Danimarka',
+                    EE: 'Estonya',
+                    ES: 'İspanya',
+                    FI: 'Finlandiya',
+                    FR: 'Fransa',
+                    GB: 'İngiltere',
+                    GR: 'Yunanistan',
+                    EL: 'Yunanistan',
+                    HU: 'Macaristan',
+                    HR: 'Hırvatistan',
+                    IE: 'Irlanda',
+                    IS: 'İzlanda',
+                    IT: 'Italya',
+                    LT: 'Litvanya',
+                    LU: 'Lüksemburg',
+                    LV: 'Letonya',
+                    MT: 'Malta',
+                    NL: 'Hollanda',
+                    NO: 'Norveç',
+                    PL: 'Polonya',
+                    PT: 'Portekiz',
+                    RO: 'Romanya',
+                    RU: 'Rusya',
+                    RS: 'Sırbistan',
+                    SE: 'İsveç',
+                    SI: 'Slovenya',
+                    SK: 'Slovakya',
+                    VE: 'Venezüella',
+                    ZA: 'Güney Afrika'
+                }
+            },
+            vin: {
+                'default': 'Lütfen geçerli bir VIN numarası giriniz'
+            },
+            zipCode: {
+                'default': 'Lütfen geçerli bir posta kodu giriniz',
+                country: 'Lütfen geçerli bir posta kodu giriniz içinde %s',
+                countries: {
+                    AT: 'Avustralya',
+                    BG: 'Bulgaristan',
+                    BR: 'Brezilya',
+                    CA: 'Kanada',
+                    CH: 'İsviçre',
+                    CZ: 'Çek Cumhuriyeti',
+                    DE: 'Almanya',
+                    DK: 'Danimarka',
+                    ES: 'İspanya',
+                    FR: 'Fransa',
+                    GB: 'İngiltere',
+                    IE: 'Irlanda',
+                    IN: 'Hindistan',
+                    IT: 'İtalya',
+                    MA: 'Fas',
+                    NL: 'Hollanda',
+                    PL: 'Polanya',
+                    PT: 'Portekiz',
+                    RO: 'Romanya',
+                    RU: 'Rusya',
+                    SE: 'İsveç',
+                    SG: 'Singapur',
+                    SK: 'Slovakya',
+                    US: 'Amerika Birleşik Devletleri'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/ua_UA.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Ukrainian language package
+     * Translated by @oleg-voloshyn
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'ua_UA': {
+            base64: {
+                'default': 'Будь ласка, введіть коректний рядок base64'
+            },
+            between: {
+                'default': 'Будь ласка, введіть значення від %s до %s',
+                notInclusive: 'Будь ласка, введіть значення між %s і %s'
+            },
+            bic: {
+                'default': 'Будь ласка, введіть правильний номер BIC'
+            },
+            callback: {
+                'default': 'Будь ласка, введіть коректне значення'
+            },
+            choice: {
+                'default': 'Будь ласка, введіть коректне значення',
+                less: 'Будь ласка, виберіть хоча б %s опцій',
+                more: 'Будь ласка, виберіть не більше %s опцій',
+                between: 'Будь ласка, виберіть %s - %s опцій'
+            },
+            color: {
+                'default': 'Будь ласка, введіть правильний номер кольору'
+            },
+            creditCard: {
+                'default': 'Будь ласка, введіть правильний номер кредитної картки'
+            },
+            cusip: {
+                'default': 'Будь ласка, введіть правильний номер CUSIP'
+            },
+            cvv: {
+                'default': 'Будь ласка, введіть правильний номер CVV'
+            },
+            date: {
+                'default': 'Будь ласка, введіть правильну дату',
+                min: 'Будь ласка, введіть дату після %s',
+                max: 'Будь ласка, введіть дату перед %s',
+                range: 'Будь ласка, введіть дату у діапазоні %s - %s'
+            },
+            different: {
+                'default': 'Будь ласка, введіть інше значення'
+            },
+            digits: {
+                'default': 'Будь ласка, введіть тільки цифри'
+            },
+            ean: {
+                'default': 'Будь ласка, введіть правильний номер EAN'
+            },
+            ein: {
+                'default': 'Будь ласка, введіть правильний номер EIN'
+            },
+            emailAddress: {
+                'default': 'Будь ласка, введіть правильну адресу e-mail'
+            },
+            file: {
+                'default': 'Будь ласка, виберіть файл'
+            },
+            greaterThan: {
+                'default': 'Будь ласка, введіть значення більше або рівне %s',
+                notInclusive: 'Будь ласка, введіть значення більше %s'
+            },
+            grid: {
+                'default': 'Будь ласка, введіть правильний номер GRId'
+            },
+            hex: {
+                'default': 'Будь ласка, введіть правильний шістнадцятковий(16) номер'
+            },
+            iban: {
+                'default': 'Будь ласка, введіть правильний номер IBAN',
+                country: 'Будь ласка, введіть правильний номер IBAN в %s',
+                countries: {
+                    AD: 'Андоррі',
+                    AE: 'Об\'єднаних Арабських Еміратах',
+                    AL: 'Албанії',
+                    AO: 'Анголі',
+                    AT: 'Австрії',
+                    AZ: 'Азербайджані',
+                    BA: 'Боснії і Герцеговині',
+                    BE: 'Бельгії',
+                    BF: 'Буркіна-Фасо',
+                    BG: 'Болгарії',
+                    BH: 'Бахрейні',
+                    BI: 'Бурунді',
+                    BJ: 'Беніні',
+                    BR: 'Бразилії',
+                    CH: 'Швейцарії',
+                    CI: 'Кот-д\'Івуарі',
+                    CM: 'Камеруні',
+                    CR: 'Коста-Ріці',
+                    CV: 'Кабо-Верде',
+                    CY: 'Кіпрі',
+                    CZ: 'Чехії',
+                    DE: 'Германії',
+                    DK: 'Данії',
+                    DO: 'Домінікані',
+                    DZ: 'Алжирі',
+                    EE: 'Естонії',
+                    ES: 'Іспанії',
+                    FI: 'Фінляндії',
+                    FO: 'Фарерських островах',
+                    FR: 'Франції',
+                    GB: 'Великобританії',
+                    GE: 'Грузії',
+                    GI: 'Гібралтарі',
+                    GL: 'Гренландії',
+                    GR: 'Греції',
+                    GT: 'Гватемалі',
+                    HR: 'Хорватії',
+                    HU: 'Венгрії',
+                    IE: 'Ірландії',
+                    IL: 'Ізраїлі',
+                    IR: 'Ірані',
+                    IS: 'Ісландії',
+                    IT: 'Італії',
+                    JO: 'Йорданії',
+                    KW: 'Кувейті',
+                    KZ: 'Казахстані',
+                    LB: 'Лівані',
+                    LI: 'Ліхтенштейні',
+                    LT: 'Литві',
+                    LU: 'Люксембурзі',
+                    LV: 'Латвії',
+                    MC: 'Монако',
+                    MD: 'Молдові',
+                    ME: 'Чорногорії',
+                    MG: 'Мадагаскарі',
+                    MK: 'Македонії',
+                    ML: 'Малі',
+                    MR: 'Мавританії',
+                    MT: 'Мальті',
+                    MU: 'Маврикії',
+                    MZ: 'Мозамбіку',
+                    NL: 'Нідерландах',
+                    NO: 'Норвегії',
+                    PK: 'Пакистані',
+                    PL: 'Польщі',
+                    PS: 'Палестині',
+                    PT: 'Португалії',
+                    QA: 'Катарі',
+                    RO: 'Румунії',
+                    RS: 'Сербії',
+                    SA: 'Саудівської Аравії',
+                    SE: 'Швеції',
+                    SI: 'Словенії',
+                    SK: 'Словаччині',
+                    SM: 'Сан-Марино',
+                    SN: 'Сенегалі',
+                    TL: 'східний Тимор',
+                    TN: 'Тунісі',
+                    TR: 'Туреччині',
+                    VG: 'Британських Віргінських островах',
+                    XK: 'Республіка Косово'
+                }
+            },
+            id: {
+                'default': 'Будь ласка, введіть правильний ідентифікаційний номер',
+                country: 'Будь ласка, введіть правильний ідентифікаційний номер в %s',
+                countries: {
+                    BA: 'Боснії і Герцеговині',
+                    BG: 'Болгарії',
+                    BR: 'Бразилії',
+                    CH: 'Швейцарії',
+                    CL: 'Чилі',
+                    CN: 'Китаї',
+                    CZ: 'Чехії',
+                    DK: 'Данії',
+                    EE: 'Естонії',
+                    ES: 'Іспанії',
+                    FI: 'Фінляндії',
+                    HR: 'Хорватії',
+                    IE: 'Ірландії',
+                    IS: 'Ісландії',
+                    LT: 'Литві',
+                    LV: 'Латвії',
+                    ME: 'Чорногорії',
+                    MK: 'Македонії',
+                    NL: 'Нідерландах',
+                    PL: 'Польщі',
+                    RO: 'Румунії',
+                    RS: 'Сербії',
+                    SE: 'Швеції',
+                    SI: 'Словенії',
+                    SK: 'Словаччині',
+                    SM: 'Сан-Марино',
+                    TH: 'Таїланді',
+                    TR: 'Туреччині',
+                    ZA: 'ПАР'
+                }
+            },
+            identical: {
+                'default': 'Будь ласка, введіть таке ж значення'
+            },
+            imei: {
+                'default': 'Будь ласка, введіть правильний номер IMEI'
+            },
+            imo: {
+                'default': 'Будь ласка, введіть правильний номер IMO'
+            },
+            integer: {
+                'default': 'Будь ласка, введіть правильне ціле значення'
+            },
+            ip: {
+                'default': 'Будь ласка, введіть правильну IP-адресу',
+                ipv4: 'Будь ласка введіть правильну IPv4-адресу',
+                ipv6: 'Будь ласка введіть правильну IPv6-адресу'
+            },
+            isbn: {
+                'default': 'Будь ласка, введіть правильний номер ISBN'
+            },
+            isin: {
+                'default': 'Будь ласка, введіть правильний номер ISIN'
+            },
+            ismn: {
+                'default': 'Будь ласка, введіть правильний номер ISMN'
+            },
+            issn: {
+                'default': 'Будь ласка, введіть правильний номер ISSN'
+            },
+            lessThan: {
+                'default': 'Будь ласка, введіть значення менше або рівне %s',
+                notInclusive: 'Будь ласка, введіть значення менше ніж %s'
+            },
+            mac: {
+                'default': 'Будь ласка, введіть правильну MAC-адресу'
+            },
+            meid: {
+                'default': 'Будь ласка, введіть правильний номер MEID'
+            },
+            notEmpty: {
+                'default': 'Будь ласка, введіть значення'
+            },
+            numeric: {
+                'default': 'Будь ласка, введіть коректне дійсне число'
+            },
+            phone: {
+                'default': 'Будь ласка, введіть правильний номер телефону',
+                country: 'Будь ласка, введіть правильний номер телефону в %s',
+                countries: {
+                    AE: 'Об\'єднаних Арабських Еміратах',
+                    BG: 'Болгарії',
+                    BR: 'Бразилії',
+                    CN: 'Китаї',
+                    CZ: 'Чехії',
+                    DE: 'Германії',
+                    DK: 'Данії',
+                    ES: 'Іспанії',
+                    FR: 'Франції',
+                    GB: 'Великобританії',
+                    IN: 'Індія',
+                    MA: 'Марокко',
+                    NL: 'Нідерландах',
+                    PK: 'Пакистані',
+                    RO: 'Румунії',
+                    RU: 'Росії',
+                    SK: 'Словаччині',
+                    TH: 'Таїланді',
+                    US: 'США',
+                    VE: 'Венесуелі'
+                }
+            },
+            promise: {
+                'default': 'Будь ласка, введіть коректне значення'
+            },
+            regexp: {
+                'default': 'Будь ласка, введіть значення відповідне до шаблону'
+            },
+            remote: {
+                'default': 'Будь ласка, введіть правильне значення'
+            },
+            rtn: {
+                'default': 'Будь ласка, введіть правильний номер RTN'
+            },
+            sedol: {
+                'default': 'Будь ласка, введіть правильний номер SEDOL'
+            },
+            siren: {
+                'default': 'Будь ласка, введіть правильний номер SIREN'
+            },
+            siret: {
+                'default': 'Будь ласка, введіть правильний номер SIRET'
+            },
+            step: {
+                'default': 'Будь ласка, введіть правильний крок %s'
+            },
+            stringCase: {
+                'default': 'Будь ласка, вводите тільки малі літери',
+                upper: 'Будь ласка, вводите тільки заголовні букви'
+            },
+            stringLength: {
+                'default': 'Будь ласка, введіть значення коректної довжини',
+                less: 'Будь ласка, введіть не більше %s символів',
+                more: 'Будь ласка, введіть, не менше %s символів',
+                between: 'Будь ласка, введіть рядок довжиною від %s до %s символів'
+            },
+            uri: {
+                'default': 'Будь ласка, введіть правильний URI'
+            },
+            uuid: {
+                'default': 'Будь ласка, введіть правильний номер UUID',
+                version: 'Будь ласка, введіть правильний номер UUID версії %s'
+            },
+            vat: {
+                'default': 'Будь ласка, введіть правильний номер VAT',
+                country: 'Будь ласка, введіть правильний номер VAT в %s',
+                countries: {
+                    AT: 'Австрії',
+                    BE: 'Бельгії',
+                    BG: 'Болгарії',
+                    BR: 'Бразилії',
+                    CH: 'Швейцарії',
+                    CY: 'Кіпрі',
+                    CZ: 'Чехії',
+                    DE: 'Германії',
+                    DK: 'Данії',
+                    EE: 'Естонії',
+                    ES: 'Іспанії',
+                    FI: 'Фінляндії',
+                    FR: 'Франції',
+                    GB: 'Великобританії',
+                    GR: 'Греції',
+                    EL: 'Греції',
+                    HU: 'Венгрії',
+                    HR: 'Хорватії',
+                    IE: 'Ірландії',
+                    IS: 'Ісландії',
+                    IT: 'Італії',
+                    LT: 'Литві',
+                    LU: 'Люксембургі',
+                    LV: 'Латвії',
+                    MT: 'Мальті',
+                    NL: 'Нідерландах',
+                    NO: 'Норвегії',
+                    PL: 'Польщі',
+                    PT: 'Португалії',
+                    RO: 'Румунії',
+                    RU: 'Росії',
+                    RS: 'Сербії',
+                    SE: 'Швеції',
+                    SI: 'Словенії',
+                    SK: 'Словаччині',
+                    VE: 'Венесуелі',
+                    ZA: 'ПАР'
+                }
+            },
+            vin: {
+                'default': 'Будь ласка, введіть правильний номер VIN'
+            },
+            zipCode: {
+                'default': 'Будь ласка, введіть правильний поштовий індекс',
+                country: 'Будь ласка, введіть правильний поштовий індекс в %s',
+                countries: {
+                    AT: 'Австрії',
+                    BG: 'Болгарії',
+                    BR: 'Бразилії',
+                    CA: 'Канаді',
+                    CH: 'Швейцарії',
+                    CZ: 'Чехії',
+                    DE: 'Германії',
+                    DK: 'Данії',
+                    ES: 'Іспанії',
+                    FR: 'Франції',
+                    GB: 'Великобританії',
+                    IE: 'Ірландії',
+                    IN: 'Індія',
+                    IT: 'Італії',
+                    MA: 'Марокко',
+                    NL: 'Нідерландах',
+                    PL: 'Польщі',
+                    PT: 'Португалії',
+                    RO: 'Румунії',
+                    RU: 'Росії',
+                    SE: 'Швеції',
+                    SG: 'Сингапурі',
+                    SK: 'Словаччині',
+                    US: 'США'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/vi_VN.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Vietnamese language package
+     * Translated by @nghuuphuoc
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'vi_VN': {
+            base64: {
+                'default': 'Vui lòng nhập chuỗi mã hoá base64 hợp lệ'
+            },
+            between: {
+                'default': 'Vui lòng nhập giá trị nằm giữa %s và %s',
+                notInclusive: 'Vui lòng nhập giá trị nằm giữa %s và %s'
+            },
+            bic: {
+                'default': 'Vui lòng nhập số BIC hợp lệ'
+            },
+            callback: {
+                'default': 'Vui lòng nhập giá trị hợp lệ'
+            },
+            choice: {
+                'default': 'Vui lòng nhập giá trị hợp lệ',
+                less: 'Vui lòng chọn ít nhất %s lựa chọn',
+                more: 'Vui lòng chọn nhiều nhất %s lựa chọn',
+                between: 'Vui lòng chọn %s - %s lựa chọn'
+            },
+            color: {
+                'default': 'Vui lòng nhập mã màu hợp lệ'
+            },
+            creditCard: {
+                'default': 'Vui lòng nhập số thẻ tín dụng hợp lệ'
+            },
+            cusip: {
+                'default': 'Vui lòng nhập số CUSIP hợp lệ'
+            },
+            cvv: {
+                'default': 'Vui lòng nhập số CVV hợp lệ'
+            },
+            date: {
+                'default': 'Vui lòng nhập ngày hợp lệ',
+                min: 'Vui lòng nhập ngày sau %s',
+                max: 'Vui lòng nhập ngày trước %s',
+                range: 'Vui lòng nhập ngày trong khoảng %s - %s'
+            },
+            different: {
+                'default': 'Vui lòng nhập một giá trị khác'
+            },
+            digits: {
+                'default': 'Vui lòng chỉ nhập số'
+            },
+            ean: {
+                'default': 'Vui lòng nhập số EAN hợp lệ'
+            },
+            ein: {
+                'default': 'Vui lòng nhập số EIN hợp lệ'
+            },
+            emailAddress: {
+                'default': 'Vui lòng nhập địa chỉ email hợp lệ'
+            },
+            file: {
+                'default': 'Vui lòng chọn file hợp lệ'
+            },
+            greaterThan: {
+                'default': 'Vui lòng nhập giá trị lớn hơn hoặc bằng %s',
+                notInclusive: 'Vui lòng nhập giá trị lớn hơn %s'
+            },
+            grid: {
+                'default': 'Vui lòng nhập số GRId hợp lệ'
+            },
+            hex: {
+                'default': 'Vui lòng nhập số hexa hợp lệ'
+            },
+            iban: {
+                'default': 'Vui lòng nhập số IBAN hợp lệ',
+                country: 'Vui lòng nhập mã IBAN hợp lệ của %s',
+                countries: {
+                    AD: 'Andorra',
+                    AE: 'Tiểu vương quốc Ả Rập thống nhất',
+                    AL: 'Albania',
+                    AO: 'Angola',
+                    AT: 'Áo',
+                    AZ: 'Azerbaijan',
+                    BA: 'Bosnia và Herzegovina',
+                    BE: 'Bỉ',
+                    BF: 'Burkina Faso',
+                    BG: 'Bulgaria',
+                    BH: 'Bahrain',
+                    BI: 'Burundi',
+                    BJ: 'Benin',
+                    BR: 'Brazil',
+                    CH: 'Thuỵ Sĩ',
+                    CI: 'Bờ Biển Ngà',
+                    CM: 'Cameroon',
+                    CR: 'Costa Rica',
+                    CV: 'Cape Verde',
+                    CY: 'Síp',
+                    CZ: 'Séc',
+                    DE: 'Đức',
+                    DK: 'Đan Mạch',
+                    DO: 'Dominican',
+                    DZ: 'Algeria',
+                    EE: 'Estonia',
+                    ES: 'Tây Ban Nha',
+                    FI: 'Phần Lan',
+                    FO: 'Đảo Faroe',
+                    FR: 'Pháp',
+                    GB: 'Vương quốc Anh',
+                    GE: 'Georgia',
+                    GI: 'Gibraltar',
+                    GL: 'Greenland',
+                    GR: 'Hy Lạp',
+                    GT: 'Guatemala',
+                    HR: 'Croatia',
+                    HU: 'Hungary',
+                    IE: 'Ireland',
+                    IL: 'Israel',
+                    IR: 'Iran',
+                    IS: 'Iceland',
+                    IT: 'Ý',
+                    JO: 'Jordan',
+                    KW: 'Kuwait',
+                    KZ: 'Kazakhstan',
+                    LB: 'Lebanon',
+                    LI: 'Liechtenstein',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MC: 'Monaco',
+                    MD: 'Moldova',
+                    ME: 'Montenegro',
+                    MG: 'Madagascar',
+                    MK: 'Macedonia',
+                    ML: 'Mali',
+                    MR: 'Mauritania',
+                    MT: 'Malta',
+                    MU: 'Mauritius',
+                    MZ: 'Mozambique',
+                    NL: 'Hà Lan',
+                    NO: 'Na Uy',
+                    PK: 'Pakistan',
+                    PL: 'Ba Lan',
+                    PS: 'Palestine',
+                    PT: 'Bồ Đào Nha',
+                    QA: 'Qatar',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SA: 'Ả Rập Xê Út',
+                    SE: 'Thuỵ Điển',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    SN: 'Senegal',
+                    TL: 'Đông Timor',
+                    TN: 'Tunisia',
+                    TR: 'Thổ Nhĩ Kỳ',
+                    VG: 'Đảo Virgin, Anh quốc',
+                    XK: 'Kosovo'
+                }
+            },
+            id: {
+                'default': 'Vui lòng nhập mã ID hợp lệ',
+                country: 'Vui lòng nhập mã ID hợp lệ của %s',
+                countries: {
+                    BA: 'Bosnia và Herzegovina',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CH: 'Thuỵ Sĩ',
+                    CL: 'Chi Lê',
+                    CN: 'Trung Quốc',
+                    CZ: 'Séc',
+                    DK: 'Đan Mạch',
+                    EE: 'Estonia',
+                    ES: 'Tây Ban Nha',
+                    FI: 'Phần Lan',
+                    HR: 'Croatia',
+                    IE: 'Ireland',
+                    IS: 'Iceland',
+                    LT: 'Lithuania',
+                    LV: 'Latvia',
+                    ME: 'Montenegro',
+                    MK: 'Macedonia',
+                    NL: 'Hà Lan',
+                    PL: 'Ba Lan',
+                    RO: 'Romania',
+                    RS: 'Serbia',
+                    SE: 'Thuỵ Điển',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    SM: 'San Marino',
+                    TH: 'Thái Lan',
+                    TR: 'Thổ Nhĩ Kỳ',
+                    ZA: 'Nam Phi'
+                }
+            },
+            identical: {
+                'default': 'Vui lòng nhập cùng giá trị'
+            },
+            imei: {
+                'default': 'Vui lòng nhập số IMEI hợp lệ'
+            },
+            imo: {
+                'default': 'Vui lòng nhập số IMO hợp lệ'
+            },
+            integer: {
+                'default': 'Vui lòng nhập số hợp lệ'
+            },
+            ip: {
+                'default': 'Vui lòng nhập địa chỉ IP hợp lệ',
+                ipv4: 'Vui lòng nhập địa chỉ IPv4 hợp lệ',
+                ipv6: 'Vui lòng nhập địa chỉ IPv6 hợp lệ'
+            },
+            isbn: {
+                'default': 'Vui lòng nhập số ISBN hợp lệ'
+            },
+            isin: {
+                'default': 'Vui lòng nhập số ISIN hợp lệ'
+            },
+            ismn: {
+                'default': 'Vui lòng nhập số ISMN hợp lệ'
+            },
+            issn: {
+                'default': 'Vui lòng nhập số ISSN hợp lệ'
+            },
+            lessThan: {
+                'default': 'Vui lòng nhập giá trị nhỏ hơn hoặc bằng %s',
+                notInclusive: 'Vui lòng nhập giá trị nhỏ hơn %s'
+            },
+            mac: {
+                'default': 'Vui lòng nhập địa chỉ MAC hợp lệ'
+            },
+            meid: {
+                'default': 'Vui lòng nhập số MEID hợp lệ'
+            },
+            notEmpty: {
+                'default': 'Vui lòng nhập giá trị'
+            },
+            numeric: {
+                'default': 'Vui lòng nhập số hợp lệ'
+            },
+            phone: {
+                'default': 'Vui lòng nhập số điện thoại hợp lệ',
+                country: 'Vui lòng nhập số điện thoại hợp lệ của %s',
+                countries: {
+                    AE: 'Tiểu vương quốc Ả Rập thống nhất',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CN: 'Trung Quốc',
+                    CZ: 'Séc',
+                    DE: 'Đức',
+                    DK: 'Đan Mạch',
+                    ES: 'Tây Ban Nha',
+                    FR: 'Pháp',
+                    GB: 'Vương quốc Anh',
+                    IN: 'Ấn Độ',
+                    MA: 'Maroc',
+                    NL: 'Hà Lan',
+                    PK: 'Pakistan',
+                    RO: 'Romania',
+                    RU: 'Nga',
+                    SK: 'Slovakia',
+                    TH: 'Thái Lan',
+                    US: 'Mỹ',
+                    VE: 'Venezuela'
+                }
+            },
+            promise: {
+                'default': 'Vui lòng nhập giá trị hợp lệ'
+            },
+            regexp: {
+                'default': 'Vui lòng nhập giá trị thích hợp với biểu mẫu'
+            },
+            remote: {
+                'default': 'Vui lòng nhập giá trị hợp lệ'
+            },
+            rtn: {
+                'default': 'Vui lòng nhập số RTN hợp lệ'
+            },
+            sedol: {
+                'default': 'Vui lòng nhập số SEDOL hợp lệ'
+            },
+            siren: {
+                'default': 'Vui lòng nhập số Siren hợp lệ'
+            },
+            siret: {
+                'default': 'Vui lòng nhập số Siret hợp lệ'
+            },
+            step: {
+                'default': 'Vui lòng nhập bước nhảy của %s'
+            },
+            stringCase: {
+                'default': 'Vui lòng nhập ký tự thường',
+                upper: 'Vui lòng nhập ký tự in hoa'
+            },
+            stringLength: {
+                'default': 'Vui lòng nhập giá trị có độ dài hợp lệ',
+                less: 'Vui lòng nhập ít hơn %s ký tự',
+                more: 'Vui lòng nhập nhiều hơn %s ký tự',
+                between: 'Vui lòng nhập giá trị có độ dài trong khoảng %s và %s ký tự'
+            },
+            uri: {
+                'default': 'Vui lòng nhập địa chỉ URI hợp lệ'
+            },
+            uuid: {
+                'default': 'Vui lòng nhập số UUID hợp lệ',
+                version: 'Vui lòng nhập số UUID phiên bản %s hợp lệ'
+            },
+            vat: {
+                'default': 'Vui lòng nhập số VAT hợp lệ',
+                country: 'Vui lòng nhập số VAT hợp lệ của %s',
+                countries: {
+                    AT: 'Áo',
+                    BE: 'Bỉ',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CH: 'Thuỵ Sĩ',
+                    CY: 'Síp',
+                    CZ: 'Séc',
+                    DE: 'Đức',
+                    DK: 'Đan Mạch',
+                    EE: 'Estonia',
+                    ES: 'Tây Ban Nha',
+                    FI: 'Phần Lan',
+                    FR: 'Pháp',
+                    GB: 'Vương quốc Anh',
+                    GR: 'Hy Lạp',
+                    EL: 'Hy Lạp',
+                    HU: 'Hungari',
+                    HR: 'Croatia',
+                    IE: 'Ireland',
+                    IS: 'Iceland',
+                    IT: 'Ý',
+                    LT: 'Lithuania',
+                    LU: 'Luxembourg',
+                    LV: 'Latvia',
+                    MT: 'Malta',
+                    NL: 'Hà Lan',
+                    NO: 'Na Uy',
+                    PL: 'Ba Lan',
+                    PT: 'Bồ Đào Nha',
+                    RO: 'Romania',
+                    RU: 'Nga',
+                    RS: 'Serbia',
+                    SE: 'Thuỵ Điển',
+                    SI: 'Slovenia',
+                    SK: 'Slovakia',
+                    VE: 'Venezuela',
+                    ZA: 'Nam Phi'
+                }
+            },
+            vin: {
+                'default': 'Vui lòng nhập số VIN hợp lệ'
+            },
+            zipCode: {
+                'default': 'Vui lòng nhập mã bưu điện hợp lệ',
+                country: 'Vui lòng nhập mã bưu điện hợp lệ của %s',
+                countries: {
+                    AT: 'Áo',
+                    BG: 'Bulgaria',
+                    BR: 'Brazil',
+                    CA: 'Canada',
+                    CH: 'Thuỵ Sĩ',
+                    CZ: 'Séc',
+                    DE: 'Đức',
+                    DK: 'Đan Mạch',
+                    ES: 'Tây Ban Nha',
+                    FR: 'Pháp',
+                    GB: 'Vương quốc Anh',
+                    IE: 'Ireland',
+                    IN: 'Ấn Độ',
+                    IT: 'Ý',
+                    MA: 'Maroc',
+                    NL: 'Hà Lan',
+                    PL: 'Ba Lan',
+                    PT: 'Bồ Đào Nha',
+                    RO: 'Romania',
+                    RU: 'Nga',
+                    SE: 'Thuỵ Sĩ',
+                    SG: 'Singapore',
+                    SK: 'Slovakia',
+                    US: 'Mỹ'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/zh_CN.js

@@ -0,0 +1,385 @@
+(function ($) {
+    /**
+     * Simplified Chinese language package
+     * Translated by @shamiao
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'zh_CN': {
+            base64: {
+                'default': '请输入有效的Base64编码'
+            },
+            between: {
+                'default': '请输入在 %s 和 %s 之间的数值',
+                notInclusive: '请输入在 %s 和 %s 之间(不含两端)的数值'
+            },
+            bic: {
+                'default': '请输入有效的BIC商品编码'
+            },
+            callback: {
+                'default': '请输入有效的值'
+            },
+            choice: {
+                'default': '请输入有效的值',
+                less: '请至少选中 %s 个选项',
+                more: '最多只能选中 %s 个选项',
+                between: '请选择 %s 至 %s 个选项'
+            },
+            color: {
+                'default': '请输入有效的颜色值'
+            },
+            creditCard: {
+                'default': '请输入有效的信用卡号码'
+            },
+            cusip: {
+                'default': '请输入有效的美国CUSIP代码'
+            },
+            cvv: {
+                'default': '请输入有效的CVV代码'
+            },
+            date: {
+                'default': '请输入有效的日期',
+                min: '请输入 %s 或之后的日期',
+                max: '请输入 %s 或以前的日期',
+                range: '请输入 %s 和 %s 之间的日期'
+            },
+            different: {
+                'default': '请输入不同的值'
+            },
+            digits: {
+                'default': '请输入有效的数字'
+            },
+            ean: {
+                'default': '请输入有效的EAN商品编码'
+            },
+            ein: {
+                'default': '请输入有效的EIN商品编码'
+            },
+            emailAddress: {
+                'default': '请输入有效的邮件地址'
+            },
+            file: {
+                'default': '请选择有效的文件'
+            },
+            greaterThan: {
+                'default': '请输入大于等于 %s 的数值',
+                notInclusive: '请输入大于 %s 的数值'
+            },
+            grid: {
+                'default': '请输入有效的GRId编码'
+            },
+            hex: {
+                'default': '请输入有效的16进制数'
+            },
+            iban: {
+                'default': '请输入有效的IBAN(国际银行账户)号码',
+                country: '请输入有效的 %s 国家或地区的IBAN(国际银行账户)号码',
+                countries: {
+                    AD: '安道​​尔',
+                    AE: '阿联酋',
+                    AL: '阿尔巴尼亚',
+                    AO: '安哥拉',
+                    AT: '奥地利',
+                    AZ: '阿塞拜疆',
+                    BA: '波斯尼亚和黑塞哥维那',
+                    BE: '比利时',
+                    BF: '布基纳法索',
+                    BG: '保加利亚',
+                    BH: '巴林',
+                    BI: '布隆迪',
+                    BJ: '贝宁',
+                    BR: '巴西',
+                    CH: '瑞士',
+                    CI: '科特迪瓦',
+                    CM: '喀麦隆',
+                    CR: '哥斯达黎加',
+                    CV: '佛得角',
+                    CY: '塞浦路斯',
+                    CZ: '捷克共和国',
+                    DE: '德国',
+                    DK: '丹麦',
+                    DO: '多米尼加共和国',
+                    DZ: '阿尔及利亚',
+                    EE: '爱沙尼亚',
+                    ES: '西班牙',
+                    FI: '芬兰',
+                    FO: '法罗群岛',
+                    FR: '法国',
+                    GB: '英国',
+                    GE: '格鲁吉亚',
+                    GI: '直布罗陀',
+                    GL: '格陵兰岛',
+                    GR: '希腊',
+                    GT: '危地马拉',
+                    HR: '克罗地亚',
+                    HU: '匈牙利',
+                    IE: '爱尔兰',
+                    IL: '以色列',
+                    IR: '伊朗',
+                    IS: '冰岛',
+                    IT: '意大利',
+                    JO: '约旦',
+                    KW: '科威特',
+                    KZ: '哈萨克斯坦',
+                    LB: '黎巴嫩',
+                    LI: '列支敦士登',
+                    LT: '立陶宛',
+                    LU: '卢森堡',
+                    LV: '拉脱维亚',
+                    MC: '摩纳哥',
+                    MD: '摩尔多瓦',
+                    ME: '黑山',
+                    MG: '马达加斯加',
+                    MK: '马其顿',
+                    ML: '马里',
+                    MR: '毛里塔尼亚',
+                    MT: '马耳他',
+                    MU: '毛里求斯',
+                    MZ: '莫桑比克',
+                    NL: '荷兰',
+                    NO: '挪威',
+                    PK: '巴基斯坦',
+                    PL: '波兰',
+                    PS: '巴勒斯坦',
+                    PT: '葡萄牙',
+                    QA: '卡塔尔',
+                    RO: '罗马尼亚',
+                    RS: '塞尔维亚',
+                    SA: '沙特阿拉伯',
+                    SE: '瑞典',
+                    SI: '斯洛文尼亚',
+                    SK: '斯洛伐克',
+                    SM: '圣马力诺',
+                    SN: '塞内加尔',
+                    TL: '东帝汶',
+                    TN: '突尼斯',
+                    TR: '土耳其',
+                    VG: '英属维尔京群岛',
+                    XK: '科索沃共和国'
+                }
+            },
+            id: {
+                'default': '请输入有效的身份证件号码',
+                country: '请输入有效的 %s 国家或地区的身份证件号码',
+                countries: {
+                    BA: '波黑',
+                    BG: '保加利亚',
+                    BR: '巴西',
+                    CH: '瑞士',
+                    CL: '智利',
+                    CN: '中国',
+                    CZ: '捷克共和国',
+                    DK: '丹麦',
+                    EE: '爱沙尼亚',
+                    ES: '西班牙',
+                    FI: '芬兰',
+                    HR: '克罗地亚',
+                    IE: '爱尔兰',
+                    IS: '冰岛',
+                    LT: '立陶宛',
+                    LV: '拉脱维亚',
+                    ME: '黑山',
+                    MK: '马其顿',
+                    NL: '荷兰',
+                    PL: '波兰',
+                    RO: '罗马尼亚',
+                    RS: '塞尔维亚',
+                    SE: '瑞典',
+                    SI: '斯洛文尼亚',
+                    SK: '斯洛伐克',
+                    SM: '圣马力诺',
+                    TH: '泰国',
+                    TR: '土耳其',
+                    ZA: '南非'
+                }
+            },
+            identical: {
+                'default': '请输入相同的值'
+            },
+            imei: {
+                'default': '请输入有效的IMEI(手机串号)'
+            },
+            imo: {
+                'default': '请输入有效的国际海事组织(IMO)号码'
+            },
+            integer: {
+                'default': '请输入有效的整数值'
+            },
+            ip: {
+                'default': '请输入有效的IP地址',
+                ipv4: '请输入有效的IPv4地址',
+                ipv6: '请输入有效的IPv6地址'
+            },
+            isbn: {
+                'default': '请输入有效的ISBN(国际标准书号)'
+            },
+            isin: {
+                'default': '请输入有效的ISIN(国际证券编码)'
+            },
+            ismn: {
+                'default': '请输入有效的ISMN(印刷音乐作品编码)'
+            },
+            issn: {
+                'default': '请输入有效的ISSN(国际标准杂志书号)'
+            },
+            lessThan: {
+                'default': '请输入小于等于 %s 的数值',
+                notInclusive: '请输入小于 %s 的数值'
+            },
+            mac: {
+                'default': '请输入有效的MAC物理地址'
+            },
+            meid: {
+                'default': '请输入有效的MEID(移动设备识别码)'
+            },
+            notEmpty: {
+                'default': '请填写必填项目'
+            },
+            numeric: {
+                'default': '请输入有效的数值,允许小数'
+            },
+            phone: {
+                'default': '请输入有效的电话号码',
+                country: '请输入有效的 %s 国家或地区的电话号码',
+                countries: {
+                    AE: '阿联酋',
+                    BG: '保加利亚',
+                    BR: '巴西',
+                    CN: '中国',
+                    CZ: '捷克共和国',
+                    DE: '德国',
+                    DK: '丹麦',
+                    ES: '西班牙',
+                    FR: '法国',
+                    GB: '英国',
+                    IN: '印度',
+                    MA: '摩洛哥',
+                    NL: '荷兰',
+                    PK: '巴基斯坦',
+                    RO: '罗马尼亚',
+                    RU: '俄罗斯',
+                    SK: '斯洛伐克',
+                    TH: '泰国',
+                    US: '美国',
+                    VE: '委内瑞拉'
+                }
+            },
+            promise: {
+                'default': '请输入有效的值'
+            },
+            regexp: {
+                'default': '请输入符合正则表达式限制的值'
+            },
+            remote: {
+                'default': '请输入有效的值'
+            },
+            rtn: {
+                'default': '请输入有效的RTN号码'
+            },
+            sedol: {
+                'default': '请输入有效的SEDOL代码'
+            },
+            siren: {
+                'default': '请输入有效的SIREN号码'
+            },
+            siret: {
+                'default': '请输入有效的SIRET号码'
+            },
+            step: {
+                'default': '请输入在基础值上,增加 %s 的整数倍的数值'
+            },
+            stringCase: {
+                'default': '只能输入小写字母',
+                upper: '只能输入大写字母'
+            },
+            stringLength: {
+                'default': '请输入符合长度限制的值',
+                less: '最多只能输入 %s 个字符',
+                more: '需要输入至少 %s 个字符',
+                between: '请输入 %s 至 %s 个字符'
+            },
+            uri: {
+                'default': '请输入一个有效的URL地址'
+            },
+            uuid: {
+                'default': '请输入有效的UUID',
+                version: '请输入版本 %s 的UUID'
+            },
+            vat: {
+                'default': '请输入有效的VAT(税号)',
+                country: '请输入有效的 %s 国家或地区的VAT(税号)',
+                countries: {
+                    AT: '奥地利',
+                    BE: '比利时',
+                    BG: '保加利亚',
+                    BR: '巴西',
+                    CH: '瑞士',
+                    CY: '塞浦路斯',
+                    CZ: '捷克共和国',
+                    DE: '德国',
+                    DK: '丹麦',
+                    EE: '爱沙尼亚',
+                    ES: '西班牙',
+                    FI: '芬兰',
+                    FR: '法语',
+                    GB: '英国',
+                    GR: '希腊',
+                    EL: '希腊',
+                    HU: '匈牙利',
+                    HR: '克罗地亚',
+                    IE: '爱尔兰',
+                    IS: '冰岛',
+                    IT: '意大利',
+                    LT: '立陶宛',
+                    LU: '卢森堡',
+                    LV: '拉脱维亚',
+                    MT: '马耳他',
+                    NL: '荷兰',
+                    NO: '挪威',
+                    PL: '波兰',
+                    PT: '葡萄牙',
+                    RO: '罗马尼亚',
+                    RU: '俄罗斯',
+                    RS: '塞尔维亚',
+                    SE: '瑞典',
+                    SI: '斯洛文尼亚',
+                    SK: '斯洛伐克',
+                    VE: '委内瑞拉',
+                    ZA: '南非'
+                }
+            },
+            vin: {
+                'default': '请输入有效的VIN(美国车辆识别号码)'
+            },
+            zipCode: {
+                'default': '请输入有效的邮政编码',
+                country: '请输入有效的 %s 国家或地区的邮政编码',
+                countries: {
+                    AT: '奥地利',
+                    BG: '保加利亚',
+                    BR: '巴西',
+                    CA: '加拿大',
+                    CH: '瑞士',
+                    CZ: '捷克共和国',
+                    DE: '德国',
+                    DK: '丹麦',
+                    ES: '西班牙',
+                    FR: '法国',
+                    GB: '英国',
+                    IE: '爱尔兰',
+                    IN: '印度',
+                    IT: '意大利',
+                    MA: '摩洛哥',
+                    NL: '荷兰',
+                    PL: '波兰',
+                    PT: '葡萄牙',
+                    RO: '罗马尼亚',
+                    RU: '俄罗斯',
+                    SE: '瑞典',
+                    SG: '新加坡',
+                    SK: '斯洛伐克',
+                    US: '美国'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 385 - 0
static/formvalidation/js/language/zh_TW.js

@@ -0,0 +1,385 @@
+(function($) {
+    /**
+     * Traditional Chinese language package
+     * Translated by @tureki
+     */
+    FormValidation.I18n = $.extend(true, FormValidation.I18n, {
+        'zh_TW': {
+            base64: {
+                'default': '請輸入有效的Base64編碼'
+            },
+            between: {
+                'default': '請輸入不小於 %s 且不大於 %s 的值',
+                notInclusive: '請輸入不小於等於 %s 且不大於等於 %s 的值'
+            },
+            bic: {
+                'default': '請輸入有效的BIC商品編碼'
+            },
+            callback: {
+                'default': '請輸入有效的值'
+            },
+            choice: {
+                'default': '請輸入有效的值',
+                less: '最少選擇 %s 個選項',
+                more: '最多選擇 %s 個選項',
+                between: '請選擇 %s 至 %s 個選項'
+            },
+            color: {
+                'default': '請輸入有效的元色碼'
+            },
+            creditCard: {
+                'default': '請輸入有效的信用卡號碼'
+            },
+            cusip: {
+                'default': '請輸入有效的CUSIP(美國證券庫斯普)號碼'
+            },
+            cvv: {
+                'default': '請輸入有效的CVV(信用卡檢查碼)代碼'
+            },
+            date: {
+                'default': '請輸入有效的日期',
+                min: '請輸入 %s 或之後的日期',
+                max: '請輸入 %s 或以前的日期',
+                range: '請輸入 %s 至 %s 之間的日期'
+            },
+            different: {
+                'default': '請輸入不同的值'
+            },
+            digits: {
+                'default': '只能輸入數字'
+            },
+            ean: {
+                'default': '請輸入有效的EAN商品編碼'
+            },
+            ein: {
+                'default': '請輸入有效的EIN商品編碼'
+            },
+            emailAddress: {
+                'default': '請輸入有效的EMAIL'
+            },
+            file: {
+                'default': '請選擇有效的檔案'
+            },
+            greaterThan: {
+                'default': '請輸入大於等於 %s 的值',
+                notInclusive: '請輸入大於 %s 的值'
+            },
+            grid: {
+                'default': '請輸入有效的GRId編碼'
+            },
+            hex: {
+                'default': '請輸入有效的16位元碼'
+            },
+            iban: {
+                'default': '請輸入有效的IBAN(國際銀行賬戶)號碼',
+                country: '請輸入有效的 %s 國家的IBAN(國際銀行賬戶)號碼',
+                countries: {
+                    AD: '安道​​爾',
+                    AE: '阿聯酋',
+                    AL: '阿爾巴尼亞',
+                    AO: '安哥拉',
+                    AT: '奧地利',
+                    AZ: '阿塞拜疆',
+                    BA: '波斯尼亞和黑塞哥維那',
+                    BE: '比利時',
+                    BF: '布基納法索',
+                    BG: '保加利亞',
+                    BH: '巴林',
+                    BI: '布隆迪',
+                    BJ: '貝寧',
+                    BR: '巴西',
+                    CH: '瑞士',
+                    CI: '象牙海岸',
+                    CM: '喀麥隆',
+                    CR: '哥斯達黎加',
+                    CV: '佛得角',
+                    CY: '塞浦路斯',
+                    CZ: '捷克共和國',
+                    DE: '德國',
+                    DK: '丹麥',
+                    DO: '多明尼加共和國',
+                    DZ: '阿爾及利亞',
+                    EE: '愛沙尼亞',
+                    ES: '西班牙',
+                    FI: '芬蘭',
+                    FO: '法羅群島',
+                    FR: '法國',
+                    GB: '英國',
+                    GE: '格魯吉亞',
+                    GI: '直布羅陀',
+                    GL: '格陵蘭島',
+                    GR: '希臘',
+                    GT: '危地馬拉',
+                    HR: '克羅地亞',
+                    HU: '匈牙利',
+                    IE: '愛爾蘭',
+                    IL: '以色列',
+                    IR: '伊朗',
+                    IS: '冰島',
+                    IT: '意大利',
+                    JO: '約旦',
+                    KW: '科威特',
+                    KZ: '哈薩克斯坦',
+                    LB: '黎巴嫩',
+                    LI: '列支敦士登',
+                    LT: '立陶宛',
+                    LU: '盧森堡',
+                    LV: '拉脫維亞',
+                    MC: '摩納哥',
+                    MD: '摩爾多瓦',
+                    ME: '蒙特內哥羅',
+                    MG: '馬達加斯加',
+                    MK: '馬其頓',
+                    ML: '馬里',
+                    MR: '毛里塔尼亞',
+                    MT: '馬耳他',
+                    MU: '毛里求斯',
+                    MZ: '莫桑比克',
+                    NL: '荷蘭',
+                    NO: '挪威',
+                    PK: '巴基斯坦',
+                    PL: '波蘭',
+                    PS: '巴勒斯坦',
+                    PT: '葡萄牙',
+                    QA: '卡塔爾',
+                    RO: '羅馬尼亞',
+                    RS: '塞爾維亞',
+                    SA: '沙特阿拉伯',
+                    SE: '瑞典',
+                    SI: '斯洛文尼亞',
+                    SK: '斯洛伐克',
+                    SM: '聖馬力諾',
+                    SN: '塞內加爾',
+                    TL: '東帝汶',
+                    TN: '突尼斯',
+                    TR: '土耳其',
+                    VG: '英屬維爾京群島',
+                    XK: '科索沃共和國'
+                }
+            },
+            id: {
+                'default': '請輸入有效的身份證字號',
+                country: '請輸入有效的 %s 身份證字號',
+                countries: {
+                    BA: '波赫',
+                    BG: '保加利亞',
+                    BR: '巴西',
+                    CH: '瑞士',
+                    CL: '智利',
+                    CN: '中國',
+                    CZ: '捷克共和國',
+                    DK: '丹麥',
+                    EE: '愛沙尼亞',
+                    ES: '西班牙',
+                    FI: '芬蘭',
+                    HR: '克羅地亞',
+                    IE: '愛爾蘭',
+                    IS: '冰島',
+                    LT: '立陶宛',
+                    LV: '拉脫維亞',
+                    ME: '蒙特內哥羅',
+                    MK: '馬其頓',
+                    NL: '荷蘭',
+                    PL: '波蘭',
+                    RO: '羅馬尼亞',
+                    RS: '塞爾維亞',
+                    SE: '瑞典',
+                    SI: '斯洛文尼亞',
+                    SK: '斯洛伐克',
+                    SM: '聖馬力諾',
+                    TH: '泰國',
+                    TR: '土耳其',
+                    ZA: '南非'
+                }
+            },
+            identical: {
+                'default': '請輸入相同的值'
+            },
+            imei: {
+                'default': '請輸入有效的IMEI(手機序列號)'
+            },
+            imo: {
+                'default': '請輸入有效的國際海事組織(IMO)號碼'
+            },
+            integer: {
+                'default': '請輸入有效的整數'
+            },
+            ip: {
+                'default': '請輸入有效的IP位址',
+                ipv4: '請輸入有效的IPv4位址',
+                ipv6: '請輸入有效的IPv6位址'
+            },
+            isbn: {
+                'default': '請輸入有效的ISBN(國際標準書號)'
+            },
+            isin: {
+                'default': '請輸入有效的ISIN(國際證券號碼)'
+            },
+            ismn: {
+                'default': '請輸入有效的ISMN(國際標準音樂編號)'
+            },
+            issn: {
+                'default': '請輸入有效的ISSN(國際標準期刊號)'
+            },
+            lessThan: {
+                'default': '請輸入小於等於 %s 的值',
+                notInclusive: '請輸入小於 %s 的值'
+            },
+            mac: {
+                'default': '請輸入有效的MAC位址'
+            },
+            meid: {
+                'default': '請輸入有效的MEID(行動設備識別碼)'
+            },
+            notEmpty: {
+                'default': '請填寫必填欄位'
+            },
+            numeric: {
+                'default': '請輸入有效的數字(含浮點數)'
+            },
+            phone: {
+                'default': '請輸入有效的電話號碼',
+                country: '請輸入有效的 %s 國家的電話號碼',
+                countries: {
+                    AE: '阿聯酋',
+                    BG: '保加利亞',
+                    BR: '巴西',
+                    CN: '中国',
+                    CZ: '捷克共和國',
+                    DE: '德國',
+                    DK: '丹麥',
+                    ES: '西班牙',
+                    FR: '法國',
+                    GB: '英國',
+                    IN: '印度',
+                    MA: '摩洛哥',
+                    NL: '荷蘭',
+                    PK: '巴基斯坦',
+                    RO: '罗马尼亚',
+                    RU: '俄羅斯',
+                    SK: '斯洛伐克',
+                    TH: '泰國',
+                    US: '美國',
+                    VE: '委内瑞拉'
+                }
+            },
+            promise: {
+                'default': '請輸入有效的值'
+            },
+            regexp: {
+                'default': '請輸入符合正規表示式所限制的值'
+            },
+            remote: {
+                'default': '請輸入有效的值'
+            },
+            rtn: {
+                'default': '請輸入有效的RTN號碼'
+            },
+            sedol: {
+                'default': '請輸入有效的SEDOL代碼'
+            },
+            siren: {
+                'default': '請輸入有效的SIREN號碼'
+            },
+            siret: {
+                'default': '請輸入有效的SIRET號碼'
+            },
+            step: {
+                'default': '請輸入 %s 的倍數'
+            },
+            stringCase: {
+                'default': '只能輸入小寫字母',
+                upper: '只能輸入大寫字母'
+            },
+            stringLength: {
+                'default': '請輸入符合長度限制的值',
+                less: '請輸入小於 %s 個字',
+                more: '請輸入大於 %s 個字',
+                between: '請輸入 %s 至 %s 個字'
+            },
+            uri: {
+                'default': '請輸入一個有效的鏈接'
+            },
+            uuid: {
+                'default': '請輸入有效的UUID',
+                version: '請輸入版本 %s 的UUID'
+            },
+            vat: {
+                'default': '請輸入有效的VAT(增值税)',
+                country: '請輸入有效的 %s 國家的VAT(增值税)',
+                countries: {
+                    AT: '奧地利',
+                    BE: '比利時',
+                    BG: '保加利亞',
+                    BR: '巴西',
+                    CH: '瑞士',
+                    CY: '塞浦路斯',
+                    CZ: '捷克共和國',
+                    DE: '德國',
+                    DK: '丹麥',
+                    EE: '愛沙尼亞',
+                    ES: '西班牙',
+                    FI: '芬蘭',
+                    FR: '法語',
+                    GB: '英國',
+                    GR: '希臘',
+                    EL: '希臘',
+                    HU: '匈牙利',
+                    HR: '克羅地亞',
+                    IE: '愛爾蘭',
+                    IS: '冰島',
+                    IT: '意大利',
+                    LT: '立陶宛',
+                    LU: '盧森堡',
+                    LV: '拉脫維亞',
+                    MT: '馬耳他',
+                    NL: '荷蘭',
+                    NO: '挪威',
+                    PL: '波蘭',
+                    PT: '葡萄牙',
+                    RO: '羅馬尼亞',
+                    RU: '俄羅斯',
+                    RS: '塞爾維亞',
+                    SE: '瑞典',
+                    SI: '斯洛文尼亞',
+                    SK: '斯洛伐克',
+                    VE: '委内瑞拉',
+                    ZA: '南非'
+                }
+            },
+            vin: {
+                'default': '請輸入有效的VIN(車輛識別號碼)'
+            },
+            zipCode: {
+                'default': '請輸入有效的郵政編碼',
+                country: '請輸入有效的 %s 國家的郵政編碼',
+                countries: {
+                    AT: '奧地利',
+                    BG: '保加利亞',
+                    BR: '巴西',
+                    CA: '加拿大',
+                    CH: '瑞士',
+                    CZ: '捷克共和國',
+                    DE: '德國',
+                    DK: '丹麥',
+                    ES: '西班牙',
+                    FR: '法國',
+                    GB: '英國',
+                    IE: '愛爾蘭',
+                    IN: '印度',
+                    IT: '意大利',
+                    MA: '摩洛哥',
+                    NL: '荷蘭',
+                    PL: '波蘭',
+                    PT: '葡萄牙',
+                    RO: '羅馬尼亞',
+                    RU: '俄羅斯',
+                    SE: '瑞典',
+                    SG: '新加坡',
+                    SK: '斯洛伐克',
+                    US: '美國'
+                }
+            }
+        }
+    });
+}(jQuery));

+ 71 - 46
templates/guest_create.html

@@ -35,22 +35,48 @@
 {% block body %}
 <script>
     $(document).ready(function() {
-        $('#os_template').chosen({
-            "disable_search": true
-        });
-
         $('body').addClass('add-transition');
         $('.add-page-transition').on('click', function(){
             var transAttr = $(this).attr('data-transition');
             $('.add-transition').attr('class', 'add-transition');
             $('.add-transition').addClass(transAttr);
         });
-    });
 
-    $(function() { "use strict";
-        $(".chosen-select").chosen();
-        $(".chosen-search").append('<i class="glyph-icon icon-search"></i>');
-        $(".chosen-single div").html('<i class="glyph-icon icon-caret-down"></i>');
+        $('#create_guest_form').formValidation({
+            framework: 'bootstrap4',
+            icon: {
+                valid: 'fa fa-check',
+                invalid: 'fa fa-times',
+                validating: 'fa fa-refresh'
+            },
+            // Since the Bootstrap Button hides the radio and checkbox
+            // We exclude the disabled elements only
+            excluded: ':disabled',
+            fields: {
+                ability: {
+                    validators: {
+                        notEmpty: {
+                        }
+                    }
+                },
+                os_template_id: {
+                    validators: {
+                        // choice: {
+                        //     min: 1,
+                        //     max: 1
+                        //     // message: ''
+                        // },
+                        notEmpty: {
+                        }
+                    }
+                }
+            }
+        })
+        .on('success.field.fv', function(e, data) {
+            if (data.fv.getInvalidFields().length > 0) {    // There is invalid field
+                data.fv.disableSubmitButtons(true);
+            }
+        });
     });
 
     $(function() { "use strict";
@@ -78,69 +104,68 @@
                 </span>
             </a>
             <div class="example-box-wrapper">
-                <form class="form-horizontal bordered-row" action="/guests/create" method="post">
+                <form id="create_guest_form" class="form-horizontal bordered-row" action="/guests/create" method="post">
                     <div class="form-group">
                         <label class="col-sm-2 control-label"><span class="glyph-icon icon-elusive-gauge"></span>&nbsp;&nbsp;运算能力</label>
                         <div class="col-sm-10">
                             <div class="btn-ability-line" data-toggle="buttons">
-                                <a href="#" class="btn btn-default btn-ability">
+                                <label class="btn btn-default btn-ability">
                                     <input title="1 CPU 1GB Memory" name="ability" type="radio" value="1c1g">1&nbsp;&nbsp;核&nbsp;&nbsp;1&nbsp;&nbsp;GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="1 CPU 2GB Memory" name="ability" type="radio" value="1c2g">1&nbsp;&nbsp;核&nbsp;&nbsp;2&nbsp;&nbsp;GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="2 CPU 2GB Memory" name="ability" type="radio" value="2c2g">2&nbsp;&nbsp;核&nbsp;&nbsp;2&nbsp;&nbsp;GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="2 CPU 4GB Memory" name="ability" type="radio" value="2c4g">2&nbsp;&nbsp;核&nbsp;&nbsp;4&nbsp;&nbsp;GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="4 CPU 4GB Memory" name="ability" type="radio" value="4c4g">4&nbsp;&nbsp;核&nbsp;&nbsp;4&nbsp;&nbsp;GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="4 CPU 8GB Memory" name="ability" type="radio" value="4c8g">4&nbsp;&nbsp;核&nbsp;&nbsp;8&nbsp;&nbsp;GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="8 CPU 8GB Memory" name="ability" type="radio" value="8c8g">8&nbsp;&nbsp;核&nbsp;&nbsp;8&nbsp;&nbsp;GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="8 CPU 16GB Memory" name="ability" type="radio" value="8c16g">8&nbsp;&nbsp;核&nbsp;&nbsp;16GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="1 CPU 16GB Memory" name="ability" type="radio" value="1c16g">1&nbsp;&nbsp;核&nbsp;&nbsp;16GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="4 CPU 32GB Memory" name="ability" type="radio" value="4c32g">4&nbsp;&nbsp;核&nbsp;&nbsp;32GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="4 CPU 64GB Memory" name="ability" type="radio" value="4c64g">4&nbsp;&nbsp;核&nbsp;&nbsp;64GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="8 CPU 64GB Memory" name="ability" type="radio" value="8c64g">8&nbsp;&nbsp;核&nbsp;&nbsp;64GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="16 CPU 16GB Memory" name="ability" type="radio" value="16c16g">16核&nbsp;&nbsp;16GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="24 CPU 24GB Memory" name="ability" type="radio" value="24c24g">24核&nbsp;&nbsp;24GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="32 CPU 32GB Memory" name="ability" type="radio" value="32c32g">32核&nbsp;&nbsp;32GB
-                                </a>
-                                <a href="#" class="btn btn-default btn-ability">
+                                </label>
+                                <label class="btn btn-default btn-ability">
                                     <input title="64 CPU 64GB Memory" name="ability" type="radio" value="64c64g">64核&nbsp;&nbsp;64GB
-                                </a>
+                                </label>
                             </div>
                         </div>
                     </div>
                     <div class="form-group">
                         <label class="col-sm-2 control-label"><span class="glyph-icon icon-elusive-inbox-alt"></span>&nbsp;&nbsp;系统模板</label>
                         <div class="col-sm-6">
-                            <select id="os_template" name="os_template_id" class="chosen-select" data-placeholder="请选择系统模板...">
-                                <option></option>
+                            <select id="os_template" name="os_template_id" title="请选择系统模板..." class="selectpicker" data-width="100%">
                                 {% for item in os_template_data %}
-                                <option value="{{ item.id }}">{{ item.label }}</option>
+                                    <option value="{{ item.id }}" data-icon="{{ item.icon }}">&nbsp;&nbsp;{{ item.label }}</option>
                                 {% endfor %}
                             </select>
                         </div>
@@ -179,7 +204,7 @@
                     <div class="form-group">
                         <label class="col-sm-2 control-label"></label>
                         <div class="col-sm-3 pull-right">
-                            <button class="btn btn-blue-alt" style="width: 180px; height: 40px; font-size: 16px;">创建</button>
+                            <button type="submit" class="btn btn-blue-alt" style="width: 180px; height: 40px; font-size: 16px;" disabled>创建</button>
                         </div>
                     </div>
                 </form>

+ 8 - 0
templates/layout.html

@@ -194,6 +194,9 @@
     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='smartwizard/css/smart_wizard_theme_circles.min.css') }}">
     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='smartwizard/css/smart_wizard_theme_dots.min.css') }}">
 
+    <!-- formvalidation CSS -->
+    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='formvalidation/css/formValidation.min.css') }}">
+
     <!-- JimV -->
     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/icons.css') }}">
     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/host-table.css') }}">
@@ -463,6 +466,11 @@
         <!--<script type="text/javascript" src="{{ url_for('static', filename='bootstrap-select/js/i18n/defaults-zh_CN.min.js') }}"></script>-->
         <!-- smartwizard JavaScript -->
         <script type="text/javascript" src="{{ url_for('static', filename='smartwizard/js/jquery.smartWizard.min.js') }}"></script>
+        <!-- formvalidation JavaScript -->
+        <script type="text/javascript" src="{{ url_for('static', filename='formvalidation/js/formValidation.min.js') }}"></script>
+        <script type="text/javascript" src="{{ url_for('static', filename='formvalidation/js/framework/bootstrap4.min.js') }}"></script>
+        <!--<script type="text/javascript" src="{{ url_for('static', filename='formvalidation/js/formValidation.popular.min.js') }}"></script>-->
+        <script type="text/javascript" src="{{ url_for('static', filename='formvalidation/js/language/zh_CN.js') }}"></script>
 
         <!-- JimV -->
         <script type="text/javascript" src="{{ url_for('static', filename='utils.js') }}"></script>

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini