").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!c.settings.submitHandler||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(null!=j&&(!j.form&&j.hasAttribute("contenteditable")&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr.pseudos||a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){!this.form&&this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name"));var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=d),!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);if("function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f){if(j=f.call(b,j),"string"!=typeof j)throw new TypeError("The normalizer should return a string value.");delete g.normalizer}for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+""),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[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])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?: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})(?:[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]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a});
Bất kỳ hệ thống mạng lớn hay nhỏ nào khi các thiết bị kết nối sử đụng địa chỉ IP động cũng đều được cấp từ DHCP Server. DHCP sẽ thực hiện các cách khác nhau đối với loại mạng khác nhau. Vậy DHCP là gì? Hoạt động ra sao? Hãy cùng Tothost trả lời nhé!
Mục lục
Mục lục
1. Giới thiệu về DHCP
DHCP (viết tắt của Dynamic Host Configuration Protocol) là một giao thức mạng dựa trên giao thức IP để cấp phát địa chỉ IP, cấu hình mạng và các thông số cho các thiết bị trong mạng.
2. Vai trò của DHCP trong hệ thống mạng
2.1. Quản lý địa chỉ IP
DHCP giúp quản lý địa chỉ IP một cách hiệu quả, tránh xảy ra tình trạng trùng lặp địa chỉ IP trên mạng, đồng thời cũng giúp giảm thời gian và công sức cấu hình địa chỉ IP thủ công cho từng thiết bị.
2.2.Tối ưu
Khi sử dụng DHCP, các thiết bị chỉ sử dụng địa chỉ IP khi thực sự cần thiết và được cấp phát theo yêu cầu của DHCP client, giúp giảm thời gian chờ đợi và tối ưu hóa tài nguyên mạng.
3. Những thành phần liên quan
3.1. DHCP client
Là một phần mềm trên các thiết bị mạng như máy tính, điện thoại, máy chủ,… sẽ yêu cầu DHCP server cấp phát địa chỉ IP và các thông số cấu hình mạng khác.
3.2. DHCP server
Máy chủ chạy phần mềm DHCP để cấp phát địa chỉ IP và các thông số cấu hình mạng khác cho các DHCP client.
3.3. DHCP relay agents
Đây là một thiết bị trung gian giữa DHCP client và DHCP server, nếu DHCP client và DHCP server không cùng một mạng con, DHCP relay agents sẽ chuyển tiếp yêu cầu của DHCP client đến DHCP server và chuyển trả lại phản hồi từ DHCP server đến DHCP client.
3.4. Binding
Quá trình kết nối giữa địa chỉ IP được cấp phát và MAC address của thiết bị mạng, để đảm bảo việc gửi và nhận dữ liệu trên mạng một cách chính xác.
3.5. DHCP Lease
Là thời gian mà DHCP client được sử dụng địa chỉ IP được cấp phát từ DHCP server, sau khi kết thúc thời gian lease, DHCP client phải yêu cầu lại DHCP server để gia hạn lease hoặc cấp phát một địa chỉ IP mới.
4. DHCP hoạt động như thế nào?
Hoạt động của DHCP bao gồm các bước sau đây:
Yêu cầu DHCP (DHCP Request)
Khi một thiết bị mới được kết nối vào mạng, nó sẽ gửi một yêu cầu DHCP Request tới máy chủ DHCP. Yêu cầu này chứa thông tin về máy khách DHCP, bao gồm địa chỉ MAC, tên máy và các thông tin khác.
Giao tiếp giữa máy khách DHCP và máy chủ DHCP
Sau khi nhận được yêu cầu DHCP Request, máy chủ DHCP sẽ gửi lại gói tin DHCP Offer chứa thông tin về địa chỉ IP và các thông số mạng khác cho máy khách DHCP. Máy khách DHCP sẽ nhận được nhiều gói tin Offer từ các máy chủ DHCP khác nhau nếu có nhiều máy chủ DHCP trong mạng.
Lựa chọn địa chỉ IP và xác nhận (DHCP Select)
Máy khách DHCP sẽ lựa chọn một trong các gói tin Offer từ máy chủ DHCP và gửi một yêu cầu DHCP Select. Yêu cầu này xác nhận việc chọn địa chỉ IP được đề xuất từ máy chủ DHCP.
Cấp phát địa chỉ IP (DHCP ACK)
Sau khi nhận được yêu cầu DHCP Select từ máy khách DHCP, máy chủ DHCP sẽ gửi một gói tin DHCP ACK (Acknowledge) xác nhận việc cấp phát địa chỉ IP và các thông số mạng khác cho máy khách DHCP.
Quản lý địa chỉ IP
Khi máy khách DHCP đã nhận được gói tin ACK, nó sẽ sử dụng địa chỉ IP được cấp phát để kết nối vào mạng. Địa chỉ IP này sẽ được cấp phát cho máy khách trong một khoảng thời gian nhất định. Sau khi khoảng thời gian này kết thúc, địa chỉ IP sẽ được trả lại cho pool của máy chủ DHCP để cấp phát cho thiết bị khác trong mạng.
5. Các thông điệp giao tiếp giữa DHCP Server và máy Client
Các thông điệp chính trong quá trình cấp phát địa chỉ IP của DHCP bao gồm:
DHCP Discover: Khi một thiết bị mới kết nối vào mạng, nó gửi một gói tin DHCP Discover tới tất cả các máy chủ DHCP trong mạng để yêu cầu cấp phát địa chỉ IP. Gói tin này chứa địa chỉ MAC của thiết bị và yêu cầu các máy chủ DHCP phản hồi với gói tin DHCP Offer.
DHCP Offer: Các máy chủ DHCP trong mạng nhận được gói tin DHCP Discover sẽ phản hồi bằng gói tin DHCP Offer, chứa thông tin về địa chỉ IP được cấp phát, thời gian thuê và các thông số mạng khác. Thiết bị nhận được nhiều gói tin DHCP Offer từ các máy chủ DHCP khác nhau có thể lựa chọn địa chỉ IP và máy chủ DHCP phù hợp.
DHCP Request: Sau khi chọn được máy chủ DHCP và địa chỉ IP phù hợp, thiết bị sẽ gửi một gói tin DHCP Request để yêu cầu xác nhận việc cấp phát địa chỉ IP đó. Gói tin này chứa địa chỉ MAC của thiết bị và địa chỉ IP được chọn.
DHCP Acknowledge: Nếu máy chủ DHCP nhận được gói tin DHCP Request hợp lệ, nó sẽ phản hồi với gói tin DHCP Acknowledge, xác nhận rằng địa chỉ IP được cấp phát cho thiết bị đã được chấp nhận và các thông số mạng khác cũng đã được cấu hình.
DHCP Nak: Nếu máy chủ DHCP không thể cấp phát địa chỉ IP được yêu cầu hoặc có lỗi xảy ra trong quá trình cấp phát, nó sẽ phản hồi với gói tin DHCP Nak, thông báo cho thiết bị rằng yêu cầu cấp phát địa chỉ IP đã bị từ chối.
DHCP Decline: Thiết bị cũng có thể gửi gói tin DHCP Decline để thông báo cho máy chủ DHCP rằng địa chỉ IP đã nhận không hoạt động hoặc đã được sử dụng trước đó.
DHCP Release: Khi thiết bị không còn sử dụng địa chỉ IP đã được cấp phát, nó sẽ gửi một gói tin DHCP Release để thông báo cho máy chủ DHCP rằng địa chỉ IP này có thể được tái sử dụng và giải phóng các tài nguyên mạng liên quan đến địa chỉ IP đó.
DHCP (viết tắt của Dynamic Host Configuration Protocol) là một giao thức mạng dựa trên giao thức IP để cấp phát địa chỉ IP, cấu hình mạng và các thông số cho các thiết bị trong mạng.
6. Vai trò của DHCP trong hệ thống mạng
6.1. Quản lý địa chỉ IP
DHCP giúp quản lý địa chỉ IP một cách hiệu quả, tránh xảy ra tình trạng trùng lặp địa chỉ IP trên mạng, đồng thời cũng giúp giảm thời gian và công sức cấu hình địa chỉ IP thủ công cho từng thiết bị.
6.2. Tối ưu
Khi sử dụng DHCP, các thiết bị chỉ sử dụng địa chỉ IP khi thực sự cần thiết và được cấp phát theo yêu cầu của DHCP client, giúp giảm thời gian chờ đợi và tối ưu hóa tài nguyên mạng.
7. Những thành phần liên quan
DHCP client: Là một phần mềm trên các thiết bị mạng như máy tính, điện thoại, máy chủ,… sẽ yêu cầu DHCP server cấp phát địa chỉ IP và các thông số cấu hình mạng khác.
DHCP server: Máy chủ chạy phần mềm DHCP để cấp phát địa chỉ IP và các thông số cấu hình mạng khác cho các DHCP client.
DHCP relay agents: Đây là một thiết bị trung gian giữa DHCP client và DHCP server, nếu DHCP client và DHCP server không cùng một mạng con, DHCP relay agents sẽ chuyển tiếp yêu cầu của DHCP client đến DHCP server và chuyển trả lại phản hồi từ DHCP server đến DHCP client.
Binding: Quá trình kết nối giữa địa chỉ IP được cấp phát và MAC address của thiết bị mạng, để đảm bảo việc gửi và nhận dữ liệu trên mạng một cách chính xác.
DHCP Lease: Là thời gian mà DHCP client được sử dụng địa chỉ IP được cấp phát từ DHCP server, sau khi kết thúc thời gian lease, DHCP client phải yêu cầu lại DHCP server để gia hạn lease hoặc cấp phát một địa chỉ IP mới.
8. DHCP hoạt động như thế nào?
Hoạt động của DHCP bao gồm các bước sau đây:
Yêu cầu DHCP (DHCP Request)
Khi một thiết bị mới được kết nối vào mạng, nó sẽ gửi một yêu cầu DHCP Request tới máy chủ DHCP. Yêu cầu này chứa thông tin về máy khách DHCP, bao gồm địa chỉ MAC, tên máy và các thông tin khác.
Giao tiếp giữa máy khách DHCP và máy chủ DHCP
Sau khi nhận được yêu cầu DHCP Request, máy chủ DHCP sẽ gửi lại gói tin DHCP Offer chứa thông tin về địa chỉ IP và các thông số mạng khác cho máy khách DHCP. Máy khách DHCP sẽ nhận được nhiều gói tin Offer từ các máy chủ DHCP khác nhau nếu có nhiều máy chủ DHCP trong mạng.
Lựa chọn địa chỉ IP và xác nhận (DHCP Select)
Máy khách DHCP sẽ lựa chọn một trong các gói tin Offer từ máy chủ DHCP và gửi một yêu cầu DHCP Select. Yêu cầu này xác nhận việc chọn địa chỉ IP được đề xuất từ máy chủ DHCP.
Cấp phát địa chỉ IP (DHCP ACK)
Sau khi nhận được yêu cầu DHCP Select từ máy khách DHCP, máy chủ DHCP sẽ gửi một gói tin DHCP ACK (Acknowledge) xác nhận việc cấp phát địa chỉ IP và các thông số mạng khác cho máy khách DHCP.
Quản lý địa chỉ IP
Khi máy khách DHCP đã nhận được gói tin ACK, nó sẽ sử dụng địa chỉ IP được cấp phát để kết nối vào mạng. Địa chỉ IP này sẽ được cấp phát cho máy khách trong một khoảng thời gian nhất định. Sau khi khoảng thời gian này kết thúc, địa chỉ IP sẽ được trả lại cho pool của máy chủ DHCP để cấp phát cho thiết bị khác trong mạng.
9. Các thông điệp giao tiếp giữa DHCP Server và máy Client
Các thông điệp chính trong quá trình cấp phát địa chỉ IP của DHCP bao gồm:
DHCP Discover: Khi một thiết bị mới kết nối vào mạng, nó gửi một gói tin DHCP Discover tới tất cả các máy chủ DHCP trong mạng để yêu cầu cấp phát địa chỉ IP. Gói tin này chứa địa chỉ MAC của thiết bị và yêu cầu các máy chủ DHCP phản hồi với gói tin DHCP Offer.
DHCP Offer: Các máy chủ DHCP trong mạng nhận được gói tin DHCP Discover sẽ phản hồi bằng gói tin DHCP Offer, chứa thông tin về địa chỉ IP được cấp phát, thời gian thuê và các thông số mạng khác. Thiết bị nhận được nhiều gói tin DHCP Offer từ các máy chủ DHCP khác nhau có thể lựa chọn địa chỉ IP và máy chủ DHCP phù hợp.
DHCP Request: Sau khi chọn được máy chủ DHCP và địa chỉ IP phù hợp, thiết bị sẽ gửi một gói tin DHCP Request để yêu cầu xác nhận việc cấp phát địa chỉ IP đó. Gói tin này chứa địa chỉ MAC của thiết bị và địa chỉ IP được chọn.
DHCP Acknowledge: Nếu máy chủ DHCP nhận được gói tin DHCP Request hợp lệ, nó sẽ phản hồi với gói tin DHCP Acknowledge, xác nhận rằng địa chỉ IP được cấp phát cho thiết bị đã được chấp nhận và các thông số mạng khác cũng đã được cấu hình.
DHCP Nak: Nếu máy chủ DHCP không thể cấp phát địa chỉ IP được yêu cầu hoặc có lỗi xảy ra trong quá trình cấp phát, nó sẽ phản hồi với gói tin DHCP Nak, thông báo cho thiết bị rằng yêu cầu cấp phát địa chỉ IP đã bị từ chối.
DHCP Decline: Thiết bị cũng có thể gửi gói tin DHCP Decline để thông báo cho máy chủ DHCP rằng địa chỉ IP đã nhận không hoạt động hoặc đã được sử dụng trước đó.
DHCP Release: Khi thiết bị không còn sử dụng địa chỉ IP đã được cấp phát, nó sẽ gửi một gói tin DHCP Release để thông báo cho máy chủ DHCP rằng địa chỉ IP này có thể được tái sử dụng và giải phóng các tài nguyên mạng liên quan đến địa chỉ IP đó.
Trong thời đại tự động hóa, việc kết nối các dịch vụ Google như Gmail, Google Sheets, Calendar... vào quy trình làm việc đang trở thành nhu cầu phổ biến với mọi cá nhân và tổ chức. Và tích hợp API Google với n8n - nền tảng workflow automation mã nguồn mở - sẽ giúp bạn xây dựng các quy trình tự động linh hoạt, tiết kiệm thời gian và giảm thiểu các tác vụ thủ công. Bài viết này sẽ hướng dẫn bạn từng bước kết nối API Google với n8n một cách chi tiết và an toàn, kể cả khi bạn chưa từng cấu hình OAuth 2.0 trước đây cũng có thể dễ dàng thực hiện thành công.
Quản lý nhiều tài khoản mạng xã hội và đăng bài thường xuyên thường tốn không ít thời gian. Bài viết này hướng dẫn bạn cách xây dựng hệ thống tự động hóa đăng bài (auto post) lên các nền tảng social media như Facebook, Twitter, LinkedIn bằng n8n – công cụ workflow automation mã nguồn mở, giúp tự động hóa quy trình, không cần thao tác thủ công hằng ngày mà vẫn đảm bảo sự hiện diện liên tục
Facebook chỉ hỗ trợ lên lịch đăng bài trên fanpage nhưng đăng bình luận thì không. Vì vậy, muốn comment vào những post đã lên lịch sẵn, chúng ta chỉ có cách canh giờ bài được đăng và vào bình luận thủ công. Làm thế nào tự động hóa toàn bộ? Trong bài viết này, TotHost sẽ hướng dẫn bạn cách xây dựng workflow trên n8n để có thể tự động comment cho các bài viết trên fanpage, kể các những bài mới chỉ có lịch đăng, chưa thực sự “lên sóng”.
Sử dụng VPS Forex để chạy nhiều tài khoản MT4/MT5 giao dịch hoặc copy trade là một lựa chọn thông minh và phổ biến. Vậy một VPS có thể chạy được bao nhiêu tài khoản cùng lúc? Cùng TotHost tìm câu trả lời trong bài viết này nhé.
Bạn có biết rằng một VPS được tối ưu đúng cách không chỉ giúp bạn khai thác tiền điện tử hiệu quả hơn mà còn tiết kiệm chi phí duy trì vận hành đáng kể? Trong bài viết này, chúng tôi sẽ hướng dẫn bạn những bí quyết thực tiễn nhất để khai thác tối đa hiệu suất của VPS – từ cách chọn cấu hình, nhà cung cấp cho đến triển khai công cụ phù hợp.
Tìm hiểu n8n - nền tảng workflow automation mã nguồn mở, linh hoạt, dễ dàng tùy biến, giúp tự động hóa quy trình marketing, CRM, IT chỉ trong vài bước đơn giản.