PageSourceSearch

https://kasperskyfuture.ru/assets/js/app.js?_v=20240603205537

js kasperskyfuture.ru collected 2026-10-04 11:37:00 UTC 19,232 bytes, 564 lines download raw bytes

1document.addEventListener("DOMContentLoaded", () => {
2  scrollClass();
3
4  let lang = "ru";
5  if (window.location.hostname.indexOf("ics.kaspersky.com") > -1) {
6    lang = "en";
7  }
8  const spContainer = document.querySelector(".speakers");
9
10  if (spContainer) {
11    const speakers = new Swiper(".speakers-slider", {
12      slidesPerView: 1,
13      spaceBetween: 84,
14      pagination: {
15        el: ".speakers-pag",
16        clickable: true,
17      },
18      centeredSlides: true,
19      navigation: {
20        nextEl: ".speakers-slider-arrow-next",
21        prevEl: ".speakers-slider-arrow-prev",
22      },
23      breakpoints: {
24        320: {
25          slidesPerView: 1,
26          spaceBetween: 3,
27        },
28        480: {
29          slidesPerView: 2,
30          spaceBetween: 24,
31        },
32        620: {
33          slidesPerView: 3,
34          spaceBetween: 24,
35        },
36        993: {
37          slidesPerView: 4,
38          spaceBetween: 60,
39          initialSlide: 1,
40        },
41      },
42    });
43  }
44
45  // Маски для телефонных номеров по коду страны
46  var maskMap = {
47    1: "(00000) 000-000",
48    3: "(0000) 000-00-00",
49    7: "(000) 000-00-00",
50    4: "(00000) 000-0000",
51    5: "(0000) 000-000",
52  };
53
54  const registration = document.querySelector(".registration");
55  if (registration) {
56    var phoneMasks = document.querySelectorAll(".mask");
57    var phoneError = document.getElementById("error");
58    phoneMasks.forEach(function (element) {
59      // Применяем новую маску к текущему элементу
60      element.maskRef = IMask(element, {
61        mask: maskMap["7"],
62      });
63
64      phoneError.style.display = "none";
65      element.addEventListener("input", function () {
66        var phoneNumber = this.value.replace(/\D/g, ""); // Убираем все нецифровые символы
67        if (phoneNumber.length < maskMap["7"].replace(/\D/g, "").length) {
68          phoneError.style.display = "block";
69          this.classList.add("phone-error"); // Добавляем класс для стилизации при ошибке
70        } else {
71          phoneError.style.display = "none";
72          this.classList.remove("phone-error");
73        }
74      });
75    });
76
77    document
78      .getElementById("country-select")
79      .addEventListener("change", function () {
80        var selectedCountryCode = this.value;
81        var selectedMask = maskMap[selectedCountryCode];
82
83        phoneMasks.forEach(function (element) {
84          // Очищаем значение элемента
85          element.value = "";
86
87          // Удаляем предыдущую маску, если она есть
88          if (element.maskRef) {
89            element.maskRef.destroy();
90          }
91
92          // Применяем новую маску к текущему элементу
93          element.maskRef = IMask(element, {
94            mask: selectedMask,
95          });
96
97          element.addEventListener("input", function () {
98            var phoneNumber = this.value.replace(/\D/g, ""); // Убираем все нецифровые символы
99            if (phoneNumber.length < selectedMask.replace(/\D/g, "").length) {
100              phoneError.style.display = "block";
101              this.classList.add("phone-error"); // Добавляем класс для стилизации при ошибке
102            } else {
103              phoneError.style.display = "none";
104              this.classList.remove("phone-error");
105            }
106          });
107
108          // Обновляем значение элемента, чтобы избежать предупреждений
109          element.maskRef.updateValue();
110
111          // Проверяем ввод номера телефона при изменении кода страны
112        });
113      });
114
115    // Функция для скрытия или показа label в зависимости от состояния input, select или textarea
116    function toggleLabelVisibility(element) {
117      var formField = element.closest(".form-field");
118      if (!formField) {
119        return;
120      }
121
122      var label = formField.querySelector("label");
123      if (!label) {
124        return;
125      }
126
127      var isSelect =
128        element.tagName && element.tagName.toLowerCase() === "select";
129
130      // Для select: показываем label, пока нет выбранного значения
131      if (isSelect) {
132        if (element.value) {
133          label.style.display = "none";
134        } else {
135          label.style.display = "block";
136        }
137        return;
138      }
139
140      // Для input/textarea: прежняя логика — скрываем по фокусу или если есть значение
141      if (element.value || element === document.activeElement) {
142        label.style.display = "none";
143      } else {
144        label.style.display = "block";
145      }
146    }
147
148    // Применяем функцию для всех целевых элементов при загрузке страницы и на событиях
149    var formElements = document.querySelectorAll("input, select, textarea");
150
151    formElements.forEach(function (element) {
152      // Проверяем состояние элемента при загрузке страницы
153      toggleLabelVisibility(element);
154
155      // Добавляем обработчики событий для изменения состояния
156      element.addEventListener("focus", function () {
157        toggleLabelVisibility(element);
158      });
159
160      element.addEventListener("blur", function () {
161        toggleLabelVisibility(element);
162      });
163
164      element.addEventListener("input", function () {
165        toggleLabelVisibility(element);
166      });
167    });
168
169    var form = document.querySelector("form");
170    var submitButton = form.querySelector("#submit");
171
172    function checkFormFields() {
173      var requiredElements = form.querySelectorAll(
174        "input[required], select[required], textarea[required]",
175      );
176      var allFilled = true;
177      var hasError = false;
178
179      requiredElements.forEach(function (element) {
180        if (
181          !document.querySelector("#checkbox").checked ||
182          !element.value.trim() ||
183          element.classList.contains("error") ||
184          element.classList.contains("no-correct") ||
185          element.classList.contains("phone-error")
186        ) {
187          allFilled = false;
188          if (
189            document.querySelector("#checkbox").checked ||
190            element.classList.contains("error") ||
191            element.classList.contains("no-correct") ||
192            element.classList.contains("phone-error")
193          ) {
194            hasError = true;
195          }
196        }
197      });
198
199      // Если все поля заполнены и нет ошибок, или есть ошибка в поле tel, то удаляем атрибут disabled
200      if (allFilled && !hasError) {
201        submitButton.removeAttribute("disabled");
202      } else {
203        submitButton.setAttribute("disabled", "disabled");
204      }
205    }
206
207    var formElements = form.querySelectorAll(
208      "input[required], select[required], textarea[required]",
209    );
210    formElements.forEach(function (element) {
211      element.addEventListener("input", checkFormFields);
212      element.addEventListener("change", checkFormFields);
213    });
214
215    checkFormFields();
216
217    var emailInput = document.getElementById("email");
218    var emailError = document.getElementById("email-error");
219    emailError.style.display = "none";
220
221    emailInput.addEventListener("input", function () {
222      if (!isValidEmail(this.value.trim())) {
223        emailError.style.display = "block";
224        this.classList.add("no-correct"); // Добавляем класс для стилизации при ошибке
225      } else {
226        emailError.style.display = "none";
227        this.classList.remove("no-correct");
228      }
229    });
230
231    function isValidEmail(email) {
232      var emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
233      return emailPattern.test(email);
234    }
235  }
236
237  const language = document.querySelector(".header-union > a");
238
239  if (language) {
240    language.addEventListener("click", (event) => {
241      event.preventDefault();
242      language.closest(".header-union").classList.toggle("active");
243      language
244        .closest(".header-union")
245        .querySelector(".language")
246        .classList.toggle("show");
247    });
248  }
249
250  const popupMap = document.querySelector(".popup-map");
251
252  if (popupMap) {
253    const popupWrapper = popupMap.querySelector(".popup-map__wrapper");
254    const popupClose = popupMap.querySelector(".popup-close");
255    const conferenceMapLinks = document.querySelectorAll(".conference-map");
256
257    conferenceMapLinks.forEach((link) => {
258      link.addEventListener("click", function (event) {
259        event.preventDefault();
260        popupMap.classList.add("show");
261      });
262    });
263
264    if (popupClose) {
265      popupClose.addEventListener("click", function () {
266        popupMap.classList.remove("show");
267      });
268    }
269
270    if (popupWrapper) {
271      document.addEventListener("click", function (event) {
272        // Проверяем, находится ли кликнутый элемент внутри блока .popup-map__wrapper или это кнопка открытия
273        if (
274          !popupWrapper.contains(event.target) &&
275          !event.target.closest(".conference-map")
276        ) {
277          popupMap.classList.remove("show");
278        }
279      });
280
281      // Предотвращаем закрытие попапа при клике внутри него
282      popupWrapper.addEventListener("click", function (event) {
283        event.stopPropagation();
284      });
285    }
286  }
287
288  const header = document.querySelector("header");
289  const nextBlock = header.nextElementSibling;
290  const headerHeight = header.offsetHeight;
291  const yearsBar = document.querySelector(".last-years").offsetHeight;
292
293  window.addEventListener("scroll", function () {
294    const scrollPosition = window.scrollY;
295
296    if (scrollPosition > yearsBar) {
297      header.classList.add("fixed");
298      if (nextBlock) {
299        nextBlock.style.marginTop = `${headerHeight}px`;
300      }
301    } else {
302      header.classList.remove("fixed");
303      if (nextBlock) {
304        nextBlock.style.marginTop = `0px`;
305      }
306    }
307  });
308
309  document.querySelector(".burger-btn").addEventListener("click", function () {
310    document
311      .querySelector(".header-menu__wrapper")
312      .classList.toggle("menu-showed");
313    this.classList.toggle("active");
314  });
315
316  const speakers = document.querySelectorAll(".speakers-slide");
317  const showAllButton = document.querySelector(".show-all-speakers");
318  let showingAll = false; // Флаг для отслеживания состояния показа
319
320  function hideSpeakers() {
321    if (window.innerWidth <= 480) {
322      speakers.forEach((speaker, index) => {
323        if (index >= 5) {
324          speaker.style.display = "none";
325        }
326      });
327    } else {
328      speakers.forEach((speaker) => {
329        speaker.style.display = "";
330      });
331    }
332  }
333
334  // hideSpeakers(); // Скрываем элементы при загрузке страницы
335
336  // window.addEventListener("resize", hideSpeakers);
337
338  if (showAllButton) {
339    showAllButton.addEventListener("click", function () {
340      if (showingAll) {
341        // Если все элементы показываются, скрываем их обратно
342        // hideSpeakers();
343      } else {
344        // Показываем все элементы
345        speakers.forEach((speaker) => {
346          speaker.style.display = "";
347        });
348      }
349      showingAll = !showingAll; // Переключаем флаг
350      showAllButton.classList.toggle("active"); // Переключаем класс кнопки для изменения текста
351
352      // Меняем текст кнопки
353      if (showingAll) {
354        showAllButton.querySelector("span").textContent = "Скрыть спикеров";
355      } else {
356        showAllButton.querySelector("span").textContent =
357          "Показать всех спикеров";
358      }
359    });
360  }
361
362  const menuLinks = document.querySelectorAll(".header-menu a");
363  const sections = document.querySelectorAll("section");
364
365  function onScroll() {
366    const scrollPos = window.scrollY + window.innerHeight / 2;
367
368    sections.forEach((section) => {
369      const sectionTop = section.offsetTop;
370      const sectionBottom = sectionTop + section.offsetHeight;
371      const id = section.getAttribute("id");
372      const menuLink = document.querySelector(`.header-menu a[href="#${id}"]`);
373
374      if (scrollPos >= sectionTop && scrollPos < sectionBottom) {
375        menuLinks.forEach((link) => link.classList.remove("active"));
376        menuLink && menuLink.classList.add("active");
377      }
378    });
379  }
380
381  window.addEventListener("scroll", onScroll);
382
383  if (form) {
384    form.addEventListener("input", () => {
385      // submitButton.disabled = !form.checkValidity();
386    });
387
388    form.addEventListener("submit", async function (event) {
389      event.preventDefault();
390
391      const formData = new FormData(form);
392
393      const data = {
394        FirstName: formData.get("name") || "",
395        LastName: formData.get("surname") || "",
396        Email: formData.get("email") || "",
397        Phone: formData.get("phone") || "",
398        Country: document.getElementById("country").value || "",
399        Company: formData.get("company") || "",
400        JobTitle: formData.get("youPos") || "",
401        Token: formData.get("token") || "",
402        Source: formData.get("source") || "",
403        Format: formData.get("format") ? "online" : "offline",
404        Status: formData.get("status") || "",
405        WorkshopParticipant: formData.get("workshopDay1") === "Да" || false,
406      };
407
408      try {
409        const response = await fetch("/api/", {
410          method: "POST",
411          headers: {
412            "Content-Type": "application/json",
413          },
414          credentials: "include",
415          body: JSON.stringify({ data }),
416        });
417
418        if (response.ok) {
419          const result = await response.json();
420          if (lang === "ru") {
421            form.innerHTML = `
422                  <h2 class="success-form__title">Благодарим <br> за регистрацию!</h2>
423                  <div class="success-form__descr">Все заявки проходят модерацию, как только мы рассмотрим вашу заявку,  вам на электронную почту придет письмо со всей подробной информацией о Kaspersky Future Conference 2026</div>
424              `;
425          } else {
426            form.innerHTML = `
427                  <h2 class="success-form__title">Thank you<br>for registration!</h2>
428                  <div class="success-form__descr">All applies going through strong moderation. As soon as we review your application, you will receive an email with all the detailed information about Kaspersky Future Conference 2026</div>
429              `;
430          }
431        } else {
432          const errorData = await response.json();
433          if (errorData.error.message.includes("must be unique")) {
434            alert(
435              "Registration failed: Duplicate value found for unique field.",
436            );
437          } else {
438            alert("Registration failed: " + errorData.error.message);
439          }
440        }
441      } catch (error) {
442        alert("Registration failed: " + error.message);
443      }
444    });
445  }
446
447  let programmsLinks = document.querySelectorAll(".programm__menu-link");
448
449  if (programmsLinks) {
450    programmsLinks.forEach(function (link, index) {
451      link.addEventListener("click", function (e) {
452        e.preventDefault();
453
454        document
455          .querySelectorAll(".programm__tab._active")
456          .forEach((tab) => tab.classList.remove("_active"));
457        document
458          .querySelectorAll(".programm__tab")
459          [index].classList.add("_active");
460
461        programmsLinks.forEach((item) => item.classList.remove("_active"));
462        link.classList.add("_active");
463      });
464    });
465  }
466
467  if (registration) {
468    const initSelectPlaceholder = (selectId) => {
469      const selectElement = document.getElementById(selectId);
470
471      if (!selectElement) {
472        return;
473      }
474
475      const handleSelectFocus = (event) => {
476        const targetSelect = event.currentTarget;
477        const emptyOption = targetSelect.querySelector('option[value=""]');
478
479        if (!emptyOption) {
480          return;
481        }
482
483        emptyOption.style.display = "none";
484      };
485
486      const handleSelectBlur = (event) => {
487        const targetSelect = event.currentTarget;
488        const emptyOption = targetSelect.querySelector('option[value=""]');
489
490        if (!emptyOption) {
491          return;
492        }
493
494        if (targetSelect.value === "") {
495          emptyOption.style.display = "block";
496        }
497      };
498
499      selectElement.addEventListener("focus", handleSelectFocus);
500      selectElement.addEventListener("blur", handleSelectBlur);
501    };
502    initSelectPlaceholder("status-select");
503    initSelectPlaceholder("workshop-day1-select");
504  }
505
506  const descriptionSpoilers = document.querySelectorAll(
507    ".programm__item-description-spoiler",
508  );
509
510  if (descriptionSpoilers.length === 0) {
511    return;
512  }
513
514  descriptionSpoilers.forEach((descriptionSpoiler) => {
515    const toggleButton = descriptionSpoiler.querySelector(
516      ".programm__item-description-toggle",
517    );
518    const descriptionWrapper = descriptionSpoiler.querySelector(
519      ".programm__item-description-wrapper",
520    );
521
522    if (!toggleButton || !descriptionWrapper) {
523      return;
524    }
525
526    const initialButtonText = toggleButton.textContent.trim();
527
528    const isInitiallyOpen = descriptionSpoiler.classList.contains(
529      "programm__item-description-spoiler_open",
530    );
531    if (!isInitiallyOpen) {
532      descriptionWrapper.style.maxHeight = "0px";
533      descriptionWrapper.setAttribute("aria-hidden", "true");
534    } else {
535      descriptionWrapper.style.maxHeight = `${descriptionWrapper.scrollHeight}px`;
536      descriptionWrapper.setAttribute("aria-hidden", "false");
537      toggleButton.textContent = "Скрыть описание";
538    }
539
540    const handleToggleClick = () => {
541      const isOpen = descriptionSpoiler.classList.contains(
542        "programm__item-description-spoiler_open",
543      );
544
545      if (isOpen) {
546        descriptionSpoiler.classList.remove(
547          "programm__item-description-spoiler_open",
548        );
549        toggleButton.textContent = initialButtonText;
550        descriptionWrapper.style.maxHeight = "0px";
551        descriptionWrapper.setAttribute("aria-hidden", "true");
552      } else {
553        descriptionSpoiler.classList.add(
554          "programm__item-description-spoiler_open",
555        );
556        toggleButton.textContent = "Скрыть описание";
557        descriptionWrapper.style.maxHeight = `${descriptionWrapper.scrollHeight}px`;
558        descriptionWrapper.setAttribute("aria-hidden", "false");
559      }
560    };
561
562    toggleButton.addEventListener("click", handleToggleClick);
563  });
564});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.