PageSourceSearch

https://giver.normisjon.no/js/script.js?v=1790692396

js normisjon.no collected 2026-10-02 07:23:36 UTC 24,227 bytes, 657 lines download raw bytes

1// $.ajaxSetup({ cache: false });
2
3// First, checks if it isn't implemented yet.
4if (!String.prototype.format) {
5    String.prototype.format = function () {
6        var args = arguments;
7        return this.replace(/{(\d+)}/g, function (match, number) {
8            return typeof args[number] != 'undefined'
9                ? args[number]
10                : match
11                ;
12        });
13    };
14}
15
16// slug: removing chars to have a nice url-part
17function convertToSlug(Text) {
18    return Text
19        .toLowerCase()
20        .replace(/ /g, '-')
21        .replace(/[^\w-]+/g, '')
22        .replace('---', '-')
23        .replace('--', '-');
24}
25
26function generateUUID() {
27    var d = new Date().getTime();
28    var d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || 0;//Time in microseconds since page-load or 0 if unsupported
29    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
30        var r = Math.random() * 16;//random number between 0 and 16
31        if (d > 0) {//Use timestamp until depleted
32            r = (d + r) % 16 | 0;
33            d = Math.floor(d / 16);
34        } else {//Use microseconds since page-load if supported
35            r = (d2 + r) % 16 | 0;
36            d2 = Math.floor(d2 / 16);
37        }
38        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
39    });
40}
41
42$(function () {
43
44    /* Legge til novalidate på alle skjema, fordi vi ønsker å fikse validering selv */
45    $("form").attr("novalidate", true);
46
47//fikse word-apostrofer
48    $("input, textarea").on("blur", function () {
49        $(this).val($(this).val().replace(/[\u2018|\u2019|\u201A]/g, "\'"))
50    })
51
52    $("input[type=text],input[type=number],input[type=password],select,textarea").addClass("form-control");
53    $("button:not(.btn):not(.vipps-button, .swedbank-button, .swish-button)").addClass("btn btn-default");
54
55
56//Validering ved submit
57    $("body").on("submit", "form", formValidate);
58});
59
60function shouldTakeVippsUserinfoRoute($form) {
61    var fieldsToCheck = [
62        '#a_tlfmobil:visible',
63        '#a_fornavn:visible',
64        '#a_etternavn:visible',
65        '#a_adresse2:visible',
66        '#a_postnummer:visible',
67        '#a_epostadr:visible',
68    ];
69
70    return $form.find(fieldsToCheck.join(',')).filter(function () {
71        return this.value.length > 0
72    }).length === 0;
73}
74
75function parseQuery(queryString) {
76    var query = {};
77    var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
78    for (var i = 0; i < pairs.length; i++) {
79        var pair = pairs[i].split('=');
80        query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
81    }
82    return query;
83}
84
85function getProduktId(input) {
86    var produktId = {};
87    if (input === undefined) {
88        return produktId;
89    }
90    var produktParts = input.split('-')
91
92    if (produktParts.length > 1 && !is_blank(produktParts[0]) && !is_blank(produktParts[1])) {
93        produktId['a_produkttype_id'] = produktParts[0];
94        produktId['l_prosjekt_id'] = produktParts[1];
95
96        if (produktParts.length === 3 && !is_blank(produktParts[2])) {
97            produktId['i_produktvariant'] = produktParts[2];
98        }
99    }
100
101    return produktId
102}
103
104function getVippsQueryString($form) {
105    var existingQuery = parseQuery(window.location.search);
106    var params = {
107        app: window.pf.l_pf3app_id
108    };
109
110    if ($form.find("[name=pris]:first").attr('type') == 'radio') {
111        params.amount = $form.find("[name=pris]:checked").val().replace(/\s|kr|,00|\.00/gm, '');
112    } else if ($form.find("#pris:visible").length) {
113        params.amount = $form.find("#pris:visible").val().replace(/\s|kr|,00|\.00/gm, '');
114    }
115
116    if (params.amount === undefined || params.amount == '') {
117        params.amount = $("form>div:visible input[name=pris]").val()
118    }
119    if (params.amount === undefined || params.amount == '') {
120        params.amount = $form.find("[name=pris]").val()
121    }
122
123    if (existingQuery.a !== undefined && existingQuery.a.match(/^\d+$/) !== null) {
124        params.l_aksjon_id = existingQuery.a;
125    }
126
127    if ($form.find('input[name=fbq_eventid]').length) {
128        params.fbq_eventid = $form.find('input[name=fbq_eventid]').val();
129    }
130
131    if ($form.find('[name=girorytme]:visible').length) {
132        params.i_girorytme = $form.find('[name=girorytme]:visible').val();
133    }
134
135    var produktIdString = $form.find("#prosjekt-produkt:visible,#medlemskap:visible").val();
136    if (is_blank(produktIdString) && existingQuery.hasOwnProperty('prosjekt-produkt')) {
137        produktIdString = existingQuery['prosjekt-produkt'];
138    }
139
140    var produktId = getProduktId(produktIdString);
141    if (Object.keys(produktId).length > 1) {
142        params = Object.assign(params, produktId);
143    }
144
145    return Object.keys(params)
146        .filter(function (key) {
147            return params[key] !== undefined
148        })
149        .map(key => `${key}=${params[key]}`)
150        .join('&');
151}
152
153function getVippsExpressUrlByForm($form) {
154    return '/vipps/gave?' + getVippsQueryString($form);
155}
156
157function getVippsUserInfoUrlByForm($form) {
158    return '/vipps/avtale?' + getVippsQueryString($form);
159}
160
161function formValidate($form) {
162    if (typeof COUNTRY_CODE == 'undefined') {
163        COUNTRY_CODE = 'no';
164    }
165    let paakrevdMsg = COUNTRY_CODE == 'se' ? 'Detta fältet är obligatoriskt' : 'Dette feltet er påkrevd';
166    let feilFormatdMsg = COUNTRY_CODE == 'se' ? 'Felaktigt format' : 'Feil format';
167    var $form = ($form === undefined || !$form.jquery) ? $(this) : $form;
168    $("#msg").remove();
169    fieldSelector = $form.data('validate-field-selector') || ':visible';
170
171    $form.find(".has-error").removeClass("has-error");
172
173    if ($form.data("prevalidate") != undefined)
174        eval($form.data("prevalidate"));
175
176    //requried radio button
177    $form.find(".form-group.required-radio" + fieldSelector).each(function () {
178        var msg;
179
180        if ($(this).find(":checked").length === 0) {
181            $(this).addClass("has-error");
182            msg = ($(this).attr("data-msg") !== undefined) ? $(this).attr("data-msg") : paakrevdMsg;
183            if ($(this).find(".help-block").length > 0)
184                $(this).find(".help-block").text(msg);
185            else
186                $(this).append("<span class=help-block>" + msg + "</span>");
187        }
188    });
189
190    //required checkbox
191    $form.find("input[type=checkbox]" + fieldSelector).each(function () {
192        var $this = $(this),
193            $formGroup = $this.closest(".form-group"),
194            msg;
195
196        if ($this.prop("required") && !$this.is(":checked")) {
197            $formGroup.addClass("has-error");
198            if ($formGroup.find(".help-block").length === 0)
199                $formGroup.append("<span class=help-block></span>");
200            msg = ($this.attr("data-msg") !== undefined) ? $this.attr("data-msg") : paakrevdMsg;
201            $formGroup.find(".help-block").html(msg);
202        }
203    });
204    $form.find("input{0}, select{0}, textarea{0}".format(fieldSelector)).each(function () {
205        var $this = $(this),
206            min = $this.attr('min'),
207            $helpTemp,
208            msg;
209
210        // Don't trim the value if this is a select with the "multiple" attribute because it would cause de-selection of options
211        if (!$this.is('select[multiple]')) {
212            //trimme alle feltene
213            $this.val($.trim($this.val()));
214        }
215
216        // ekstra sjekk på Fødselsnummer
217        if ($this.attr("name") == 'a_navneid') {
218            var navneIdOk = true;
219            var value = $this.val();
220            if (value.length > 0 && /^0+$/.test(value)) {
221                navneIdOk = false;
222            } else if (value.length == 11) {
223                if (!birthNumber(value)) {
224                    navneIdOk = false;
225                }
226            } else if (value.length == 9) {
227                if (!organizationNumber(value)) {
228                    navneIdOk = false;
229                }
230            } else if (value.length == 12 && COUNTRY_CODE == 'se') {
231                pin = value
232                    .replace(/\D/g, "")     // strip out all but digits
233                    .split("")              // convert string to array
234                    .reverse()              // reverse order for Luhn
235                if (pin.length != 12) {
236                    navneIdOk = false;
237                } else {
238
239                    pin = pin.slice(0, 10);
240
241                    if (pin.length != 10) {
242                        navneIdOk = false;
243                    } else {
244                        var sum = pin
245                            .map(function (n) {
246                                return Number(n);
247                            })
248                            .reduce(function (previous, current, index) {
249                                if (index % 2) current *= 2;
250                                if (current > 9) current -= 9;
251                                return previous + current;
252                            });
253                        navneIdOk = 0 === sum % 10;
254                    }
255                }
256            } else if (value.length > 0) {
257                navneIdOk = false;
258            }
259
260            if (!navneIdOk) {
261                $this.closest(".form-group").addClass("has-error");
262                $helpTemp = $this;
263                if (!$helpTemp.next().hasClass("help-block"))
264                    $helpTemp.after("<span class=help-block></span>");
265                let defaultMsg = COUNTRY_CODE == 'se' ? "Detta fält är ogiltigt" : "Dette feltet er ugyldig";
266                msg = ($this.attr("data-msg") != undefined) ? $this.attr("data-msg") : defaultMsg;
267                $helpTemp.next().html(msg);
268            }
269        }
270
271
272
273        //ekstra validering av født dato (brukes i arrangement modulen)
274        if ($this.attr("data-type") == 'foedt') {
275            let value = $.trim($this.val());
276
277            // La tom verdi passere her; "required" valideres separat nedenfor.
278            if (value === "") {
279                // Hvis feltet ikke er påkrevd, fjern eventuell tidligere feilmarkering.
280                if (!$this.prop("required")) {
281                    $this.closest('.form-group').removeClass('has-error');
282                    if ($this.closest('.form-group').find(".help-block").length) {
283                        $this.closest('.form-group').find(".help-block").html("");
284                    }
285                }
286            } else {
287                // Streng validering av dd.mm.yyyy
288                let match = /^(\d{2})\.(\d{2})\.(\d{4})$/.exec(value);
289                let isValidDate = false;
290
291                if (match) {
292                    let day = parseInt(match[1], 10);
293                    let month = parseInt(match[2], 10);
294                    let year = parseInt(match[3], 10);
295                    let date = new Date(year, month - 1, day);
296                    if (date.getFullYear() === year &&
297                        date.getMonth() === month - 1 &&
298                        date.getDate() === day) {
299                        isValidDate = true;
300                    }
301                }
302
303                if (!isValidDate) {
304                    if ($this.closest('.form-group').find(".help-block").length == 0) {
305                        $this.closest('.form-group').append("<span class=help-block></span>");
306                    }
307                    msg = ($this.attr("data-msg") != undefined) ? $this.attr("data-msg") : feilFormatdMsg;
308                    $this.closest('.form-group').find(".help-block").html(msg);
309                    $this.closest('.form-group').addClass('has-error');
310                } else {
311                    $this.closest('.form-group').removeClass('has-error');
312                }
313            }
314        }
315
316        // required, funker på dropdowns
317        if ($this.prop("required") && $this.val() === "") {
318            $this.closest(".form-group").addClass("has-error");
319            if ($this.parent().hasClass("input-group"))
320                $helpTemp = $this.parent();
321            else
322                $helpTemp = $this;
323            if (!$helpTemp.next().hasClass("help-block"))
324                $helpTemp.after("<span class=help-block></span>");
325            msg = ($this.attr("data-msg") != undefined) ? $this.attr("data-msg") : paakrevdMsg;
326            $helpTemp.next().html(msg);
327        } else if ($this.data("validate") === 'email' && !$this.val().match(/^$|^[\w\.\-]+@([\w\-]+\.)+[a-zA-Z]+$/)) {
328            $this.closest(".form-group").addClass("has-error");
329            if ($this.parent().hasClass("input-group")) {
330                $helpTemp = $this.parent();
331            } else {
332                $helpTemp = $this;
333            }
334            if ($helpTemp.parent().find(".help-block").length == 0) {
335                $helpTemp.parent().append("<span class=help-block></span>");
336            }
337            msg = ($this.attr("data-msg") != undefined) ? $this.attr("data-msg") : feilFormatdMsg;
338            $helpTemp.parent().find(".help-block").html(msg);
339        }
340        //reg.ex. validering
341        else if ($this.attr("pattern") != undefined && !$this.val().match($this.attr("pattern"))) {
342            $this.closest(".form-group").addClass("has-error");
343            if ($this.parent().hasClass("input-group"))
344                $helpTemp = $this.parent();
345            else
346                $helpTemp = $this;
347            if ($helpTemp.parent().find(".help-block").length == 0)
348                $helpTemp.parent().append("<span class=help-block></span>");
349            msg = ($this.attr("data-msg") != undefined) ? $this.attr("data-msg") : feilFormatdMsg;
350            $helpTemp.parent().find(".help-block").html(msg);
351        } else if ($this.data("validate") === 'date' && !$this.val().match("^$|^(0[1-9]|1[0-9]|2[0-9]|3[01]).(0[1-9]|1[012]).[0-9]{4}$")) {
352            $this.closest(".form-group").addClass("has-error");
353
354            // KendoUI datepicker
355            if ($this.closest('.k-datepicker').length) {
356                $this.prev().addClass("k-invalid");
357                $helpTemp = $this.parent();
358                if (!$helpTemp.next().hasClass("help-block"))
359                    $helpTemp.after("<div class=help-block></div>");
360            } else {
361                if ($this.parent().hasClass("input-group"))
362                    $helpTemp = $this.parent();
363                else
364                    $helpTemp = $this;
365                if ($helpTemp.parent().find(".help-block").length == 0)
366                    $helpTemp.parent().append("<span class=help-block></span>");
367            }
368
369            msg = ($this.attr("data-msg") != undefined) ? $this.attr("data-msg") : paakrevdMsg;
370            $helpTemp.parent().find(".help-block").html(msg);
371        }
372
373
374        if (min && ($this.val() == '' || parseInt($this.val()) < parseInt(min))) {
375            $this.closest(".form-group").addClass("has-error");
376            $helpTemp = $this;
377            if (!$helpTemp.next().hasClass("help-block"))
378                $helpTemp.after("<span class=help-block></span>");
379            msg = ($this.attr("data-msg") != undefined) ? $this.attr("data-msg") : 'Må være minst ' + min;
380            $helpTemp.next().html(msg);
381        }
382    });
383
384    if ($form.data("postValidate") != undefined)
385        eval($form.data("postValidate"));
386
387    //Hvis feilmelding dersom error er satt
388    if ($form.find(".has-error").length > 0) {
389        $(".has-error input, .has-error select, .has-error textarea").on("focus", function () {
390            $(this).closest(".has-error").removeClass("has-error");
391        })
392
393        var btn = $form.find(".btn:visible:last").length == 1 ? $form.find(".btn:visible:last") : $form.parent().find(".btn:visible:last")
394
395        // vi ønsker ikke en meldig i bunn når det er snakk om videre knapp her. Det tukler til vipps hurtigkasse også.
396        if (btn.length && btn.attr('id') && btn.attr('id').match('videre') !== null) {
397            return false;
398        }
399        btn.parent().prepend('<div id="msg" style="display: none; text-align: left"></div>');
400
401        $("#msg").addClass("alert alert-danger").html(COUNTRY_CODE == 'se' ? "Granska de rödmarkerade fälten för att gå vidare" : "Informasjon mangler eller har feil format. Sjekk felt som nå er blitt røde.").slideDown();
402
403        return false;
404    }
405
406    if ($form.find('[name=netsTest]:checked').length) {
407        toastr.warning('Valgt betaling mot NETS&nbsp;Test');
408    }
409
410    if ($form.find('[name=stripeTest]:checked').length) {
411        toastr.warning('Valgt betaling mot Stripe&nbsp;Test');
412    }
413
414    if ($form.find('[name=vippsRecurringTest]:checked').length) {
415        toastr.warning('Valgt testmiljø for Vipps&nbsp;Faste&nbsp;betalinger');
416    }
417
418    return true;
419}
420
421
422function isIframe() {
423    try {
424        return window.self !== window.top;
425    } catch (e) {
426        return true;
427    }
428}
429
430function setCookie(cname, cvalue, exdays) {
431    var d = new Date();
432    d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
433    var expires = "expires=" + d.toUTCString();
434    document.cookie = cname + "=" + cvalue + "; " + expires;
435}
436
437function getCookie(cname) {
438    var name = cname + "=";
439    var ca = document.cookie.split(';');
440    for (var i = 0; i < ca.length; i++) {
441        var c = ca[i];
442        while (c.charAt(0) == ' ') {
443            c = c.substring(1);
444        }
445        if (c.indexOf(name) == 0) {
446            return c.substring(name.length, c.length);
447        }
448    }
449    return "";
450}
451
452// is_blank, samme som Func::is_blank
453function is_blank(mixedVar) {
454    if (mixedVar === undefined) {
455        return true;
456    }
457    if (mixedVar === null) {
458        return true;
459    }
460    if (mixedVar === '') {
461        return true;
462    }
463    return false;
464}
465
466function stripTrailingSlash(str) {
467    if (str.substr(-1) === '/') {
468        return str.substr(0, str.length - 1);
469    }
470    return str;
471}
472
473
474var mod11OfNumberWithControlDigit = function (input) {
475    var controlNumber = 2,
476        sumForMod = 0,
477        i, result;
478
479    for (i = input.length - 2; i >= 0; --i) {
480        sumForMod += input.charAt(i) * controlNumber;
481        if (++controlNumber > 7)
482            controlNumber = 2;
483    }
484    result = (11 - sumForMod % 11);
485
486    return result === 11 ? 0 : result;
487};
488
489var accountNumber = function (accountNumber) {
490    if (!accountNumber) {
491        return false;
492    }
493    accountNumber = accountNumber.toString().replace(/\./g, '');
494    if (accountNumber.length !== 11) {
495        return false;
496    }
497    return parseInt(accountNumber.charAt(accountNumber.length - 1), 10)
498        === mod11OfNumberWithControlDigit(accountNumber);
499};
500
501var organizationNumber = function (orgNumber) {
502    orgNumber += '';
503    if (!orgNumber || orgNumber.length !== 9) {
504        return false;
505    }
506    return parseInt(orgNumber.charAt(orgNumber.length - 1), 10)
507        === mod11OfNumberWithControlDigit(orgNumber);
508};
509
510var birthNumber = function (birthNumber) {
511    birthNumber = birthNumber.toString();
512    if (!birthNumber || birthNumber.length !== 11) {
513        return false;
514    }
515
516    var sum = function (number, factors) {
517        var sum = 0;
518        for (var i = 0, l = factors.length; i < l; ++i) {
519            sum += parseInt(number.charAt(i), 10) * factors[i];
520        }
521        return sum;
522    };
523
524    var checksum1 = 11 - (sum(birthNumber, [3, 7, 6, 1, 8, 9, 4, 5, 2]) % 11);
525    if (checksum1 === 11) checksum1 = 0;
526    var checksum2 = 11 - (sum(birthNumber, [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]) % 11);
527    if (checksum2 === 11) checksum2 = 0;
528    return checksum1 === parseInt(birthNumber.charAt(9), 10)
529        && checksum2 === parseInt(birthNumber.charAt(10), 10);
530};
531
532var kidNumber = function (kidNumber) {
533    kidNumber = kidNumber.toString();
534    var controlDigit = kidNumber.charAt(kidNumber.length - 1);
535    return parseInt(controlDigit, 10) === mod11OfNumberWithControlDigit(kidNumber)
536        || parseInt(controlDigit, 10) === luhnValue(kidNumber);
537};
538
539var luhnValue = function (number) {
540    var sum = 0, dbl = 0, i;
541    for (i = number.length - 2; i >= 0; i -= 2) {
542        dbl = (parseInt(number.charAt(i), 10) * 2).toString();
543        sum += parseInt(dbl.charAt(0), 10) + parseInt(dbl.charAt(1) || 0, 10);
544    }
545    for (i = number.length - 3; i >= 0; i -= 2) {
546        sum += parseInt(number.charAt(i), 10);
547    }
548    sum = sum.toString();
549    return 10 - parseInt(sum.charAt(sum.length - 1), 10);
550};
551
552// See https://stackoverflow.com/a/901144
553function getUrlQueryParam(name, url) {
554    if (!url) url = window.location.href;
555    name = name.replace(/[\[\]]/g, '\\$&');
556    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
557        results = regex.exec(url);
558    if (!results) return null;
559    if (!results[2]) return '';
560    return decodeURIComponent(results[2].replace(/\+/g, ' '));
561}
562
563function removeEmptyAttributes(obj) {
564    Object.keys(obj).forEach(function (key) {
565        (obj[key] && typeof obj[key] === 'object') && removeEmptyAttributes(obj[key]) || (obj[key] === '' || obj[key] === null) && delete obj[key]
566    });
567    return obj;
568}
569
570function getPostalCodePattern(countryCode, customerCountry) {
571    if (countryCode == 'SE') {
572        return "^$|^\\d{5}$|^\\d{3} \\d{2}$";
573    }
574    if (customerCountry === 'SE') {
575        if (countryCode === customerCountry || countryCode === '') {
576            return "^$|^\\d{5}$|^\\d{3} \\d{2}$";
577        }
578
579        return "^\.{0,10}$"
580    }
581
582    if (countryCode === customerCountry || countryCode === '') {
583        return "^$|^\\d{4}$";
584    }
585
586    return "^\.{0,10}$"
587}
588
589function normalizeBirthdate($input) {
590    const today = new Date();
591    today.setHours(0,0,0,0);
592
593    function twoDigitYearToFull(yyStr) {
594        const yy = Number(yyStr);
595        const currentYY = new Date().getFullYear() % 100;
596        return (yy <= currentYY) ? (2000 + yy) : (1900 + yy);
597    }
598    const pad2 = n => (n = String(n), n.length === 1 ? '0'+n : n);
599
600    function isValidDate(y, m, d) {
601        const dt = new Date(y, m - 1, d);
602        return dt.getFullYear() === y && (dt.getMonth()+1) === m && dt.getDate() === d;
603    }
604    function isFutureDate(y, m, d) {
605        const dt = new Date(y, m - 1, d);
606        dt.setHours(0,0,0,0);
607        return dt > today;
608    }
609    const format = (y,m,d) => `${pad2(d)}.${pad2(m)}.${y}`;
610
611    function parseFlexibleBirthdate(input) {
612        if (!input) return null;
613        input = String(input).trim();
614        if (!input) return null;
615
616        // yyyy[-./ ]m[-./ ]d
617        let m = input.match(/^(\d{4})[.\-/\s](\d{1,2})[.\-/\s](\d{1,2})$/);
618        if (m) {
619            const y = +m[1], mo = +m[2], d = +m[3];
620            return (isValidDate(y,mo,d)&&!isFutureDate(y,mo,d)) ? format(y,mo,d) : null;
621        }
622
623        // D/M/Y (eller D.M.Y)
624        const parts = input.split(/[^0-9]+/).filter(Boolean);
625        if (parts.length === 3) {
626            let [p1,p2,p3] = parts;
627            if (/^\d{4}$/.test(p1)) {
628                const y = +p1, mo = +p2, d = +p3;
629                return (isValidDate(y,mo,d)&&!isFutureDate(y,mo,d)) ? format(y,mo,d) : null;
630            }
631            const y = /^\d{2}$/.test(p3) ? twoDigitYearToFull(p3) : +p3;
632            const mo = +p2, d = +p1;
633            return (isValidDate(y,mo,d)&&!isFutureDate(y,mo,d)) ? format(y,mo,d) : null;
634        }
635
636        // Bare siffer: ddmmyy / ddmmyyyy / yyyymmdd
637        const digits = input.replace(/\D+/g,'');
638        if (/^\d{6}$/.test(digits)) {
639            const d = +digits.slice(0,2), mo = +digits.slice(2,4), y = twoDigitYearToFull(digits.slice(4,6));
640            return (isValidDate(y,mo,d)&&!isFutureDate(y,mo,d)) ? format(y,mo,d) : null;
641        }
642        if (/^\d{8}$/.test(digits)) {
643            let d = +digits.slice(0,2), mo = +digits.slice(2,4), y = +digits.slice(4,8);
644            if (isValidDate(y,mo,d)&&!isFutureDate(y,mo,d)) return format(y,mo,d);
645            y = +digits.slice(0,4); mo = +digits.slice(4,6); d = +digits.slice(6,8);
646            return (isValidDate(y,mo,d)&&!isFutureDate(y,mo,d)) ? format(y,mo,d) : null;
647        }
648        return null;
649    }
650
651    const parsed = parseFlexibleBirthdate($input.val());
652    if (parsed) {
653        $input.val(parsed).get(0).setCustomValidity('');
654    } else {
655        $input.val(''); // Blank ut feltet hvis ugyldig
656    }
657}

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.