function getFlagBase(){
const el=document.getElementById('dpBlock');
return ((el&&el.dataset.flagBase)||'/wp-content/uploads/flags/4x3/').replace(/\/+$/, '') + '/';
}
function toggleAllCountries(btn){
const extra=document.getElementById('countriesExtra');
extra.classList.toggle('open');
btn.classList.toggle('open');
btn.querySelector('span.btn-show-all-count').textContent=extra.classList.contains('open') ? 'скрыть':'190+';
}
document.addEventListener('DOMContentLoaded', function (){
const menuBtn=document.getElementById('menuBtn');
const mobileNav=document.getElementById('mobileNav');
if(menuBtn&&mobileNav){
const setMobileMenuOpen=function (isOpen){
mobileNav.classList.toggle('open', isOpen);
menuBtn.classList.toggle('is-active', isOpen);
menuBtn.setAttribute('aria-expanded', isOpen ? 'true':'false');
document.documentElement.classList.toggle('mobile-menu-open', isOpen);
document.body.classList.toggle('mobile-menu-open', isOpen);
};
menuBtn.setAttribute('aria-expanded', mobileNav.classList.contains('open') ? 'true':'false');
setMobileMenuOpen(mobileNav.classList.contains('open'));
menuBtn.addEventListener('click', function (){
setMobileMenuOpen(!mobileNav.classList.contains('open'));
});
window.addEventListener('resize', function (){
if(window.innerWidth > 900&&mobileNav.classList.contains('open')){
setMobileMenuOpen(false);
}});
}
document.addEventListener('click', function (e){
var link=e.target.closest('.mobile-nav .menu-item-has-children > a');
if(!link) return;
var item=link.parentElement;
var submenu=item ? item.querySelector(':scope > .sub-menu'):null;
if(!item||!submenu) return;
e.preventDefault();
item.classList.toggle('sub-open');
link.setAttribute('aria-expanded', item.classList.contains('sub-open') ? 'true':'false');
});
const reveals=document.querySelectorAll('.reveal');
if(reveals.length){
const observer=new IntersectionObserver(entries=> {
entries.forEach(e=> { if(e.isIntersecting) e.target.classList.add('visible'); });
}, { threshold: 0.12 });
reveals.forEach(el=> observer.observe(el));
}});
function toggleFaq(btn){
const answer=btn.nextElementSibling;
const isOpen=btn.classList.contains('open');
document.querySelectorAll('.faq-question.open').forEach(b=> {
b.classList.remove('open');
const a=b.nextElementSibling;
a.classList.remove('open');
a.style.maxHeight=null;
});
if(!isOpen){
btn.classList.add('open');
answer.classList.add('open');
answer.style.maxHeight=answer.scrollHeight + 'px';
}}
let mCurrentPrice='';
let mCurrentPackageCode='';
let mAppliedPromo='';
let mDiscountedPrice='';
let mCurrentDays=0;
const REDESIM_PARTNER_COOKIE_DAYS=Math.max(1, parseInt(window.REDESIM_PARTNER_COOKIE_DAYS||'60', 10)||60);
const REDESIM_PARTNER_PARAM='partner';
const REDESIM_PARTNER_COOKIE='redesim_partner_code';
const REDESIM_PARTNER_SOURCE_COOKIE='redesim_partner_source';
const REDESIM_PARTNER_UTM_COOKIE='redesim_partner_utm';
const REDESIM_PARTNER_CUSTOM_UTM_COOKIE='redesim_partner_custom_utm';
const REDESIM_PARTNER_REWARD_ALLOWED_COOKIE='redesim_partner_reward_allowed';
const REDESIM_PROMO_COOKIE='redesim_promo_code';
const REDESIM_PROMO_SOURCE_COOKIE='redesim_promo_source';
const REDESIM_PROMO_REMOVED_COOKIE='redesim_promo_removed';
const REDESIM_PARTNER_BLOCKING_UTM_KEYS=Array.isArray(window.REDESIM_PARTNER_BLOCKING_UTM_KEYS)
? window.REDESIM_PARTNER_BLOCKING_UTM_KEYS
.map(function (key){ return String(key||'').trim(); })
.filter(Boolean)
: [];
function getCookie(name){
const match=document.cookie.match(new RegExp('(?:^|;)' + name + '=([^;]*)'));
return match ? decodeURIComponent(match[1]):'';
}
function setCookie(name, value, days){
const d=new Date();
d.setTime(d.getTime() + days * 864e5);
document.cookie=name + '=' + encodeURIComponent(value) + ';path=/;expires=' + d.toUTCString();
}
function deleteCookie(name){
document.cookie=name + '=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT';
}
function safeLocalStorageSet(name, value){
try { localStorage.setItem(name, value); } catch (e){ }}
function safeLocalStorageGet(name){
try { return localStorage.getItem(name)||''; } catch (e){ return ''; }}
function normalizeAffiliateCode(value){
return String(value||'')
.trim()
.replace(/[^a-zA-Z0-9_-]/g, '')
.slice(0, 36);
}
function getPartnerCodeFromUrl(){
try {
const params=new URLSearchParams(window.location.search||'');
return normalizeAffiliateCode(params.get(REDESIM_PARTNER_PARAM)||'');
} catch (e){
return '';
}}
function collectPartnerUtm(){
const allowedKeys=['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
const result={};
try {
const params=new URLSearchParams(window.location.search||'');
allowedKeys.forEach(function (key){
const value=String(params.get(key)||'').trim().slice(0, 255);
if(value) result[key]=value;
});
} catch (e){ }
return result;
}
function collectBlockingCustomUtm(){
const result={};
if(!REDESIM_PARTNER_BLOCKING_UTM_KEYS.length){
return result;
}
try {
const params=new URLSearchParams(window.location.search||'');
REDESIM_PARTNER_BLOCKING_UTM_KEYS.forEach(function (key){
const cleanKey=String(key||'').trim();
if(!cleanKey||!params.has(cleanKey)) return;
const value=String(params.get(cleanKey)||'').trim().slice(0, 255);
if(value) result[cleanKey]=value;
});
} catch (e){ }
return result;
}
function hasObjectKeys(obj){
return !!obj&&Object.keys(obj).length > 0;
}
function clearPartnerAttributionOnly(){
deleteCookie(REDESIM_PARTNER_COOKIE);
deleteCookie(REDESIM_PARTNER_SOURCE_COOKIE);
deleteCookie(REDESIM_PARTNER_UTM_COOKIE);
safeLocalStorageSet(REDESIM_PARTNER_COOKIE, '');
safeLocalStorageSet(REDESIM_PARTNER_SOURCE_COOKIE, '');
safeLocalStorageSet(REDESIM_PARTNER_UTM_COOKIE, '');
}
function setBlockingCustomUtmAttribution(customUtm){
if(!hasObjectKeys(customUtm)) return;
const customUtmJson=JSON.stringify(customUtm);
clearPartnerAttributionOnly();
setCookie(REDESIM_PARTNER_CUSTOM_UTM_COOKIE, customUtmJson, REDESIM_PARTNER_COOKIE_DAYS);
setCookie(REDESIM_PARTNER_REWARD_ALLOWED_COOKIE, '0', REDESIM_PARTNER_COOKIE_DAYS);
safeLocalStorageSet(REDESIM_PARTNER_CUSTOM_UTM_COOKIE, customUtmJson);
safeLocalStorageSet(REDESIM_PARTNER_REWARD_ALLOWED_COOKIE, '0');
}
function getStoredCustomUtm(){
return String(getCookie(REDESIM_PARTNER_CUSTOM_UTM_COOKIE)||safeLocalStorageGet(REDESIM_PARTNER_CUSTOM_UTM_COOKIE)||'').trim();
}
function hasBlockingCustomUtmAttribution(){
return !!getStoredCustomUtm()||getCookie(REDESIM_PARTNER_REWARD_ALLOWED_COOKIE)==='0'||safeLocalStorageGet(REDESIM_PARTNER_REWARD_ALLOWED_COOKIE)==='0';
}
function getPartnerRewardAllowed(){
return hasBlockingCustomUtmAttribution() ? 0:1;
}
function setPartnerAttribution(code, source){
code=normalizeAffiliateCode(code);
if(!code||hasBlockingCustomUtmAttribution()) return;
const utm=collectPartnerUtm();
const utmJson=JSON.stringify(utm);
setCookie(REDESIM_PARTNER_COOKIE, code, REDESIM_PARTNER_COOKIE_DAYS);
setCookie(REDESIM_PARTNER_SOURCE_COOKIE, source||'link', REDESIM_PARTNER_COOKIE_DAYS);
setCookie(REDESIM_PARTNER_UTM_COOKIE, utmJson, REDESIM_PARTNER_COOKIE_DAYS);
setCookie(REDESIM_PARTNER_REWARD_ALLOWED_COOKIE, '1', REDESIM_PARTNER_COOKIE_DAYS);
safeLocalStorageSet(REDESIM_PARTNER_COOKIE, code);
safeLocalStorageSet(REDESIM_PARTNER_SOURCE_COOKIE, source||'link');
safeLocalStorageSet(REDESIM_PARTNER_UTM_COOKIE, utmJson);
safeLocalStorageSet(REDESIM_PARTNER_REWARD_ALLOWED_COOKIE, '1');
}
function getStoredPartnerCode(){
return normalizeAffiliateCode(getCookie(REDESIM_PARTNER_COOKIE)||safeLocalStorageGet(REDESIM_PARTNER_COOKIE));
}
function getStoredPartnerSource(){
return String(getCookie(REDESIM_PARTNER_SOURCE_COOKIE)||safeLocalStorageGet(REDESIM_PARTNER_SOURCE_COOKIE)||'').trim();
}
function getStoredPartnerUtm(){
return String(getCookie(REDESIM_PARTNER_UTM_COOKIE)||safeLocalStorageGet(REDESIM_PARTNER_UTM_COOKIE)||'').trim();
}
function isPromoAutoApplySuppressed(){
return getCookie(REDESIM_PROMO_REMOVED_COOKIE)==='1'
|| safeLocalStorageGet(REDESIM_PROMO_REMOVED_COOKIE)==='1';
}
function suppressPromoAutoApply(){
setCookie(REDESIM_PROMO_REMOVED_COOKIE, '1', REDESIM_PARTNER_COOKIE_DAYS);
safeLocalStorageSet(REDESIM_PROMO_REMOVED_COOKIE, '1');
}
function clearPromoAutoApplySuppression(){
deleteCookie(REDESIM_PROMO_REMOVED_COOKIE);
safeLocalStorageSet(REDESIM_PROMO_REMOVED_COOKIE, '');
}
function initAffiliateTracking(){
const customUtmFromUrl=collectBlockingCustomUtm();
const partnerFromUrl=getPartnerCodeFromUrl();
if(hasObjectKeys(customUtmFromUrl)){
setBlockingCustomUtmAttribution(customUtmFromUrl);
}
if(partnerFromUrl){
if(!hasBlockingCustomUtmAttribution()){
setPartnerAttribution(partnerFromUrl, 'link');
}
if(!getCookie(REDESIM_PROMO_COOKIE)){
setCookie(REDESIM_PROMO_COOKIE, partnerFromUrl, REDESIM_PARTNER_COOKIE_DAYS);
setCookie(REDESIM_PROMO_SOURCE_COOKIE, 'partner_link', REDESIM_PARTNER_COOKIE_DAYS);
}}
}
function getPreferredPromoCode(){
const partnerFromUrl=getPartnerCodeFromUrl();
if(partnerFromUrl) return partnerFromUrl;
if(isPromoAutoApplySuppressed()) return '';
const savedPromo=normalizeAffiliateCode(getCookie(REDESIM_PROMO_COOKIE));
if(savedPromo) return savedPromo;
return getStoredPartnerCode();
}
function rememberPromoCode(code, source){
code=normalizeAffiliateCode(code);
if(!code) return;
source=source||'manual';
clearPromoAutoApplySuppression();
setCookie(REDESIM_PROMO_COOKIE, code, REDESIM_PARTNER_COOKIE_DAYS);
setCookie(REDESIM_PROMO_SOURCE_COOKIE, source, REDESIM_PARTNER_COOKIE_DAYS);
if(source==='manual'&&!getStoredPartnerCode()&&!hasBlockingCustomUtmAttribution()){
setPartnerAttribution(code, 'promo_code');
}}
function rememberManualPromoCode(code){
rememberPromoCode(code, 'manual');
}
initAffiliateTracking();
function getModalEls(){
return {
flag: document.getElementById('mFlag'),
name: document.getElementById('mName'),
spec: document.getElementById('mSpec'),
price: document.getElementById('mPriceEl'),
total: document.getElementById('mTotal'),
totalOld: document.getElementById('mTotalOld'),
promo: document.getElementById('mPromo'),
promoInputRow: document.getElementById('promoInputRow'),
promoApplied: document.getElementById('promoApplied'),
promoAppliedCode: document.getElementById('promoAppliedCode'),
promoRemove: document.getElementById('promoRemove'),
promoError: document.getElementById('promoError'),
email: document.getElementById('mEmail'),
form: document.getElementById('mForm'),
success: document.getElementById('mSuccess'),
successIcon: document.getElementById('mSuccessIcon'),
successTitle: document.getElementById('mSuccessTitle'),
successText: document.getElementById('mSuccessText'),
successBtn: document.getElementById('mSuccessBtn'),
successClose: document.getElementById('mSuccessClose'),
modal: document.getElementById('modal'),
chkError: document.getElementById('chkError'),
packageCode: document.getElementById('mPackageCode'),
};}
const modalEls=new Proxy({}, {
get(_, key){ return getModalEls()[key]; }});
const REQUIRED_CHECKBOXES=['chkOferta', 'chkPd', 'chkEsim'];
function getEmailDomain(email){
const value=String(email||'').trim().toLowerCase();
if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)){
return '';
}
return value.split('@').pop()||'';
}
function setEmailValidationError(message){
if(!modalEls.email) return;
modalEls.email.setCustomValidity(message||'');
if(message&&typeof modalEls.email.reportValidity==='function'){
modalEls.email.reportValidity();
}}
async function checkEmailDomainMX(email){
return true;
const domain=getEmailDomain(email);
if(!domain){
return false;
}
const url=`https://dns.google/resolve?name=${encodeURIComponent(domain)}&type=MX`;
const controller=new AbortController();
const timeoutId=setTimeout(function (){
controller.abort();
}, 3000);
try {
const response=await fetch(url, {
method: 'GET',
headers: {
accept: 'application/json'
},
signal: controller.signal
});
clearTimeout(timeoutId);
if(!response.ok){
return false;
}
const data=await response.json();
if(Number(data.Status)!==0||!Array.isArray(data.Answer)||!data.Answer.length){
return false;
}
return data.Answer.some(function (answer){
if(!answer||Number(answer.type)!==15){
return false;
}
const answerData=String(answer.data||'').trim();
if(!answerData||answerData==='.'||/^\d+\s+\.$/.test(answerData)){
return false;
}
return true;
});
} catch (e){
clearTimeout(timeoutId);
return false;
}}
if(modalEls.email){
modalEls.email.addEventListener('input', function (){
setEmailValidationError('');
});
}
(function (){
function encodeBase64Url(value){
value=String(value||'');
try {
return btoa(unescape(encodeURIComponent(value)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/g, '');
} catch (e){
return '';
}}
function decodeBase64Url(value){
value=String(value||'').trim();
if(!value) return '';
try {
let normalized=value.replace(/-/g, '+').replace(/_/g, '/');
while (normalized.length % 4) normalized +='=';
const decoded=atob(normalized);
try {
return decodeURIComponent(Array.prototype.map.call(decoded, function (ch){
return '%' + ('00' + ch.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
} catch (e){
return decoded;
}} catch (e){
return '';
}}
function parseTfPayload(decodedValue){
decodedValue=String(decodedValue||'').trim();
if(!decodedValue){
return { packageCode: '', days: 0 };}
const match=decodedValue.match(/^(.+?)(?::|\|)(\d{1,3})$/);
if(!match){
return { packageCode: decodedValue, days: 0 };}
return {
packageCode: String(match[1]||'').trim(),
days: Math.max(0, parseInt(match[2], 10)||0)
};}
function makeTfPayload(packageCode, days){
packageCode=String(packageCode||'').trim();
days=parseInt(days, 10)||0;
if(!packageCode) return '';
return days > 0 ? packageCode + ':' + days:packageCode;
}
function getTfDataFromHash(){
const hash=String(window.location.hash||'').replace(/^#/, '');
if(!hash||hash.indexOf('tf=')!==0){
return { packageCode: '', days: 0 };}
return parseTfPayload(decodeBase64Url(hash.slice(3)));
}
function getTfCodeFromHash(){
return getTfDataFromHash().packageCode;
}
function getTfDaysFromHash(){
return getTfDataFromHash().days;
}
function setTfHash(packageCode, days){
const payload=makeTfPayload(packageCode, days);
if(!payload) return;
const encoded=encodeBase64Url(payload);
if(!encoded) return;
const url=window.location.pathname + window.location.search + '#tf=' + encoded;
window.history.replaceState(null, '', url);
}
function clearTfHash(){
const hash=String(window.location.hash||'').replace(/^#/, '');
if(hash.indexOf('tf=')!==0) return;
const url=window.location.pathname + window.location.search;
window.history.replaceState(null, '', url);
}
function findTariffRow(packageCode){
packageCode=String(packageCode||'').trim();
if(!packageCode) return null;
if(window.CSS&&typeof window.CSS.escape==='function'){
const row=document.querySelector('.t-row[data-id="' + window.CSS.escape(packageCode) + '"]');
if(row) return row;
}
return Array.prototype.find.call(document.querySelectorAll('.t-row[data-id]'), function (row){
return row.dataset.id===packageCode;
})||null;
}
window.RedesimTariffHash={
encode: encodeBase64Url,
decode: decodeBase64Url,
parse: parseTfPayload,
buildPayload: makeTfPayload,
getData: getTfDataFromHash,
getCode: getTfCodeFromHash,
getDays: getTfDaysFromHash,
set: setTfHash,
clear: clearTfHash,
findRow: findTariffRow
};})();
function getSelectedTariffDays(){
const directInputs=[
document.getElementById('dayInp'),
document.getElementById('sdInp')
];
for (const input of directInputs){
const value=parseInt(input?.value, 10)||0;
if(value > 0) return value;
}
const activeDayBtn=document.querySelector('.dc.act[data-d], .dc.active[data-d], .sdc.act[data-d], .sdc.active[data-d], [data-d].act, [data-d].active');
const btnValue=parseInt(activeDayBtn?.dataset?.d, 10)||0;
return btnValue > 0 ? btnValue:0;
}
function setSelectedTariffDays(days){
days=parseInt(days, 10)||0;
if(days <=0) return false;
let changed=false;
const dayButtons=document.querySelectorAll('.dc[data-d], .sdc[data-d]');
dayButtons.forEach(function (btn){
const isActive=String(btn.dataset.d||'')===String(days);
btn.classList.toggle('act', isActive);
btn.classList.toggle('active', isActive);
if(isActive) changed=true;
});
['dayInp', 'sdInp'].forEach(function (id){
const input=document.getElementById(id);
if(!input) return;
input.value=String(days);
input.dispatchEvent(new Event('input', { bubbles: true }));
input.dispatchEvent(new Event('change', { bubbles: true }));
changed=true;
});
if(typeof window.filterTariffs==='function'){
window.filterTariffs();
}
return changed;
}
function isDailyTariffContext(data, row){
const text=[
data?.data,
data?.spec,
data?.name,
row ? row.textContent:''
].join(' ').toLowerCase();
return text.indexOf('в день')!==-1||!!row?.querySelector('.tb-day');
}
function parseDaysFromText(value){
value=String(value||'').toLowerCase();
if(!value) return 0;
const matches=Array.from(value.matchAll(/(?:на|за|срок(?:ом)?\s*)\s*(\d{1,3})\s*(?:день|дня|дней|дн\.?)/g));
if(matches.length){
const last=matches[matches.length - 1];
return parseInt(last[1], 10)||0;
}
const simple=value.match(/(\d{1,3})\s*(?:день|дня|дней|дн\.?)/);
return simple ? (parseInt(simple[1], 10)||0):0;
}
function resolveTariffDaysForHash(data, row){
data=data||{};
const explicitDays=parseInt(data.days, 10)||0;
if(explicitDays > 0) return explicitDays;
const textDays=parseDaysFromText([
data.name,
data.data,
data.spec,
row ? row.textContent:''
].join(' '));
if(textDays > 0&&isDailyTariffContext(data, row)) return textDays;
const selectedDays=getSelectedTariffDays();
if(selectedDays > 0&&isDailyTariffContext(data, row)) return selectedDays;
const durationDays=parseInt(data.duration, 10)||0;
if(durationDays > 0&&isDailyTariffContext(data, row)) return durationDays;
return 0;
}
function enrichTariffModalData(data, sourceEl){
data=data||{};
const row=sourceEl?.closest?.('.t-row[data-id]')||null;
if(row&&typeof window.getTariffCheckoutDataFromRow==='function'){
data=Object.assign({}, window.getTariffCheckoutDataFromRow(row), data);
}
if(!data.packageCode&&row?.dataset?.id){
data.packageCode=row.dataset.id;
}
if(!data.countryCode){
const provCols=sourceEl?.closest?.('[data-country-code]')||row?.closest?.('[data-country-code]');
if(provCols?.dataset?.countryCode) data.countryCode=provCols.dataset.countryCode;
}
const resolvedDays=resolveTariffDaysForHash(data, row);
if(resolvedDays > 0){
data.days=resolvedDays;
}
return data;
}
(function (){
let countryTfOpening=false;
function openCountryTariffFromHash(){
if(!window.RedesimTariffHash||typeof openModal!=='function') return false;
const hashData=window.RedesimTariffHash.getData();
const packageCode=hashData.packageCode;
const days=hashData.days;
if(!packageCode||countryTfOpening) return false;
if(!document.querySelector('.prov-cols, .prov-col, .t-row[data-id]')) return false;
const row=window.RedesimTariffHash.findRow(packageCode);
if(!row) return false;
countryTfOpening=true;
try {
if(days > 0){
setSelectedTariffDays(days);
}
const freshRow=window.RedesimTariffHash.findRow(packageCode)||row;
const modalTrigger=freshRow.querySelector('[data-modal]')||freshRow.closest('[data-modal]')||freshRow;
const modalAttr=modalTrigger?.getAttribute?.('data-modal')||freshRow.getAttribute('data-modal')||'';
if(modalAttr){
const modalData=enrichTariffModalData(JSON.parse(modalAttr), modalTrigger);
if(days > 0) modalData.days=days;
openModal(modalData);
return true;
}
const clickTarget=freshRow.querySelector('.t-buy, .btn-buy, button[data-modal], [data-modal]');
if(clickTarget){
clickTarget.click();
return true;
}} catch (e){
console.warn('Не удалось открыть тариф по #tf на странице страны', e);
} finally {
setTimeout(function (){ countryTfOpening=false; }, 0);
}
return false;
}
document.addEventListener('DOMContentLoaded', function (){
setTimeout(openCountryTariffFromHash, 350);
});
window.addEventListener('hashchange', function (){
openCountryTariffFromHash();
});
})();
(function (){
let homeTfOpening='';
function isHomePagePickerAvailable(){
return !!document.getElementById('dpBlock')||!!document.querySelector('.dest-picker');
}
function normalizePrice(value){
value=String(value||'').trim();
if(!value) return '';
return value.indexOf('₽')!==-1 ? value:value + ' ₽';
}
function formatGbLocal(megabyte){
const mb=Number(megabyte||0);
if(!mb) return '';
if(mb >=1024){
const gb=mb / 1024;
return Number.isInteger(gb) ? `${gb} ГБ`:`${gb.toFixed(1)} ГБ`;
}
return `${mb} МБ`;
}
function pluralDaysLocal(days){
const n=Math.abs(Number(days)) % 100;
const n1=n % 10;
if(n > 10&&n < 20) return 'дней';
if(n1 > 1&&n1 < 5) return 'дня';
if(n1===1) return 'день';
return 'дней';
}
function getFlagHtmlLocal(countryName, countryCode){
const code=String(countryCode||'').toLowerCase();
if(!code) return '';
const safeName=String(countryName||'').replace(/&/g, '&amp;').replace(/"/g, '&quot;');
return '<img class="countries-flag-mini" alt="' + safeName + '" src="' + getFlagBase() + code + '.svg">';
}
function firstLocalField(item, keys){
if(!item) return '';
for (const key of keys){
if(Object.prototype.hasOwnProperty.call(item, key)){
const value=item[key];
if(value===null||value===undefined) continue;
if(Array.isArray(value)){
const joined=value.map(function (part){
if(part&&typeof part==='object') return part.name||part.title||part.value||'';
return String(part||'');
}).filter(Boolean).join(', ');
if(joined) return joined;
}else if(typeof value==='object'){
const objectValue=value.name||value.title||value.value||Object.values(value).filter(Boolean).join(', ');
if(objectValue) return String(objectValue).replace(/\s+/g, ' ').trim();
}else{
const text=String(value).replace(/\s+/g, ' ').trim();
if(text) return text;
}}
}
return '';
}
function resolveHomeLocation(item, countryName){
const location=firstLocalField(item, ['location_cities', 'locationCountries', 'location_countries', 'countries', 'country_list', 'coverage', 'coverage_countries', 'location_name', 'location']);
const countryCode=String(item?.country_code||item?.countryCode||'').toUpperCase();
const normalizedLocation=String(location||'').toUpperCase();
if(countryName&&normalizedLocation&&/^[A-Z]{2}$/.test(normalizedLocation)) return countryName;
if(countryName&&countryCode&&normalizedLocation===countryCode) return countryName;
return location||countryName||'';
}
function resolveHomeTopup(item){
const supportValue=firstLocalField(item, ['support_topup_type', 'supportTopupType', 'support_topup', 'supportTopup', 'package_topup', 'packageTopup']);
if(supportValue) return String(supportValue).trim()==='1' ? 'Недоступно':'Доступно';
const raw=firstLocalField(item, ['recharge', 'rechargeable', 'topup', 'top_up', 'can_topup', 'can_recharge', 'is_rechargeable', 'is_topup', 'refill']).toLowerCase();
if(['0', 'false', 'no', 'n', 'not_available', 'недоступно'].includes(raw)) return 'Недоступно';
if(raw) return 'Доступно';
return 'Доступно';
}
function resolveHomeActivation(item){
const raw=firstLocalField(item, ['active_type', 'activeType', 'activation_policy', 'activationPolicy', 'activation', 'activation_type', 'start_policy', 'startPolicy', 'start_type', 'validity_start', 'validityStart', 'begin_at', 'start_at']);
if(String(raw).trim()==='1') return 'После установки на устройство';
if(String(raw).trim()==='0') return 'По приезду в страну';
return raw||'По приезду в страну';
}
function resolveHomeHotspot(item){
const raw=firstLocalField(item, ['hotspot', 'tethering', 'internet_sharing', 'internetSharing', 'sharing', 'share_internet', 'shareInternet']).toLowerCase();
if(['0', 'false', 'no', 'n', 'not_available', 'недоступно'].includes(raw)) return 'Недоступно';
if(raw) return 'Доступно';
return 'Доступно';
}
function buildHomeDetails(topup, activation, hotspot){
const details=[];
if(topup) details.push({ label: 'Пополнение пакета', value: topup });
if(activation) details.push({ label: 'Начало действия', value: activation });
if(hotspot) details.push({ label: 'Раздача интернета', value: hotspot });
return details;
}
function buildModalDataFromPackage(item, chip){
const countryCode=String(item.country_code||chip?.dataset?.cCode||'').toLowerCase();
const countryName=item.country_name?.name||chip?.dataset?.name||chip?.dataset?.nameEn||'';
const gb=formatGbLocal(item.megabyte||item.format_megabyte||item.volume||0);
const days=item.duration||item.period||'';
const speed=item.speed||'';
const price=normalizePrice(item.price_rub_format||item.price_rub||item.priceRUB||item.price||'');
const specTitle=[gb, days ? `${days} ${pluralDaysLocal(days)}`:'', speed].filter(Boolean).join(' · ');
const topup=resolveHomeTopup(item);
const activation=resolveHomeActivation(item);
const hotspot=resolveHomeHotspot(item);
return {
name: countryName,
flag: getFlagHtmlLocal(countryName, countryCode),
specTitle: specTitle,
spec: specTitle,
data: specTitle,
price: price,
packageCode: item.package_code||item.packageCode||'',
countryCode: countryCode,
provider: item.provider||chip?.dataset?.p||'',
megabyte: String(item.megabyte||item.format_megabyte||item.volume||''),
duration: String(days||''),
days: 0,
speed: speed,
location: resolveHomeLocation(item, countryName),
operators: firstLocalField(item, ['location_network_list_formatted', 'location_network_list', 'network_list', 'networks', 'operators', 'operator_list', 'network']),
details: buildHomeDetails(topup, activation, hotspot)
};}
async function fetchPackagesForChip(chip){
const countryCode=String(chip?.dataset?.cCode||'').toLowerCase();
const pc=String(chip?.dataset?.packages||'').trim();
const pr=String(chip?.dataset?.p||'').trim();
if(!countryCode||!pc||!pr) return [];
const url=`/api/v2/countries/popular/packages?pc=${encodeURIComponent(pc)}&cc=${encodeURIComponent(countryCode)}&pr=${encodeURIComponent(pr)}`;
const response=await fetch(url, {
method: 'GET',
headers: { Accept: 'application/json' }});
if(!response.ok) return [];
const json=await response.json();
return json&&json.success&&Array.isArray(json.data) ? json.data:[];
}
function openExistingDpOption(packageCode, hashDays){
const options=Array.prototype.slice.call(document.querySelectorAll('.dp-opt[data-package-code]'));
const option=options.find(function (opt){
return String(opt.dataset.packageCode||'')===packageCode;
});
if(!option) return false;
openModal({
name: option.dataset.countryName||'',
flag: option.dataset.countryFlag||'',
specTitle: option.dataset.data||'',
spec: option.dataset.data||'',
data: option.dataset.data||'',
price: option.dataset.price||'',
packageCode: option.dataset.packageCode||'',
countryCode: option.dataset.countryCode||'',
provider: option.dataset.provider||'',
megabyte: option.dataset.megabyte||'',
duration: option.dataset.duration||'',
days: hashDays||0,
speed: option.dataset.speed||'',
location: option.dataset.location||option.dataset.countryName||'',
operators: option.dataset.operators||'',
details: buildHomeDetails(
option.dataset.packageTopup||'Доступно',
option.dataset.activation||'По приезду в страну',
option.dataset.hotspot||'Доступно'
)
});
return true;
}
async function openHomeTariffFromHash(){
if(!isHomePagePickerAvailable()||!window.RedesimTariffHash||typeof openModal!=='function'){
return false;
}
const hashData=window.RedesimTariffHash.getData ? window.RedesimTariffHash.getData():{ packageCode: window.RedesimTariffHash.getCode(), days: 0 };
const packageCode=hashData.packageCode;
const hashDays=hashData.days||0;
if(!packageCode) return false;
if(homeTfOpening===packageCode) return false;
if(modalEls.modal?.classList.contains('open')&&String(modalEls.packageCode?.value||'')===packageCode){
return true;
}
homeTfOpening=packageCode;
try {
if(openExistingDpOption(packageCode, hashDays)) return true;
const chips=Array.prototype.slice.call(document.querySelectorAll('.dp-chip[data-packages][data-c-code][data-p]'));
for (const chip of chips){
const packages=await fetchPackagesForChip(chip);
const found=packages.find(function (item){
return String(item.package_code||item.packageCode||'')===packageCode;
});
if(found){
const modalData=buildModalDataFromPackage(found, chip);
if(hashDays > 0) modalData.days=hashDays;
openModal(modalData);
return true;
}}
} catch (e){
console.warn('Не удалось открыть тариф по #tf на главной странице', e);
} finally {
setTimeout(function (){ homeTfOpening=''; }, 0);
}
return false;
}
document.addEventListener('DOMContentLoaded', function (){
setTimeout(openHomeTariffFromHash, 300);
});
window.addEventListener('hashchange', function (){
openHomeTariffFromHash();
});
})();
function renderFlag(flagHtml, countryCode){
const el=modalEls.flag;
if(!el) return;
if(flagHtml){
el.innerHTML=flagHtml;
return;
}
if(countryCode){
const base=getFlagBase();
el.innerHTML='<img class="modal-flag-img" src="' + base + countryCode.toLowerCase() + '.svg" alt="">';
return;
}
el.innerHTML='';
}
function normalizeCheckoutText(value){
return String(value||'').replace(/\s+/g, ' ').trim();
}
function shouldCollapseCheckoutText(value){
const text=normalizeCheckoutText(value);
if(!text) return false;
const parts=text.split(',').map(function (item){
return item.trim();
}).filter(Boolean);
return text.length > 135||parts.length > 8;
}
function getCheckoutPlainText(el){
if(!el) return '';
const expanded=el.querySelector('.tariff-expandable-text');
if(expanded) return expanded.dataset.fullText||expanded.textContent||'';
return el.textContent||'';
}
function renderCheckoutExpandableValue(value, fallback){
const text=normalizeCheckoutText(value||fallback||'');
const safeText=text||fallback||'уточняется';
if(!shouldCollapseCheckoutText(text)){
return '<span class="modal-tariff-detail-value-text">' + safeText + '</span>';
}
return '' +
'<span class="tariff-expandable-text is-collapsed" data-full-text="' + safeText + '">' + safeText + '</span>' +
'<button class="tariff-expandable-btn" type="button" data-tariff-text-toggle aria-expanded="false">' +
'Показать полностью' +
'</button>';
}
function renderCheckoutDetailRow(label, value, extraClass){
const text=normalizeCheckoutText(value);
if(!text) return '';
const isLong=shouldCollapseCheckoutText(text);
return '' +
'<div class="modal-tariff-detail-row' + (extraClass ? ' ' + extraClass:'') + (isLong ? ' has-tariff-expandable-text':'') + '">' +
'<span class="modal-tariff-detail-label">' + escapeHtml(label) + '</span>' +
'<strong class="modal-tariff-detail-value">' + renderCheckoutExpandableValue(text, 'уточняется') + '</strong>' +
'</div>';
}
function isCheckoutLongListLabel(label){
const normalized=String(label||'').trim().toLowerCase();
return normalized.includes('оператор') ||
normalized.includes('сеть') ||
normalized.includes('стра') ||
normalized.includes('зона');
}
function renderCheckoutTariffSpec(data){
const specEl=modalEls.spec;
if(!specEl) return;
data=data||{};
const mainSpec=normalizeCheckoutText(data.specTitle||data.spec||data.data||'');
const speed=normalizeCheckoutText(data.speed||'');
const location=normalizeCheckoutText(data.location||data.countries||data.zone||'');
const operators=normalizeCheckoutText(data.operators||data.networks||data.network||'');
const details=Array.isArray(data.details) ? data.details:[];
const detailRows=[];
detailRows.push(renderCheckoutDetailRow('Зона действия', location, 'modal-tariff-detail-row--location'));
detailRows.push(renderCheckoutDetailRow('Операторы', operators, 'modal-tariff-detail-row--operators'));
details.forEach(function (item){
const label=normalizeCheckoutText(item&&item.label);
const value=normalizeCheckoutText(item&&item.value);
if(!label||!value) return;
if(isCheckoutLongListLabel(label)) return;
if(/price|цена|стоим/i.test(label)) return;
detailRows.push(renderCheckoutDetailRow(label, value, 'modal-tariff-detail-row--minor'));
});
const rowsHtml=detailRows.filter(Boolean).join('');
const summaryNote=mainSpec ? '<span class="modal-tariff-params-note">' + escapeHtml(mainSpec) + '</span>':'';
specEl.classList.add('modal-tariff-spec--enhanced');
specEl.dataset.checkoutEnhanced='1';
specEl.innerHTML='' +
'<details class="modal-tariff-params">' +
'<summary class="modal-tariff-params-summary">' +
'<span class="modal-tariff-params-title">Параметры тарифа</span>' +
summaryNote +
'<span class="modal-tariff-params-chevron" aria-hidden="true"></span>' +
'</summary>' +
'<div class="modal-tariff-params-body">' + (rowsHtml||'<div class="modal-tariff-summary-main">' + escapeHtml(mainSpec||'Информация уточняется') + '</div>') + '</div>' +
'</details>';
const tariffBox=specEl.closest('.modal-tariff');
if(tariffBox) tariffBox.classList.add('modal-tariff--enhanced');
}
function openModal(t){
mCurrentPrice=t.price||'';
mCurrentPackageCode=t.packageCode||t.pack_code||'';
mAppliedPromo='';
mDiscountedPrice='';
mCurrentDays=parseInt(t.days||0, 10)||0;
if(!mCurrentDays){
const row=mCurrentPackageCode&&window.RedesimTariffHash
? window.RedesimTariffHash.findRow(mCurrentPackageCode)
: null;
mCurrentDays=resolveTariffDaysForHash(t, row);
}
renderFlag(t.flag||'', t.countryCode||'');
if(modalEls.name) modalEls.name.textContent=t.name||'';
renderCheckoutTariffSpec(t);
if(modalEls.price) modalEls.price.textContent=t.price||'';
if(modalEls.packageCode) modalEls.packageCode.value=mCurrentPackageCode;
resetPromoUI();
setTotalPrice(mCurrentPrice, '');
const savedPromo=getPreferredPromoCode();
if(savedPromo){
if(modalEls.promo) modalEls.promo.value=savedPromo;
applyPromo('saved');
}
if(modalEls.email) modalEls.email.value='';
if(modalEls.form) modalEls.form.style.display='';
if(modalEls.success) modalEls.success.style.display='none';
if(typeof resetChecks==='function') resetChecks();
modalEls.modal.classList.add('open');
document.body.style.overflow='hidden';
if(window.RedesimTariffHash&&mCurrentPackageCode){
window.RedesimTariffHash.set(mCurrentPackageCode, mCurrentDays);
}}
function closeModal(){
modalEls.modal.classList.remove('open');
document.body.style.overflow='';
if(window.RedesimTariffHash){
window.RedesimTariffHash.clear();
}}
function setTotalPrice(newPrice, oldPrice){
if(modalEls.total) modalEls.total.textContent=newPrice||'';
if(modalEls.totalOld){
if(oldPrice){
modalEls.totalOld.textContent=oldPrice;
modalEls.totalOld.classList.add('visible');
}else{
modalEls.totalOld.textContent='';
modalEls.totalOld.classList.remove('visible');
}}
}
function resetPromoUI(){
if(modalEls.promoInputRow) modalEls.promoInputRow.style.display='';
if(modalEls.promoApplied) modalEls.promoApplied.style.display='none';
if(modalEls.promoError) modalEls.promoError.style.display='none';
if(modalEls.promoError) modalEls.promoError.textContent='';
if(modalEls.promo) modalEls.promo.value='';
mAppliedPromo='';
mDiscountedPrice='';
}
function applyPromo(source){
source=source||'manual';
const code=(modalEls.promo?.value||'').trim();
const packCode=mCurrentPackageCode||(modalEls.packageCode?.value||'');
if(!code) return;
const btn=document.querySelector('.btn-promo');
if(btn){ btn.disabled=true; btn.textContent='...'; }
if(modalEls.promoError){ modalEls.promoError.style.display='none'; modalEls.promoError.textContent=''; }
fetch('/api/v2/promo/get', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code: code, pack_code: packCode, ...(mCurrentDays ? { days: mCurrentDays }:{}) })
})
.then(r=> r.json())
.then(data=> {
if(btn){ btn.disabled=false; btn.textContent='Применить'; }
if(data.success){
const priceNew=Number(data.data.price_promo).toLocaleString('ru-RU') + '₽';
const priceOld=Number(data.data.price).toLocaleString('ru-RU') + '₽';
mAppliedPromo=code;
mDiscountedPrice=priceNew;
mCurrentPrice=priceOld;
setTotalPrice(priceNew, priceOld);
rememberPromoCode(code, source);
if(modalEls.promoInputRow) modalEls.promoInputRow.style.display='none';
if(modalEls.promoApplied) modalEls.promoApplied.style.display='flex';
if(modalEls.promoAppliedCode) modalEls.promoAppliedCode.textContent=code.toUpperCase();
}else{
mAppliedPromo='';
mDiscountedPrice='';
setTotalPrice(mCurrentPrice, '');
if(modalEls.promoInputRow) modalEls.promoInputRow.style.display='';
if(modalEls.promoApplied) modalEls.promoApplied.style.display='none';
if(modalEls.promoError){
modalEls.promoError.textContent=data.message||'Промокод не найден';
modalEls.promoError.style.display='block';
}}
})
.catch(()=> {
if(btn){ btn.disabled=false; btn.textContent='Применить'; }
mAppliedPromo='';
mDiscountedPrice='';
setTotalPrice(mCurrentPrice, '');
if(modalEls.promoInputRow) modalEls.promoInputRow.style.display='';
if(modalEls.promoApplied) modalEls.promoApplied.style.display='none';
if(modalEls.promoError){
modalEls.promoError.textContent='Ошибка соединения';
modalEls.promoError.style.display='block';
}});
}
function removePromo(){
deleteCookie(REDESIM_PROMO_COOKIE);
deleteCookie(REDESIM_PROMO_SOURCE_COOKIE);
suppressPromoAutoApply();
resetPromoUI();
setTotalPrice(mCurrentPrice, '');
}
const ALL_CHECKBOXES=['chkOferta', 'chkPd', 'chkEsim', 'chkAds'];
function toggleAllChecks(chkAll){
const checked=chkAll.checked;
ALL_CHECKBOXES.forEach(function (id){
const el=document.getElementById(id);
if(el){
el.checked=checked;
if(checked){
const row=el.closest('.check-row');
if(row) row.classList.remove('check-row--error');
}}
});
if(checked){
const chkError=document.getElementById('chkError');
if(chkError) chkError.style.display='none';
}}
function syncAllCheck(){
const chkAll=document.getElementById('chkAll');
if(!chkAll) return;
chkAll.checked=ALL_CHECKBOXES.every(function (id){
const el=document.getElementById(id);
return el&&el.checked;
});
}
function resetChecks(){
const chkAll=document.getElementById('chkAll');
if(chkAll) chkAll.checked=false;
ALL_CHECKBOXES.forEach(function (id){
const el=document.getElementById(id);
if(el){
el.checked=false;
const row=el.closest('.check-row');
if(row) row.classList.remove('check-row--error');
}});
const chkError=document.getElementById('chkError');
if(chkError) chkError.style.display='none';
}
function sendYmAddToCart(product){
if(!product||!product.id) return false;
window.dataLayer=window.dataLayer||[];
window.dataLayer.push({
ecommerce: {
purchase: {
actionField: {
id: String(product.id)
},
products: [
{
id: product.package_code||'',
name: product.name||'eSIM тариф',
price: Number(product.price||0),
quantity: Number(product.quantity||1)
}
]
}}
});
}
async function submitPurchase(payButton){
const email=modalEls.email?.value.trim();
setEmailValidationError('');
if(!email||!getEmailDomain(email)){
setEmailValidationError('Введите корректный email.');
modalEls.email?.focus();
return;
}
if(payButton){
payButton.disabled=true;
payButton.classList.add('is-loading');
}
const emailDomainHasMX=await checkEmailDomainMX(email);
if(payButton){
payButton.disabled=false;
payButton.classList.remove('is-loading');
}
if(!emailDomainHasMX){
setEmailValidationError('Проверьте email: возможно он введен не корректно');
modalEls.email?.focus();
return;
}
const allOk=REQUIRED_CHECKBOXES.every((id)=> {
const el=document.getElementById(id);
return el&&el.checked;
});
if(!allOk){
REQUIRED_CHECKBOXES.forEach(function (id){
const el=document.getElementById(id);
if(!el) return;
const row=el.closest('.check-row');
if(!row) return;
if(!el.checked){
row.classList.add('check-row--error');
el.addEventListener('change', function onFix(){
row.classList.remove('check-row--error');
el.removeEventListener('change', onFix);
const allNowOk=REQUIRED_CHECKBOXES.every(function (rid){
const rel=document.getElementById(rid);
return rel&&rel.checked;
});
if(allNowOk&&modalEls.chkError){
modalEls.chkError.style.display='none';
}});
}});
if(modalEls.chkError){
modalEls.chkError.style.display='flex';
modalEls.chkError.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
return;
}
REQUIRED_CHECKBOXES.forEach(function (id){
const el=document.getElementById(id);
if(el) el.closest('.check-row')?.classList.remove('check-row--error');
});
if(modalEls.chkError) modalEls.chkError.style.display='none';
if(modalEls.form) modalEls.form.style.display='none';
if(modalEls.success) modalEls.success.style.display='block';
if(modalEls.successIcon) modalEls.successIcon.textContent='⏳';
if(modalEls.successTitle) modalEls.successTitle.textContent='Создаём заказ...';
if(modalEls.successText) modalEls.successText.textContent='Подождите несколько секунд.';
if(modalEls.successBtn){ modalEls.successBtn.style.display='none'; }
if(modalEls.successClose){ modalEls.successClose.style.display='none'; }
const payload={
email: email,
package_code: mCurrentPackageCode||modalEls.packageCode?.value||'',
promo_code: mAppliedPromo||'',
partner_code: getPartnerRewardAllowed() ? getStoredPartnerCode():'',
partner_source: getStoredPartnerSource(),
partner_utm: getStoredPartnerUtm(),
partner_custom_utm: getStoredCustomUtm(),
partner_reward_allowed: getPartnerRewardAllowed(),
days: mCurrentDays||undefined,
};
fetch('/api/v2/order/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
.then(r=> r.json())
.then(data=> {
if(data.success&&data.data?.url){
const paymentUrl=data.data.url;
let redirectedToPayment=false;
function goToPayment(){
if(redirectedToPayment) return;
redirectedToPayment=true;
window.location.href=paymentUrl;
}
setTimeout(function (){
goToPayment();
}, 1000);
return;
}else{
if(modalEls.successIcon) modalEls.successIcon.innerHTML='<img class="modal_icon" src="/wp-content/uploads/img/warning.png">';
if(modalEls.successTitle) modalEls.successTitle.textContent='Что-то пошло не так';
if(modalEls.successText) modalEls.successText.textContent=data.message||'Не удалось создать заказ. Попробуйте ещё раз.';
if(modalEls.successClose) modalEls.successClose.style.display='';
}})
.catch(()=> {
if(modalEls.successIcon) modalEls.successIcon.innerHTML='<img class="modal_icon" src="/wp-content/uploads/img/warning.png">';
if(modalEls.successTitle) modalEls.successTitle.textContent='Что-то пошло не так';
if(modalEls.successText) modalEls.successText.textContent='Сервис банка временно недоступен. Попробуйте повторить позднее.';
if(modalEls.successClose) modalEls.successClose.style.display='';
});
}
document.addEventListener('keydown', (e)=> {
if(e.key==='Escape'&&modalEls.modal?.classList.contains('open')){
closeModal();
}});
function dpSearch(val){
const query=val.trim();
const FLAG_BASE=getFlagBase();
if(!query){
resetDpSearchState();
return;
}
fetch(`/search/?q=${encodeURIComponent(query)}*`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}})
.then(resp=> resp.json())
.then(comp=> {
const hits=comp?.hits?.hits||[];
const total=comp?.hits?.total?.value||0;
if(!total||!hits.length){
showDpNoResults();
return;
}
let html='';
const used=new Set();
hits.forEach(element=> {
const source=element?._source||{};
const countryCodeRaw=source.country_code||'';
const cCode=String(countryCodeRaw).toLowerCase();
if(!cCode||cCode==='ua'||cCode==='ru'){
return;
}
const cName=source.country_name||'';
let cNameE=source.country_name_en||'';
if(!cName||!cNameE){
return;
}
const uniqKey=cNameE.toLowerCase();
if(used.has(uniqKey)){
return;
}
used.add(uniqKey);
let hrefName=cNameE;
let flagHtml=`<img loading="lazy" class="countries-flag-mini" alt="${escapeHtml(cName)}" src="${FLAG_BASE}${escapeHtml(cCode)}.svg">`;
if(cNameE==='Europe'||cNameE==='Asia'||cNameE==='Africa'||cNameE==='Global'){
hrefName=`region-${cNameE}`;
flagHtml=`<span class="countries-flag-mini countries-flag-mini--none"></span>`;
}
const href=`/esim/${slugifyCountryName(hrefName)}`;
html +=`
<a class="dp-search-item" href="${escapeHtml(href)}/">
<span class="dp-search-item-flag">${flagHtml}</span>
<span class="dp-search-item-name">${escapeHtml(cName)}</span>
</a>
`;
});
if(!html){
showDpNoResults();
return;
}
showDpSearchResults(html);
})
.catch((e)=> {
console.log(e);
showDpNoResults();
});
}
function resetDpSearchState(){
const dpSearchResults=document.getElementById('dpSearchResults');
const dpResult=document.getElementById('dpResult');
const dpNoResult=document.getElementById('dpNoResult');
const dpChips=document.getElementById('dpChips');
const dpChipsLabel=document.getElementById('dpChipsLabel');
if(dpSearchResults){
dpSearchResults.style.display='none';
dpSearchResults.innerHTML='';
}
if(dpResult) dpResult.classList.add('show');
if(dpNoResult) dpNoResult.classList.remove('show');
if(dpChips) dpChips.style.display='';
if(dpChipsLabel) dpChipsLabel.textContent='Популярные направления';
}
function showDpSearchResults(html){
const dpSearchResults=document.getElementById('dpSearchResults');
const dpResult=document.getElementById('dpResult');
const dpNoResult=document.getElementById('dpNoResult');
const dpChips=document.getElementById('dpChips');
const dpChipsLabel=document.getElementById('dpChipsLabel');
if(dpResult) dpResult.classList.remove('show');
if(dpNoResult) dpNoResult.classList.remove('show');
if(dpChips) dpChips.style.display='none';
if(dpChipsLabel) dpChipsLabel.textContent='Результаты поиска';
if(dpSearchResults){
dpSearchResults.innerHTML=html;
dpSearchResults.style.display='block';
}}
function showDpNoResults(){
const dpSearchResults=document.getElementById('dpSearchResults');
const dpResult=document.getElementById('dpResult');
const dpNoResult=document.getElementById('dpNoResult');
const dpChips=document.getElementById('dpChips');
const dpChipsLabel=document.getElementById('dpChipsLabel');
if(dpSearchResults){
dpSearchResults.style.display='none';
dpSearchResults.innerHTML='';
}
if(dpResult) dpResult.classList.remove('show');
if(dpChips) dpChips.style.display='none';
if(dpChipsLabel) dpChipsLabel.textContent='Результаты поиска';
if(dpNoResult) dpNoResult.classList.add('show');
}
function slugifyCountryName(name){
return String(name||'')
.trim()
.toLowerCase()
.replace(/\s|,|'|`/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '');
}
function escapeHtml(str){
return String(str||'')
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
document.addEventListener('DOMContentLoaded', ()=> {
const dpInput=document.getElementById('dpInput');
const dpClearBtn=document.getElementById('dpClearBtn');
const cSearch=document.getElementById('cSearch');
const dpResult=document.getElementById('dpResult');
const dpNoResult=document.getElementById('dpNoResult');
const dpOptions=document.getElementById('dpOptions');
const dpResultName=document.getElementById('dpResultName');
let dpAbortController=null;
let dpRequestId=0;
if(!dpInput) return;
function toggleDpClearBtn(){
if(!dpClearBtn) return;
dpClearBtn.classList.toggle('show', dpInput.value.trim().length > 0);
}
function clearDpSearch(){
dpInput.value='';
resetDpSearchState();
toggleDpClearBtn();
dpInput.focus();
}
let dpSearchTimeout;
if(dpClearBtn){
dpClearBtn.addEventListener('click', clearDpSearch);
}
if(cSearch){
cSearch.addEventListener('click', ()=> {
const value=dpInput.value.trim();
if(value.length >=4){
dpSearch(value);
}else if(value.length===0){
resetDpSearchState();
}
toggleDpClearBtn();
});
}
dpInput.addEventListener('input', (event)=> {
const search=event.target.value.trim();
clearTimeout(dpSearchTimeout);
toggleDpClearBtn();
if(!search){
resetDpSearchState();
return;
}
if(search.length >=4){
dpSearchTimeout=setTimeout(()=> {
dpSearch(search);
}, 500);
}});
dpInput.addEventListener('keydown', (event)=> {
if(event.key==='Enter'){
const value=event.target.value.trim();
if(!value){
resetDpSearchState();
toggleDpClearBtn();
return;
}
if(value.length >=4){
dpSearch(value);
}}
});
toggleDpClearBtn();
bindDpChipEvents();
const activeChip=document.querySelector('.dp-chip.active');
if(activeChip){
dpSelect(
activeChip,
activeChip.dataset.nameEn,
activeChip.dataset.packages,
activeChip.dataset.p,
activeChip.dataset.cCode
);
}
function bindDpChipEvents(){
const chips=document.querySelectorAll('.dp-chip');
chips.forEach((chip)=> {
chip.addEventListener('click', ()=> {
dpSelect(
chip,
chip.dataset.nameEn,
chip.dataset.packages,
chip.dataset.p,
chip.dataset.cCode
);
});
});
}
function setResultVisibility(hasResult){
if(!dpResult||!dpNoResult) return;
dpResult.classList.toggle('show', hasResult);
dpNoResult.classList.toggle('show', !hasResult);
}
function clearOptions(){
if(dpOptions) dpOptions.innerHTML='';
}
function getFlagHtml(countryName, countryCode){
const code=String(countryCode||'').toLowerCase();
if(!code) return '';
const flagUrl=`${getFlagBase()}${code}.svg`;
return `<img class="countries-flag-mini" alt="${escapeHtml(countryName)}" src="${flagUrl}">`;
}
async function dpRenderResult(key, pack, provider, cCode){
if(!dpResultName||!dpOptions||!dpResult||!dpNoResult) return;
const countryCode=String(cCode||'').toLowerCase();
const pc=String(pack||'').trim();
const pr=String(provider||'').trim();
if(!countryCode||!pc||!pr){
clearOptions();
setResultVisibility(false);
return;
}
const currentRequestId=++dpRequestId;
if(dpAbortController){
dpAbortController.abort();
}
dpAbortController=new AbortController();
dpResult.classList.add('is-loading');
setResultVisibility(true);
try {
const url=`/api/v2/countries/popular/packages?pc=${encodeURIComponent(pc)}&cc=${encodeURIComponent(countryCode)}&pr=${encodeURIComponent(pr)}`;
const response=await fetch(url, {
method: 'GET',
headers: {
Accept: 'application/json'
},
signal: dpAbortController.signal
});
if(!response.ok){
throw new Error(`HTTP ${response.status}`);
}
const json=await response.json();
if(currentRequestId!==dpRequestId){
return;
}
if(!json.success||!Array.isArray(json.data)||json.data.length===0){
clearOptions();
setResultVisibility(false);
return;
}
const packages=json.data.slice().sort((a, b)=> {
if((a.megabyte||0)!==(b.megabyte||0)){
return (a.megabyte||0) - (b.megabyte||0);
}
return (a.duration||0) - (b.duration||0);
});
const countryName=packages[0].country_name?.name||key||'';
const resultCountryCode=String(packages[0].country_code||cCode||'').toLowerCase();
const countryFlagHtml=getFlagHtml(countryName, resultCountryCode);
const bestIndex=getBestPackageIndex(packages);
const newOptionsHtml=packages.map((item, index)=> {
const gb=formatGb(item.megabyte);
const days=item.duration||'';
const speed=item.speed||'';
const price=item.price_rub_format||item.price_rub||'';
const label=item.description||'';
const isBest=index===bestIndex;
const location=getDpPackageLocation(item, countryName);
const operators=getDpPackageOperators(item);
const packageTopup=getDpPackageTopup(item);
const activation=getDpPackageActivation(item);
const hotspot=getDpPackageHotspot(item);
return `
<div class="dp-opt${isBest ? ' best':''}"
data-country-name="${escapeHtml(countryName)}"
data-country-flag="${escapeHtml(countryFlagHtml)}"
data-data="${escapeHtml(`${gb} · ${days} ${pluralDays(days)} · ${speed}`)}"
data-price="${escapeHtml(`${price} ₽`)}"
data-package-code="${escapeHtml(item.package_code||'')}"
data-country-code="${escapeHtml(item.country_code||'')}"
data-provider="${escapeHtml(item.provider||'')}"
data-megabyte="${escapeHtml(String(item.megabyte||''))}"
data-duration="${escapeHtml(String(item.duration||''))}"
data-speed="${escapeHtml(speed||'')}"
data-location="${escapeHtml(location||'')}"
data-operators="${escapeHtml(operators||'')}"
data-package-topup="${escapeHtml(packageTopup||'')}"
data-activation="${escapeHtml(activation||'')}"
data-hotspot="${escapeHtml(hotspot||'')}">
<div class="dp-opt-left">
<div class="dp-opt-name">
${escapeHtml(gb)} · ${escapeHtml(String(days))} ${pluralDays(days)}${isBest ? ' ⭐':''}
</div>
<div class="dp-opt-meta">
${escapeHtml(speed)}${label ? ' · ' + escapeHtml(label):''}
</div>
</div>
<div class="dp-opt-right">
<span class="dp-opt-price">${escapeHtml(String(price))} ₽</span>
<button class="dp-opt-buy" type="button">Купить</button>
</div>
</div>
`;
}).join('');
dpResultName.innerHTML=`${countryFlagHtml ? `<span class="dp-chip-flag">${countryFlagHtml}</span> `:''}${escapeHtml(countryName)}`;
dpOptions.innerHTML=newOptionsHtml;
dpOptions.querySelectorAll('.dp-opt').forEach((opt, index)=> {
opt.addEventListener('click', ()=> {
openModal(getDpOptionCheckoutData(opt, packages[index]||null));
});
});
setResultVisibility(true);
} catch (error){
if(error.name==='AbortError'){
return;
}
console.error('Ошибка загрузки пакетов:', error);
clearOptions();
setResultVisibility(false);
} finally {
if(currentRequestId===dpRequestId){
dpResult.classList.remove('is-loading');
}}
}
function dpSelect(el, key, pack, provider, cCode){
document.querySelectorAll('.dp-chip').forEach((chip)=> {
chip.classList.remove('active');
});
el.classList.add('active');
dpInput.value='';
toggleDpClearBtn();
resetDpSearchState();
dpRenderResult(key, pack, provider, cCode);
}
function stringifyDpValue(value){
if(value===null||value===undefined) return '';
if(Array.isArray(value)){
return value
.map((item)=> stringifyDpValue(item))
.filter(Boolean)
.join(', ');
}
if(typeof value==='object'){
if(value.name) return stringifyDpValue(value.name);
if(value.title) return stringifyDpValue(value.title);
if(value.value) return stringifyDpValue(value.value);
return Object.values(value)
.map((item)=> stringifyDpValue(item))
.filter(Boolean)
.join(', ');
}
return String(value).replace(/\s+/g, ' ').trim();
}
function firstDpField(item, keys){
if(!item) return '';
for (const key of keys){
if(Object.prototype.hasOwnProperty.call(item, key)){
const value=stringifyDpValue(item[key]);
if(value) return value;
}}
return '';
}
function normalizeDpBoolValue(value){
const text=stringifyDpValue(value).toLowerCase();
if(!text) return '';
if(['1', 'true', 'yes', 'y', 'available', 'доступно'].includes(text)) return 'Доступно';
if(['0', 'false', 'no', 'n', 'not_available', 'недоступно'].includes(text)) return 'Недоступно';
return stringifyDpValue(value);
}
function getDpPackageLocation(item, countryName){
const location=firstDpField(item, [
'location_cities',
'locationCountries',
'location_countries',
'countries',
'country_list',
'coverage',
'coverage_countries',
'location_name',
'location'
]);
const countryCode=stringifyDpValue(item&&(item.country_code||item.countryCode)).toUpperCase();
const normalizedLocation=stringifyDpValue(location).toUpperCase();
if(countryName&&normalizedLocation&&/^[A-Z]{2}$/.test(normalizedLocation)){
return countryName;
}
if(countryName&&countryCode&&normalizedLocation===countryCode){
return countryName;
}
return location||countryName||'';
}
function getDpPackageOperators(item){
return firstDpField(item, [
'location_network_list_formatted',
'location_network_list',
'network_list',
'networks',
'operators',
'operator_list',
'network'
]);
}
function getDpPackageTopup(item){
const invertedSupportKeys=[
'support_topup_type',
'supportTopupType',
'support_topup',
'supportTopup',
'package_topup',
'packageTopup'
];
for (const key of invertedSupportKeys){
if(item&&Object.prototype.hasOwnProperty.call(item, key)){
const value=stringifyDpValue(item[key]);
if(value){
return String(value).trim()==='1' ? 'Недоступно':'Доступно';
}}
}
const raw=firstDpField(item, [
'recharge',
'rechargeable',
'topup',
'top_up',
'can_topup',
'can_recharge',
'is_rechargeable',
'is_topup',
'refill'
]);
if(!raw) return 'Доступно';
return normalizeDpBoolValue(raw)||'Доступно';
}
function getDpPackageActivation(item){
const raw=firstDpField(item, [
'active_type',
'activeType',
'activation_policy',
'activationPolicy',
'activation',
'activation_type',
'start_policy',
'startPolicy',
'start_type',
'validity_start',
'validityStart',
'begin_at',
'start_at'
]);
if(String(raw).trim()==='1') return 'После установки на устройство';
if(String(raw).trim()==='0') return 'По приезду в страну';
return raw||'По приезду в страну';
}
function getDpPackageHotspot(item){
const raw=firstDpField(item, [
'hotspot',
'tethering',
'internet_sharing',
'internetSharing',
'sharing',
'share_internet',
'shareInternet'
]);
return normalizeDpBoolValue(raw)||'Доступно';
}
function getDpOptionCheckoutDetails(opt, sourceItem){
const details=[];
const topup=opt?.dataset?.packageTopup||getDpPackageTopup(sourceItem);
const activation=opt?.dataset?.activation||getDpPackageActivation(sourceItem);
const hotspot=opt?.dataset?.hotspot||getDpPackageHotspot(sourceItem);
if(topup){
details.push({ label: 'Пополнение пакета', value: topup });
}
if(activation){
details.push({ label: 'Начало действия', value: activation });
}
if(hotspot){
details.push({ label: 'Раздача интернета', value: hotspot });
}
return details;
}
function getDpOptionCheckoutData(opt, sourceItem){
const name=opt?.dataset?.countryName||'';
const gb=formatGb(opt?.dataset?.megabyte||sourceItem?.megabyte||0);
const days=opt?.dataset?.duration||sourceItem?.duration||'';
const speed=opt?.dataset?.speed||firstDpField(sourceItem, ['speed'])||'';
const specTitle=[gb, days ? `${days} ${pluralDays(days)}`:'', speed].filter(Boolean).join(' · ');
const location=opt?.dataset?.location||getDpPackageLocation(sourceItem, name);
const operators=opt?.dataset?.operators||getDpPackageOperators(sourceItem);
return {
name: name,
flag: opt?.dataset?.countryFlag||'',
specTitle: specTitle,
spec: specTitle||opt?.dataset?.data||'',
data: opt?.dataset?.data||'',
price: opt?.dataset?.price||'',
packageCode: opt?.dataset?.packageCode||'',
countryCode: opt?.dataset?.countryCode||'',
provider: opt?.dataset?.provider||'',
megabyte: opt?.dataset?.megabyte||'',
duration: opt?.dataset?.duration||'',
days: 0,
speed: speed,
location: location,
operators: operators,
details: getDpOptionCheckoutDetails(opt, sourceItem)
};}
function getBestPackageIndex(packages){
if(!Array.isArray(packages)||!packages.length) return -1;
const selectedPackageId =
packages.find((item)=> item.package_selected)?.package_selected ?? null;
if(selectedPackageId!==null&&selectedPackageId!==undefined&&selectedPackageId!==''){
const selectedIndex=packages.findIndex((item)=> {
return String(item.package_code)===String(selectedPackageId);
});
if(selectedIndex!==-1){
return selectedIndex;
}}
if(packages.length > 1) return 1;
return 0;
}
function formatGb(megabyte){
const mb=Number(megabyte||0);
if(!mb) return '';
if(mb >=1024){
const gb=mb / 1024;
return Number.isInteger(gb) ? `${gb} ГБ`:`${gb.toFixed(1)} ГБ`;
}
return `${mb} МБ`;
}
function pluralDays(days){
const n=Math.abs(Number(days)) % 100;
const n1=n % 10;
if(n > 10&&n < 20) return 'дней';
if(n1 > 1&&n1 < 5) return 'дня';
if(n1===1) return 'день';
return 'дней';
}
function escapeHtml(str){
return String(str)
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#039;');
}});
document.addEventListener('DOMContentLoaded', function (){
document.addEventListener('click', function (e){
var btn=e.target.closest('[data-scroll-to]');
if(!btn) return;
var el=document.getElementById(btn.getAttribute('data-scroll-to'));
if(el){
el.scrollIntoView({ behavior: 'smooth' });
}else{
var fb=btn.getAttribute('data-fallback');
if(fb) window.location.href=fb;
}});
document.addEventListener('click', function (e){
var btn=e.target.closest('[data-href]');
if(btn) window.location.href=btn.getAttribute('data-href');
});
var modalOverlay=document.getElementById('modal');
if(modalOverlay){
modalOverlay.addEventListener('click', function (e){
if(e.target===modalOverlay) closeModal();
});
}
document.addEventListener('click', function (e){
if(e.target.closest('.modal-close')||e.target.closest('[data-action="close-modal"]')){
closeModal();
}});
document.addEventListener('click', function (e){
if(e.target.closest('.btn-promo')) applyPromo();
});
document.addEventListener('click', function (e){
if(e.target.closest('#promoRemove')) removePromo();
});
document.addEventListener('click', function (e){
var btn=e.target.closest('[data-action="submit-purchase"]');
if(btn){
e.preventDefault();
submitPurchase(btn);
}});
document.addEventListener('click', function (e){
var btn=e.target.closest('.day-adj[data-delta]');
if(btn) adjustDays(parseInt(btn.getAttribute('data-delta'), 10));
});
var btnShowAll=document.getElementById('btnShowAll');
if(btnShowAll){
btnShowAll.addEventListener('click', function (){ toggleAllCountries(btnShowAll); });
}
document.addEventListener('click', function (e){
var btn=e.target.closest('.faq-question');
if(btn) toggleFaq(btn);
});
document.addEventListener('click', function (e){
var btn=e.target.closest('.filter-btn[data-filter]');
if(btn) filterTariffs(btn, btn.getAttribute('data-filter'));
});
var cPrev=document.getElementById('cPrev');
var cNext=document.getElementById('cNext');
if(cPrev) cPrev.addEventListener('click', function (){ carouselMove(-1); });
if(cNext) cNext.addEventListener('click', function (){ carouselMove(1); });
document.addEventListener('click', function (e){
var btn=e.target.closest('.resort-buy[data-resort]');
if(btn) goToResort(btn.getAttribute('data-resort'));
});
document.addEventListener('click', function (e){
var btn=e.target.closest('[data-modal]');
if(btn){
try {
var md=JSON.parse(btn.getAttribute('data-modal'));
if(typeof enrichTariffModalData==='function'){
md=enrichTariffModalData(md, btn);
}else{
if(!md.countryCode){
var provCols=btn.closest('[data-country-code]');
if(provCols) md.countryCode=provCols.dataset.countryCode;
}
if(!md.packageCode){
var tRow=btn.closest('[data-id]');
if(tRow) md.packageCode=tRow.dataset.id;
}}
openModal(md);
} catch (_){ }}
});
document.addEventListener('click', function (e){
var btn=e.target.closest('.t-det-toggle[data-pkg]');
if(!btn) return;
toggleDet(btn.getAttribute('data-pkg'), btn);
e.stopPropagation();
});
var chkAll=document.getElementById('chkAll');
if(chkAll) chkAll.addEventListener('change', function (){
if(typeof toggleAllChecks==='function') toggleAllChecks(chkAll);
});
['chkOferta', 'chkPd', 'chkEsim', 'chkAds'].forEach(function (id){
var el=document.getElementById(id);
if(el) el.addEventListener('change', function (){
if(typeof syncAllCheck==='function') syncAllCheck();
});
});
});
document.addEventListener('DOMContentLoaded', function (){
document.querySelectorAll('.js-email').forEach(function (el){
const user=el.dataset.user||'';
const domain=el.dataset.domain||'';
if(!user||!domain) return;
const email=user + '@' + domain;
el.textContent=email;
});
});
function initCookieNotice(){
const COOKIE_NAME='redesim_cookie_notice_closed';
const COOKIE_DAYS=365;
if(document.cookie.split('; ').some(row=> row.startsWith(COOKIE_NAME + '='))){
return;
}
if(document.getElementById('cookieNotice')){
return;
}
const notice=document.createElement('div');
notice.id='cookieNotice';
notice.className='cookie-notice';
notice.innerHTML=`
<p class="cookie-notice__text">
Мы используем файлы cookie. Оставаясь на сайте, вы соглашаетесь с<br>
<a href="/privacy-policy/" target="_blank" rel="noopener noreferrer">Политика конфиденциальности</a>, <a href="/soglasie-na-obrabotku-personalnyh-dannyh/" target="_blank" rel="noopener noreferrer">Согласие на обработку персональных данных</a>
</p>
<button type="button" class="cookie-notice__close" aria-label="Закрыть уведомление">
Закрыть
</button>
`;
document.body.appendChild(notice);
const closeBtn=notice.querySelector('.cookie-notice__close');
closeBtn.addEventListener('click', function (){
const expires=new Date();
expires.setTime(expires.getTime() + COOKIE_DAYS * 24 * 60 * 60 * 1000);
document.cookie =
COOKIE_NAME + '=1; expires=' + expires.toUTCString() + '; path=/; SameSite=Lax';
notice.remove();
});
}
document.addEventListener('DOMContentLoaded', initCookieNotice);
(function (){
let primaryCode='';
let tiers=[];
let filterBuilt=false;
let filterMode='';
const selectedRegionCodes=new Set();
const REGION_CODES=new Set([
'glb', 'global', 'world', 'all',
'eu', 'eur', 'europe',
'asia',
'cas', 'central-asia', 'central_asia',
'afr', 'africa',
'sam', 'south-america', 'south_america',
'nam', 'north-america', 'north_america',
'meg', 'gulf-region', 'gulf_region',
'mer', 'middle-east', 'middle_east'
]);
function normalizeSearchText(value){
return String(value||'')
.toLowerCase()
.replace(/ё/g, 'е')
.replace(/\s+/g, ' ')
.trim();
}
function getProvColsEl(){
return document.querySelector('.prov-cols[data-country-code]');
}
function getRowLocationEntries(row){
const raw=row&&row.dataset ? row.dataset.locationCities||'':'';
let entries=[];
if(raw){
try {
const parsed=JSON.parse(raw);
if(Array.isArray(parsed)){
entries=parsed
.map(function (item){
return {
code: String((item&&item.code)||'').toUpperCase(),
name: String((item&&item.name)||'').trim()
};})
.filter(function (e){ return e.code; });
}} catch (e){ }}
if(!entries.length){
entries=String(row&&row.dataset ? row.dataset.location||'':'')
.toUpperCase()
.split(',')
.map(function (c){ return c.trim(); })
.filter(Boolean)
.map(function (code){ return { code: code, name: code };});
}
return entries;
}
function isRegionCode(code){
const normalized=String(code||'').toLowerCase().trim();
return REGION_CODES.has(normalized);
}
function isRegionPage(rows){
const provColsEl=getProvColsEl();
const pageCode=String((provColsEl&&provColsEl.dataset.countryCode)||'').toLowerCase().trim();
if(isRegionCode(pageCode)) return true;
const allCodes=new Set();
rows.forEach(function (row){
getRowLocationEntries(row).forEach(function (entry){
if(entry.code) allCodes.add(entry.code);
});
});
return !!primaryCode&&!allCodes.has(primaryCode)&&allCodes.size > 2;
}
function setWrapEmpty(isEmpty){
document.querySelectorAll('.location-filter-wrap').forEach(function (wrap){
wrap.classList.toggle('is-empty', !!isEmpty);
});
}
function collectRegionCountryItems(rows){
const map=new Map();
rows.forEach(function (row){
getRowLocationEntries(row).forEach(function (entry){
if(!entry.code||isRegionCode(entry.code)) return;
const name=entry.name||entry.code;
if(!map.has(entry.code)){
map.set(entry.code, { code: entry.code, name: name });
}});
});
return Array.from(map.values()).sort(function (a, b){
return a.name.localeCompare(b.name, 'ru')||a.code.localeCompare(b.code);
});
}
function buildRegionCountryFilter(wrap, rows){
const countries=collectRegionCountryItems(rows);
if(!countries.length) return false;
filterMode='region';
const countriesHtml=countries.map(function (item){
const key=normalizeSearchText(item.name + ' ' + item.code);
return '' +
'<label class="region-country-option" data-region-country-option data-search="' + escapeHtml(key) + '">' +
'<input type="checkbox" value="' + escapeHtml(item.code) + '" data-region-country-code="' + escapeHtml(item.code) + '">' +
'<span class="region-country-box"></span>' +
'<span class="region-country-name">' + escapeHtml(item.name) + '</span>' +
'</label>';
}).join('');
wrap.innerHTML='' +
'<hr class="picker-sep location-filter-sep">' +
'<div class="location-filter region-country-filter" data-region-country-filter>' +
'<p class="lf-title">' +
'<div class="feature-icon-nobg"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
'<circle cx="12" cy="12" r="10"></circle>' +
'<path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>' +
'</svg>Какие страны вам нужны?</div>' +
'</p>' +
'<p class="lf-hint">Выберите одну или несколько стран — останутся тарифы, где есть все выбранные страны</p>' +
'<label class="region-country-search">' +
'<span aria-hidden="true">⌕</span>' +
'<input type="search" placeholder="Начните вводить страну" autocomplete="off" data-region-country-search>' +
'</label>' +
'<div class="region-country-selected" data-region-country-selected style="display:none"></div>' +
'<div class="region-country-list" data-region-country-list>' + countriesHtml + '</div>' +
'<div class="region-country-empty" data-region-country-empty style="display:none">Страна не найдена</div>' +
'<button type="button" class="region-country-reset" data-region-country-reset style="display:none">Сбросить выбор</button>' +
'</div>';
filterBuilt=true;
setWrapEmpty(false);
syncRegionCountryFilterUi();
return true;
}
function buildCountryLocationFilter(wrap, rows){
const codeNames={};
const extraSetsMap=new Map();
const provColsEl=getProvColsEl();
rows.forEach(function (row){
getRowLocationEntries(row).forEach(function (e){
if(e.name) codeNames[e.code]=e.name;
});
});
rows.forEach(function (row){
const codes=getRowLocationEntries(row).map(function (e){ return e.code; });
const extras=codes.filter(function (c){ return c!==primaryCode; });
if(!extras.length) return;
const key=Array.from(new Set(extras)).sort().join(',');
if(!extraSetsMap.has(key)) extraSetsMap.set(key, new Set());
extras.forEach(function (c){ extraSetsMap.get(key).add(c); });
});
if(!extraSetsMap.size) return false;
filterMode='country';
tiers=Array.from(extraSetsMap.entries())
.map(function (entry){
return { key: entry[0], codes: Array.from(entry[1]).sort() };})
.sort(function (a, b){
return a.codes.length - b.codes.length||a.key.localeCompare(b.key);
});
const primaryName=codeNames[primaryCode]||(provColsEl&&provColsEl.dataset.countryName)||primaryCode;
const tiersHtml=tiers.map(function (tier, idx){
const names=tier.codes.map(function (c){ return codeNames[c]||c; }).join(' + ');
return '' +
'<label class="lf-check" id="lfTier' + idx + '">' +
'<input type="radio" name="locFilter" value="' + escapeHtml(tier.key) + '">' +
'<span class="lf-box"></span>' +
'+ ' + escapeHtml(names) +
'</label>';
}).join('');
wrap.innerHTML='' +
'<hr class="picker-sep location-filter-sep">' +
'<div class="location-filter">' +
'<p class="lf-title">' +
'<div class="feature-icon-nobg"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
'<circle cx="12" cy="12" r="10"></circle>' +
'<path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>' +
'</svg>Какие страны вам нужны?</div>' +
'</p>' +
'<p class="lf-hint">Некоторые тарифы покрывают ' + escapeHtml(primaryName) + ' вместе с соседними странами</p>' +
'<div class="lf-group">' +
'<label class="lf-check act" id="lfPrimary">' +
'<input type="radio" name="locFilter" value="primary" checked>' +
'<span class="lf-box"></span>' +
'Только ' + escapeHtml(primaryName) +
'</label>' +
tiersHtml +
'</div>' +
'</div>';
filterBuilt=true;
setWrapEmpty(false);
return true;
}
function buildLocationFilter(){
const wrap=document.getElementById('locationFilterWrap');
if(!wrap||wrap.dataset.built==='1') return false;
const provColsEl=getProvColsEl();
primaryCode=String((provColsEl&&provColsEl.dataset.countryCode)||'').toUpperCase();
wrap.dataset.built='1';
setWrapEmpty(true);
if(!primaryCode) return false;
const rows=Array.from(document.querySelectorAll('.t-row[data-location]'));
if(!rows.length) return false;
const built=isRegionPage(rows)
? buildRegionCountryFilter(wrap, rows)
: buildCountryLocationFilter(wrap, rows);
if(!built){
wrap.innerHTML='';
setWrapEmpty(true);
}
return built;
}
function getLocFilter(){
var checked=document.querySelector('input[name="locFilter"]:checked');
return checked ? checked.value:'primary';
}
function setLocFilter(value){
document.querySelectorAll('input[name="locFilter"]').forEach(function (inp){
inp.checked=inp.value===value;
});
}
function rowMatchesLocationValue(row, val){
const codes=getRowLocationEntries(row).map(function (e){ return e.code; });
if(!codes.length) return false;
if(val==='primary'){
return codes.length===1&&codes[0]===primaryCode;
}
const tier=tiers.find(function (t){ return t.key===val; });
if(!tier) return false;
return tier.codes.some(function (c){ return codes.indexOf(c)!==-1; });
}
function rowMatchesSelectedRegionCountries(row){
if(!selectedRegionCodes.size) return true;
const codes=getRowLocationEntries(row).map(function (e){ return e.code; });
if(!codes.length) return false;
return Array.from(selectedRegionCodes).every(function (code){
return codes.indexOf(code)!==-1;
});
}
function matchesRow(row){
if(!filterBuilt) return true;
if(filterMode==='region'){
return rowMatchesSelectedRegionCountries(row);
}
if(filterMode==='country'){
return rowMatchesLocationValue(row, getLocFilter());
}
return true;
}
function getActiveProviderColumn(){
var active=document.querySelector('.prov-col.provider-active');
if(active) return active;
var activeTab=document.querySelector('.provider-tab.is-active[data-provider-target]');
if(activeTab){
return document.querySelector('.prov-col[data-provider-panel="' + activeTab.dataset.providerTarget + '"]');
}
return document.querySelector('.prov-col:not(#bestPickCard)');
}
function hasRowsForLocation(col, value){
if(!col) return false;
return Array.from(col.querySelectorAll('.t-row[data-location]')).some(function (row){
return rowMatchesLocationValue(row, value);
});
}
function updateLocationFilterOptions(){
if(filterMode!=='country') return true;
var col=getActiveProviderColumn();
var values=Array.from(document.querySelectorAll('input[name="locFilter"]'))
.map(function (inp){ return inp.value; })
.filter(function (value, index, arr){ return value&&arr.indexOf(value)===index; });
if(!values.length||!col) return getLocFilter();
var available=values.filter(function (value){
return hasRowsForLocation(col, value);
});
const shouldHideFilter=available.length <=1;
document.querySelectorAll('.location-filter-wrap').forEach(function (wrap){
wrap.classList.toggle('is-empty', shouldHideFilter);
});
document.querySelectorAll('.location-filter, .location-filter-sep').forEach(function (filter){
filter.classList.toggle('lf-filter-hidden', shouldHideFilter);
});
document.querySelectorAll('.lf-check').forEach(function (lbl){
var inp=lbl.querySelector('input[name="locFilter"]');
if(!inp) return;
var isAvailable=available.indexOf(inp.value)!==-1;
lbl.classList.toggle('lf-option-hidden', !isAvailable);
inp.disabled = !isAvailable;
});
var current=getLocFilter();
if(available.length&&available.indexOf(current)===-1){
current=available[0];
setLocFilter(current);
}
return current;
}
function updateLocationFilterActiveState(val){
document.querySelectorAll('.lf-check').forEach(function (lbl){
var inp=lbl.querySelector('input[name="locFilter"]');
if(inp) lbl.classList.toggle('act', inp.value===val&&!inp.disabled);
});
}
function filterRegionCountryList(root){
if(!root) return;
const input=root.querySelector('[data-region-country-search]');
const empty=root.querySelector('[data-region-country-empty]');
const query=normalizeSearchText(input ? input.value:'');
let visible=0;
root.querySelectorAll('[data-region-country-option]').forEach(function (option){
const searchText=option.dataset.search||'';
const isVisible = !query||searchText.indexOf(query)!==-1;
option.classList.toggle('is-filtered-out', !isVisible);
if(isVisible) visible++;
});
if(empty) empty.style.display=visible ? 'none':'';
}
function clearRegionCountrySearch(root){
if(!root) return;
const input=root.querySelector('[data-region-country-search]');
if(input) input.value='';
filterRegionCountryList(root);
}
function keepPageScrollPosition(callback){
const scrollX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;
const scrollY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;
const anchor=document.getElementById('tariffPage')||document.querySelector('.tariff-layout')||document.getElementById('pickerSection');
const anchorTop=anchor ? anchor.getBoundingClientRect().top:null;
const restore=function (){
window.scrollTo(scrollX, scrollY);
if(anchor&&anchorTop!==null&&document.documentElement.contains(anchor)){
const delta=anchor.getBoundingClientRect().top - anchorTop;
if(Math.abs(delta) > 1){
window.scrollBy(0, delta);
}}
};
try {
callback();
} finally {
restore();
window.requestAnimationFrame(restore);
setTimeout(restore, 0);
setTimeout(restore, 120);
setTimeout(restore, 260);
}}
window.RedesimKeepPageScrollPosition=keepPageScrollPosition;
function syncRegionCountryFilterUi(){
document.querySelectorAll('[data-region-country-filter]').forEach(function (root){
root.querySelectorAll('[data-region-country-code]').forEach(function (inp){
const code=String(inp.value||inp.dataset.regionCountryCode||'').toUpperCase();
const checked=selectedRegionCodes.has(code);
const option=inp.closest('[data-region-country-option]');
inp.checked=checked;
if(option) option.classList.toggle('is-checked', checked);
});
const selectedEl=root.querySelector('[data-region-country-selected]');
const resetBtn=root.querySelector('[data-region-country-reset]');
const selectedCount=selectedRegionCodes.size;
if(selectedEl){
selectedEl.textContent=selectedCount ? 'Выбрано стран: ' + selectedCount:'';
selectedEl.style.display=selectedCount ? '':'none';
}
if(resetBtn) resetBtn.style.display=selectedCount ? '':'none';
filterRegionCountryList(root);
});
}
function applyLocationFilter(options){
if(!filterBuilt) return;
options=options||{};
if(filterMode==='country'){
var val=updateLocationFilterOptions();
updateLocationFilterActiveState(val);
}
if(filterMode==='region'){
syncRegionCountryFilterUi();
}
var rows=document.querySelectorAll('.t-row[data-location]');
rows.forEach(function (row){
row.classList.toggle('lf-hidden', !matchesRow(row));
});
if(!options.skipFilterTariffs&&typeof window.filterTariffs==='function'){
window.filterTariffs();
}}
window.RedesimLocationFilter={
apply: applyLocationFilter,
syncForActiveProvider: function (){
applyLocationFilter({ skipFilterTariffs: true });
},
rowMatchesLocationValue: rowMatchesLocationValue,
matchesRow: matchesRow,
hasActiveSelection: function (){
if(!filterBuilt) return false;
if(filterMode==='region') return selectedRegionCodes.size > 0;
if(filterMode==='country') return getLocFilter()!=='primary';
return false;
},
syncInputs: syncRegionCountryFilterUi
};
document.addEventListener('change', function (e){
if(e.target.matches('input[name="locFilter"]')){
applyLocationFilter();
return;
}
if(e.target.matches('[data-region-country-code]')){
keepPageScrollPosition(function (){
const code=String(e.target.value||e.target.dataset.regionCountryCode||'').toUpperCase();
if(code){
if(e.target.checked){
selectedRegionCodes.add(code);
}else{
selectedRegionCodes.delete(code);
}}
clearRegionCountrySearch(e.target.closest('[data-region-country-filter]'));
applyLocationFilter();
});
}});
document.addEventListener('input', function (e){
if(!e.target.matches('[data-region-country-search]')) return;
filterRegionCountryList(e.target.closest('[data-region-country-filter]'));
});
document.addEventListener('click', function (e){
const reset=e.target.closest('[data-region-country-reset]');
if(!reset) return;
e.preventDefault();
keepPageScrollPosition(function (){
selectedRegionCodes.clear();
clearRegionCountrySearch(reset.closest('[data-region-country-filter]'));
applyLocationFilter();
});
});
document.addEventListener('DOMContentLoaded', function (){
var built=buildLocationFilter();
if(built){
applyLocationFilter();
}});
})();
document.addEventListener('DOMContentLoaded', function (){
document.querySelectorAll('.email-obf').forEach(function (el){
const email=el.dataset.u + '@' + el.dataset.d + '.' + el.dataset.t;
el.textContent=email;
el.href='mailto:' + email;
});
});
document.addEventListener('DOMContentLoaded', function (){
document.querySelectorAll('.phone-obf').forEach(function (el){
const rawPhone=el.dataset.one + el.dataset.two;
const cleanPhone=rawPhone.replace(/[^\d+]/g, '');
let visiblePhone=rawPhone;
if(cleanPhone.length===12&&cleanPhone.startsWith('+7')){
visiblePhone=cleanPhone.replace(/^(\+7)(\d{3})(\d{3})(\d{2})(\d{2})$/,
'$1 $2 $3-$4-$5'
);
}
el.textContent=visiblePhone;
el.href='tel:' + cleanPhone;
});
});
window.addEventListener('load', function (){
const yandexRating=document.querySelector('#yandex_rating');
if(!yandexRating) return;
yandexRating.innerHTML=`
<iframe
src="https://yandex.ru/sprav/widget/rating-badge/213113173212?type=rating"
width="150"
height="50"
frameborder="0"
loading="lazy">
</iframe>
`;
});
document.addEventListener('click', function (e){
const button=e.target.closest('.openchat');
if(!button) return;
e.preventDefault();
function openChatwoot(){
if(window.$chatwoot&&typeof window.$chatwoot.toggle==='function'){
window.$chatwoot.toggle('open');
}}
if(window.$chatwoot){
openChatwoot();
return;
}
window.addEventListener('chatwoot:ready', openChatwoot, { once: true });
});