1(function () { 2 function ready(fn) { 3 if (document.readyState !== 'loading') fn(); 4 else document.addEventListener('DOMContentLoaded', fn); 5 } 6 7 function initScheduleBlocks() { 8 var scriptVersion = '20260826-chapel-nikolay'; 9 var roots = Array.prototype.slice.call(document.querySelectorAll('[data-msdm-schedule]')); 10 if (!roots.length) return; 11 12 roots.forEach(function (root) { 13 if (root.getAttribute('data-msdm-schedule-initialized') === '1' 14 && root.getAttribute('data-msdm-schedule-version') === scriptVersion) { 15 if (typeof root.msdmScheduleRefresh === 'function') { 16 root.msdmScheduleRefresh(); 17 } 18 return; 19 } 20 21 root.setAttribute('data-msdm-schedule-version', scriptVersion); 22 23 var headDate = root.querySelector('[data-msdm-schedule-head-date]'); 24 var tabs = Array.prototype.slice.call(root.querySelectorAll('[data-msdm-schedule-tab]')); 25 var groups = Array.prototype.slice.call(root.querySelectorAll('[data-msdm-schedule-group]')); 26 var templeTabs = Array.prototype.slice.call(root.querySelectorAll('[data-msdm-schedule-temple-tab]')); 27 var templeTabWraps = Array.prototype.slice.call(root.querySelectorAll('[data-msdm-schedule-temple-tab-wrap]')); 28 var mobileTemple = root.querySelector('[data-msdm-schedule-temple-mobile]'); 29 var mobileTempleCurrent = root.querySelector('[data-msdm-schedule-temple-mobile-current]'); 30 var mobileTempleToggle = root.querySelector('[data-msdm-schedule-temple-mobile-toggle]'); 31 var mobileTempleMenu = root.querySelector('[data-msdm-schedule-temple-mobile-menu]'); 32 var templeTabsIndicator = root.querySelector('[data-msdm-schedule-temple-tabs-indicator]'); 33 var activeTempleGroup = ''; 34 var prevBtn = root.querySelector('[data-msdm-schedule-prev]'); 35 var nextBtn = root.querySelector('[data-msdm-schedule-next]'); 36 var swiperEl = root.querySelector('[data-msdm-schedule-swiper]'); 37 var fullVisibleItemsCount = 3; 38 var currentDayPastFullItemsCount = 2; 39 var nowMinutes = parseInt(root.getAttribute('data-msdm-schedule-now-minutes') || '', 10); 40 var todayYmd = root.getAttribute('data-msdm-schedule-today') || ''; 41 42 if (!tabs.length) return; 43 root.setAttribute('data-msdm-schedule-initialized', '1'); 44 if (isNaN(nowMinutes)) nowMinutes = 0; 45 46 function formatHeaderDate(ymd) { 47 var parts = (ymd || '').split('-'); 48 if (parts.length !== 3) return ymd; 49 50 var y = parseInt(parts[0], 10); 51 var m = parseInt(parts[1], 10); 52 var d = parseInt(parts[2], 10); 53 54 var months = { 55 1: 'ЯнваÑÑ', 2: 'ФевÑалÑ', 3: 'ÐаÑÑа', 4: 'ÐпÑелÑ', 5: 'ÐаÑ', 6: 'ÐÑнÑ', 56 7: 'ÐÑлÑ', 8: 'ÐвгÑÑÑа', 9: 'СенÑÑбÑÑ', 10: 'ÐкÑÑбÑÑ', 11: 'ÐоÑбÑÑ', 12: 'ÐекабÑÑ' 57 }; 58 59 return d + ' ' + (months[m] || '') + ' ' + y + ' г.'; 60 } 61 62 function getActiveIndex() { 63 var idx = tabs.findIndex(function (t) { 64 return t.getAttribute('aria-selected') === 'true'; 65 }); 66 return idx >= 0 ? idx : 0; 67 } 68 69 function getWindowStart(items) { 70 if (!items.length || items.length <= fullVisibleItemsCount) { 71 return 0; 72 } 73 74 var nextIndex = items.findIndex(function (item) { 75 var itemMinutes = parseInt(item.getAttribute('data-msdm-schedule-minutes') || '', 10); 76 return !isNaN(itemMinutes) && itemMinutes >= nowMinutes; 77 }); 78 79 if (nextIndex === -1) { 80 nextIndex = items.length; 81 } 82 83 var startIndex = nextIndex - (currentDayPastFullItemsCount + 1); 84 85 if (startIndex < 0) startIndex = 0; 86 87 return startIndex; 88 } 89 90 function getNextIndex(items) { 91 var nextIndex = items.findIndex(function (item) { 92 var itemMinutes = parseInt(item.getAttribute('data-msdm-schedule-minutes') || '',
9210); 93 return !isNaN(itemMinutes) && itemMinutes >= nowMinutes; 94 }); 95 96 return nextIndex === -1 ? items.length : nextIndex; 97 } 98 99 function getCurrentDayWindow(items) { 100 var lastFullStartIndex = Math.max(0, items.length - fullVisibleItemsCount); 101 var nextIndex = getNextIndex(items); 102 103 if (nextIndex >= items.length - 2) { 104 return { 105 startIndex: lastFullStartIndex > 0 ? lastFullStartIndex - 1 : lastFullStartIndex, 106 hasTopClip: lastFullStartIndex > 0, 107 hasBottomClip: false 108 }; 109 } 110 111 var startIndex = getWindowStart(items); 112 var fullItemsStartIndex = startIndex; 113 114 if (fullItemsStartIndex > lastFullStartIndex) { 115 fullItemsStartIndex = lastFullStartIndex; 116 } 117 118 var hasTopClip = fullItemsStartIndex > 0; 119 var hasBottomClip = (fullItemsStartIndex + fullVisibleItemsCount) < (items.length - 1); 120 121 if (!hasBottomClip && (fullItemsStartIndex + fullVisibleItemsCount) > items.length) { 122 fullItemsStartIndex = lastFullStartIndex; 123 hasTopClip = fullItemsStartIndex > 0; 124 } 125 126 return { 127 startIndex: hasTopClip ? fullItemsStartIndex - 1 : fullItemsStartIndex, 128 hasTopClip: hasTopClip, 129 hasBottomClip: hasBottomClip 130 }; 131 } 132 133 function getOtherDayWindow(items) { 134 return { 135 startIndex: 0, 136 hasTopClip: false, 137 hasBottomClip: items.length > (fullVisibleItemsCount + 1) 138 }; 139 } 140 141 function isCurrentDateGroup(group) { 142 var dateKey = group.getAttribute('data-msdm-schedule-group') || ''; 143 return dateKey !== '' && dateKey === todayYmd; 144 } 145 146 function getAvailableTempleGroups(group) { 147 var available = {}; 148 if (!group) return available; 149 150 group.querySelectorAll('[data-msdm-schedule-item][data-msdm-schedule-temple-group]').forEach(function (item) { 151 var templeGroup = item.getAttribute('data-msdm-schedule-temple-group') || ''; 152 if (templeGroup) available[templeGroup] = true; 153 }); 154 155 return available; 156 } 157 158 function updateTempleTabs(activeGroup) { 159 if (!templeTabs.length) return; 160 161 var available = getAvailableTempleGroups(activeGroup); 162 if (!available[activeTempleGroup]) { 163 activeTempleGroup = templeTabs.reduce(function (firstAvailable, tab) { 164 var value = tab.getAttribute('data-msdm-schedule-temple-tab') || ''; 165 return firstAvailable || (available[value] ? value : ''); 166 }, ''); 167 } 168 169 templeTabWraps.forEach(function (wrap) { 170 var tab = wrap.querySelector('[data-msdm-schedule-temple-tab]'); 171 var value = tab ? (tab.getAttribute('data-msdm-schedule-temple-tab') || '') : ''; 172 var isVisible = !!available[value]; 173 var isActive = isVisible && value === activeTempleGroup; 174 175 wrap.hidden = !isVisible; 176 wrap.classList.toggle('active', isActive); 177 if (tab) tab.setAttribute('aria-selected', isActive ? 'true' : 'false'); 178 }); 179 renderMobileTempleMenu(); 180 updateTempleIndicator(true); 181 } 182 183 function updateTempleIndicator(animate) { 184 if (!templeTabsIndicator || window.innerWidth <= 998) return; 185 var active = root.querySelector('[data-msdm-schedule-temple-tab][aria-selected="true"]'); 186 var tabsWrap = root.querySelector('.msdm-schedule-temple-tabs'); 187 if (!active || !tabsWrap) return; 188 var wrapRect = tabsWrap.getBoundingClientRect(); 189 var rect = active.getBoundingClientRect(); 190 if (!animate) templeTabsIndicator.style.transition = 'none'; 191 templeTabsIndicator.style.width = rect.width + 'px'; 192 templeTabsIndicator.style.height = rect.height + 'px'; 193 templeTabsIndicator.style.transform = 'translate3d(' + (rect.left - wrapRect.left) + 'px,' + (rect.top - wrapRect.top) + 'px,0)'; 194 if (!animate) requestAnimationFrame(function () { templeTabsIndicator.style.transition = ''; }); 195 } 196 197 function closeMobileTempleMenu() { 198 if (!mobileTempleMenu || !mobileTempleToggle) return; 199 mobileTempleMenu.hidden = true; 200 mobileTempleToggle.classList.remove('is-open'); 201 mobileTempleToggle.setAttribute('aria-expanded', 'false'); 202 } 203 204 function renderMobileTempleMenu() { 205 if (!mobileTempleCurrent || !mobileTempleMenu) return; 206 var active = root.querySelector('[data-msdm-schedule-temple-tab][aria-selected="true"]'); 207 mobileTempleCurrent.textContent = active ? active.textContent.trim() : ''; 208 mobileTempleMenu.innerHTML = '';
209 templeTabs.forEach(function (tab) { 210 if (tab.closest('[hidden]') || tab.getAttribute('aria-selected') === 'true') return; 211 var option = document.createElement('div'); 212 option.className = 'msdm-schedule-temple-mobile__option'; 213 option.setAttribute('role', 'button'); 214 option.setAttribute('tabindex', '0'); 215 var details = tab.closest('.msdm-schedule-temple-tabs__item').querySelector('.msdm-schedule-temple-tabs__details'); 216 option.innerHTML = '<span class="msdm-schedule-temple-mobile__option-main"><strong>' + tab.textContent.trim() 217 + '</strong><span class="msdm-schedule-temple-mobile__option-arrow" aria-hidden="true">âº</span></span>' 218 + '<span class="msdm-schedule-temple-mobile__option-meta">' + (details ? details.innerHTML : '') + '</span>'; 219 Array.prototype.slice.call(option.querySelectorAll('a')).forEach(function (link) { 220 link.target = '_blank'; 221 link.rel = 'noopener'; 222 link.addEventListener('click', function (event) { event.stopPropagation(); }); 223 }); 224 option.addEventListener('click', function () { 225 activeTempleGroup = tab.getAttribute('data-msdm-schedule-temple-tab') || ''; 226 var activeGroup = groups.find(function (group) { return group.style.display !== 'none'; }); 227 updateTempleTabs(activeGroup); 228 applyVisibleWindow(activeGroup); 229 closeMobileTempleMenu(); 230 }); 231 option.addEventListener('keydown', function (event) { 232 if (event.key === 'Enter' || event.key === ' ') option.click(); 233 }); 234 mobileTempleMenu.appendChild(option); 235 }); 236 } 237 238 function applyVisibleWindow(activeGroup) { 239 groups.forEach(function (group) { 240 var items = Array.prototype.slice.call(group.querySelectorAll('[data-msdm-schedule-item]')); 241 items.forEach(function (item) { 242 var matchesTemple = !activeTempleGroup 243 || (item.getAttribute('data-msdm-schedule-temple-group') || '')
243=== activeTempleGroup; 244 item.hidden = !matchesTemple; 245 item.classList.toggle('calendar-item_hidden', !matchesTemple); 246 }); 247 }); 248 249 root.classList.remove('msdm-schedule_has-top-fade', 'msdm-schedule_has-bottom-fade'); 250 251 if (!activeGroup) { 252 return; 253 } 254 255 var items = Array.prototype.slice.call(activeGroup.querySelectorAll('[data-msdm-schedule-item]')).filter(function (item) { 256 return !item.hidden; 257 }); 258 if (items.length <= fullVisibleItemsCount) { 259 return; 260 } 261 262 var isCurrentGroup = isCurrentDateGroup(activeGroup); 263 var windowConfig = isCurrentGroup ? getCurrentDayWindow(items) : getOtherDayWindow(items); 264 var startIndex = windowConfig.startIndex; 265 var hasTopClip = windowConfig.hasTopClip; 266 var hasBottomClip = windowConfig.hasBottomClip; 267 var visibleItemsCount = fullVisibleItemsCount + (hasTopClip ? 1 : 0) + (hasBottomClip ? 1 : 0); 268 var endIndex = startIndex + visibleItemsCount; 269 270 items.forEach(function (item, index) { 271 var isVisible = index >= startIndex && index < endIndex; 272 item.hidden = !isVisible; 273 item.classList.toggle('calendar-item_hidden', !isVisible); 274 }); 275 276 if (hasTopClip) { 277 root.classList.add('msdm-schedule_has-top-fade'); 278 } 279 280 if (hasBottomClip) { 281 root.classList.add('msdm-schedule_has-bottom-fade'); 282 } 283 } 284 285 function setActiveByIndex(index, options) { 286 if (index < 0 || index >= tabs.length) return; 287 var opts = options || {}; 288 var skipTabScroll = !!opts.skipTabScroll; 289 290 var dateKey = tabs[index].getAttribute('data-msdm-schedule-tab'); 291
292 tabs.forEach(function (btn, i) { 293 var isActive = (i === index); 294 btn.setAttribute('aria-selected', isActive ? 'true' : 'false'); 295 296 // на вÑÑкий ÑлÑÑай â ÑазнÑе ÑÑили могÑÑ Ð¶Ð´Ð°ÑÑ ÑазнÑе клаÑÑÑ 297 btn.classList.toggle('is-active', isActive); 298 btn.classList.toggle('active', isActive); 299 }); 300 301 var activeGroup = null; 302 groups.forEach(function (g) { 303 var isActive = g.getAttribute('data-msdm-schedule-group') === dateKey; 304 g.style.display = isActive ? '' : 'none'; 305 if (isActive) { 306 activeGroup = g; 307 } 308 }); 309 310 updateTempleTabs(activeGroup); 311 applyVisibleWindow(activeGroup); 312 313 if (headDate) headDate.textContent = formatHeaderDate(dateKey); 314 315 // ÑкÑолл Ñабов к акÑÐ¸Ð²Ð½Ð¾Ð¼Ñ 316 if (skipTabScroll) { 317 return; 318 } 319 320 if (swiper && typeof swiper.slideTo === 'function') { 321 swiper.slideTo(index); 322 } else { 323 tabs[index].scrollIntoView({behavior: 'smooth', inline: 'center', block: 'nearest'}); 324 } 325 } 326 327 // клики по Ñабам
328 tabs.forEach(function (btn, index) { 329 btn.addEventListener('click', function () { 330 setActiveByIndex(index); 331 }); 332 }); 333 334 templeTabs.forEach(function (btn) { 335 btn.addEventListener('click', function () { 336 var templeGroup = btn.getAttribute('data-msdm-schedule-temple-tab') || ''; 337 if (!templeGroup || templeGroup === activeTempleGroup) return; 338 339 activeTempleGroup = templeGroup; 340 var activeGroup = groups.find(function (group) { 341 return group.style.display !== 'none'; 342 }); 343 updateTempleTabs(activeGroup); 344 applyVisibleWindow(activeGroup); 345 }); 346 }); 347 348 if (mobileTempleToggle && mobileTempleMenu) { 349 mobileTempleToggle.addEventListener('click', function () { 350 var isOpen = mobileTempleMenu.hidden; 351 mobileTempleMenu.hidden = !isOpen; 352 mobileTempleToggle.classList.toggle('is-open', isOpen); 353 mobileTempleToggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); 354 }); 355 document.addEventListener('click', function (event) { 356 if (mobileTemple && !mobileTemple.contains(event.target)) closeMobileTempleMenu(); 357 }); 358 } 359 360 // ÑÑÑелки пеÑеклÑÑаÑÑ ÑÐ°Ð±Ñ 361 if (prevBtn) { 362 prevBtn.addEventListener('click', function (e) { 363 e.preventDefault(); 364 var i = getActiveIndex(); 365 if (i > 0) setActiveByIndex(i - 1); 366 }); 367 } 368 369 if (nextBtn) { 370 nextBtn.addEventListener('click', function (e) { 371 e.preventDefault(); 372 var i = getActiveIndex(); 373 if (i < tabs.length - 1) setActiveByIndex(i + 1); 374 }); 375 } 376 377 // клик по каÑÑоÑке ведÑÑ Ð½Ð° data-link 378 root.addEventListener('click', function (e) { 379 if (e.target.closest('a')) return; 380 381 var item = e.target.closest('.calendar-item[role="link"]'); 382 if (!item || !root.contains(item)) return; 383 384 var link = item.getAttribute('data-link') || ''; 385 if (!link) return; 386 387 window.location.href = link; 388 }); 389 390 // Swiper (еÑли подклÑÑен) 391 var swiper = null; 392 if (window.Swiper && swiperEl) { 393 try { 394 if (swiperEl.swiper) { 395 swiper = swiperEl.swiper; 396 } else { 397 swiper = new window.Swiper(swiperEl, { 398 slidesPerView: 3, 399 spaceBetween: 22, 400 watchOverflow: true, 401 breakpoints: { 402 768: { 403 slidesPerView: 7, 404 } 405 }, 406 }); 407 } 408 } catch (err) { 409 swiper = null; 410 } 411 } 412 413 // гаÑанÑиÑÑем коÑÑекÑнÑÑ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ Ð°ÐºÑивного Ñаба 414 setActiveByIndex(getActiveIndex(), {skipTabScroll: true}); 415 requestAnimationFrame(function () { updateTempleIndicator(false); }); 416 root.msdmScheduleRefresh = function () {
417 setActiveByIndex(getActiveIndex(), {skipTabScroll: true}); 418 }; 419 window.addEventListener('resize', function () { updateTempleIndicator(false); }); 420 }); 421 } 422 423 ready(initScheduleBlocks); 424 425 if (window.BX && typeof window.BX.addCustomEvent === 'function') { 426 window.BX.addCustomEvent('onFrameDataReceived', function () { 427 window.setTimeout(initScheduleBlocks, 0); 428 }); 429 } 430 431 if ('MutationObserver' in window) { 432 var observerTimer = 0; 433 var observer = new MutationObserver(function (mutations) { 434 var hasScheduleChanges = mutations.some(function (mutation) { 435 return Array.prototype.slice.call(mutation.addedNodes || []).some(function (node) { 436 if (!node || node.nodeType !== 1) return false; 437 438 return (node.matches && node.matches('[data-msdm-schedule]')) 439 || (node.querySelector && node.querySelector('[data-msdm-schedule]')); 440 }); 441 }); 442 443 if (!hasScheduleChanges) return; 444 445 window.clearTimeout(observerTimer); 446 observerTimer = window.setTimeout(initScheduleBlocks, 0); 447 }); 448 449 ready(function () { 450 if (document.body) { 451 observer.observe(document.body, {childList: true, subtree: true}); 452 } 453 }); 454 } 455 456 window.setTimeout(initScheduleBlocks, 100); 457 window.setTimeout(initScheduleBlocks, 500); 458 window.setTimeout(initScheduleBlocks, 1500); 459 window.msdmInitScheduleBlocks = initScheduleBlocks; 460})();
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.