Help
RSS
API
Feed
Maltego
Contact
Domain > kmapp.ru
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2019-07-16
87.236.16.125
(
ClassC
)
2026-02-16
93.189.229.199
(
ClassC
)
Port 80
HTTP/1.1 301 Moved PermanentlyServer: nginx/1.18.0 (Ubuntu)Date: Mon, 16 Feb 2026 13:12:12 GMTContent-Type: text/htmlContent-Length: 178Connection: keep-aliveLocation: https://kmapp.ru/ html>head>title>301 Moved Permanently/title>/head>body>center>h1>301 Moved Permanently/h1>/center>hr>center>nginx/1.18.0 (Ubuntu)/center>/body>/html>
Port 443
HTTP/1.1 200 OKServer: nginx/1.18.0 (Ubuntu)Date: Mon, 16 Feb 2026 13:12:12 GMTContent-Type: text/html; charsetUTF-8Content-Length: 49005Connection: keep-aliveVary: Origin, Accept-EncodingAccess-Control-Allow-Credentials: trueContent-Security-Policy: default-src self;base-uri self;script-src self https://telegram.org https://cdnjs.cloudflare.com;script-src-elem self unsafe-inline https://telegram.org https://cdnjs.cloudflare.com;style-src self unsafe-inline https://fonts.googleapis.com https://cdnjs.cloudflare.com https://telegram.org;font-src self https://fonts.gstatic.com https://cdnjs.cloudflare.com;img-src self data: https: blob:;connect-src self https://api.telegram.org https://localhost:3000;frame-src self https://telegram.org;object-src none;media-src self;form-action self;upgrade-insecure-requests;frame-ancestors self;script-src-attr noneCross-Origin-Opener-Policy: same-originCross-Origin-Resource-Policy: cross-originOrigin-Agent-Cluster: ?1Referrer-Policy: strict-origin-when-cross-originStrict-Transport-Security: max-age31536000; includeSubDomainsX-DNS-Prefetch-Control: offX-Permitted-Cross-Domain-Policies: noneX-XSS-Protection: 0X-Frame-Options: DENYX-Content-Type-Options: nosniffX-Download-Options: noopenRateLimit-Policy: 100;w300RateLimit-Limit: 100RateLimit-Remaining: 98RateLimit-Reset: 198Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidatePragma: no-cacheExpires: 0Accept-Ranges: bytes !DOCTYPE html>html langru>head> title>Калькулятор Бацзы онлайн - Расчет карты судьбы по дате рождения./title> meta http-equivContent-Type contenttext/html; charsetUTF-8> meta nameviewport contentwidthdevice-width, initial-scale1, maximum-scale1, user-scalableno, viewport-fitcover> meta namemobile-web-app-capable contentyes> meta nameapple-mobile-web-app-capable contentyes> meta nameapple-mobile-web-app-status-bar-style contentblack-translucent> meta namecopyright contentKonstantin Moiseenko> meta namedescription contentОнлайн-калькулятор Бацзы. Узнайте свои элементы личности, удачные периоды жизни и потенциал судьбы. Расчет карты по дате, времени и месту рождения. Полная расшифровка небесных стволов, земных ветвей, элементов личности и скрытых небесных стволов.> meta propertyog:title contentКалькулятор Бацзы онлайн - Расчет карты> meta propertyog:description contentУзнайте свои элементы личности, удачные периоды жизни и потенциал судьбы по дате рождения.> meta propertyog:type contentwebsite> meta propertyog:site_name contentОнлайн-калькулятор Бацзы> !-- link relpreconnect hrefhttps://fonts.googleapis.com> link relpreconnect hrefhttps://fonts.gstatic.com crossorigin> link hrefhttps://fonts.googleapis.com/css2?familyNoto+Sans+TC:wght@200;300;400;500;700&displayswap relstylesheet> --> link relmanifest href./manifest.json> link relpreconnect hrefhttps://fonts.googleapis.com> link relpreconnect hrefhttps://fonts.gstatic.com crossorigin> link hrefhttps://fonts.googleapis.com/css2?familyExo+2:ital,wght@0,100..900;1,100..900&familyNoto+Sans+TC:wght@100..900&familyZen+Kaku+Gothic+New:wght@300;400;500&displayswap relstylesheet> script typetext/javascript> (function(m,e,t,r,i,k,a){ mimi||function(){(mi.ami.a||).push(arguments)}; mi.l1*new Date(); for (var j 0; j document.scripts.length; j++) {if (document.scriptsj.src r) { return; }} ke.createElement(t),ae.getElementsByTagName(t)0,k.async1,k.srcr,a.parentNode.insertBefore(k,a) })(window, document,script,https://mc.yandex.ru/metrika/tag.js?id105124451, ym); ym(105124451, init, {ssr:true, webvisor:true, clickmap:true, ecommerce:dataLayer, accurateTrackBounce:true, trackLinks:true}); /script> link relstylesheet typetext/css href./css/index.css> link relstylesheet typetext/css href./css/ysin.css> link relstylesheet typetext/css href./css/menu.css> link relstylesheet typetext/css href./css/modal.css> link relstylesheet typetext/css href./css/interaction.css> link relstylesheet typetext/css href./css/cards.css> link relstylesheet typetext/css href./css/interactgan.css> script srchttps://telegram.org/js/telegram-web-app.js defer>/script> script src./cards.js defer>/script> /head>body> noscript> p stylecolor:red;>Ваш браузер не поддерживает JavaScript или он отключен!/p> p>Для корректной работы включите JavaScript в настройках браузера./p> /noscript> nav classbottom-menu> button classmenu-item data-sectionsection1> i classfas fa-calendar-day menu-icon>/i> span>Текущий день/span> /button> button classmenu-item active data-sectionsection2> i classfas fa-list-alt menu-icon>/i> span>Личная карта/span> /button> button classmenu-item data-sectionsection3> i classfas fa-book menu-icon>/i> span>Картотека/span> /button> button classmenu-item data-sectionsection4> i classfas fa-gear menu-icon>/i> span>Настройки/span> /button> /nav> div classcontent> div idsection1 classcontent-section> div classdatetime-selector-today> button typebutton classdate-nav data-actionprev> i classfas fa-arrow-left>/i> /button> div classform-group> select idday>/select> select idmonth> option value1>Январь/option> option value2>Февраль/option> option value3>Март/option> option value4>Апрель/option> option value5>Май/option> option value6>Июнь/option> option value7>Июль/option> option value8>Август/option> option value9>Сентябрь/option> option value10>Октябрь/option> option value11>Ноябрь/option> option value12>Декабрь/option> /select> select idyear>/select> div idlocalcity>/div> /div> button typebutton classdate-nav data-actionnext> i classfas fa-arrow-right>/i> /button> !-- div> select idhour>/select> select idminute>/select> /div> --> div styledisplay: contents;> select idhour hidden>/select> select idminute hidden>/select> /div> /div> div classcontent-below> div idresultToday>/div> !-- div classcalendar-container> div classcalendar-header idcalendarHeader> Календарь на месяц. В разработке... /div> table classcalendar-table idcalendarTable> thead> tr> th>Пн/th> th>Вт/th> th>Ср/th> th>Чт/th> th>Пт/th> th>Сб/th> th>Вс/th> /tr> /thead> tbody idcalendarBody> /tbody> /table> /div> --> /div> /div> div idsection2 classcontent-section> !-- content-section active --> button idinfoBlock classinfo-block> Нажмите и введите данные для расчета ... /button> button classaddCard-floating-btn idaddCardBtn styledisplay: none;> i classfas fa-plus>/i> /button> div idresult>/div> /div> div idsection3 classcontent-section> h1>Картотека/h1> div classuser-cards>/div> div styletext-align: center; margin-top: 10px;>В разработке.../div> /div> div idsection4 classcontent-section> h1>Настройки/h1> div classsettings-container> h3>Выберите таблицы для отображения:/h3> div classios-settings-container> div classios-setting-item> span classios-setting-text>Фазы/span> label classios-switch> input typecheckbox nametables valuephaseTable checked> span classios-switch-slider>/span> /label> /div> div classios-setting-item> span classios-setting-text>Звезды/span> label classios-switch> input typecheckbox nametables valuestarsTable checked> span classios-switch-slider>/span> /label> /div> div classios-setting-item> span classios-setting-text>Диаграмма У-Син/span> label classios-switch> input typecheckbox nametables valuewuXing checked> span classios-switch-slider>/span> /label> /div> div classios-setting-item> span classios-setting-text>Взаимодействия ЗВ/span> label classios-switch> input typecheckbox nametables valueinteractCircle checked> span classios-switch-slider>/span> /label> /div> div classios-setting-item> span classios-setting-text>Такты/span> label classios-switch> input typecheckbox nametables valueluckyTable checked> span classios-switch-slider>/span> /label> /div> div classios-setting-item> span classios-setting-text>Года тактов/span> label classios-switch> input typecheckbox nametables valueyearsTable checked> span classios-switch-slider>/span> /label> /div> /div> button classsubmit-btn data-actionapply-settings> Применить /button> /div> /div> /div>script> let lastSelectedGender null; let lastSelectedCity null; let selectedCity null; const NOW_DATE new Date(); let born_date new Date(); let BORN_DATA {}; let ticking false; let lastScrollPosition 0; const SCROLL_THRESHOLD 50; // // СИСТЕМА ОЧИСТКИ РЕСУРСОВ // function createCleanupManager(name Unnamed) { const cleanupFunctions ; let executed false; return { add: function(fn, description anonymous) { if (executed) { console.warn(`CleanupManager ${name} Cannot add after execution: ${description}`); return; } if (typeof fn function) { cleanupFunctions.push({ fn, description }); console.log(`CleanupManager ${name} Added: ${description}, total: ${cleanupFunctions.length}`); } }, execute: function() { if (executed) { console.warn(`CleanupManager ${name} Already executed`); return; } executed true; console.log(`CleanupManager ${name} Executing ${cleanupFunctions.length} cleanup functions`); for (let i cleanupFunctions.length - 1; i > 0; i--) { try { console.log(`CleanupManager ${name} Cleaning up: ${cleanupFunctionsi.description}`); cleanupFunctionsi.fn(); } catch (e) { console.error(`CleanupManager ${name} Error in ${cleanupFunctionsi.description}:`, e); } } cleanupFunctions.length 0; }, count: function() { return cleanupFunctions.length; }, getState: function() { return { name, pendingCleanups: cleanupFunctions.length, descriptions: cleanupFunctions.map(cf > cf.description) }; } }; } // // КОНТРОЛЛЕР ВЫБОРА ГОРОДА // class City { constructor(data) { this.id data.id; this.name_ru data.name_ru; this.name_en data.name_en; this.lat data.lat; this.lng data.lng; this.country data.country; this.iso data.iso; this.region data.region; this.population data.population; } displayInfo() { return `${this.name_ru} (${this.name_en}), ${this.region}, ${this.country}`; } getCoordinates() { return { lat: this.lat, lng: this.lng }; } } function initCityController() { //document.addEventListener(DOMContentLoaded, function() { const searchMode advanced; // prefix или advanced const cityInput document.getElementById(city-input); const suggestionList document.getElementById(suggestion-list); let debounceTimer; // Функция для поиска городов async function searchCities(query) { if (query.length 1) { hideSuggestions(); return; } try { const response await fetch(`/api/cities/search?q${encodeURIComponent(query)}&mode${searchMode}`); const cities await response.json(); displaySuggestions(cities, query); } catch (error) { console.error(Search error:, error); hideSuggestions(); } } // Функция для получения полных данных города по ID async function getCityById(cityId) { try { const response await fetch(`/api/cities/${cityId}`); const cityData await response.json(); return new City(cityData); } catch (error) { console.error(Error fetching city data:, error); return null; } } // Функция для отображения подсказок с подсветкой function displaySuggestions(cities, query) { if (cities.length 0) { hideSuggestions(); return; } suggestionList.innerHTML ; cities.forEach(cityDATA > { const div document.createElement(div); div.className suggestion-item; // Подсветка совпадающей части const highlightedText highlightMatch(cityDATA.name_ru, query) || highlightMatch(cityDATA.name_en, query) || cityDATA.name_ru; div.innerHTML ` div classcity-name>${highlightedText}/div> div classcity-details>${cityDATA.region ? cityDATA.region + , : }${cityDATA.country}/div> `; div.dataset.cityId cityDATA.id; div.addEventListener(click, async function() { cityInput.value cityDATA.name_ru; hideSuggestions(); selectedCity await getCityById(cityDATA.id); if (selectedCity) { onCitySelected(selectedCity); } }); suggestionList.appendChild(div); }); suggestionList.style.display block; } // Функция для подсветки совпадения function highlightMatch(text, query) { if (!text || !query) return text; const lowerText text.toLowerCase(); const lowerQuery query.toLowerCase(); const matchIndex lowerText.indexOf(lowerQuery); if (matchIndex -1) return text; const before text.substring(0, matchIndex); const match text.substring(matchIndex, matchIndex + query.length); const after text.substring(matchIndex + query.length); return `${before}strong>${match}/strong>${after}`; } // Функция для скрытия подсказок function hideSuggestions() { suggestionList.style.display none; } // Функция, которая вызывается когда город выбран function onCitySelected(cityDATA) { // Диспатч события для других частей приложения window.dispatchEvent(new CustomEvent(citySelected, { detail: cityDATA })); // // Показываем информацию о городе // displayCityInfo(cityDATA); } // // Функция для отображения информации о городе // function displayCityInfo(cityDATA) { // let infoDiv document.getElementById(city-info); // if (!infoDiv) { // infoDiv document.createElement(div); // infoDiv.id city-info; // cityInput.parentNode.appendChild(infoDiv); // } // infoDiv.innerHTML ` // strong>${cityDATA.name_ru}/strong> (${cityDATA.name_en})br> // Страна: ${cityDATA.country} (${cityDATA.iso})br> // Регион: ${cityDATA.region}br> // Население: ${cityDATA.population ? cityDATA.population.toLocaleString() : нет данных}br> // Координаты: ${cityDATA.lat.toFixed(4)}, ${cityDATA.lng.toFixed(4)} // `; // } // Дебаунс для ограничения частоты запросов function debounceSearch(query) { clearTimeout(debounceTimer); debounceTimer setTimeout(() > { searchCities(query); }, 200); } // Обработчики событий cityInput.addEventListener(input, function(e) { const query e.target.value.trim(); if (query.length 0) { hideSuggestions(); // Очищаем информацию о городе если поле пустое const infoDiv document.getElementById(city-info); if (infoDiv) infoDiv.remove(); selectedCity null; } else { debounceSearch(query); } }); cityInput.addEventListener(focus, function(e) { const query e.target.value.trim(); if (query.length > 0) { debounceSearch(query); } }); // Скрывать подсказки при клике вне поля ввода document.addEventListener(click, function(e) { if (!e.target.closest(#suggestions) && e.target ! cityInput) { hideSuggestions(); } }); // Обработка клавиш (стрелки, Enter, Escape) cityInput.addEventListener(keydown, function(e) { const items suggestionList.querySelectorAll(.suggestion-item); const activeItem suggestionList.querySelector(.suggestion-item.active); if (e.key ArrowDown) { e.preventDefault(); if (items.length > 0) { const nextItem activeItem ? activeItem.nextElementSibling || items0 : items0; items.forEach(item > item.classList.remove(active)); nextItem.classList.add(active); nextItem.scrollIntoView({ block: nearest }); } } else if (e.key ArrowUp) { e.preventDefault(); if (items.length > 0) { const prevItem activeItem ? activeItem.previousElementSibling || itemsitems.length - 1 : itemsitems.length - 1; items.forEach(item > item.classList.remove(active)); prevItem.classList.add(active); prevItem.scrollIntoView({ block: nearest }); } } else if (e.key Enter) { e.preventDefault(); if (activeItem) { const cityId parseInt(activeItem.dataset.cityId); const cityName activeItem.querySelector(.city-name).textContent; cityInput.value cityName; hideSuggestions(); // Получаем полные данные о городе и создаем экземпляр City getCityById(cityId).then(cityDATA > { if (cityDATA) { selectedCity cityDATA; onCitySelected(cityDATA); } }); } } else if (e.key Escape) { hideSuggestions(); } }); } function getSelectedCity() { return selectedCity; } function resetSelectedCity() { selectedCity null; } // // УТИЛИТЫ ДАТЫ И ВРЕМЕНИ // function setupEventListeners() { // Обработчики для кнопок навигации даты document.querySelectorAll(.date-navdata-actionprev).forEach(btn > { btn.addEventListener(click, () > changeDate(-1)); }); document.querySelectorAll(.date-navdata-actionnext).forEach(btn > { btn.addEventListener(click, () > changeDate(1)); }); // Обработчик для кнопки применения настроек document.querySelectorAll(data-actionapply-settings).forEach(btn > { btn.addEventListener(click, changeSet); }); // Обработчики для переключения секций document.querySelectorAll(.menu-item).forEach(item > { item.addEventListener(click, () > { const sectionId item.dataset.section; activateSection(sectionId); }); }); } function getClientDateTime() { return { year: NOW_DATE.getFullYear(), month: NOW_DATE.getMonth() + 1, day: NOW_DATE.getDate(), hour: NOW_DATE.getHours(), minute: NOW_DATE.getMinutes(), timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, offset: NOW_DATE.getTimezoneOffset(), // минуты от UTC offsetHours: -NOW_DATE.getTimezoneOffset() / 60, // часы от UTC isoString: NOW_DATE.toISOString(), localeString: NOW_DATE.toLocaleString(ru-RU) }; } function fillSelect(select, start, end) { select.innerHTML ; for (let i start; i end; i++) { select.appendChild(new Option(i, i)); } } function setDateToInputs(date, dayEl, monthEl, yearEl, hourEL, minutesEL) { yearEl.value date.getFullYear(); monthEl.value date.getMonth() + 1; updateDaysInMonth(dayEl, monthEl, yearEl); dayEl.value date.getDate(); hourEL.value date.getHours(); minutesEL.value date.getMinutes(); } function updateDaysInMonth(dayEl, monthEl, yearEl) { const year +yearEl.value || NOW_DATE.getFullYear(); const month +monthEl.value || NOW_DATE.getMonth() + 1; const lastDay new Date(year, month, 0).getDate(); const selectedDay Math.min(Math.max(1, +dayEl.value || 1), lastDay); fillSelect(dayEl, 1, lastDay); dayEl.value selectedDay; } function initDate(date, dayId, monthId, yearId, hourId, minuteId, suff) { fillSelect(dayId, 1, 31); fillSelect(yearId, 1900, 2030); fillSelect(hourId, 0, 23); fillSelect(minuteId, 0, 59); setDateToInputs(date, dayId, monthId, yearId, hourId, minuteId); const dateChangeCallback suff && typeof loadTodayMap function ? loadTodayMap : undefined; // Устанавливаем обработчики setupDateSelectors( dayId, monthId, yearId, hourId, minuteId, dateChangeCallback ); } function setupDateSelectors(dayEl, monthEl, yearEl, hourEL, minutesEL, callback) { // Проверка обязательных параметров if (!dayEl || !monthEl || !yearEl) { console.warn(setupDateSelectors: отсутствуют обязательные элементы (day, month, year)); return null; } // Фильтруем только существующие элементы с поддержкой addEventListener const changeElements monthEl, yearEl, hourEL, minutesEL .filter(el > el && typeof el.addEventListener function); const changeHandler () > { updateDaysInMonth(dayEl, monthEl, yearEl, hourEL, minutesEL); callback?.(); // Используем optional chaining }; // Добавляем обработчики changeElements.forEach(el > { el.addEventListener(change, changeHandler); }); let dayCallback null; if (callback) { dayCallback callback; dayEl.addEventListener(change, dayCallback); } // Функция для очистки return () > { changeElements.forEach(el > { el.removeEventListener(change, changeHandler); }); if (dayCallback) { dayEl.removeEventListener(change, dayCallback); } }; } function changeDate(days) { const day +daySelect.value + days; const date new Date( +yearSelect.value, +monthSelect.value - 1, day, +hourSelect.value, +minuteSelect.value ); setDateToInputs(date, daySelect, monthSelect, yearSelect, hourSelect, minuteSelect); loadTodayMap(); } // // ЛИЧНАЯ КАРТА // async function ClickInfoBlock() { try { const response await fetch(/api/get-modal-html, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify({ modalType: personalData }) }); const data await response.json(); showModal(data.html); initPersonalDataForm(); } catch (error) { showError(Ошибка загрузки формы!); } } function initPersonalDataForm() { const cleanup createCleanupManager(PersonalDataForm); initCityController(); setTimeout(() > { const elements { day: document.getElementById(modalBornDay), month: document.getElementById(modalBornMonth), year: document.getElementById(modalBornYear), hour: document.getElementById(modalBornHour), minute: document.getElementById(modalBornMinute), cityInput: document.getElementById(city-input), submitBtn: document.getElementById(modalSubmitBtn) }; initDate( born_date, elements.day, elements.month, elements.year, elements.hour, elements.minute ); const dateCleanup setupDateSelectors( elements.day, elements.month, elements.year, elements.hour, elements.minute ); if (dateCleanup) cleanup.add(dateCleanup, dateSelectorsCleanup); if (lastSelectedCity) { elements.cityInput.value lastSelectedCity.name_ru; } if (lastSelectedGender) { const genderRadio document.querySelector(`inputnamemodalGendervalue${lastSelectedGender}`); if (genderRadio) genderRadio.checked true; } const submitHandler () > { if (!elements.cityInput.value) { showError(Сначала выберите город из списка...); return; } let selectedCity getSelectedCity(); if (selectedCity) { lastSelectedCity selectedCity; resetSelectedCity(); } lastSelectedGender document.querySelector(inputnamemodalGender:checked)?.value;; BORN_DATA { bornDay: +elements.day.value, bornMonth: +elements.month.value, bornYear: +elements.year.value, bornHour: elements.hour.value, bornMinute: elements.minute.value, gender: lastSelectedGender, city: lastSelectedCity.name_ru, lng: lastSelectedCity.lng, lat: lastSelectedCity.lat }; loadPersonalMap(BORN_DATA); cleanup.execute(); closeModal(); }; elements.submitBtn.addEventListener(click, submitHandler); cleanup.add(() > { elements.submitBtn.removeEventListener(click, submitHandler); console.log(`ClickInfoBlock Removed submit handler`); }, submitHandler); // Добавляем обработчик закрытия модального окна const modalCloseHandler () > { cleanup.execute(); }; // Находим кнопку закрытия модального окна const closeBtn document.querySelector(.modal-close, .close-modal); if (closeBtn) { closeBtn.addEventListener(click, modalCloseHandler); cleanup.add(() > { closeBtn.removeEventListener(click, modalCloseHandler); }, modalCloseHandler); } // Также очищаем при клике на фон модального окна const modalBackground document.querySelector(.modal-background); if (modalBackground) { modalBackground.addEventListener(click, modalCloseHandler); cleanup.add(() > { modalBackground.removeEventListener(click, modalCloseHandler); }, modalBackgroundHandler); } cleanup.add(() > { console.log(`ClickInfoBlock Final cleanup`); }, finalCleanup); }, 0); } async function loadPersonalMap(DATA) { const getTableState (value) > { const element document.querySelector(`inputnametablesvalue${value}`); return element ? element.checked : false; }; const selectedTables { phaseTable: getTableState(phaseTable), starsTable: getTableState(starsTable), luckyTable: getTableState(luckyTable), yearsTable: getTableState(yearsTable), wuXing: getTableState(wuXing), interactCircle: getTableState(interactCircle) }; const requestData { ...DATA, curYear: NOW_DATE.getFullYear(), tables: selectedTables }; try { const response await fetch(/api/calc-person-map, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify(requestData) }); if (response.ok) { const html await response.text(); const infoHtml, resultHtml html.split(!-- split -->); const infoBlock document.getElementById(infoBlock); const resultBlock document.getElementById(result); if (infoBlock && resultBlock) { infoBlock.innerHTML infoHtml; resultBlock.innerHTML resultHtml; } else { console.error(Required elements not found); } born_date new Date( DATA.bornYear, DATA.bornMonth - 1, DATA.bornDay, DATA.bornHour, DATA.bornMinute ); BORN_DATA DATA; const addCardBtn document.getElementById(addCardBtn); addCardBtn.style.display flex; } else { console.error(Server error:, response.status); document.getElementById(addCardBtn).style.display none; } } catch (error) { console.error(Error:, error); } } // // КАРТА ТЕКУЩЕГО ДНЯ // const daySelect document.getElementById(day); const monthSelect document.getElementById(month); const yearSelect document.getElementById(year); const hourSelect document.getElementById(hour); const minuteSelect document.getElementById(minute); const resultElement document.getElementById(resultToday); async function loadTodayMap() { const data { DD: +daySelect.value, MM: +monthSelect.value, YY: +yearSelect.value, h: +hourSelect.value, m: +minuteSelect.value, city: Красноярск, lng: 92.8524806, lat: 56.0093879 }; try { const response await fetch(/api/calc-today-map, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify(data) }); if (!response.ok) { console.error(Server error:, response.status); } const html await response.text(); resultElement.innerHTML html; } catch (error) { console.error(Error:, error); resultElement.innerHTML div classerror>Ошибка загрузки данных/div>; } } // // УПРАВЛЕНИЕ ИНТЕРФЕЙСОМ // function activateSection(sectionId) { const menuItem document.querySelector(`data-section${sectionId}`); const section document.getElementById(sectionId); if (!menuItem || !section) return; // Находим контейнеры для более точного поиска const allMenuItems document.querySelectorAll(.menu-item); const allSections document.querySelectorAll(.content-section); allMenuItems.forEach(item > item.classList.remove(active)); allSections.forEach(sec > sec.classList.remove(active)); menuItem.classList.add(active); section.classList.add(active); window.scrollTo({ top: 0, behavior: smooth }); } function changeSet() { const resultElement document.getElementById(result); if (resultElement) { activateSection(section2); if (Object.keys(BORN_DATA).length > 0) { loadPersonalMap(BORN_DATA); } else ClickInfoBlock(); } } function showError(message) { alert(Ошибка: + message); } // // ОБРАБОТЧИКИ SCROLL И NAVIGATION // function handleScrollAddCard() { const addCardBtn document.getElementById(addCardBtn); const infoBlock document.querySelector(.info-block); if (!addCardBtn || !infoBlock) return; const currentScrollPosition Math.max(window.scrollY, document.documentElement.scrollTop, 0); if (!ticking) { requestAnimationFrame(() > { const scrollingDown currentScrollPosition > lastScrollPosition; const pastThreshold currentScrollPosition > SCROLL_THRESHOLD; const shouldHide scrollingDown && pastThreshold; addCardBtn.classList.toggle(hidden, shouldHide); infoBlock.classList.toggle(hidden, shouldHide); lastScrollPosition currentScrollPosition; ticking false; }); ticking true; } } // // СИСТЕМА МОДАЛЬНЫХ ОКОН // function initializeModalSystem() { if (window.modalSystemInitialized) return; window.modalSystemInitialized true; const modalState { currentModal: null, isOpen: false, isFetching: false }; let abortController null; window.showModal (html) > { closeModal(); const overlay document.createElement(div); overlay.className modal-overlay; const modalContent document.createElement(div); modalContent.className modal-content; modalContent.innerHTML html; document.body.classList.add(body-no-scroll); const closeBtn document.createElement(span); closeBtn.className close-btn; closeBtn.innerHTML ×; closeBtn.setAttribute(role, button); modalContent.prepend(closeBtn); overlay.appendChild(modalContent); document.body.appendChild(overlay); document.body.style.overflow hidden; modalState.currentModal overlay; modalState.isOpen true; }; window.closeModal () > { if (!modalState.currentModal) return; modalState.currentModal.remove(); modalState.currentModal null; document.body.style.overflow ; document.body.classList.remove(body-no-scroll); modalState.isOpen false; if (abortController) { abortController.abort(); abortController null; } modalState.isFetching false; }; const handleKeyDown (e) > { if (e.key Escape && modalState.isOpen) { closeModal(); } }; const handleModalClose (e) > { // Закрытие по клику на overlay или кнопку закрытия if (e.target.classList.contains(modal-overlay) || e.target.classList.contains(close-btn) || e.target.closest(.close-btn)) { closeModal(); return true; // Останавливаем дальнейшую обработку } return false; }; const CLICK_HANDLERS { selector: #phaseTable tddata-id, endpoint: /api/phase-info }, { selector: #starsTable tddata-id, endpoint: /api/star-info }, { selector: #tableMap tr:not(.sns) tddata-id, endpoint: /api/ganzhi-info }, { selector: #tableMapToday tr:first-child tddata-id, endpoint: /api/ganzhi-info }, { selector: #wuxing-svg pathdata-id, endpoint: /api/gods-info }, { selector: #combinations divdata-iddata-type, endpoint: /api/interact-info, extractValue: (el) > { const type encodeURIComponent(el.getAttribute(data-type)); const id encodeURIComponent(el.getAttribute(data-id)); return `${type}/${id}`; } }, { selector: #infoBlock, handler: ClickInfoBlock } // ,{ selector: #addCardBtn, handler: addCard } ; const fetchInfo async (value, endpoint) > { if (abortController) { abortController.abort(); } if (modalState.isFetching) return; abortController new AbortController(); modalState.isFetching true; try { let url; if (endpoint /api/interact-info) { url `${endpoint}/${value}`; } else { url `${endpoint}?value${encodeURIComponent(value)}`; } const response await fetch(url, { signal: abortController.signal, headers: {Accept: application/json} }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data await response.json(); if (data.error) { showError(`Server error: ${data.error}`); return; } showModal(data.modalHtml); } catch (error) { if (error.name AbortError) return; showError(Невозможно загрузить данные с сервера.); } finally { modalState.isFetching false; abortController null; } }; const handleDocumentClick (e) > { // Сначала проверяем закрытие модалки if (handleModalClose(e)) { return; } // Затем проверяем другие клики for (const handler of CLICK_HANDLERS) { const element e.target.closest(handler.selector); if (element) { e.preventDefault(); if (handler.handler) { handler.handler(); return; } const value handler.extractValue ? handler.extractValue(element) : element.getAttribute(data-id); if (value) { fetchInfo(value, handler.endpoint); } return; } } }; document.addEventListener(keydown, handleKeyDown); document.addEventListener(click, handleDocumentClick); // Только один обработчик // document.addEventListener(selectstart, function(e) { e.preventDefault(); }); window.cleanupModalSystem function() { document.removeEventListener(keydown, handleKeyDown); document.removeEventListener(click, handleDocumentClick); // document.removeEventListener(selectstart, handleSelectStart); closeModal(); }; window.addEventListener(beforeunload, () > { if (window.cleanupModalSystem) { window.cleanupModalSystem(); } }); } // // TELEGRAM WEB APP ИНИЦИАЛИЗАЦИЯ // function initializeTelegramWebApp() { if (window.Telegram?.WebApp) { const tg window.Telegram.WebApp; tg.ready(); tg.expand(); const version parseFloat(tg.version) || 0; try { if (version > 6.1 && tg.disableVerticalSwipes) tg.disableVerticalSwipes(); if (version > 6.1 && tg.disableHorizontalSwipes) tg.disableHorizontalSwipes(); tg.BackButton.show(); tg.BackButton.onClick(() > { tg.showConfirm(Закрыть приложение?, (confirmed) > { if (confirmed) { tg.close(); } }); }); } catch (error) { console.log(Some WebApp features not available:, error.message); } } else { console.log(Running outside Telegram - WebApp API not available); } } // // ИНИЦИАЛИЗАЦИЯ ПРИЛОЖЕНИЯ // function __init() { const clientData getClientDateTime(); activateSection(section2); initDate( NOW_DATE, daySelect, monthSelect, yearSelect, hourSelect, minuteSelect, Today ); loadTodayMap(); // Обработчики window.addEventListener(scroll, handleScrollAddCard, { passive: true }); // Инициализация систем setupEventListeners(); initializeModalSystem(); initializeTelegramWebApp(); } // Запуск приложения __init();/script>/body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]