PageSourceSearch

https://about.au.reachout.com/funraisin.4.1/js/funraisin.4.1.js?ver=3.80

js reachout.com collected 2026-09-24 08:32:28 UTC 56,305 bytes, 1,006 lines download raw bytes

1jQuery.validator.addMethod("notEqual",function(value,element,param){return this.optional(element)||value!=param},"Please specify a different (non-default) value");jQuery.validator.addMethod("afterDate",function(value,element,param){var arr=value.split("-");var arr2=param.split("-");var startDate=new Date(arr[2],arr[1]-1,arr[0],0,0,0,0);var thisDate=new Date(arr2[2],arr2[1]-1,arr2[0],0,0,0,0);if(startDate<thisDate){return!1}
2else{return!0}},"Please specify a different (non-default) value");jQuery.validator.addMethod("validEmail",function(value,element,param){var re=/^[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])?)+$/;return re.test(String(value).toLowerCase())},"Please specify a valid email");jQuery.validator.addMethod("strictPassword",function(value,element,param){var re=/^.*(?=.{4,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[-!$\#\?\*@%^&*()_+|~=`{}\[\]:";'<>?,.\/]).*$/;return re.test(value)},"Please enter a stronger password.");$.fn.visibleIn=function(){this.animate({'opacity':1},300,function(){});this.find('input').attr('disabled',!1);this.find('select').attr('disabled',!1);this.find('.hider').remove()};$.fn.visibleOut=function(){this.animate({'opacity':0.3},300,function(){});this.find('input').attr('disabled','disabled');this.find('select').attr('disabled','disabled');this.css('position','relative');this.append('<div class="hider" style="position:absolute;top:0;left:0;width:100%;height:100%;"></div>')};$.fn.visibleInReadonly=function(){this.animate({'opacity':1},300,function(){});this.find('input').attr('readonly',!1);this.find('select').attr('readonly',!1);this.find('.hider').remove()};$.fn.visibleOutReadonly=function(){this.animate({'opacity':0.3},300,function(){});this.find('input').attr('readonly','readonly');this.find('select').attr('readonly','readonly');this.css('position','relative');this.append('<div class="hider" style="position:absolute;top:0;left:0;width:100%;height:100%;"></div>')};var resizeLightbox=function(){var ScrollTop=($(document).scrollTop()>0)?$(document).scrollTop():0;var PopHeight=parseInt($('#popup').height());if(PopHeight<10){}
3else{if($(window).height()<PopHeight){var WinTop=0}
4else{var WinTop=parseInt($(window).height())/2-(PopHeight/2)}
5var child=$('#popup div:first');var WinLeft=($(window).width()-child.width())/2}
6hideActivity()};$(document).ready(function(){if($('.btn-payment-element').length == 1) {$('.btn-payment-element').hide();}$('#kw_address').on('focus',function(){$('#kw_address').attr('autocomplete','new-password');});$('#d_address').on('focus',function(){$('#d_address').attr('autocomplete','new-password');});$('input[type=checkbox]#optin_fees,input[type=checkbox]#d_optin_fees').addClass('optincheckbox');$('.hasDatepicker').attr('autocomplete','new-password');new WOW().init();$('.funraisin-page-left .funraisin-dropdown-nav a').each(function(){if($(this).parent().find('ul').length>0){$(this).append("<span class='pull-right indicator'>+</span>")}});$('.funraisin-page-left .funraisin-dropdown-nav').on('click','a',function(e){if($(this).parent().find('ul').length>0){if($(this).parent().find('ul').is(':visible')){if($(e.target).hasClass('indicator')){$(this).parent().find('ul').hide();$(this).find('.indicator').html("+");return!1}}
7else{$(this).parent().find('ul').show();$(this).find('.indicator').html("-");return!1}}});$('a').each(function(){var p=/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;if($(this).attr('href')){if($(this).attr('href').match(p)){$(this).addClass('fancybox-media')}}});if(jQuery().fancybox){$('.fancybox').fancybox();$('.fancybox-media').fancybox({openEffect:'none',closeEffect:'none',helpers:{media:{}}})}
8if(window.location.hash!=''){const h=window.location.hash;try{if(h=='#content'){if($(document).scrollTop()<=100){$('html,body').animate({scrollTop:$('#content-main').offset().top-60},1e3)}}else{const t=document.querySelector(h);if(t){$('html,body').animate({scrollTop:$(t).offset().top-60},500)}}}catch(e){console.warn('Invalid hash in URL:',h)}}
9if($('.funraisin-desktop-nav .funraisin-header-nav').length>0){var $el=$('.funraisin-desktop-nav .funraisin-header-nav');var bottom=$el.position().top+$el.offset().top+$el.outerHeight(!0);StickyHeader=!1;
9$(document).scroll(function(){var DocPosition=parseInt($(document).scrollTop());if(DocPosition>(bottom+30)){if(!StickyHeader){$('#sticky-nav').addClass('sticky');$('#sticky-nav').removeClass('sticky-hide');StickyHeader=!0}}
10if(DocPosition<(bottom+25)){if(StickyHeader){$('#sticky-nav').addClass('sticky-hide');$('#sticky-nav').removeClass('sticky');StickyHeader=!1}}})}
11var fadeStart=100,fadeUntil=850,heroHeader=$('.heroTop'),pageHeader=$('.headerSlider .PageWrapper');$(window).bind('scroll',function(){var offset=$(document).scrollTop(),opacity=0;var scroll=$(window).scrollTop();if(offset<=fadeStart){opacity=1}else if(offset<=fadeUntil){opacity=1-offset/fadeUntil}
12heroHeader.css('opacity',opacity).css("transform","translateY("+(scroll/2)+"px)");pageHeader.css('opacity',opacity).css("transform","translateY("+(scroll/2)+"px)")});$('.radiobuttonset label').click(function(){$(this).parent().find('input[type=radio]').attr('checked',!1);$('#'+$(this).attr('for')).attr('checked','checked');$(this).parent().find('label').removeClass('selected');$(this).addClass('selected');$('#'+$(this).attr('for')).trigger('click')});$('.visibleout').each(function(){$(this).css('position','relative');$(this).append('<div class="hider" style="position:absolute;top:0;left:0;width:100%;height:100%;"></div>');$(this).find('input').attr('disabled','disabled');$(this).find('select').attr('disabled','disabled');$(this).find('a').click(function(){return!1});$(this).find('label').click(function(){return!1})});$('.visibleoutreadonly').each(function(){$(this).css('position','relative');$(this).append('<div class="hider" style="position:absolute;top:0;left:0;width:100%;height:100%;"></div>');$(this).find('input').attr('readonly','readonly');$(this).find('select').attr('readonly','readonly');$(this).find('a').click(function(){return!1});$(this).find('label').click(function(){return!1})});if($('#card_number').length){$('#card_number').validateCreditCard(function(result){$(this).removeClass('mastercard').removeClass('visa').removeClass('amex').removeClass('diners').removeClass('maestro').removeClass('discover');var cardtype=(result.card_type==null?'':result.card_type.name);$(this).addClass(cardtype)})}
13historyurl='';$('body').on('click','.lightbox',function(){showActivity();var ScrollTop=($(document).scrollTop()>0)?$(document).scrollTop():0;var WinTop=($(document).scrollTop()>0)?(parseInt($(window).height())/2)-150+parseInt(ScrollTop):'50%';var WinLeft=0;showLightboxPanel(65530);$("#popup").css('z-index','65532');$("#popup").css("top",WinTop);$("#popup").fadeIn(1000);$('#popup').load(this.href,function(responseTxt,statusTxt,xhr){if(statusTxt=="success")
14resizeLightbox();$('select.selectpicker').selectpicker('refresh')});return!1});$('body').on('click touchstart','.BtClosePopup,.BtClose,.closelightbox,#LightboxPanel,#AdminLightboxPanel',function(){if($(this).hasClass('noclick')) {return false;}if($('#popup .editor').length>0){$('#popup .editor').each(function(){tinyMCE.execCommand('mceRemoveEditor',!1,$(this).attr('id'))})}
15$('#popup,#Adminpopup,#AdminNewRow,#AdminNewLump,#AdminTemplate,#AdminNewPage,#AdminCreatePage').hide();$("#popup,#Adminpopup,#AdminNewRow,#AdminNewLump,#AdminTemplate,#AdminNewPage,#AdminCreatePage").css('z-index','1');$('#popup,#Adminpopup,#AdminNewRow,#AdminNewLump,#AdminTemplate,#AdminNewPage,#AdminCreatePage').html('');$("#LightboxPanel,#AdminLightboxPanel").fadeOut(500);$('#AdminLightboxPanel').removeClass('noclick');$('body').css('overflow','auto');showFields();showFlash();hideActivity()});$('.slide-left').click(function(){$('.funraisin-page-left,.funraisin-page-right').css('height',$('body').height());if(parseInt($('.funraisin-mobile-nav').css('left'))<1){$('.funraisin-page-left').animate({left:'0px'},300);$('.slide-left').attr('aria-expanded','true');$('.funraisin-header-wrapper,.funraisin-mobile-nav, main, #Footer').animate({'left':'250px'},300);$(this).find('.slideleft').addClass("open")}
16else{$('.slide-left').attr('aria-expanded','false');$('.funraisin-header-wrapper,.funraisin-mobile-nav, main, #Footer').animate({'left':'0px'},300);$('.funraisin-page-left').animate({left:'-250px'},300);$(this).find('.slideleft').removeClass("open")}
17return!1});$('#PageLeftClose span').click(function(){$('.funraisin-page-center').animate({'left':'0'},300,function(){$('.funraisin-page-left').hide()})});$('.slide-right').click(function(){$('.funraisin-page-left,.funraisin-page-right').css('height',$('body').height());if(parseInt($('.funraisin-mobile-nav').css('left'))==0){$('.funraisin-page-right').animate({right:'0'},300);$('.funraisin-header-wrapper,.funraisin-mobile-nav, main, #Footer').animate({'left':'-250px'},300);$('.right-close').addClass('is-active');$('.slide-right.m5').addClass('hidden')}
18else{$('.funraisin-header-wrapper,.funraisin-mobile-nav, main, #Footer').animate({'left':'0'},300);$('.funraisin-page-right').animate({right:'-250px'},300);$('.right-close').removeClass('is-active');$('.slide-right.m5').removeClass('hidden')}
19return!1});$('body').on('click','.funraisin-lightbox',function(){var ScrollTop=($(document).scrollTop()>0)?$(document).scrollTop():0;var WinTop=50+parseInt(ScrollTop);var WinLeft=0;$("#popup").css('width','100%');showLightboxPanel(65529);$("#popup").css('z-index','65530');$("#popup").fadeIn(1000);$('#popup').load(this.href);return!1});$('body').on('click','.funraisin-mediabrowser',function(){var ScrollTop=($(document).scrollTop()>0)?$(document).scrollTop():0;var WinTop=50+parseInt(ScrollTop);var WinLeft=0;$("#popup").css('width','100%');showLightboxPanel(65529);$("#mediapopup").css('z-index','75530');$("#mediapopup").fadeIn(1000);$('#mediapopup').load(this.href);return!1});$('.toggle-btn').on('click',function(){$(this).parent().find('.toggle-btn').removeClass('bg-primary border-primary');$(this).addClass('bg-primary border-primary')});$('a[href^=\\#]:not([href=\\#]):not([data-toggle="tab"]):not([data-toggle="collapse"])').on('click',function(){var target=$(this.hash);target=target.length?target:$('[name='+this.hash.slice(1)+']');if(target.length){$('html,body').animate({scrollTop:target.offset().top-150},1000);return!1}});$('body').on('click','.qty-group .btn-number',function(e){e.preventDefault();fieldName=$(this).attr('data-field');type=$(this).attr('data-type');var group=$(this).closest('.qty-group');var input=group.find("#"+fieldName+"");var currentVal=parseInt(input.val());console.log(currentVal);
19if(!isNaN(currentVal)){if(type=='minus'){if(currentVal>input.attr('min')){input.val(--currentVal).change()}
20if(parseInt(input.val())==input.attr('min')){$(this).attr('disabled',!0)}}else if(type=='plus'){if(currentVal<input.attr('max')){input.val(++currentVal).change()}
21if(parseInt(input.val())==input.attr('max')){$(this).attr('disabled',!0)}}if(currentVal>input.attr('min')) {group.find('[data-type="minus"]').attr('disabled',false)}if(currentVal<input.attr('max')){group.find('[data-type="plus"]').attr('disabled',false)}}else{input.val(0)}});$('.qty-group #qty').change(function(){minValue=parseInt($(this).attr('min'));maxValue=parseInt($(this).attr('max'));valueCurrent=parseInt($(this).val());var elem=$(this).closest('.qty-group');name=$(this).attr('id');if(valueCurrent>minValue){elem.find(".btn-number[data-type='minus'][data-field='"+name+"']").removeAttr('disabled')}else{$(this).val(minValue)}
22if(valueCurrent<maxValue){elem.find(".btn-number[data-type='plus'][data-field='"+name+"']").removeAttr('disabled')}else{$(this).val(maxValue)}});});var inited=!1;var showTick=function(){if(inited){$(".trigger").toggleClass("drawn")}
23else{$(".trigger").toggleClass("drawn");setTimeout(showTick,2000);inited=!0}};var triggerTopPage=function(which,url){DisplayHeight=($(window).height()<800)?800:$(window).height();ParentBG=$(which).parent().css('background-color');PageUrl=url;PageRel=$(which).attr('rel');if(ActivePage!=PageRel){$('#TopPage .wrapper').html(' ')}
24$('#TopPage').css('background',ParentBG).animate({'height':DisplayHeight-280+'px'},1000,function(){IsClosed=!1;if(ActivePage!=PageRel){$('#TopPage .wrapper').html(' ').html('<div class="loader"></div>').load(PageUrl);ActivePage=PageRel}})};var triggerProfilebox=function(url){showActivity();var WinTop='180px';var WinLeft=0;$("#popup").css('z-index','490');$("#popup").fadeIn(1000);$('#popup').load(url)};var focusFormField=function(el,defaultvalue){if($(el).val()==defaultvalue){$(el).val('')}};var blurFormField=function(el,defaultvalue){if($(el).val()==''){$(el).val(defaultvalue)}};var triggerLightbox=function(url){showActivity();var WinTop=($(document).scrollTop()>0)?'calc(50% + '+parseInt($(document).scrollTop()+60)+'px)':'50%';var WinLeft=0;console.log($(document).scrollTop());console.log(WinTop);showLightboxPanel(6500);$("#popup").css('z-index','1000000');$("#popup").css("top",WinTop);$("#popup").fadeIn(1000);$('#popup').load(url)}
25var showActivity=function(){$("#ajaxloader").height($(window).height());$("#ajaxloader").width($(window).width());$("#ajaxloader").css('padding-top',parseInt($(window).height())/2);$('#ajaxloader').show()}
26var hideActivity=function(){$('#ajaxloader').hide()};var showLightboxPanel=function(zindex){$("#LightboxPanel").height($(document).height());$("#LightboxPanel").width($(document).width());$("#LightboxPanel").css("left",0);$("#LightboxPanel").css("top",0);$("#LightboxPanel").css("z-index",zindex);$("#LightboxPanel").css("opacity",".75");$("#LightboxPanel").fadeIn(500)}
27var showLightboxPanelNoFade=function(zindex){$("#LightboxPanel").height($(document).height());$("#LightboxPanel").width($(document).width());$("#LightboxPanel").css("left",0);$("#LightboxPanel").css("top",0);$("#LightboxPanel").css("z-index",zindex);$("#LightboxPanel").fadeIn(500)}
28function showFields(){var flashObjects=document.getElementsByTagName("select");for(i=0;i<flashObjects.length;i++){flashObjects[i].style.visibility="visible"}}
29function hideFields(){var flashObjects=document.getElementsByTagName("select");for(i=0;i<flashObjects.length;i++){flashObjects[i].style.visibility="hidden"}}
30function showFlash(){var flashObjects=document.getElementsByTagName("object");for(i=0;i<flashObjects.length;i++){flashObjects[i].style.visibility="visible"}
31var flashEmbeds=document.getElementsByTagName("embed");for(i=0;i<flashEmbeds.length;i++){flashEmbeds[i].style.visibility="visible"}}
32function hideFlash(){var flashObjects=document.getElementsByTagName("object");for(i=0;i<flashObjects.length;i++){flashObjects[i].style.visibility="hidden"}
33var flashEmbeds=document.getElementsByTagName("embed");for(i=0;i<flashEmbeds.length;i++){flashEmbeds[i].style.visibility="hidden"}}
34function RemoveJunk(El,DataType,format){var V=El.value;if(format===undefined){format='EN'}
35if(DataType=="int"){if(/[^0-9\.]/g.test(V)){El.value=V.replace(/[^0-9\.]/g,'')}}
36else if(DataType=="string"){if(/[^a-zA-Z\.]/g.test(V)){El.value=V.replace(/[^a-zA-Z\.]/g,'')}}
37else if(DataType=="stringint"){if(/[^a-zA-Z0-9]/g.test(V)){El.value=V.replace(/[^a-zA-Z0-9]/g,'')}}
38else if(DataType=="username"){if(/[^a-zA-Z0-9_\-]/g.test(V)){El.value=V.replace(/[^a-zA-Z0-9_\-]/g,'')}}
39else if(DataType=="password"){if(/[^a-zA-Z0-9_!\$\.]/g.test(V)){El.value=V.replace(/[^a-zA-Z0-9_!\$\.]/g,'')}}
40else if(DataType=="amount"){if(/[^0-9\.]/g.test(V)){El.value=V.replace(/[^0-9\.]/g,'')}}
41else if(DataType=="nofloat"){if(format=='EUR'){if(/[^0-9\$,.]/g.test(V)){$(El).tooltip({title:'Please just enter euros and cents with no period, thank you'}).tooltip('show');El.value=V.replace(/[^0-9\$,.]/g,'')}}
42else{if(/[^0-9\.]/g.test(V)){$(El).tooltip({title:'Please just enter dollars and cents with no commas, thank you'}).tooltip('show');El.value=V.replace(/[^0-9\.]/g,'')}}}}
43function validEmail(email){var re=/^[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])?)+$/;return re.test(String(email).toLowerCase())}
44function parseDate(dYear,dMonth,dDay){return new Date(dYear,dMonth,dDay)}
45function calculateAge(dateOfBirth,dateToCalculate){var calculateYear=dateToCalculate.getFullYear();var calculateMonth=dateToCalculate.getMonth();var calculateDay=dateToCalculate.getDate();var birthYear=dateOfBirth.getFullYear();var birthMonth=dateOfBirth.getMonth();var birthDay=dateOfBirth.getDate();var age=calculateYear-birthYear;var ageMonth=calculateMonth-birthMonth;var ageDay=calculateDay-birthDay;if(ageMonth<0||(ageMonth==0&&ageDay<0)){age=parseInt(age)-1}
46return age}
47function dateDiff(first,second){return Math.round((second-first)/(1000*60*60*24))}
48var print_r=function(obj,t){var tab=t||'';var isArr=Object.prototype.toString.call(obj)==='[object Array]';var str=isArr?('Array\n'+tab+'[\n'):('Object\n'+tab+'{\n');for(var prop in obj){if(obj.hasOwnProperty(prop)){var val1=obj[prop];var val2='';var type=Object.prototype.toString.call(val1);switch(type){case '[object Array]':case '[object Object]':val2=print_r(val1,(tab+'\t'));break;case '[object String]':val2='\''+val1+'\'';break;default:val2=val1}
49str+=tab+'\t'+prop+' => '+val2+',\n'}}
50str=str.substring(0,str.length-2)+'\n'+tab;return isArr?(str+']'):(str+'}')};function darkerhex(color, percent){var r=parseInt(color.slice(1,3),16);var g=parseInt(color.slice(3,5),16);var b=parseInt(color.slice(5,7),16);r=Math.floor(r*(100-percent)/100);g=Math.floor(g*(100-percent)/100);b=Math.floor(b*(100-percent)/100);return"#"+((r<<16)|(g<<8)|b).toString(16).padStart(6,'0');}
51$(document).ready(function(){if($('#d_address_state').length) {function handleSelectOptionsChange(mutationsList, observer) {mutationsList.forEach((mutation) => {if (mutation.type === 'childList' && mutation.target.tagName === 'SELECT') {if($('#d_address_state').val() == null) {$('select#d_address_state').prepend('<option value=""></option>');$('select#d_address_state').val('');$('.selectpicker').selectpicker('refresh');}}});}function observeSelectOptions(selectElement) {const observer = new MutationObserver(handleSelectOptionsChange);const config = { childList: true, subtree: true };observer.observe(selectElement, config);}const selectElement = document.getElementById('d_address_state');observeSelectOptions(selectElement);}});
52function progressCelebration(t,n){switch(n){case"hearts":var e=document.createElementNS("http://www.w3.org/2000/svg","path");e.setAttribute("d","M316.722,29.761c66.852,0,121.053,54.202,121.053,121.041c0,110.478-2
5218.893,257.212-218.893,257.212S0,266.569,0,150.801C0,67.584,54.202,29.761,121.041,29.761c40.262,0,75.827,19.745,97.841,49.976C240.899,49.506,276.47,29.761,316.722,29.761z")}var r=document.createElementNS("http://www.w3.org/2000/svg","svg");r.setAttribute("viewBox","0 0 512 512"),r.setAttribute("height","20"),r.setAttribute("width","20"),r.appendChild(e),party.scene.current.createEmitter({emitterOptions:{loops:1,useGravity:!1,modules:[new party.ModuleBuilder().drive("size").by(function(t){return.5+.3*(Math.cos(10*t)+1)}).build(),new party.ModuleBuilder().drive("rotation").by(function(t){return new party.Vector(0,0,100).scale(t)}).relative().build()]},emissionOptions:{rate:0,bursts:[{time:0,count:party.variation.range(20,40)}],sourceSampler:party.sources.dynamicSource($("#NudgeProgress .nudge-icon")[0]),angle:party.variation.range(0,360),initialSpeed:300,initialColor:party.Color.fromHex(t)},rendererOptions:{shapeFactory:r,applyLighting:void 0}})}
53function preventElementsRedirect(){history.pushState(null,null,window.location.href);window.onpopstate=function(event){history.pushState(null,null,window.location.href)};$('.content a').addClass('disabled-link')}
54function enableElementsRedirect(){history.pushState({canGoBack:true},null,window.location.href);$('.content a').removeClass('disabled-link')}
55
56const showRgUpsellIcon = () => {
57	const el = $('#rgupsell #animated-icon');
58	if (el.length === 0) return;
59
60	lottie.loadAnimation({
61		container: el[0],
62		renderer: 'svg',
63		loop: true,
64		autoplay: true,
65		path: '/funraisin.4.1/js/lottie/default.json',
66	});
67};
68
69$(document).ready(function(){
70	// handle frequency change if paypal recurring is disabled
71	if (!$('.paypal_recurring_enabled').val()) {
72		$('form #donation_frequency').each(function (index, el) {
73			const frequencyObserver = new MutationObserver(mutations => {
74				mutations.forEach(mutation => {
75					const selectedFrequency = mutation.target.value.trim();
76					if (selectedFrequency != '') {
77						$('.btn-payment-element[data-rel="paypal"]').hide();
78						$('#venmo-button-container').hide();
79					} else {
80						$('.btn-payment-element[data-rel="paypal"]').show();
81						$('#venmo-button-container').show();
82					}
83				});
84			});
85
86			frequencyObserver.observe(el, {
87				attributes: true,
88				attributeFilter: ['value']
89			});
90		});
91	}
92});
93
94var inited = !1;
95var showTick = function () {
96    if (inited) {
97        $(".trigger").toggleClass("drawn");
98    } else {
99        $('#tick').css('z-index', '99999999');
100        $(".trigger").toggleClass("drawn");
101        setTimeout(showTick, 2000);
102        inited = !0;
103    }
104};
105
106var triggerDonationLightbox = function (url, embed = '') {
107    showActivity();
108    var WinLeft = 0;
109    console.log($(document).scrollTop());
110    showDonationLightboxPanel(6500);
111    $("#popup").css("z-index", "1000000");
112    $("#popup").fadeIn(1000);
113    console.log(url);
114    $("#popup").load(url, {embed: embed}, function(response, status, xhr){
115        if (status === "success") {
116            var scrollTop = $(window).scrollTop();
117            var winHeight = $(window).height();
118            var popupHeight = $("#popup").outerHeight();
119
120            var top = scrollTop + Math.max(
121                ((winHeight - popupHeight) / 2) + 400,
122                50
123            );
124            
125            top = scrollTop > 0 ? top + "px" : "50%"; 
126            $("#popup").css("top", top);
127
128            let popupColor = $('#popup .panel').css('background-color');
129            if(typeof popupColor === 'string' && popupColor.startsWith('prefix')){
130                if (popupColor.startsWith("rgba")) {
131                    // extract the alpha value from the rgba string
132                    let alpha = parseFloat(popupColor.split(",")[3]);
133                    if (isNaN(alpha)) {
134                        alpha = 1; // default to 1 if parsing fails
135                    }
136
137                    if (alpha == 0) {
138                        $('#popup').css('box-shadow', 'none');
139                    }
140                    else {
141                        $('#popup').css('box-shadow', '0 0 20px rgba(0,0,0,0.3)');
142                    }
143            }
144            }
145        }
146    });
147
148    
149};
150
151if (!window.FunraisinStripePaymentMethod) {
152    window.FunraisinStripePaymentMethod = {
153        create: function (config) {
154            var settings = config || {};
155            var stripe = settings.stripe;
156            if (!stripe) {
157                throw new Error('FunraisinStripePaymentMethod requires a Stripe instance');
158            }
159
160            var formSelector = settings.formSelector || '#DonationForm';
161            var errorSelector = settings.errorSelector || '.error';
162            var submitButtonSelector = settings.submitButtonSelector || formSelector + ' button[type=submit]';
163            var resetButtonHtml = settings.resetButtonHtml || '';
164            var paymentMethodSelector = settings.paymentMethodSelector || '#payment_method_id';
165            var cardNumberSelector = settings.cardNumberSelector || '#pm_card_number';
166            var expiryMonthSelector = settings.expiryMonthSelector || '#pm_card_expiry_month';
167            var expiryYearSelector = settings.expiryYearSelector || '#pm_card_expiry_year';
168            var numberSelector = settings.cardNumberElementSelector || '#card_number';
169            var expirySelector = settings.cardExpiryElementSelector || '#card_expiry';
170            var cvcSelector = settings.cardCvcElementSelector || '#card_cvv';
171
172            if ($(numberSelector).length === 0 || $(expirySelector).length === 0 || $(cvcSelector).length === 0) {
173                throw new Error('FunraisinStripePaymentMethod requires card number, expiry, and CVC elements to be present in the DOM');
174            }
175
176            var elements = stripe.elements();
177            var cardNumber = elements.create('cardNumber');
178            var cardExpiry = elements.create('cardExpiry');
179            var cardCvc = elements.create('cardCvc');
180
181            cardNumber.mount(numberSelector);
182            cardExpiry.mount(expirySelector);
183            cardCvc.mount(cvcSelector);
184
185            var responseHandler = function (result) {
186                var form = $(formSelector);
187                if (result.error) {
188                    $(errorSelector).html(result.error.message).show().removeClass('hidden');
189                    $(submitButtonSelector).html(resetButtonHtml).attr('disabled', false);
190                    $('html, body').animate({ scrollTop: 0 }, 0);
191                    return;
192                }
193
194                $(paymentMethodSelector).val(result.paymentMethod.id);
195                $(cardNumberSelector).val('************' + result.paymentMethod.card.last4);
196                $(expiryMonthSelector).val(result.paymentMethod.card.exp_month);
197                $(expiryYearSelector).val(String(result.paymentMethod.card.exp_year).slice(-2));
198
199                form.get(0).submit();
200            };
201
202            return { cardNumber: cardNumber, cardExpiry: cardExpiry, cardCvc: cardCvc, responseHandler: responseHandler };
203        }
204    }
205}
206
207var showDonationLightboxPanel = function (zindex) {
208    $("#LightboxPanel").css("width", "100vw");
209    $("#LightboxPanel").css("height", "100vh");
210    $("#LightboxPanel").css("position", "fixed");
211    $("#LightboxPanel").css("left", 0);
212    $("#LightboxPanel").css("top", 0);
213    $("#LightboxPanel").css("z-index", zindex);
214    $("#LightboxPanel").css("opacity", "0.5");
215    $("#LightboxPanel").fadeIn(500);
216};
217
218$(document).ready(function () {
219    var $popup = $('#popup');
220    if (!$popup.length) {
221        return;
222    }
223
224    var otherOpenDialogsSelector = '#Adminpopup, #AdminNewRow, #AdminNewLump, #AdminTemplate, #AdminNewPage, #AdminCreatePage';
225    var isFocusInOtherOpenDialog = function (activeEl) {
226        if (!activeEl) {
227            return false;
228        }
229
230        var isInside = false;
231        $(otherOpenDialogsSelector).filter(':visible').each(function () {
232            if (this.contains(activeEl)) {
233                isInside = true;
234                return false;
235            }
236        });
237
238        return isInside;
239    };
240
241    var isPopupEditableTarget = function (target) {
242        if (!target || !$popup.is(':visible')) {
243            return false;
244        }
245
246        var $target = $(target);
247        return $target.closest('#popup #m_comments_field, #popup #t_comments_field, #popup [contenteditable="true"]').length > 0;
248    };
249
250    if (!window.__popupEditableArrowCaptureBound) {
251        var popupEditableArrowCaptureHandler = function (event) {
252            var isHorizontalArrow = event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.which === 37 || event.which === 39 || event.keyCode === 37 || event.keyCode === 39;
253
254            // Prevent Slick slide navigation when left/right arrows are used inside editable components (for example, contenteditable divs).
255            if (!isHorizontalArrow || !isPopupEditableTarget(event.target)) {
256                return;
257            }
258
259            event.stopPropagation();
260            if (typeof event.stopImmediatePropagation === 'function') {
261                event.stopImmediatePropagation();
262            }
263        };
264
265        document.addEventListener('keydown', popupEditableArrowCaptureHandler, true);
266        document.addEventListener('keyup', popupEditableArrowCaptureHandler, true);
267        window.__popupEditableArrowCaptureBound = true;
268    }
269
270    var focusableSelector = 'a[href],a.BtClose,a.BtClosePopup,a.closelightbox,area[href],input:not([type="hidden"]),select,textarea,button,iframe,object,embed,[contenteditable],[tabindex],.toggle-btn';
271    var bindPopupEditableArrowGuard = function () {
272        $popup
273            .off('keydown.popupEditableArrowGuard', '[contenteditable="true"],#m_comments_field,#t_comments_field')
274            .on('keydown.popupEditableArrowGuard', '[contenteditable="true"],#m_comments_field,#t_comments_field', function (event) {
275                var isHorizontalArrow = event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.which === 37 || event.which === 39 || event.keyCode === 37 || event.keyCode === 39;
276
277                if (!isHorizontalArrow) {
278                    return;
279                }
280
281                // Keep caret movement in editable fields and prevent parent slick sliders from consuming arrow keys.
282                event.stopPropagation();
283            });
284    };
285
286    var normalizePopupCloseControls = function () {
287        $popup.find('a.BtClosePopup,a.BtClose,a.closelightbox').each(function () {
288            var $anchor = $(this);
289            var $button = $('<button type="button"></button>');
290            var attrs = this.attributes;
291
292            for (var attrIndex = 0; attrIndex < attrs.length; attrIndex++) {
293                var name = attrs[attrIndex].name;
294                var value = attrs[attrIndex].value;
295
296                if (name === 'href' || name === 'target' || name === 'rel') {
297                    continue;
298                }
299
300                $button.attr(name, value);
301            }
302
303            $button.attr('type', 'button');
304            if (!$button.attr('aria-label')) {
305                $button.attr('aria-label', 'Close modal');
306            }
307
308            $button.html($anchor.html());
309            $anchor.replaceWith($button);
310        });
311    };
312
313    var getPopupFocusableElements = function () {
314        normalizePopupCloseControls();
315
316        var $activeSlides = $popup.find('.slick-slide.slick-active:visible').not('.slick-cloned');
317        var hasSlickActive = $activeSlides.length > 0;
318
319        return $popup.find(focusableSelector).filter(function () {
320            var $el = $(this);
321            var tabindex = $el.attr('tabindex');
322            var inActiveSlide = $el.closest('.slick-slide.slick-active').length > 0 && $el.closest('.slick-cloned').length === 0;
323            var isCloseControl = $el.is('.BtClose, .BtClosePopup, .closelightbox');
324            var isSlickDotControl = $el.is('button') && $el.closest('ul.slick-dots[role="tablist"],ul.slick-dots').length > 0;
325            var isBootstrapSelectToggle = $el.is('.bootstrap-select > button.dropdown-toggle, .bootstrap-select button.dropdown-toggle');
326            var isBootstrapSelectListbox = $el.is('.bootstrap-select .dropdown-menu .inner[role="listbox"], .bootstrap-select .inner[role="listbox"]');
327            var isRoleButtonTabIndex = $el.attr('role') === 'button' && typeof $el.attr('tabindex') !== 'undefined' && parseInt($el.attr('tabindex'), 10) >= 0 && $el.closest('#personaldonation').length > 0 && $el.closest('.slick-slide').length === 0;
328            var hasRadioChildToggleBtn = $el.is('.toggle-btn') && $el.find('input[type="radio"]').length > 0;
329            var isToggleBtnInStepTeam = $el.is('.toggle-btn') && $el.closest('#StepTeam').length > 0 && $el.closest('.slick-slide').length === 0;
330            var isRadioInToggleBtnInStepTeam = $el.is('input[type="radio"]') && $el.closest('.toggle-btn').length > 0 && $el.closest('#StepTeam').length > 0 && $el.closest('.slick-slide').length === 0;
331
332            if (hasRadioChildToggleBtn) {
333                return false;
334            }
335
336            if (hasSlickActive && !(inActiveSlide || isCloseControl || isSlickDotControl || isRoleButtonTabIndex || isToggleBtnInStepTeam || isRadioInToggleBtnInStepTeam)) {
337                return false;
338            }
339
340            if (typeof tabindex !== 'undefined') {
341                if ((isBootstrapSelectToggle || isBootstrapSelectListbox || isSlickDotControl) && parseInt(tabindex, 10) < 0) {
342                    $el.attr('tabindex', tabindex = '0');
343                }
344
345                if ($el.is('a.BtClose, a.BtClosePopup, a.closelightbox') && !$el.is('[href]')) {
346                    $el.attr('tabindex', tabindex = '0');
347                }
348            } else {
349                if ($el.is('.toggle-btn')) {
350                    $el.attr('tabindex', tabindex = '0');
351                }
352            }
353
354            if ($el.is(':disabled') || $el.attr('aria-hidden') === 'true' || (typeof tabindex !== 'undefined' && parseInt(tabindex, 10) < 0)) {
355                return false;
356            }
357
358            return $el.is(':visible');
359        });
360    };
361
362    var focusFirstPopupElement = function (forceFocus) {
363        normalizePopupCloseControls();
364
365        var activeEl = document.activeElement;
366
367        if ($popup.find('*').length === 0 || !$popup.is(':visible')) {
368            return;
369        }
370
371        if (!forceFocus && activeEl && $popup[0].contains(activeEl)) {
372            return;
373        }
374
375        var $focusables = getPopupFocusableElements();
376
377        if ($focusables.length) {
378            $focusables[0].focus();
379        }
380    };
381
382    var focusActivePopupComponentOrClose = function () {
383        normalizePopupCloseControls();
384
385        if ($popup.find('*').length === 0 || !$popup.is(':visible')) {
386            return;
387        }
388
389        var $focusables = getPopupFocusableElements();
390        var $activeComponent = $focusables.filter(function () {
391            var $el = $(this);
392            var inActiveSlide = $el.closest('.slick-slide.slick-active').length > 0 && $el.closest('.slick-cloned').length === 0;
393            var isSlickDotControl = $el.is('button') && $el.closest('ul.slick-dots[role="tablist"],ul.slick-dots').length > 0;
394            var isCloseControl = $el.is('.BtClose, .BtClosePopup, .closelightbox');
395
396            return inActiveSlide && !isSlickDotControl && !isCloseControl;
397        }).first();
398
399        if ($activeComponent.length) {
400            $activeComponent[0].focus();
401            return;
402        }
403
404        var $closeControl = $popup.find('button.BtClosePopup,button.BtClose,button.closelightbox,a.BtClosePopup,a.BtClose,a.closelightbox').filter(':visible').first();
405        if ($closeControl.length) {
406            if (typeof $closeControl.attr('tabindex') === 'undefined') {
407                $closeControl.attr('tabindex', '0');
408            }
409            $closeControl[0].focus();
410        }
411    };
412
413    if (typeof MutationObserver === 'function') {
414        var popupObserver = new MutationObserver(function (mutations) {
415            var hasContentChange = false;
416
417            for (var i = 0; i < mutations.length; i++) {
418                if (mutations[i].type === 'childList' && (mutations[i].addedNodes.length || mutations[i].removedNodes.length)) {
419                    hasContentChange = true;
420                    break;
421                }
422            }
423
424            if (hasContentChange) {
425                setTimeout(function () {
426                    if ($popup.find('*').length === 0 || !$popup.is(':visible')) {
427                        return;
428                    }
429
430                    var activeEl = document.activeElement;
431                    var focusIsInsidePopup = activeEl && $popup[0].contains(activeEl);
432
433                    if (focusIsInsidePopup) {
434                        return;
435                    }
436
437                    // If focus is inside a separate admin dialog/panel that happens to be open
438                    // at the same time (e.g. the page builder's lump editor), it was never lost -
439                    // leave it alone instead of yanking it into this popup.
440                    if (isFocusInOtherOpenDialog(activeEl)) {
441                        return;
442                    }
443
444                    bindPopupEditableArrowGuard();
445                    focusFirstPopupElement(true);
446                }, 0);
447            }
448        });
449
450        popupObserver.observe($popup[0], {
451            childList: true,
452            subtree: true
453        });
454    }
455
456    $(document).off('keydown.popupFocusTrap').on('keydown.popupFocusTrap', function (event) {
457        if (event.key !== 'Tab' || !$popup.is(':visible') || $popup.find('*').length === 0) {
458            return;
459        }
460
461        if (isFocusInOtherOpenDialog(document.activeElement)) {
462            // Focus is legitimately inside another open admin dialog/panel - let it handle Tab itself.
463            return;
464        }
465
466        var $focusables = getPopupFocusableElements();
467
468        if (!$focusables.length) {
469            event.preventDefault();
470            return;
471        }
472
473        var focusableEls = $focusables.toArray();
474        var activeEl = document.activeElement;
475
476        if (!$popup[0].contains(activeEl)) {
477            event.preventDefault();
478            focusableEls[0].focus();
479            return;
480        }
481
482        var activeIndex = focusableEls.indexOf(activeEl);
483
484        if (activeIndex < 0) {
485            for (var i = 0; i < focusableEls.length; i++) {
486                if (focusableEls[i].contains(activeEl)) {
487                    activeIndex = i;
488                    break;
489                }
490            }
491        }
492
493        if (activeIndex < 0) {
494            event.preventDefault();
495            if (event.shiftKey) {
496                focusableEls[focusableEls.length - 1].focus();
497            } else {
498                focusableEls[0].focus();
499            }
500            return;
501        }
502
503        event.preventDefault();
504
505        var nextIndex = event.shiftKey ? activeIndex - 1 : activeIndex + 1;
506        if (nextIndex < 0) {
507            nextIndex = focusableEls.length - 1;
508        }
509        if (nextIndex >= focusableEls.length) {
510            nextIndex = 0;
511        }
512
513        focusableEls[nextIndex].focus();
514    });
515
516    $(document).off('keydown.popupSkipSpace').on('keydown.popupSkipSpace', '#popup a.skip', function (event) {
517        if (event.key !== ' ' && event.key !== 'Spacebar' && event.code !== 'Space') {
518            return;
519        }
520
521        event.preventDefault();
522        this.click();
523    });
524
525    $(document).off('keydown.popupEscape').on('keydown.popupEscape', function (event) {
526        if (event.key === 'Escape' && $popup.is(':visible')) {
527            event.preventDefault();
528            $popup.fadeOut(500);
529            $('#LightboxPanel').fadeOut(500);
530        }
531    });
532
533    $(document).off('click.popupSlickDots')
534        .on('click.popupSlickDots', '#popup ul.slick-dots button[role="tab"], #popup ul.slick-dots button', function () {
535            setTimeout(function () {
536                focusActivePopupComponentOrClose();
537            }, 0);
538        });
539
540    $popup.off('keydown.popupBootstrapSelect').on('keydown.popupBootstrapSelect', '.bootstrap-select > button.dropdown-toggle, .bootstrap-select .dropdown-menu .inner[role="listbox"], .bootstrap-select .dropdown-menu .dropdown-item, .bootstrap-select .dropdown-menu a[role="option"]', function (event) {
541        var isArrowKey = event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.which === 37 || event.which === 38 || event.which === 39 || event.which === 40 || event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40;
542
543        if (!isArrowKey) {
544            return;
545        }
546
547        // Keep arrow keys inside bootstrap-select and away from document-level bootstrap dropdown handlers.
548        event.stopPropagation();
549    });
550
551    $popup.off('shown.bs.select.popupBootstrapSelect').on('shown.bs.select.popupBootstrapSelect', 'select.selectpicker', function () {
552        var $select = $(this);
553
554        setTimeout(function () {
555            var $bootstrapSelect = $select.closest('.bootstrap-select');
556            $bootstrapSelect.data('ignoreConfirmKeyUntil', Date.now() + 200);
557            var $activeOption = $bootstrapSelect.find('.dropdown-menu li.active a, .dropdown-menu .dropdown-item.active').first();
558
559            if ($activeOption.length) {
560                var activeTabindex = $activeOption.attr('tabindex');
561                if (typeof activeTabindex === 'undefined' || parseInt(activeTabindex, 10) < 0) {
562                    $activeOption.attr('tabindex', '0');
563                }
564
565                $activeOption.focus();
566                return;
567            }
568
569            var $listbox = $bootstrapSelect.find('.dropdown-menu .inner[role="listbox"]').first();
570
571            if (!$listbox.length) {
572                return;
573            }
574
575            var listboxTabindex = $listbox.attr('tabindex');
576            if (typeof listboxTabindex === 'undefined' || parseInt(listboxTabindex, 10) < 0) {
577                $listbox.attr('tabindex', '0');
578            }
579
580            $listbox.focus();
581        }, 0);
582    });
583
584    var closeBootstrapSelectAfterChoose = function ($select) {
585        var $bootstrapSelect = $select.closest('.bootstrap-select');
586        var isOpen = $bootstrapSelect.hasClass('show') || $bootstrapSelect.hasClass('open') || $bootstrapSelect.find('.dropdown-menu').hasClass('show');
587        var selectedValue = $select.val();
588        var hasSelectedValue = $.isArray(selectedValue) ? selectedValue.length > 0 : selectedValue !== null && selectedValue !== '';
589
590        if (!$select.length || !$bootstrapSelect.length || $select.prop('multiple') || !isOpen || !hasSelectedValue) {
591            return;
592        }
593
594        $bootstrapSelect.find('> .dropdown-menu').removeClass('show');
595
596        var $toggleButton = $bootstrapSelect.find('> button.dropdown-toggle');
597        if ($toggleButton.length) {
598            var toggleTabindex = $toggleButton.attr('tabindex');
599            if (typeof toggleTabindex === 'undefined' || parseInt(toggleTabindex, 10) < 0) {
600                $toggleButton.attr('tabindex', '0');
601            }
602        }
603
604        if (document.activeElement && typeof document.activeElement.blur === 'function') {
605            document.activeElement.blur();
606        }
607
608        setTimeout(function () {
609            $toggleButton.focus();
610        }, 0);
611    };
612
613    $(document).off('click.popupBootstrapSelectClose').on('click.popupBootstrapSelectClose', '#popup .bootstrap-select .dropdown-menu .dropdown-item, #popup .bootstrap-select .dropdown-menu a[role="option"]', function () {
614        var $select = $(this).closest('.bootstrap-select').find('select.selectpicker').first();
615
616        setTimeout(function () {
617            closeBootstrapSelectAfterChoose($select);
618        }, 0);
619    });
620
621    $(document).off('keyup.popupBootstrapSelectClose').on('keyup.popupBootstrapSelectClose', '#popup .bootstrap-select .dropdown-menu .dropdown-item, #popup .bootstrap-select .dropdown-menu a[role="option"]', function (event) {
622        var isConfirmKey = event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar' || event.code === 'Space' || event.which === 13 || event.which === 32 || event.keyCode === 13 || event.keyCode === 32;
623        var $bootstrapSelect = $(this).closest('.bootstrap-select');
624        var ignoreConfirmKeyUntil = parseInt($bootstrapSelect.data('ignoreConfirmKeyUntil'), 10) || 0;
625        var shouldIgnoreConfirmKey = Date.now() < ignoreConfirmKeyUntil;
626
627        if (!isConfirmKey || shouldIgnoreConfirmKey) {
628            return;
629        }
630
631        var $select = $(this).closest('.bootstrap-select').find('select.selectpicker').first();
632
633        setTimeout(function () {
634            closeBootstrapSelectAfterChoose($select);
635        }, 0);
636    });
637
638    $popup.off('afterChange.popupSlickDots').on('afterChange.popupSlickDots', '.slick-slider', function () {
639        setTimeout(function () {
640            focusActivePopupComponentOrClose();
641        }, 0);
642    });
643
644    bindPopupEditableArrowGuard();
645    focusFirstPopupElement();
646
647    // ignore clicks on empty links in the navbar to prevent page reloads
648    $('.navbar-nav a:not([href]), .navbar-nav a[href=""]').on('click', function(e){
649        e.preventDefault();
650        e.stopPropagation();
651    });
652});
653
654$(document).ready(function () {
655    if (!window.BootstrapDialog) return;
656    var originalShow = BootstrapDialog.show;
657
658    // Support multiple dialogs (stack-safe)
659    var focusStack = [];
660
661    function getFocusable($container) {
662        return $container.find(`
663            a[href],
664            button:not([disabled]):not([tabindex="-1"]),
665            textarea:not([disabled]),
666            input:not([disabled]),
667            select:not([disabled]),
668            [tabindex]:not([tabindex="-1"])
669        `).filter(':visible');
670    }
671
672    function handleKeydown(e, $modal, dialogRef) {
673        const key = e.key;
674
675        if (key === 'Escape') {
676            e.preventDefault();
677            dialogRef.close();
678            return;
679        }
680
681        if (key !== 'Tab') return;
682
683        const $focusable = getFocusable($modal);
684        if (!$focusable.length) return;
685
686        const first = $focusable[0];
687        const last = $focusable[$focusable.length - 1];
688        const active = document.activeElement;
689
690        if (!active || !$modal[0].contains(active)) {
691            e.preventDefault();
692            $(first).focus();
693            return;
694        }
695
696        if (e.shiftKey) {
697            if (active === first) {
698                e.preventDefault();
699                $(last).focus();
700            }
701        } else {
702            if (active === last) {
703                e.preventDefault();
704                $(first).focus();
705            }
706        }
707    }
708
709    BootstrapDialog.show = function (options) {
710        var userOnShown = options.onshown;
711        var userOnHide = options.onhide;
712
713        var previouslyFocusedElement = document.activeElement;
714
715        options.onshown = function (dialogRef) {
716            var $modal = $(dialogRef.getModal());
717
718            // Save last focused element (stack)
719            focusStack.push(previouslyFocusedElement);
720
721            // ARIA + focusable container
722            var $modalContent = $modal.find('.modal-content').first();
723            var $ariaTarget = $modalContent.length ? $modalContent : $modal;
724            $ariaTarget.attr({
725                role: 'dialog',
726                'aria-modal': 'true',
727                tabindex: '-1'
728            });
729
730            // Link title for screen readers
731            var $title = $modal.find('.bootstrap-dialog-title');
732            if ($title.length) {
733                var id = 'dialog-title-' + Date.now();
734                $title.attr('id', id);
735                $ariaTarget.attr('aria-labelledby', id);
736            }
737
738            // Focus first element or fallback
739            setTimeout(function() {
740                var $closeButton = $modal.find('.bootstrap-dialog-close-button button.close, button.close').filter(':visible').first();
741                if ($closeButton.length) {
742                    // Ensure proper aria-label for screen readers
743                    if (!$closeButton.attr('aria-label') || $closeButton.attr('aria-label').toLowerCase() === 'close') {
744                        $closeButton.attr('aria-label', 'Close dialog');
745                    }
746                    
747                    if (!$closeButton.attr('tabindex') || parseInt($closeButton.attr('tabindex'), 10) < 0) {
748                        $closeButton.attr('tabindex', '0');
749                    }
750                    $closeButton.focus();
751                } else {
752                    var $focusable = getFocusable($modal);
753                    if ($focusable.length) {
754                        $focusable.first().focus();
755                    } else {
756                        $modal.focus();
757                    }
758                }
759            }, 300);
760
761            // Attach focus trap
762            $modal.on('keydown.a11yTrap', function (e) {
763                handleKeydown(e, $modal, dialogRef);
764            });
765
766            // (Optional but recommended) prevent background scroll
767            $('body').css('overflow', 'hidden');
768
769            if (typeof userOnShown === 'function') {
770                userOnShown(dialogRef);
771            }
772        };
773
774        options.onhide = function (dialogRef) {
775            var $modal = $(dialogRef.getModal());
776
777            // Remove trap
778            $modal.off('keydown.a11yTrap');
779
780            // Restore focus (stack-safe)
781            var last = focusStack.pop();
782            if (last && document.body.contains(last)) {
783                setTimeout(function() {
784                    try {
785                        $(last).focus();
786                    } catch(e) {
787                        document.body.focus();
788                    }
789                }, 10);
790            }
791
792            // Restore scroll
793            if ($('.modal:visible').length === 0) {
794                $('body').css('overflow', '');
795            }
796
797            if (typeof userOnHide === 'function') {
798                userOnHide(dialogRef);
799            }
800        };
801
802        return originalShow.call(this, options);
803    };
804    
805    const $tabs = $('.a11y-tab');
806    $tabs.on('keydown', function (e) {
807
808        const currentIndex = $tabs.index(this);
809        let nextIndex = null;
810
811        switch (e.key) {
812
813            case 'ArrowRight':
814                nextIndex = (currentIndex + 1) % $tabs.length;
815                break;
816
817            case 'ArrowLeft':
818                nextIndex = (currentIndex - 1 + $tabs.length) % $tabs.length;
819                break;
820
821            case 'Home':
822                nextIndex = 0;
823                break;
824
825            case 'End':
826                nextIndex = $tabs.length - 1;
827                break;
828
829            default:
830                return;
831        }
832
833        e.preventDefault();
834        const $nextTab = $tabs.eq(nextIndex);
835        // Update ARIA states
836        $tabs.attr({
837            'aria-selected': 'false',
838            'tabindex': '-1'
839        });
840
841        $nextTab.attr({
842            'aria-selected': 'true',
843            'tabindex': '0'
844        });
845
846        // Focus next tab
847        $nextTab.focus();
848
849        // Activate Bootstrap tab
850        const targetId = $nextTab.attr('data-bs-target') || $nextTab.attr('href');
851        if (targetId) {
852            $('.tab-pane').removeClass('in active');
853            $(targetId).addClass('in active');
854            $(targetId).trigger('shown.bs.tab');
855            $nextTab.trigger('shown.bs.tab');
856        }
857    });
858
859    // Sync accessibility states after click/tab change
860    $tabs.on('shown.bs.tab', function (e) {
861
862        $tabs.attr({
863            'aria-selected': 'false',
864            'tabindex': '-1'
865        }).removeClass('active');
866
867        $(e.target).attr({
868            'aria-selected': 'true',
869            'tabindex': '0'
870        }).addClass('active');
871    });
872});
873// Facebook sharing function that uses the Web Share API on iOS and falls back to the Facebook sharer URL on other platforms
874function shareToFacebook(url, title, description) {
875    if (url.includes('facebook.com/sharer/sharer.php')) {
876        const urlParams = new URLSearchParams(url.split('?')[1]);
877        url = urlParams.get('u') || url;
878    }
879    description = description || title;
880    const isiOS = /iPhone|iPad|iPod/.test(navigator.userAgent) ||
881                (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
882
883    if (isiOS && navigator.share) {
884        const shareData = {
885            title: title,
886            text: description,
887            url: url
888        };
889
890        navigator.share(shareData)
891            .then(() => {
892                $.get('/login/recordstep/shared-page');
893                $.get('/login/recordstep/shared-page-facebook');
894            })
895            .catch((err) => {
896                if (err.name !== 'AbortError') {
897                    console.error(err.name, err.message);
898                }
899            });
900
901    } else {
902        const fbUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}&t=${encodeURIComponent(title)}`;
903        window.open(fbUrl, 'win', 'width=800,height=400,scrollbars=1');
904
905        $.get('/login/recordstep/shared-page');
906        $.get('/login/recordstep/shared-page-facebook');
907    }
908};
909// Gift Aid Form Handlers
910$(document).on('click change', '#gift-aid-form .gift-aid-radio', function() {
911    $('#gift-aid-form .gift-aid-option-label').removeClass('selected');
912    if ($(this).is(':checked')) {
913        $(this).closest('.gift-aid-option-label').addClass('selected');
914    }
915});
916
917// Trigger change event when form is inserted into DOM
918$(document).on('DOMNodeInserted', '#gift-aid-form', function() {
919    $('#gift-aid-form .gift-aid-radio:checked').trigger('click');
920});
921
922// Gift Aid Next Button Handler
923$(document).on('click', '#gift-aid-form .gift-aid-next-btn', function(e) {
924    e.preventDefault();
925    
926    const selectedValue = $('#gift-aid-form .gift-aid-radio:checked').val();
927    console.log('Gift Aid: Selection:', selectedValue);
928    
929    const $container = $(this).closest('[id^="giftaid-container-"]');
930    
931    if ($container.length > 0) {
932        // Multistep form (inside lump)
933        const containerId = $container.attr('id');
934        const lumpId = containerId ? containerId.replace('giftaid-container-', '') : '';
935        
936        $container.slideUp(300, function() {
937            const $paymentWrapper = $('#payment-form-wrapper-' + lumpId);
938            if ($paymentWrapper.length > 0) {
939                $('#back-to-giftaid-' + lumpId).show();
940                $paymentWrapper.slideDown(300);
941                console.log('Gift Aid: Payment form displayed');
942            } else {
943                console.error('Gift Aid: Payment wrapper not found for lump ID:', lumpId);
944            }
945        });
946    } else {
947        // Template form (not in lump)
948        const $giftAidCard = $(this).closest('#gift-aid-form');
949        if ($giftAidCard.length > 0) {
950            $giftAidCard.slideUp(300, function() {
951                console.log('Gift Aid: Template form - proceeding');
952            });
953        } else {
954            console.log('Gift Aid: Form type not detected, proceeding');
955        }
956    }
957});
958
959// Back to Personal Details Button Handler
960$(document).on('click', '#gift-aid-form .back-to-personaldetails-form-btn', function(e) {
961    e.preventDefault();
962    console.log('Gift Aid: Back to personal details clicked');
963    
964    const $giftaidContainer = $(this).closest('.giftaid-dynamic-container');
965    
966    if ($giftaidContainer.length > 0) {
967        // Multistep form (inside lump)
968        const containerId = $giftaidContainer.attr('id');
969        const lumpId = containerId ? containerId.replace('giftaid-container-', '') : '';
970        console.log('Gift Aid: Found lump ID:', lumpId);
971        
972        $giftaidContainer.slideUp(300);
973        
974        const $donationSteps = $('#DonationForm_' + lumpId + ' .donation-steps');
975        if ($donationSteps.length > 0 && typeof $donationSteps.slick === 'function') {
976            console.log('Gift Aid: Navigating to personal details tab (multistep)');
977            $donationSteps.slick('slickGoTo', $donationSteps.find('#personaldetails').data('slick-index'));
978        } else {
979            console.log('Gift Aid: Scrolling to personal details section');
980            const $personalDetails = $('#DonationForm_' + lumpId + ' #personaldetails');
981            if ($personalDetails.length > 0) {
982                $('html, body').animate({
983                    scrollTop: $personalDetails.offset().top - 100
984                }, 300);
985            }
986        }
987    } else {
988        // Template form (not in lump)
989        console.log('Gift Aid: Template form - hiding card');
990        $(this).closest('#gift-aid-form').slideUp(300);
991    }
992});
993
994// Sidebar tab resize with col-* classes
995function sidebarTabReload(component = '#sidebar-form-toggler li:visible', colClass = 'col-sm-') {
996    const $items = $(component);
997    const validCols = [1, 2, 3, 4, 6, 12]; // make it only these column sizes
998    const calculatedCol = Math.floor(12 / $items.length);
999    const colPerItem = validCols.includes(calculatedCol) ? calculatedCol : validCols.reduce((prev, curr) => Math.abs(curr - calculatedCol) < Math.abs(prev - calculatedCol) ? curr : prev);
1000
1001    $items.removeClass(function(index, className) {
1002        return (className.match(new RegExp(`(^|\\s)${colClass}\\S+`, 'g')) || []).join(' ');
1003    });
1004
1005    $items.addClass(`${colClass}${colPerItem}`);
1006};

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.