(function(){var $,Range,Trie,indexOf=[].indexOf||function(item){for(var i=0,l=this.length;i<l;i++)if(i in this&&this[i]===item)return i;return-1};Trie=function(){function Trie(){this.trie={}}return Trie.prototype.push=function(value){var char,i,j,len,obj,ref,results;for(value=value.toString(),obj=this.trie,results=[],i=j=0,len=(ref=value.split("")).length;j<len;i=++j)null==obj[char=ref[i]]&&(i===value.length-1?obj[char]=null:obj[char]={}),results.push(obj=obj[char]);return results},Trie.prototype.find=function(value){var char,i,j,len,obj,ref;for(value=value.toString(),obj=this.trie,i=j=0,len=(ref=value.split("")).length;j<len;i=++j){if(char=ref[i],!obj.hasOwnProperty(char))return!1;if(null===obj[char])return!0;obj=obj[char]}},Trie}(),Range=function(){function Range(trie1){if(this.trie=trie1,this.trie.constructor!==Trie)throw Error("Range constructor requires a Trie parameter")}return Range.rangeWithString=function(ranges){var j,k,len,n,r,range,ref,ref1,trie;if("string"!=typeof ranges)throw Error("rangeWithString requires a string parameter");for(ranges=(ranges=ranges.replace(/ /g,"")).split(","),trie=new Trie,j=0,len=ranges.length;j<len;j++)if(r=(range=ranges[j]).match(/^(\d+)-(\d+)$/))for(n=k=ref=r[1],ref1=r[2];ref<=ref1?k<=ref1:k>=ref1;n=ref<=ref1?++k:--k)trie.push(n);else{if(!range.match(/^\d+$/))throw Error("Invalid range '"+r+"'");trie.push(range)}return new Range(trie)},Range.prototype.match=function(number){return this.trie.find(number)},Range}(),($=jQuery).fn.validateCreditCard=function(callback,options){var bind,card,card_type,card_types,get_card_type,is_valid_length,is_valid_luhn,j,len,normalize,ref,validate,validate_number,_this;for(card_types=[{name:"amex",range:"34,37",valid_length:[15]},{name:"diners_club_carte_blanche",range:"300-305",valid_length:[14]},{name:"diners_club_international",range:"36",valid_length:[14]},{name:"jcb",range:"3528-3589",valid_length:[16]},{name:"laser",range:"6304, 6706, 6709, 6771",valid_length:[16,17,18,19]},{name:"visa_electron",range:"4026, 417500, 4508, 4844, 4913, 4917",valid_length:[16]},{name:"visa",range:"4",valid_length:[13,14,15,16,17,18,19]},{name:"mastercard",range:"51-55,2221-2720",valid_length:[16]},{name:"discover",range:"6011, 622126-622925, 644-649, 65",valid_length:[16]},{name:"dankort",range:"5019",valid_length:[16]},{name:"maestro",range:"50, 56-69",valid_length:[12,13,14,15,16,17,18,19]},{name:"uatp",range:"1",valid_length:[15]}],bind=!1,callback&&("object"==typeof callback?(options=callback,bind=!1,callback=null):"function"==typeof callback&&(bind=!0)),null==options&&(options={}),null==options.accept&&(options.accept=function(){var j,len,results;for(results=[],j=0,len=card_types.length;j<len;j++)card=card_types[j],results.push(card.name);return results}()),j=0,len=(ref=options.accept).length;j<len;j++)if(card_type=ref[j],indexOf.call(function(){var k,len1,results;for(results=[],k=0,len1=card_types.length;k<len1;k++)card=card_types[k],results.push(card.name);return results}(),card_type)<0)throw Error("Credit card type '"+card_type+"' is not supported");return get_card_type=function(number){var k,len1,r,ref1;for(ref1=function(){var l,len1,ref1,results;for(results=[],l=0,len1=card_types.length;l<len1;l++)ref1=(card=card_types[l]).name,indexOf.call(options.accept,ref1)>=0&&results.push(card);return results}(),k=0,len1=ref1.length;k<len1;k++)if(card_type=ref1[k],(r=Range.rangeWithString(card_type.range)).match(number))return card_type;return null},is_valid_luhn=function(number){var digit,k,len1,n,ref1,sum;for(sum=0,n=k=0,len1=(ref1=number.split("").reverse()).length;k<len1;n=++k)digit=+(digit=ref1[n]),sum+=n%2?(digit*=2)<10?digit:digit-9:digit;return sum%10==0},is_valid_length=function(number,card_type){var ref1;return ref1=number.length,indexOf.call(card_type.valid_length,ref1)>=0},validate_number=function(number){var length_valid,luhn_valid;return luhn_valid=!1,length_valid=!1,null!=(card_type=get_card_type(number))&&(luhn_valid=is_valid_luhn(number),length_valid=is_valid_length(number,card_type)),{card_type:card_type,valid:luhn_valid&&length_valid,luhn_valid:luhn_valid,length_valid:length_valid}},_this=this,validate=function(){var number;return number=normalize($(_this).val()),validate_number(number)},normalize=function(number){return number.replace(/[ -]/g,"")},bind?(this.on("input.jccv",function(_this){return function(){return $(_this).off("keyup.jccv"),callback.call(_this,validate())}}(this)),this.on("keyup.jccv",function(_this){return function(){return callback.call(_this,validate())}}(this)),callback.call(this,validate()),this):validate()}}).call(this);