1(function(){function log(...args){console.log('[Namastay Debug]:',...args);} 2function getFullUrl(url){if(!url)return null;if(url.startsWith('#')){return window.location.origin+window.location.pathname+url;} 3if(url.startsWith('http'))return url;return new URL(url,window.location.origin).href;} 4function isBookingLink(url){return url&&url.includes('#/booking/');} 5function extractCode(url){try{const parsed=new URL(getFullUrl(url));if(parsed.hash){const hashQuery=parsed.hash.split('?')[1];if(hashQuery){const params=new URLSearchParams(hashQuery);const data=params.get('data');if(data){const gpMatch=data.match(/gp!'([^']+)'/);if(gpMatch&&gpMatch[1]){log('GP code found from data param:',gpMatch[1]);return gpMatch[1];} 6const cpoMatch=data.match(/Cpo!'([^']+)'/);if(cpoMatch&&cpoMatch[1]){log('Cpo promo code found from data param:',cpoMatch[1]);return cpoMatch[1];}} 7const promo=params.get('promo');const group=params.get('group');if(promo){log('Promo found:',promo);return promo;} 8if(group){log('Group found (mapped to promoCode):',group);return group;}}} 9const data=parsed.searchParams.get('data');if(data){const gpMatch=data.match(/gp!'([^']+)'/);if(gpMatch&&gpMatch[1]){log('GP code found from query data param:',gpMatch[1]);return gpMatch[1];} 10const cpoMatch=data.match(/Cpo!'([^']+)'/);if(cpoMatch&&cpoMatch[1]){log('Cpo promo code found from query data param:',cpoMatch[1]);return cpoMatch[1];}} 11const promo=parsed.searchParams.get('promo');const group=parsed.searchParams.get('group');if(promo)return promo;if(group)return group;}catch(e){log('Extraction error:',e);} 12return null;} 13function extractDatesAndGuests(url){const result={startDate:null,endDate:null,adult:null,children:null,rooms:null};try{const parsed=new URL(getFullUrl(url));const searchParams=parsed.searchParams;const getParam=(keys)=>{for(const key of keys){const val=searchParams.get(key);if(val)return val;} 14return null;};result.startDate=getParam(['startDate','checkIn','checkin','arrival','check-in']);result.endDate=getParam(['endDate','checkOut','checkout','departure','check-out']);result.adult=getParam(['adult','adults','guests']);result.children=getParam(['children','child','kids']);result.rooms=getParam(['rooms','roomCount','room','rn']);if(!result.startDate||!result.endDate){let dataStr='';if(parsed.hash){const hashQuery=parsed.hash.split('?')[1];if(hashQuery){const params=new URLSearchParams(hashQuery);dataStr=params.get('data')||'';}} 15if(!dataStr){dataStr=searchParams.get('data')||'';} 16if(dataStr){const decodedData=decodeURIComponent(dataStr);let year=new Date().getFullYear();const yearMatch=decodedData.match(/20[2-9][0-9]/)||url.match(/20[2-9][0-9]/);if(yearMatch){year=parseInt(yearMatch[0],10);} 17const aeMatch=decodedData.match(/ae!'([0-9]{2})[\/%2F]([0-9]{2})/);if(aeMatch){const month=aeMatch[1];const day=aeMatch[2];result.startDate=`${year}-${month}-${day}`;} 18const dtMatch=decodedData.match(/dt!'([0-9]{2})[\/%2F]([0-9]{2})/);if(dtMatch){const month=dtMatch[1];const day=dtMatch[2];let depYear=year;if(result.startDate){const checkInMonth=parseInt(aeMatch[1],10);const checkOutMonth=parseInt(month,10);if(checkOutMonth<checkInMonth){depYear=year+1;}} 19result.endDate=`${depYear}-${month}-${day}`;} 20const adultMatch=decodedData.match(/rBat!([0-9]+)/);if(adultMatch){result.adult=adultMatch[1];} 21const cnMatch=decodedData.match(/cn!([0-9]+)/);if(cnMatch){result.children=parseInt(cnMatch[1],10);} 22const rnMatch=decodedData.match(/rn[.!]([0-9]+)/);
22if(rnMatch){result.rooms=rnMatch[1];}}}}catch(e){log('Error extracting dates and guests:',e);} 23return result;} 24function buildNamastayUrl(url,code){const parsed=new URL(getFullUrl(url));const details=extractDatesAndGuests(url);parsed.hash='';parsed.search='';parsed.searchParams.set('namastay','true');if(code){parsed.searchParams.set('promoCode',code);} 25if(details.startDate){parsed.searchParams.set('startDate',details.startDate);} 26if(details.endDate){parsed.searchParams.set('endDate',details.endDate);} 27if(details.adult){parsed.searchParams.set('adult',details.adult);} 28if(details.children!==null&&details.children!==undefined){parsed.searchParams.set('children',details.children);parsed.searchParams.set('child',details.children);} 29if(details.rooms){parsed.searchParams.set('rooms',details.rooms);parsed.searchParams.set('room',details.rooms);parsed.searchParams.set('roomCount',details.rooms);} 30const finalUrl=parsed.toString();log('Final URL:',finalUrl);return finalUrl;} 31function instantRedirect(url){if(!isBookingLink(url))return;if(url.includes('namastay=true'))return;const code=extractCode(url);const finalUrl=buildNamastayUrl(url,code);if(window.location.href!==finalUrl){log('â¡ Instant redirect:',finalUrl);window.location.replace(finalUrl);}} 32instantRedirect(window.location.href);document.addEventListener('DOMContentLoaded',function(){instantRedirect(window.location.href);});window.addEventListener('hashchange',function(){instantRedirect(window.location.href);});document.addEventListener('click',function(e){let el=e.target;while(el&&el.tagName!=='A'){el=el.parentElement;} 33if(!el)return;const href=el.getAttribute('href')||el.href;if(!href)return;if(!isBookingLink(href))return;e.preventDefault();const code=extractCode(href);const finalUrl=buildNamastayUrl(href,code);log('â¡ Click redirect:',finalUrl);window.location.replace(finalUrl);});})();
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.