PageSourceSearch

https://www.nooritravel.co.uk/js/card-payment.js

js nooritravel.co.uk collected 2026-10-07 20:56:38 UTC 15,061 bytes, 499 lines download raw bytes

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