PageSourceSearch

https://profi-centr.kz/assets/js/site.js

js profi-centr.kz collected 2026-10-05 00:04:20 UTC 2,719 bytes, 89 lines download raw bytes

1
2"use strict";
3document.documentElement.classList.add("js");
4
5const state = {
6  language: localStorage.getItem("profiLanguage") || "ru",
7  content: null
8};
9
10const $ = (s, root=document) => root.querySelector(s);
11const $$ = (s, root=document) => [...root.querySelectorAll(s)];
12
13async function loadContent(){
14  const r = await fetch("data/site-content.json", {cache:"no-store"});
15  if(!r.ok) throw new Error("site-content.json");
16  state.content = await r.json();
17  applyLanguage();
18}
19
20function applyLanguage(){
21  if(!state.content) return;
22  const t = state.content[state.language];
23  document.documentElement.lang = state.language === "kk" ? "kk" : "ru";
24
25  $$("[data-i18n]").forEach(el => {
26    const key = el.dataset.i18n;
27    if(Object.prototype.hasOwnProperty.call(t,key)) el.textContent = t[key];
28  });
29
30  $$("[data-lang-btn]").forEach(btn => {
31    const active = btn.dataset.langBtn === state.language;
32    btn.classList.toggle("active", active);
33    btn.setAttribute("aria-pressed", active ? "true":"false");
34  });
35
36  const year = $("#currentYear");
37  if(year) year.textContent = new Date().getFullYear();
38
39  window.dispatchEvent(new CustomEvent("profi-language-change", {detail:{language:state.language, content:t}}));
40}
41
42$$("[data-lang-btn]").forEach(btn => {
43  btn.addEventListener("click", () => {
44    state.language = btn.dataset.langBtn;
45    localStorage.setItem("profiLanguage", state.language);
46    applyLanguage();
47  });
48});
49
50const menuBtn = $("#menuBtn");
51const mobileNav = $("#mobileNav");
52
53function closeMenu(){
54  if(!menuBtn || !mobileNav) return;
55  menuBtn.classList.remove("active");
56  mobileNav.classList.remove("open");
57  menuBtn.setAttribute("aria-expanded","false");
58  document.body.classList.remove("menu-open");
59}
60if(menuBtn && mobileNav){
61  menuBtn.addEventListener("click", () => {
62    const open = mobileNav.classList.toggle("open");
63    menuBtn.classList.toggle("active", open);
64    menuBtn.setAttribute("aria-expanded", open ? "true":"false");
65    document.body.classList.toggle("menu-open", open);
66  });
67  $$("#mobileNav a").forEach(a => a.addEventListener("click", closeMenu));
68  window.addEventListener("resize", () => { if(innerWidth > 1020) closeMenu(); });
69}
70
71function initReveal(){
72  const items = $$(".reveal");
73  if(!("IntersectionObserver" in window)){
74    items.forEach(i => i.classList.add("visible"));
75    return;
76  }
77  const io = new IntersectionObserver(entries => {
78    entries.forEach(e => {
79      if(e.isIntersecting){
80        e.target.classList.add("visible");
81        io.unobserve(e.target);
82      }
83    });
84  }, {threshold:.12});
85  items.forEach(i => io.observe(i));
86}
87document.addEventListener("DOMContentLoaded", initReveal);
88
89loadContent().catch(console.error);

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.