1// Generated by CoffeeScript 1.4.0 2(function() { 3 var $, cardFromNumber, cardFromType, cards, formatBackCardNumber, formatBackExpiry, formatCardNumber, formatExpiry, formatForwardExpiry, formatForwardSlash, hasTextSelected, luhnCheck, restrictCVC, restrictCardNumber, restrictExpiry, restrictNumeric, setCardType, trim, 4 __slice = [].slice, 5 __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; }, 6 _this = this; 7 8 $ = jQuery; 9 10 $.payment = {}; 11 12 $.payment.fn = {}; 13 14 $.fn.payment = function() { 15 var args, method; 16 method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 17 return $.payment.fn[method].apply(this, args); 18 }; 19 20 cards = [ 21 { 22 type: 'maestro', 23 pattern: /^(5018|5020|5038|6304|6759|676[1-3])/, 24 length: [12, 13, 14, 15, 16, 17, 18, 19], 25 cvcLength: [3], 26 luhn: true 27 }, { 28 type: 'dinersclub', 29 pattern: /^(36|38|30[0-5])/, 30 length: [14], 31 cvcLength: [3], 32 luhn: true 33 }, { 34 type: 'laser', 35 pattern: /^(6304|6706|6771|6709)/, 36 length: [16, 17, 18, 19], 37 cvcLength: [3], 38 luhn: true 39 }, { 40 type: 'jcb', 41 pattern: /^35/, 42 length: [16], 43 cvcLength: [3], 44 luhn: true 45 }, { 46 type: 'unionpay', 47 pattern: /^62/, 48 length: [16, 17, 18, 19], 49 luhn: false 50 }, {
51 type: 'discover', 52 pattern: /^(6011|65|64[4-9]|622)/, 53 length: [16], 54 cvcLength: [3], 55 luhn: true 56 }, { 57 type: 'mastercard', 58 pattern: /^5[1-5]/, 59 length: [16], 60 cvcLength: [3], 61 luhn: true 62 }, { 63 type: 'amex', 64 pattern: /^3[47]/, 65 length: [15], 66 cvcLength: [3, 4], 67 luhn: true 68 }, { 69 type: 'visa', 70 pattern: /^4/, 71 length: [13, 14, 15, 16], 72 cvcLength: [3], 73 luhn: true 74 } 75 ]; 76 77 cardFromNumber = function(num) { 78 var card, _i, _len; 79 num = (num + '').replace(/\D/g, ''); 80 for (_i = 0, _len = cards.length; _i < _len; _i++) { 81 card = cards[_i]; 82 if (card.pattern.test(num)) { 83 return card; 84 } 85 } 86 }; 87 88 cardFromType = function(type) { 89 var card, _i, _len; 90 for (_i = 0, _len = cards.length; _i < _len; _i++) { 91 card = cards[_i]; 92 if (card.type === type) { 93 return card; 94 } 95 } 96 }; 97 98 trim = function(str) { 99 return (str + '').replace(/^\s+|\s+$/g, ''); 100 }; 101 102 luhnCheck = function(num) { 103 var digit, digits, odd, sum, _i, _len; 104 odd = true; 105 sum = 0; 106 digits = (num + '').split('').reverse(); 107 for (_i = 0, _len = digits.length; _i < _len; _i++) { 108 digit = digits[_i]; 109 digit = parseInt(digit, 10); 110 if ((odd = !odd)) { 111 digit *= 2; 112 } 113 if (digit > 9) { 114 digit -= 9; 115 } 116 sum += digit; 117 } 118 return sum % 10 === 0; 119 }; 120 121 hasTextSelected = function($target) { 122 var _ref; 123 if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== $target.prop('selectionEnd')) { 124 return true; 125 } 126 if (typeof document !== "undefined" && document !== null ? (_ref = document.selection) != null ? typeof _ref.createRange === "function" ? _ref.createRange().text : void 0 : void 0 : void 0) { 127 return true; 128 } 129 return false; 130 }; 131 132 formatCardNumber = function(e) { 133 var $target, card, digit, length, re, upperLength, value; 134 digit = String.fromCharCode(e.which); 135 if (!/^\d+$/.test(digit)) { 136 return; 137 } 138 $target = $(e.currentTarget); 139 value = $target.val(); 140 card = cardFromNumber(value + digit); 141 length = (value.replace(/\D/g, '') + digit).length; 142 upperLength = 16; 143 if (card) { 144 upperLength = card.length[card.length.length - 1]; 145 } 146 if (length >= upperLength) { 147 return; 148 } 149 if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) { 150 return; 151 } 152 if (card && card.type === 'amex') { 153 re = /^(\d{4}|\d{4}\s\d{6})$/; 154 } else { 155 re = /(?:^|\s)(\d{4})$/; 156 } 157 if (re.test(value)) { 158 e.preventDefault(); 159 return $target.val(value + ' ' + digit); 160 } else if (re.test(value + digit)) { 161 e.preventDefault(); 162 return $target.val(value + digit + ' '); 163 } 164 }; 165 166 formatBackCardNumber = function(e) { 167 var $target, value; 168 $target = $(e.currentTarget); 169 value = $target.val(); 170 if (e.meta) { 171 return; 172 } 173 if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) { 174 return; 175 } 176 if (e.which === 8 && /\s\d?$/.test(value)) { 177 e.preventDefault(); 178 return $target.val(value.replace(/\s\d?$/, '')); 179 } 180 }; 181 182 formatExpiry = function(e) { 183 var $target, digit, val; 184 digit = String.fromCharCode(e.which); 185 if (!/^\d+$/.test(digit)) { 186 return; 187 } 188 $target = $(e.currentTarget); 189 val = $target.val() + digit; 190 if (/^\d$/.test(val) && (val !== '0' && val !== '1')) { 191 e.preventDefault(); 192 return $target.val("0" + val + " / "); 193 } else if (/^\d\d$/.test(val)) { 194 e.preventDefault(); 195 return $target.val("" + val + " / "); 196 } 197 }; 198 199 formatForwardExpiry = function(e) { 200 var $target, digit, val; 201 digit = String.fromCharCode(e.which); 202 if (!/^\d+$/.test(digit)) { 203 return; 204 } 205 $target = $(e.currentTarget); 206 val = $target.val(); 207 if (/^\d\d$/.test(val)) { 208 return $target.val("" + val + " / "); 209 } 210 }; 211 212 formatForwardSlash = function(e) { 213 var $target, slash, val; 214 slash = String.fromCharCode(e.which); 215 if (slash !== '/') { 216 return; 217 } 218 $target = $(e.currentTarget); 219 val = $target.val(); 220 if (/^\d$/.test(val) && val !== '0') { 221 return $target.val("0" + val + " / "); 222 } 223 }; 224 225 formatBackExpiry = function(e) { 226 var $target, value; 227 if (e.meta) { 228 return; 229 } 230 $target = $(e.currentTarget); 231 value = $target.val(); 232 if (e.which !== 8) { 233 return; 234 } 235 if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) { 236 return; 237 } 238 if (/\s\/\s?$/.test(value)) { 239 e.preventDefault(); 240 return $target.val(value.replace(/\s\/\s?$/, '')); 241 } 242 }; 243 244 restrictNumeric = function(e) { 245 var char; 246 if (e.metaKey) { 247 return true; 248 } 249 if (e.which === 32) { 250 return false;
251 } 252 if (e.which === 0) { 253 return true; 254 } 255 if (e.which < 33) { 256 return true; 257 } 258 char = String.fromCharCode(e.which); 259 return !!/[\d\s]/.test(char); 260 }; 261 262 restrictCardNumber = function(e) { 263 var $target, card, digit, value; 264 $target = $(e.currentTarget); 265 digit = String.fromCharCode(e.which); 266 if (!/^\d+$/.test(digit)) { 267 return; 268 } 269 if (hasTextSelected($target)) { 270 return; 271 } 272 value = ($target.val() + digit).replace(/\D/g, ''); 273 card = cardFromNumber(value); 274 if (card) { 275 return value.length <= card.length[card.length.length - 1]; 276 } else { 277 return value.length <= 16; 278 } 279 }; 280 281 restrictExpiry = function(e) { 282 var $target, digit, value; 283 $target = $(e.currentTarget); 284 digit = String.fromCharCode(e.which); 285 if (!/^\d+$/.test(digit)) { 286 return; 287 } 288 if (hasTextSelected($target)) { 289 return; 290 } 291 value = $target.val() + digit; 292 value = value.replace(/\D/g, ''); 293 if (value.length > 6) { 294 return false; 295 } 296 }; 297 298 restrictCVC = function(e) { 299 var $target, val; 300 $target = $(e.currentTarget); 301 val = $target.val(); 302 return val.length <= 4; 303 }; 304 305 setCardType = function(e) { 306 var $target, allTypes, card, cardType, val; 307 $target = $(e.currentTarget); 308 val = $target.val(); 309 cardType = $.payment.cardType(val) || 'unknown'; 310 if (!$target.hasClass(cardType)) { 311 allTypes = (function() { 312 var _i, _len, _results; 313 _results = []; 314 for (_i = 0, _len = cards.length; _i < _len; _i++) { 315 card = cards[_i]; 316 _results.push(card.type); 317 } 318 return _results; 319 })(); 320 $target.removeClass('unknown'); 321 $target.removeClass(allTypes.join(' ')); 322 $target.addClass(cardType); 323 $target.toggleClass('identified', cardType !== 'unknown'); 324 return $target.trigger('payment.cardType', cardType); 325 } 326 }; 327 328 $.payment.fn.formatCardCVC = function() { 329 this.payment('restrictNumeric'); 330 this.on('keypress', restrictCVC); 331 return this; 332 }; 333 334 $.payment.fn.formatCardExpiry = function() { 335 this.payment('restrictNumeric'); 336 this.on('keypress', restrictExpiry); 337 this.on('keypress', formatExpiry); 338 this.on('keypress', formatForwardSlash); 339 this.on('keypress', formatForwardExpiry); 340 this.on('keydown', formatBackExpiry); 341 return this; 342 }; 343 344 $.payment.fn.formatCardNumber = function() { 345 this.payment('restrictNumeric'); 346 this.on('keypress', restrictCardNumber); 347 this.on('keypress', formatCardNumber); 348 this.on('keydown', formatBackCardNumber); 349 this.on('keyup', setCardType); 350 return this; 351 }; 352 353 $.payment.fn.restrictNumeric = function() { 354 this.on('keypress', restrictNumeric); 355 return this; 356 }; 357 358 $.payment.fn.cardExpiryVal = function() { 359 return $.payment.cardExpiryVal($(this).val()); 360 }; 361 362 $.payment.cardExpiryVal = function(value) { 363 var month, prefix, year, _ref; 364 value = value.replace(/\s/g, ''); 365 _ref = value.split('/', 2), month = _ref[0], year = _ref[1]; 366 if ((year != null ? year.length : void 0) === 2 && /^\d+$/.test(year)) { 367 prefix = (new Date).getFullYear(); 368 prefix = prefix.toString().slice(0, 2); 369 year = prefix + year; 370 } 371 month = parseInt(month, 10); 372 year = parseInt(year, 10); 373 return { 374 month: month, 375 year: year 376 }; 377 }; 378 379 $.payment.validateCardNumber = function(num) { 380 var card, _ref; 381 num = (num + '').replace(/\s+|-/g, ''); 382 if (!/^\d+$/.test(num)) { 383 return false; 384 } 385 card = cardFromNumber(num); 386 if (!card) { 387 return false; 388 } 389 return (_ref = num.length, __indexOf.call(card.length, _ref) >= 0) && (card.luhn === false || luhnCheck(num)); 390 }; 391 392 $.payment.validateCardExpiry = function(month, year) { 393 var currentTime, expiry, _ref; 394 if (typeof month === 'object' && 'month' in month) { 395 _ref = month, month = _ref.month, year = _ref.year; 396 } 397 if (!(month && year)) { 398 return false; 399 } 400 month = trim(month); 401 year = trim(year); 402 if (!/^\d+$/.test(month)) { 403 return false;
404 } 405 if (!/^\d+$/.test(year)) { 406 return false; 407 } 408 if (!(parseInt(month, 10) <= 12)) { 409 return false; 410 } 411 expiry = new Date(year, month); 412 currentTime = new Date; 413 expiry.setMonth(expiry.getMonth() - 1); 414 expiry.setMonth(expiry.getMonth() + 1, 1); 415 return expiry > currentTime; 416 }; 417 418 $.payment.validateCardCVC = function(cvc, type) { 419 var _ref, _ref1; 420 cvc = trim(cvc); 421 if (!/^\d+$/.test(cvc)) { 422 return false; 423 } 424 if (type) { 425 return _ref = cvc.length, __indexOf.call((_ref1 = cardFromType(type)) != null ? _ref1.cvcLength : void 0, _ref) >= 0; 426 } else { 427 return cvc.length >= 3 && cvc.length <= 4; 428 } 429 }; 430 431 $.payment.cardType = function(num) { 432 var _ref; 433 if (!num) { 434 return null; 435 } 436 return ((_ref = cardFromNumber(num)) != null ? _ref.type : void 0) || null; 437 }; 438 439}).call(this);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.