Connect with us

Привет, что-то ищете?

The Times On Ru
  1. The Times On RU
  2. /
  3. Бизнес
  4. /
  5. Прогнозируй или проиграешь

Бизнес

Прогнозируй или проиграешь

Осенью в России пройдут выборы депутатов Государственной Думы 9-го созыва. «Коммерсант» запускает «политический лотерею», предоставляющую читателям возможность прогнозировать результаты партий, явку, активность избирателей в регионах и т. д. Ваши «рейтинги-прогнозы» будут опубликованы на страницах «Коммерсанта», а после выборов те, кто наиболее точно предскажет их исход, получат ценные (но некоммерческие) призы.

Зайдите в личный кабинет, сделайте хотя бы один прогноз и получите приз как лучший аналитик* Правила участия Чтобы принять участие в конкурсе прогнозов, достаточно зарегистрироваться на сайте «Коммерсанта» и заполнить любой из предложенных пунктов. Прогноз можно уточнять, но не чаще одного раза в сутки. «Тотализатор» закрывается за неделю до начала голосования на выборах 18 сентября. <уш/><уш/> Выборы в нижнюю палату парламента проводятся по смешанной системе: 225 мандатов распределяются между партиями в соответствии с их долей голосов по всей стране, другая половина — между победителями в местных одномандатных округах. <б>Чтобы читатели могли глубже погрузиться в закулисье избирательной кампании и сделать максимально точный прогноз, еженедельник «Коммерсантъ» публикует экспертные аналитические материалы о партийной деятельности в рамках спецпроекта «Навстречу выборам». <уш/><уш/>Те, чьи прогнозы наиболее близки к официальным результатам голосования, получат сувениры-сюрпризы от участников избирательного процесса. Мы объявим победителей в общем зачете и в индивидуальных номинациях — за наиболее точный прогноз явки (вопросы №1-3), результативности партии (№4-7) и фракции, добавившей места (№8). Расчеты будут основываться на данных итогового протокола Центральной избирательной комиссии.

Ваш прогноз сохранен!

Сравните это с общими ожиданиями или прочитайте обзор эксперта.
Завтра вы сможете уточнить свой выбор. Повышение точности Повышайте точность прогнозов с помощью аналитики «Коммерсанта»

Ваш прогноз

Какую итоговую явку избирателей в стране зафиксирует Центризбирком?

Прогноз читателей

№1

Где и какая будет самая высокая явка? Субъект Российской Федерации

Прогноз читателей

№2

Где и какая будет самая низкая явка? Субъект Российской Федерации

Прогноз читателей

№3

Какой процент голосов партии получат в одном округе?

Прогноз читателей

№4

Выберите один регион, результаты которого вы хотите предсказать. Сколько голосов получат партии в списке? Субъект Российской Федерации Вечеринка + Добавить партию

Прогноз читателей

№5

Где победитель покажет лучший результат и какой? Субъект Российской Федерации

Прогноз читателей

№6

Где победившая сторона покажет худший результат и какой? Субъект РФ

Прогноз читателей

№7

Какая партия покажет наибольший прирост парламентских мандатов? Вечеринка

Прогноз читателей

№8

Отдайте свой голос

Прогноз можно менять раз в сутки.

Войдите, чтобы принять участие в игре

Вечеринка const truncateNumber = (число, десятичные дроби = 1) =>{ f (!num && num !== 0) возвращает ноль return Math.trunc(num * Math.pow(10, десятичные дроби))/Math.pow(10, десятичные дроби); } functon ntEle2026Felds(scope = document) { const nputs =scope.querySelectorAll(‘.ele2026_feld__nput’); nputs.forEach((nput) => { f (nput.dataset.ele2026FeldInted === ‘true’) return; nput.dataset.ele2026FeldInted = ‘истина’; const label = nput.closest(‘.ele2026_feld’); const brck = nput.closest(‘.ele2026_house__brck’); f (!label || !brck) return; const getErrorElement = () => { const next = label.nextElementSblng; вернуться к следующему && next.classLst.contans(‘ele2026_feld__error’) ? next: null; }; const showError = (сообщение) =>{ пусть ошибка = getErrorElement(); е (! ошибка) { ошибка = document.createElement(‘p’); error.className = ‘ele2026_feld__error’; label.after (ошибка); } error.textContent = сообщение; brck.classLst.add(‘ele2026_house__brck—error’); }; const hdeError = () => { константная ошибка = getErrorElement(); е (ошибка) { ошибка.удалить(); } brck.classLst.remove(‘ele2026_house__brck—error’); }; constnormalzeValue = (значение) => { возвращаемое значение.replace(/s+/g, »).replace(/,/g, ‘.’); }; const sNumercLke = (значение) => { return /^-?(?:d+|d*.d+)$/.test(value); }; const formatValue = (число) =>{ const округленный = truncateNumber(число) return Strng(округлено).replace(‘.’, ‘,’); }; const valdateInput = () =>{ const rawValue = nput.value.trm(); е (!rawValue) { nput.setCustomValdty(»); хдеОшибка(); возвращаться; } constnormalzedValue =normalzeValue(rawValue); пусть сообщение = »; е (!sNumercLke(normalzedValue)) { message = ‘Можно вводить только цифры’; } else f (nput.getAttrbute(‘nputmode’) === ‘number’ && !Number.sInteger(+normalzedValue)) { message = ‘Можно вводить только целые числа’; } еще { константное число = Число (normalzedValue); е (число < 0) { message = 'Значение должно быть не менее 0'; } else f (число >nput.max) { message = `Значение не должно быть больше ${nput.max}`; } еще { nput.value = formatValue(число); } } nput.setCustomValdty(сообщение); ж (сообщение) { showError (сообщение) nput.closest(‘[data-queston-d]’).scrollIntoVew() } еще { хдеОшибка(); } }; nput.addEventLstener(‘blur’, valdateInput); nput.addEventLstener(‘nput’, () => { nput.setCustomValdty(»); хдеОшибка(); }); }); } ntEle2026Felds(); (() =>{ const INSTANCES = новый WeakMap(); класс Ele2026Выберите { конструктор (корень, индекс = 0) { е (!root || INSTANCES.has(root)) { вернуть INSTANCES.get(корень); } ths.root = корень; ths.natve = root.querySelector(«.ele2026_select__natve»); f (!ths.natve) возврат; ths.ndex = индекс; ths.placeholder = root.dataset.placeholder || «Выбирать»; ths.lstId = `ele2026-select-lst-${ndex + 1}`; ths.button = ноль; ths.label = ноль; ths.lst = ноль; ths.tems = []; ths.sOpen = ложь; ths.actveIndex = -1; ths.sDestroyed = ложь; ths.sRenderng = ложь; ths.onDocumentClck = ths.onDocumentClck.bnd(ths); ths.onNatveChange = ths.onNatveChange.bnd(ths); ths.onButtonClck = ths.onButtonClck.bnd(ths); ths.onButtonKeydown = ths.onButtonKeydown.bnd(ths); ths.onMutatons = ths.onMutatons.bnd(ths); ths.render(); ths.bnd(); ths.observe(); INSTANCES.set(корень, тыс.); } sSelectDsabled() { вернуть ths.natve.dsabled; } getFrstEnabledIndex() { return ths.tems.fndIndex((tem) => !tem.dsabled); } getLastEnabledIndex() { for (let = ths.tems.length — 1; >= 0; —) { f (!ths.tems[].dsabled) return ; } вернуть -1; } getSelectedOpton() { const ndex = ths.natve.selectedIndex; индекс возврата >= 0 ? ths.natve.optons[ndex] : null; } бнд() { document.addEventLstener(«clck», ths.onDocumentClck); ths.natve.addEventLstener(«изменение», ths.onNatveChange); } разблокировать() { document.removeEventLstener(«clck», ths.onDocumentClck); ths.natve.removeEventLstener(«изменить», ths.onNatveChange); е (эта кнопка) { ths.button.removeEventLstener( «щелк» ths.onButtonClck ); ths.button.removeEventLstener( «нажатие клавиши», ths.onButtonKeydown ); } } наблюдать() { ths.observer = новый MutatonObserver(ths.onMutatons); ths.observer.observe(ths.natve, { chldLst: правда, поддерево: правда, атрибуты: правда, attrbuteFlter: [«dsabled», «selected», «label», «value»], данные персонажа: правда, }); } dsconnectObserver() { f (!ths.observer) return; ths.observer.dsconnect(); ths.observer = ноль; } onMutatons (мутатоны) { f (ths.sDestroyed || ths.sRenderng) return; const mustRerender = mutatons.some((мутатон) =>{ f (mutaton.type === «chldLst») возвращает true; f (mutaton.type === «characterData») возвращает true; f (mutaton.type === «атрибуты») { константная цель = mutaton.target; f (цель === ths.natve) { return mutaton.attrbuteName === «dsabled»; } f (target.tagName === «ОПЦИЯ») { вернуть [ «dsabled», «выбранный», «этикетка», «ценность», ].ncludes(mutaton.attrbuteName); } } вернуть ложь; }); f (!shouldRender) return; ths.render(); } onNatveChange() { f (ths.sDestroyed) возврат; ths.syncDsabledState(); ths.syncSeletonFromNatve(); } onDocumentClck (е) { f (ths.sDestroyed) возврат; f (!ths.root.contans(e.target) && ths.sOpen) { ths.close(ложь); } } onButtonClck() { f (ths.sSelectDsabled()) return; ths.sOpen ? ths.close() : ths.open(); } onButtonKeydown (е) { f (ths.sSelectDsabled()) return; переключатель (e.key) { случай «Стрелка вниз»: е.preventDefault(); е (!ths.sOpen) ths.open(); иначе ths.move(1); перерыв; случай «СтрелкаВверх»: е.preventDefault(); е (!ths.sOpen) ths.open(); иначе ths.move(-1); перерыв; случай «Ввод»: случай » «: е.preventDefault(); е (!ths.sOpen) { ths.open(); } еще f ( ths.actveIndex >= 0 && !ths.tems[ths.actveIndex]?.dsabled ) { ths.selectIndex(ths.actveIndex); этос.закрыть(); } перерыв; кейс «Домой»: е.preventDefault(); е (!ths.sOpen) ths.open(); ths.setActve(ths.getFrstEnabledIndex()); перерыв; случай «Конец»: е.preventDefault(); е (!ths.sOpen) ths.open(); ths.setActve(ths.getLastEnabledIndex()); перерыв; кейс «Побег»: е (ths.sOpen) { е.preventDefault(); этос.закрыть(); } перерыв; корпус «Таб»: е (ths.sOpen) { ths.close(ложь); } перерыв; } } обеспечениеКнопка() { const oldButton = ths.root.querySelector( «.ele2026_select__button» ); е (oldButton) { oldButton.removeEventLstener(«clck», ths.onButtonClck); oldButton.removeEventLstener( «нажатие клавиши», ths.onButtonKeydown ); стараяКнопка.удалить(); } ths.button = document.createElement(«кнопка»); ths.button.type = «кнопка»; ths.button.className = «ele2026_select__button»; ths.button.setAttrbute(«ara-haspopup», «lstbox»); ths.button.setAttrbute(«ara-expanded», Strng(ths.sOpen)); ths.button.setAttrbute(«ara-controls», ths.lstId); ths.label = document.createElement(«span»); ths.label.className = «ele2026_select__label»; ths.button.appendChld(ths.label); ths.natve.nsertAdjacentElement(«afterend», ths.button); ths.button.addEventLstener(«clck», ths.onButtonClck); ths.button.addEventLstener(«keydown», ths.onButtonKeydown); } rebuldLst() { ths.lst?.remove(); ths.lst = document.createElement(«ul»); ths.lst.className = «ele2026_select__lst»; ths.lst.d = ths.lstId; ths.lst.setAttrbute(«роль», «lstbox»); ths.lst.tabIndex = -1; ths.tems = Array.from(ths.natve.optons).map( (natveOpton, индекс) =>{ const l = document.createElement(«l»); const dsabled = natveOpton.dsabled; const sPlaceholder = natveOpton.value === «»; l.className = «ele2026_select__opton»; l.setAttrbute(«роль», «оптон»); l.dataset.ndex = Strng(ndex); l.dataset.optonId = natveOpton.d; l.dataset.value = natveOpton.value; л.tabIndex = -1; l.textContent = natveOpton.textContent ?? «»; е (dsabled) { l.classLst.add(«s-dsabled»); l.setAttrbute(«ara-dsabled», «true»); } е (sPlaceholder) { l.classLst.add(«s-placeholder»); } l.addEventLstener(«clck», () => { f (ths.sSelectDsabled() || dsabled) return; ths.selectIndex(ndex); этос.закрыть(); }); l.addEventLstener(«mousemove», () =>{ f (!ths.sOpen || dsabled) return; ths.setActive(ndex); }); ths.lst.appendChld(л); вернуть { эль: л, натвеОптон, индекс инвалид }; } ); ths.button.nsertAdjacentElement(«afterend», ths.lst); } syncDsabledState() { const dsabled = ths.sSelectDsabled(); ths.root.classLst.toggle(«s-dsabled», dsabled); ths.button.dsabled = dsabled; ths.button.setAttrbute(«ara-dsabled», Strng(dsabled)); f (dsabled && ths.sOpen) { ths.close(ложь); } } syncSeletonFromNatve() { const selectedIndex = ths.natve.selectedIndex; const selectedOpton = ths.getSelectedOpton(); константа имеетЗначение = выбранныйИндекс >= 0 && выбраноОптон && selectedOpton.value !== «»; е (имеет значение) { ths.label.textContent = selectedOpton.textContent; ths.root.classLst.add(«s-selected»); ths.actveIndex = selectedOpton.dsabled ? ths.getFrstEnabledIndex() : выбранныйИндекс; } еще { ths.label.textContent = ths.placeholder; ths.root.classLst.remove(«s-selected»); ths.actveIndex = ths.getFrstEnabledIndex(); } ths.syncItemsState(); } syncItemsState() { ths.tems.forEach(({ el, natveOpton, dsabled }, ndex) => { е (dsabled) { el.removeAttrbute(«ara-selected»); } еще { el.setAttrbute( «ара-выбрано», Strng(natveOpton.selected) ); } el.classLst.toggle( «с-действовать», индекс === ths.actveIndex ); }); } setActive (индекс) { f (индекс < 0 || индекс >= ths.tems.length) return; f (ths.tems[ndex].dsabled) return; ths.actveIndex = индекс; ths.syncItemsState(); ths.tems[ndex].el.scrollIntoVew({block: «ближайший» }); } перемещение (дельта) { f (!ths.tems.length) return; пусть следующий = ths.actveIndex; f (следующий < 0) следующий = ths.getFrstEnabledIndex(); f (следующий < 0) возврат; пусть охранник = 0; сделать { следующий += дельта; f (следующий < 0) следующий = ths.tems.length - 1; е (следующий >= ths.tems.length) next = 0; охранник++; } пока ( ths.tems[next].dsabled && охранник = 0 && выбраноОптон && !selectedOpton.dsabled && selectedOpton.value !== «» ) { ths.actveIndex = selectedIndex; } еще { ths.actveIndex = ths.getFrstEnabledIndex(); } ths.sOpen = правда; ths.root.classLst.add(«s-open»); ths.button.setAttrbute(«ara-expanded», «true»); ths.syncItemsState(); f (ths.actveIndex >= 0) { ths.tems[ths.actveIndex].el.scrollIntoVew({ блок: «ближайший», }); } } закрыть (returnFocus = true) { ths.sOpen = ложь; ths.root.classLst.remove(«s-open»); ths.button.setAttrbute(«ara-expanded», «false»); f (returnFocus && !ths.sSelectDsabled()) { эта.кнопка.фокус(); } } рендер() { f (ths.sDestroyed) возврат; ths.sRenderng = правда; const wasOpen = ths.sOpen; ths.ensureButton(); ths.rebuldLst(); ths.syncDsabledState(); ths.syncSeletonFromNatve(); е (!wasOpen) { ths.close(ложь); } еще f (ths.sSelectDsabled()) { ths.close(ложь); } еще { ths.sOpen = правда; ths.root.classLst.add(«s-open»); ths.button.setAttrbute(«ara-expanded», «true»); ths.syncItemsState(); } ths.sRenderng = ложь; } уничтожить() { f (ths.sDestroyed) возврат; ths.sDestroyed = правда; ths.dsconnectObserver(); ths.unbnd(); ths.lst?.remove(); эта.кнопка?.remove(); ths.root.classLst.remove( «с-открыть», «s-выбрано», «s-dsabled» ); ИНСТАНЦИИ.delete(ths.root); } } functon ntEle2026Selects (область = документ) { return Array.from(scope.querySelectorAll(«[data-select]»)) .map((корень, индекс) =>новый Ele2026Select(корень, индекс)) .flter(логическое значение); } wndow.Ele2026Select = { nt: ntEle2026Выбирает, получить (корень) { return INSTANCES.get(root) || нулевой; }, уничтожить (корень) { const nstance = INSTANCES.get(root); f (nstance) nstance.destroy(); }, }; ntEle2026Выбирает(); })(); (асинхронная функция() { const SITEKEY = ‘ysc1_V3g8MjuvrVFqTJS4m1Qbde68seTWeD38k2dgofFV00d2c29c’ const ALREADY_VOTED = ‘ele2026_voted’ const GET_DATA_API = ‘/e2026/get’ const captchaReload = document.querySelector(‘.captcha-reload’) const voicesForm = document.querySelector(‘.ele2026_forecast’) const submtButton = voicesForm.querySelector(‘.ele2026_house__basement_button’) constarchveTpl = document.querySelector(‘#archve-template’) константная пустая форма = { yaCaptchaResponse: ноль, прогноз: { TurnoutGen: ноль, TurnoutHghRegId: ноль, TurnoutHghProc: ноль, TurnoutLowRegId: ноль, TurnoutLowProc: ноль, Хгествнрегид: ноль, ХгестВнПрок: ноль, Самый низкийWnRegId: ноль, Самый низкийWnProc: ноль, Макспартиинкид: ноль, Макспартиинккуан: ноль, ByPartyLstsRegId: ноль, Вечеринки: [], Regbypartylsts: [], } } пусть formData = JSON.parse(JSON.strngfy(emptyForm)) пусть captchaWdgetId = ноль пусть sCaptchaLoaded = ложь пусть sValdatonError = false пусть SAPIError = ложь пусть canSendForm = false пусть regonsLst = [] пусть partsLst = [] пусть userData = ноль пусть sArchveOpen = false пусть ArchveLst = [] пусть actveSectionId = ноль const getCooke = (имя) =>{ const match = document.cooke.match(new RegExp(‘(^| )’ + name + ‘=([^;]+)’)); вернуть совпадение ? match[2] : null; }; const setCooke = (имя, значение, секунды) =>{ пусть выражается = «»; е (секунды) { константная дата = новая дата(); date.setTme(date.getTme() + (секунды * 1000)); expres = «; expres=» + date.toUTCStrng(); } document.cooke = name + «=» + (value || «») + expres + «; path=/»; } const showCrtcalError = () =>{ let подвал = voicesForm.querySelector(‘.ele2026_house__basement’) f (!подвал) возврат подвал.nnerHTML = » пусть ошибка = document.createElement(‘p’) error.className = ‘ele2026_house__basement_error’ error.textContent = ‘Произошла неизвестная ошибка. Пожалуйста, обновите страницу или попробуйте проголосовать позже» подвал.append (ошибка) } const showSuccess = () =>{ const DoneSection = voicesForm.querySelector(‘.ele2026_forecast_done’) f (!doneSection) возврат DoneSection.classLst.remove(‘hdden’) voicesForm.querySelector(‘.ele2026_forecast__rules’)?.scrollIntoVew() } const showCommonError = (сообщение) => { let подвал = voicesForm.querySelector(‘.ele2026_house__basement’) f (!подвал) возврат подвал.querySelector(‘.ele2026_house__basement_error’)?.remove() пусть ошибка = document.createElement(‘p’) error.className = ‘ele2026_house__basement_error’ error.textContent = сообщение подвал.append (ошибка) } const showNotAuthorzed = () =>{ showCommonError(‘Войдите, чтобы проголосовать’) } const showServerValdatonError = (errorObj) =>{ Object.keys(errorObj).forEach(f => { const feld = f.replace(‘прогноз.’, ») const msg = errorObj[f][0] пусть ФельдЭл f (feld === ‘Partylstres’) { feldEl = voicesForm.querySelector(‘[data-queston-d=»4″]’) } else f (feld === ‘Partylstres’) { feldEl = voicesForm.querySelector(‘[data-queston-d=»5″]’) } еще { feldEl = voicesForm.querySelector(`[name=»${feld}»]`) } submtError (feldEl, сообщение) feldEl.scrollIntoVew() }) } const fetchData = async (url, sCrtcal = false) =>{ попробуй { константный ответ = awat fetch (url) е (ответ.редректированный) { показатьNotAuthorized() вернуть ноль } е (!response.ok) { выдать новую ошибку(`Статус ${response.status}`) } return (AWAT response.json()) || ноль } поймать (ошибка) { е (sCrtcal) { SAPIError = правда showCrtcalError() выдать новую ошибку(`Ошибка получения данных: ${error.message}`) } } } const getCatalogData = async (catalogId) => { return awat fetchData(`https://wt.kommersant.ru/ap/v1/catalog/get?catalogId=${catalogId}&start=0&lmt=1000`, true) } const getChartData = асинхронный (метод) =>{ return awat fetchData(`/e2026/${method}`) } const getRegonsLst = async() =>{ regonsLst = (awat getCatalogData(122))?.data f (!regonsLst?.length) { SAPIError = правда showCrtcalError() } еще { regonsLst = regonsLst.flter(r => r.IsShow) } } const getPartesLst = async() => { partesLst = (awat getCatalogData(1319))?.data f (!partesLst?.length) { SAPIError = правда showCrtcalError() } еще { partesLst = partesLst.flter(r => r.IsShow) } } const flllRegons = (селектор) => { regonsLst.forEach(regon =>{ f (!regon.IsShow) возврат пусть opton = document.createElement(‘opton’) opton.textContent = regon.Name opton.d = regon.Id selector.appendChld(оптон) }) } const fllPartes = (селектор) => { partesLst.forEach(party => { f (!party.IsShow) возврат пусть opton = document.createElement(‘opton’) opton.textContent = party.Name opton.d = party.Id selector.appendChld(оптон) }) } const fllNotSelectedPartes = (newGroup) => { const secton_5 = voicesForm.querySelector(‘[data-queston-d=»5″]’) const allGroups = secton_5.querySelectorAll(‘.ele2026_house__group’) const allSelectedPartes = [] //сохраняем все уже выбранные игры в вопросе №5 allGroups.forEach(группа =>{ const partyId = +group.querySelector(‘select’)?.optonId || ноль !!partyId && allSelectedPartes.push(partyId) }) allSelectedPartes.length === partsLst.length ? secton_5.querySelector(‘.ele2026_house__brck_add’).classLst.add(‘hdden’) : secton_5.querySelector(‘.ele2026_house__brck_add’).classLst.remove(‘hdden’) const fllInnerGroup = (группа) =>{ const selector = group.querySelector(‘select’) ?? группа const partyId = +selector?.optonId || ноль whle(selector.frstChld) { selector.removeChld(selector.frstChld); } //сначала добавляем заполнитель пусть opton = document.createElement(‘opton’) opton.textContent = ‘Вечеринка’ оптон.значение = «» е (!partyId) { opton.selected = правда } selector.appendChld(оптон) partesLst.forEach(party => { f (allSelectedPartes.ncludes(party.Id) && party.Id !== partyId) return пусть opton = document.createElement(‘opton’) opton.textContent = party.Name opton.d = party.Id е (party.Id === partyId) { opton.selected = правда selector.optonId = идентификатор вечеринки } selector.appendChld(оптон) }) } //заполняем выпадающие списки партий без учета ранее выбранных allGroups.forEach(fllInnerGroup) !!newGroup && fllInnerGroup(новаягруппа) } const fllSelectors = () =>{ voicesForm.querySelectorAll(‘.ele2026_select__regon’).forEach(fllRegons) voicesForm.querySelectorAll(‘.ele2026_select__party’).forEach(fllPartes) } const sToday = (someDate) => { f (!someDate) return; const getDate = новая дата(+someDate) f (!(getDate nstanceof Date) || sNaN(getDate.getTme())) return const сегодня = новая дата(); return getDate.getDate() === Today.getDate() && getDate.getMonth() === Today.getMonth() && getDate.getFullYear() === Today.getFullYear(); } const captchaLoad = () => { const eleCaptchaContaner = voicesForm.querySelector(‘.js-lk-form-restore-captcha-contaner’) captchaWdgetId = wndow.smartCaptcha.render(eleCaptchaContaner, { обратный вызов: (токен) =>{ f (typeof token === ‘strng’ && token.length >0) { formData.yaCaptchaResponse = токен отправитьДанные() } wndow.smartCaptcha.reset(captchaWdgetId); }, гл: ‘ру’, нвсбле: правда, стекки: SITEKEY, вебвью: wndow.kommersant.sWebVew, }); sCaptchaLoaded = правда; }; функция startCountdown (tmestamp) { функция formatTme(ms) { const totalSeconds = Math.max(0, Math.floor(ms/1000)); const часы = Math.floor(totalSeconds/3600); const mnutes = Math.floor((totalSeconds % 3600)/60); константные секунды = TotalSeconds% 60; вернуть [ Strng(часы).padStart(2, ‘0’), Strng(минуты).padStart(2, ‘0’), Strng(секунды).padStart(2, ‘0’) ].jon(‘:’); } функция updateButton (кнопка) { const dff = tmestamp — Date.now() f (dff { const mustContnue = updateButton(submtButton) е (!shouldContnue) { ClearInterval (tmerId) } }, 1000) } const EnableVotng = () => { voicesForm.querySelectorAll(` .ele2026_feld > вход, select.ele2026_select__natve, button.ele2026_house__basement_button `)?.forEach(el =>el.dsabled = ложь) submtButton.classLst.remove(‘s_countdown’) submtButton.dsabled = ложь submtButton.textContent = ‘Отправить голос’ voicesForm.querySelectorAll(‘.ele2026_house__basement_note’).forEach(note =>{ note.classLst.contans(‘общий’) ? note.classLst.remove(‘hdden’) : note.classLst.add(‘hdden’) }) } const dsableVotng = (sCountng = false) => { е(sCountng) { const завтра = новая дата() завтра.setDate((новая дата()).getDate() + 1) завтра.setHours(0, 0, 0, 0) startCountdown(завтра) } voicesForm.querySelectorAll(` .ele2026_feld > вход, select.ele2026_select__natve, button.ele2026_house__basement_button `)?.forEach(el => el.dsabled = true) } const loadScrpt = (url) => { вернуть новое обещание((разрешить, отклонить) =>{ е (wndow.Hghcharts) { вернуть решение (wndow.Hghcharts); } let scrpt = document.createElement(‘scrpt’); scrpt.src = URL; scrpt.async = правда; document.head.appendChld(сценарий); константа lmt = 10; пусть повторит = 0; const ntervalID = setInterval(() => { е (wndow.Hghcharts) { ClearInterval (ID интервала); разрешить (wndow.Hghcharts); } else f (++retry >= lmt) { ClearInterval (ID интервала); ignore(new Error(‘Превышен лимит времени загрузки Hghcharts’)); } }, 500); }); }; const ntHghcharts = async () =>{ попробуй { awat loadScrpt(‘https://v.kommersant.ru/ContentFlex/js/custom/lbs/hghchats/hghcharts-v12.5.0.js’); } поймать (ошибка) { showCrtcalError() console.log(ошибка) throw new Error(‘Ошибка загрузки hghcharts.js’); } } const drawChartTurnout = (rawData) => { const secton = voicesForm.querySelector(`[data-queston-d=»1″]`) f (!section || !rawData?.length) return secton.querySelector(‘.ele2026_house__meda’)?.classLst.remove(‘hdden’) const formatedData = rawData.map((tem) =>{ вернуть [ новая дата(tem.date).getTme(), +tem.val ] }) Hghcharts.chart(section.querySelector(‘.ele2026_house__meda_chart’), { немного: { текст: незащищенный }, yAxs: { немного: { включено: ложь, }, ярлыки: { формат: ‘{value}%’, }, }, инструментp: { valueSuffx: ‘%’, }, хАкс: { введите: ‘dateme’, ярлыки: { форматтер: functon() { const curDate = новая дата (ths.value) return curDate.toLocaleStrng(‘ru-RU’, { день: ‘число’, месяц: ‘длинный’ }) } } }, сюжетОптонс: { серия: { метка: { ConnectorAllowed: ложь, }, маркер: { включено: ложь, }, } }, серия: [{ название: «Общая явка», данные: форматированные данные, }], }) } const getMaxVotes = (данные) => { вернуть data.reduce((a, b) =>{ let frst = новая дата(a?.count ?? a).getTme() пусть секунда = новая дата(b?.count ?? b).getTme() вернуть Math.max(первый, второй) }) } const getMnVal = (данные) => { return data.reduce((a, b) =>{ let frst = новая дата(a?.date ?? a).getTme() let второй = новая дата(b?.date ?? b).getTme() вернуть Math.mn(первый, второй) }) } //возвращает 5 лучших объектов по количеству голосов за все время //+ объект, за который проголосовал пользователь //всего: 6 (!) объектов или меньше const getTopFve = (данные, userObjectId) => { const ObjectId = Object.keys(данные) f (objectsId?.length +o) константные голоса = идентификатор объекта .map(d => {return { d, voices: getMaxVotes(data[d]) }}) .sort((a, b) => b.votes — a.votes) .flter(a => +ad !== +userObjectId) //оп 5 по количеству голосов const topFve = voices.slce(0, 5).map(v =>+в.д) //+ пользовательский объект !!userObjectId && topFve.push(+userObjectId) вернуться в топFve } const drawChart = (rawData, sId, userData) => { const secton = voicesForm.querySelector(`[data-queston-d=»${sId}»]`) const sPartySection = sId === 8 const каталог = [4, 5, 8].ncludes(sId) ? partesLst : regonsLst f (!section || !rawData?.length) return пусть regonsData = {} rawData.forEach(данные =>{ const regonAsIndex = data.objectId.toStrng() е (!regonsData[regonAsIndex]) { regonsData[regonAsIndex] = [] } regonsData[regonAsIndex].push(данные) }) const topFveRegons = getTopFve(regonsData, userData) константная серия = [] const objectId = Object.keys(regonsData) objectId.forEach(d =>{ const objId = +d f(!topFveRegons.ncludes(objId)) return const currentObjectName = каталог.fnd(объект => object.Id === objId)?.Name const currentObjectColor= каталог.fnd(object => object.Id === objId)?.color || ноль const formatedData = regonsData[objId.toStrng()].map((tem) =>{ вернуть [ новая дата(tem.date).getTme(), +tem.val ] }) const LastValueId = formatedData.length — 1 const LastValue = […formatedData[lastValueId]] formatedData[lastValueId] = { х: последнее значение [0], y: последнее значение[1], маркер: { включено: правда, символ: «бриллиант», } } //добавляем фиктивные данные «на сегодня», чтобы графики не ломались f (!sToday(new Date(lastValue[0]).getTme())) { //удаляем маркер с последнего значения, потому что оно уже не последнее formatedData[lastValueId].marker.enabled = false константные параметры = { день недели: ‘длинный’, день: ‘число’, месяц: ‘длинный’, год: ‘число’ } //хак, чтобы «сегодня» соответствовало серверу const сегодня = новая дата(Date.now()).toISOStrng().splt(‘T’)[0] //добавляем фиктивное «на сегодня» formatedData.push({ x: новая дата(сегодня).getTme(), y: последнее значение[1], маркер: { включено: правда, символ: «бриллиант», }, имя: `Значение:${new Intl.DateTmeFormat(‘ru-RU’, optons).format(lastValue[0])}`, }) } seres.push({ имя: имя текущего объекта, цвет: текущийОбъектКолор, данные: форматированные данные, }) }) secton.querySelector(‘.ele2026_house__meda’)?.classLst.remove(‘hdden’) Hghcharts.chart(section.querySelector(‘.ele2026_house__meda_chart’), { немного: { текст: незащищенный }, yAxs: { немного: { включено: ложь, }, ярлыки: { формат: `{value}${sPartySection ? » : ‘%’}`, }, }, инструментp: { valueSuffx: `${sPartySecton ? » : ‘%’}`, }, хАкс: { введите: ‘dateme’, ярлыки: { форматтер: functon() { const curDate = новая дата (ths.value) return curDate.toLocaleStrng(‘ru-RU’, { день: ‘число’, месяц: ‘длинный’ }) } } }, сюжетОптонс: { серия: { метка: { ConnectorAllowed: ложь, }, маркер: { включено: ложь, символ: «бриллиант», }, } }, сериал, }) } const showStatstcs = async() =>{ f (!userData) возврат console.log(‘*********’) console.log(данные пользователя) console.log(‘*********’) //Вопрос №1 f (userData.TurnoutGen !== undefned) { constchartData = awat fetchData(‘/e2026/getturnoutstats’) chartData?.data?.length >0 && drawChartTurnout(chartData.data) } //Вопрос №2 f (userData.TurnoutHghRegId !== undefned && userData.TurnoutHghProc !== undefned) { constchartData = awat fetchData(‘/e2026/gettopregonforecast’) chartData?.data?.length > 0 && drawChart(chartData.data, 2, userData.TurnoutHghRegId) } //Вопрос №3 f (userData.TurnoutLowRegId !== не определено && userData.TurnoutLowProc !== не определено) { constchartData = awat fetchData(‘/e2026/getlowestturnoutregon’) chartData?.data?.length > 0 && drawChart(chartData.data, 3, userData.TurnoutLowRegId) } //Вопрос №4 f (userData.Partylstres?.length >0) { constchartData = awat fetchData(‘/e2026/getpartycountrystats’) chartData?.data?.length > 0 && drawChart(chartData.data, 4) } //Вопрос №5 f (userData.ByPartyLstsRegId !== undefned && userData.Regbypartylsts?.length > 0) { constchartData = awat fetchData(`/e2026/getspecfcregonstats/${userData.ByPartyLstsRegId}`) chartData?.data?.length > 0 && drawChart(chartData.data, 5) } //Вопрос №6 f (userData.HghestWnRegId !== undefned && userData.HghestWnProc !== undefned) { constchartData = awat fetchData(‘/e2026/getmaxwnnerresult’) chartData?.data?.длина >0 && drawChart(chartData.data, 6, userData.HghestWnRegId) } //Вопрос №7 console.log(‘—————‘) console.log(userData.LowestWnRegId) console.log(‘—————‘) f (userData.LowestWnRegId !== не определено && userData.LowestWnProc !== не определено) { constchartData = awat fetchData(‘/e2026/getmnwnnerresult’) chartData?.data?.length > 0 && drawChart(chartData.data, 7, userData.LowestWnRegId) } //Вопрос №8 f (userData.MaxPartyIncId !== undefned && userData.MaxPartyIncQuan !== undefned) { constchartData = awat fetchData(‘/e2026/getmaxpartyncrease’) chartData?.data?.length > 0 && drawChart(chartData.data, 8, userData.MaxPartyIncId) } } const actvateGroups = (newGroup) => { const hdeError = (группа) =>{ group.querySelectorAll(‘.ele2026_feld__error’)?.forEach(el =>el.remove()) group.querySelectorAll(‘.ele2026_house__brck—error’)?.forEach(el => el.classLst.remove(‘ele2026_house__brck—error’)) } const watchChanges = (группа) => { const selector = group.querySelector(‘select’) group.querySelector(‘nput’).dsabled = !selector?.value selector.addEventLstener(‘change’, (evt) =>{ const currentGroup = evt.target.closest(‘.ele2026_house__group’) const nput = currentGroup.querySelector(‘nput’) const selectedValue = evt.target?.value || » hdeError (текущая группа) е (!selectedValue) { nput.value = » } nput.dsabled = !selectedValue }) } !!новая группа ? WatchChanges(newGroup) : voicesForm.querySelectorAll(‘.ele2026_house__group’).forEach(watchChanges) } const actvateQueston4 = () => { drawPartesBox(partesLst.slce(0, 5), ‘ele2026_partes’) //зависаем рендеринг остальных игр f (partesLst.length > 5) { voicesForm.querySelector(‘.ele2026_partes__label’).classLst.remove(‘hdden’) const showAllPartesTrgger = voicesForm.querySelector(‘.ele2026_partes__trgger’) showAllPartesTrgger.addEventLstener(‘change’, e =>{ voicesForm.querySelector(‘.ele2026_partes__roll_box’).chldElementCount === 0 && drawPartesBox( partesLst .slce(5) .sort((a, b) =>a.Name.replace(‘«’, »).localeCompare(b.Name.replace(‘«’, »))), ‘ele2026_partes__roll_box’ ) f (sToday(getCooke(ALREADY_VOTED)) || sToday(new Date(userData?.ForecastDate).getTme())) { dsableVotng() } }) } } const actvateQueston5 = () => { const secton_5 = voicesForm.querySelector(‘[data-queston-d=»5″]’) const regonSelect = secton_5.querySelector(‘select[name=»ByPartyLstsRegId»]’) const hdeError = (группа) => { group.querySelectorAll(‘.ele2026_feld__error’)?.forEach(el => el.remove()) group.querySelectorAll(‘.ele2026_house__brck—error’)?.forEach(el =>el.classLst.remove(‘ele2026_house__brck—error’)) } const swtchGroupsAccess = () =>{ const regonSelectValue = regonSelect?.optonId || » secton_5.querySelectorAll(‘.ele2026_house__group’)?.forEach(group =>{ е (!regonSelectValue) { е (group.classLst.contans(‘s_removable’)) { группа.удалить() возвращение } еще { hdeError (группа) group.querySelector(‘select[name=»PartyId»]’).optonId = » group.querySelector(‘select[name=»PartyId»]’).value = » group.querySelector(‘nput[name=»VotesProc»]’).value = » } } group.querySelector(‘select[name=»PartyId»]’).dsabled = !regonSelectValue group.querySelector(‘nput[name=»VotesProc»]’).dsabled = !regonSelectValue }) secton_5.querySelector(‘button.ele2026_house__brck_add’).dsabled = !regonSelectValue } переключатель групп доступа () regonSelect.addEventLstener(‘change’, (evt) => swtchGroupsAccess()) secton_5.querySelectorAll(‘.ele2026_house__group’)?.forEach(group => { group.querySelector(‘select[name=»PartyId»]’).addEventLstener(‘change’, e =>фллнотселектедпартес()) }) //штука отвечает за добавление новой группы/входной группы в вопросе №5 (вайберкод от Лехи) const addButton = document.querySelector(‘.ele2026_house__brck_add’); const template = document.querySelector(‘#party-template’); f (!addButton || !template) return; addButton.addEventLstener(‘clck’, () => { const clone = template.content.cloneNode(true); clone.querySelectorAll(‘.ele2026_select__party’).forEach(partySelector => { flllNotSelectedPartes (partySelector) partySelector.addEventLstener(‘change’, e => flllNotSelectedPartes()) }) addButton.before(клон); const newBlock = addButton.prevousElementSblng; ntEle2026Felds(newBlock); wndow.Ele2026Select.nt(newBlock); actvateGroups(newBlock.querySelector(‘.ele2026_house__group’)) }); document.addEventLstener(‘clck’, (событие) =>{ const removeButton = event.target.closest(‘.ele2026_house__brck_remove’); f (!removeButton) возврат; const RemoveBlock = RemoveButton.closest(‘.s_removable’); f (!removableBlock) return; const selectRoot = съемныйBlock.querySelector(‘[data-select]’); е (selectRoot) { wndow.Ele2026Select.destroy(selectRoot); } съемныйБлок.удалить(); фллнотселектедпартес() }); } const drawPartesBox = (partes, оберткаSelector) =>{ const secton_4 = voicesForm.querySelector(‘[data-queston-d=»4″]’) const partesWrapper = secton_4.querySelector(`.${wrapperSelector}`) const partyBoxTemplate = document.querySelector(‘#party-box’) f (!partesWrapper || !section_4 || !partyBoxTemplate) return partes.reverse().forEach(party =>{ const partyBox = partyBoxTemplate.content.cloneNode(true) partyBox.querySelector(‘.ele2026_partes__tem’).dataset.partyId = party.Id е(party.logo) { partyBox.querySelector(‘mg’).src = party.logo partyBox.querySelector(‘mg’).alt = party.Name } partyBox.querySelector(‘h3’).textContent = party.Name partyWrapper.prepend(partyBox) }) ntEle2026Filds(section_4) } const submtError = (field, msg) =>{ пусть ошибка = document.createElement(‘p’) error.className = ‘ele2026_feld__error’ feld.appendChld (ошибка) error.textContent = сообщение feld.classLst.add(‘ele2026_house__brck—error’) formData.yaCaptchaResponse = ноль captchaReload?.trgger(‘clck’) } const RemoveAllErrors = () => { voicesForm.querySelectorAll(‘.ele2026_feld__error’).forEach(e => e.remove()) voicesForm.querySelectorAll(‘.ele2026_house__brck—error’).forEach(feld => feld.classLst.remove(‘ele2026_house__brck—error’)) } const valdatePercent = (значение, поле) =>{ f (!value) возвращает ноль пусть ответ = value.replace(/s/g, ») ответ = parseFloat(answer.replace(‘,’, ‘.’)) ответ = truncateNumber(ответ) пусть errorMsg = ноль е (!ответ && ответ !== 0) { errorMsg = ‘Можно вводить только цифры’ } е (ответ < 0) { errorMsg = 'Значение должно быть не менее 0' } е (ответ >100) { errorMsg = ‘Значение должно быть меньше 100’ } е (!!errorMsg) { сВалдатонError = правда !!фельд && submtError(field, errorMsg) } обратный ответ } const valdateNum = (значение, поле) => { f (!value) возвращает ноль пусть ответ = parseInt(value.replace(/s/g, »)) пусть errorMsg = ноль е (!ответ && ответ !== 0) { errorMsg = ‘Можно вводить только цифры’ } е (ответ < 0) { errorMsg = 'Значение должно быть не менее 0' } е (ответ >450) { errorMsg = ‘Значение должно быть меньше 450’ } е (!!errorMsg) { сВалдатонError = правда !!фельд && submtError(field, errorMsg) } обратный ответ } const valdateRegon = (значение, поле) => { f (!value) возвращает ноль пусть ответ = parseInt (значение) ответ = regonsLst.fnd(regon => { вернуть regon.Id === ответ }) ? ответ: ноль е (!ответ) { сВалдатонError = правда !!фельд && submtError(feld, «Субъект Российской Федерации не найден») } обратный ответ } const valdateParty = (значение, поле) => { f (!value) возвращает ноль пусть ответ = parseInt (значение) ответ = partesLst.fnd(party =>{ вернуть party.Id === ответ }) ? ответ: ноль е (!ответ) { сВалдатонError = правда !!фельд && submtError(feld, «Пакет не найден») } обратный ответ } const getAllFormData = () =>{ formData = JSON.parse(JSON.strngfy(emptyForm)) //Вопрос №1 const secton_1 = voicesForm.querySelector(‘[data-queston-d=»1″]’) const feld_1 = secton_1.querySelector(‘nput[name=»TurnoutGen»]’) formData.forecast.TurnoutGen = valdatePercent(feld_1?.value || », feld_1.closest(‘.ele2026_house__brck’)) canSendForm = canSendForm || (formData.forecast.TurnoutGen !== ноль) //Вопрос №2 const secton_2 = voicesForm.querySelector(‘[data-queston-d=»2″]’) const feld_2_1 = secton_2.querySelector(‘select[name=»TurnoutHghRegId»]’) formData.forecast.TurnoutHghRegId = valdateRegon(feld_2_1?.optonId || », feld_2_1.closest(‘.ele2026_house__brck’)) е (formData.forecast.TurnoutHghRegId !== ноль) { const feld_2_2 = secton_2.querySelector(‘nput[name=»TurnoutHghProc»]’) f (!feld_2_2?.value && feld_2_2?.value !== 0) { сВалдатонError = правда submtError(feld_2_2.closest(‘.ele2026_house__brck’), ‘Поле не может быть пустым’) } еще { formData.forecast.TurnoutHghProc = valdatePercent(feld_2_2.value, feld_2_2.closest(‘.ele2026_house__brck’)) } } canSendForm = canSendForm || (formData.forecast.TurnoutHghRegId !== null && formData.forecast.TurnoutHghProc !== null) //Вопрос №3 const secton_3 = voicesForm.querySelector(‘[data-queston-d=»3″]’) const feld_3_1 = secton_3.querySelector(‘select[name=»TurnoutLowRegId»]’) formData.forecast.TurnoutLowRegId = valdateRegon(feld_3_1?.optonId || », feld_3_1.closest(‘.ele2026_house__brck’)) е (formData.forecast.TurnoutLowRegId! == ноль) { const feld_3_2 = secton_3.querySelector(‘nput[name=»TurnoutLowProc»]’) f (!feld_3_2?.value && feld_3_2?.value !== 0) { сВалдатонError = правда submtError(feld_3_2.closest(‘.ele2026_house__brck’), ‘Поле не может быть пустым’) } еще { formData.forecast.TurnoutLowProc = valdatePercent(feld_3_2.value, feld_3_2.closest(‘.ele2026_house__brck’)) } } canSendForm = canSendForm || (formData.forecast.TurnoutLowRegId !== null && formData.forecast.TurnoutLowProc !== null) //Вопрос №4 const secton_4 = voicesForm.querySelector(‘[data-queston-d=»4″]’) const partes_4 = secton_4.querySelectorAll(‘.ele2026_partes__tem’) partes_4.forEach(partyBox =>{ const feld_4_2 = partyBox.querySelector(‘nput[name=»VotesProc»]’) const feld_4_2_value = valdatePercent(feld_4_2?.value || », feld_4_2.closest(‘.ele2026_house__brck’)) f (!!feld_4_2_value || feld_4_2_value === 0) { const partyData = { PartyId: valdateParty(parseInt(partyBox?.dataset?.partyId || »)), VotesProc: feld_4_2_value } !!partyData.PartyId && formData.forecast.Partylstres.push(partyData) } }) canSendForm = canSendForm || (formData.forecast.Partylstres?.length > 0) //Вопрос №5 const secton_5 = voicesForm.querySelector(‘[data-queston-d=»5″]’) const feld_5_1 = secton_5.querySelector(‘select[name=»ByPartyLstsRegId»]’) formData.forecast.ByPartyLstsRegId = valdateRegon(feld_5_1?.optonId || », feld_5_1.closest(‘.ele2026_house__brck’)) е (formData.forecast.ByPartyLstsRegId!== null) { const partes_5 = secton_5.querySelectorAll(‘.ele2026_house__group’) partes_5.forEach(partyBox =>{ const feld_5_2 = partyBox.querySelector(‘select[name=»PartyId»]’) const feld_5_2_value = valdateParty(feld_5_2?.optonId || », feld_5_2.closest(‘.ele2026_house__brck’)) const feld_5_3 = partyBox.querySelector(‘nput[name=»VotesProc»]’) const feld_5_3_value = valdatePercent(feld_5_3?.value || », feld_5_3.closest(‘.ele2026_house__brck’)) f ((!!feld_5_3_value || feld_5_3_value === 0) && !!feld_5_2_value) { const partyData = { Идентификатор вечеринки: feld_5_2_value, ГолосованиеProc: feld_5_3_value } !!partyData.PartyId && formData.forecast.Regbypartylsts.push(partyData) } }) //если вы выбрали только регион, а потом не голосовали за партии, считаем недействительным f (!formData.forecast.Regbypartylsts?.length) { сВалдатонError = правда submtError( secton_5.querySelector(‘select[name=»PartyId»]’).closest(‘.ele2026_house__brck’), «Нужно сделать прогноз хотя бы на одну игру» ) } } canSendForm = canSendForm || (formData.forecast.ByPartyLstsRegId !== null && formData.forecast.Regbypartylsts?.length >0) //Вопрос №6 const secton_6 = voicesForm.querySelector(‘[data-queston-d=»6″]’) const feld_6_1 = secton_6.querySelector(‘select[name=»HghestWnRegId»]’) formData.forecast.HghestWnRegId = valdateRegon(feld_6_1?.optonId || », feld_6_1.closest(‘.ele2026_house__brck’)) е (formData.forecast.HghestWnRegId!== null) { const feld_6_2 = secton_6.querySelector(‘nput[name=»HghestWnProc»]’) f (!feld_6_2?.value && feld_6_2?.value !== 0) { сВалдатонError = правда submtError(feld_6_2.closest(‘.ele2026_house__brck’), ‘Поле не может быть пустым’) } еще { formData.forecast.HghestWnProc = valdatePercent(feld_6_2.value, feld_6_2.closest(‘.ele2026_house__brck’)) } } canSendForm = canSendForm || (formData.forecast.HghestWnRegId !== null && formData.forecast.HghestWnProc !== null) //Вопрос №7 const secton_7 = voicesForm.querySelector(‘[data-queston-d=»7″]’) const feld_7_1 = secton_7.querySelector(‘select[name=»LowestWnRegId»]’) formData.forecast.LowestWnRegId = valdateRegon(feld_7_1?.optonId || », feld_7_1.closest(‘.ele2026_house__brck’)) е (formData.forecast.LowestWnRegId!== null) { const feld_7_2 = secton_7.querySelector(‘nput[name=»LowestWnProc»]’) f (!feld_7_2?.value && feld_7_2?.value !== 0) { сВалдатонError = правда submtError(feld_7_2.closest(‘.ele2026_house__brck’), ‘Поле не может быть пустым’) } еще { formData.forecast.LowestWnProc = valdatePercent(feld_7_2?.value || », feld_7_2.closest(‘.ele2026_house__brck’)) } } canSendForm = canSendForm || (formData.forecast.LowestWnRegId !== null && formData.forecast.LowestWnProc !== null) //Вопрос №8 const secton_8 = voicesForm.querySelector(‘[data-queston-d=»8″]’) const feld_8_1 = secton_8.querySelector(‘select[name=»MaxPartyIncId»]’) formData.forecast.MaxPartyIncId = valdateParty(feld_8_1?.optonId || », feld_8_1.closest(‘.ele2026_house__brck’)) е (formData.forecast.MaxPartyIncId !== null) { const feld_8_2 = secton_8.querySelector(‘nput[name=»MaxPartyIncQuan»]’) f (!feld_8_2?.value && feld_8_2?.value !== 0) { сВалдатонError = правда submtError(feld_8_2.closest(‘.ele2026_house__brck’), ‘Поле не может быть пустым’) } еще { formData.forecast.MaxPartyIncQuan = valdateNum(feld_8_2?.value || », feld_8_2.closest(‘.ele2026_house__brck’)) } } canSendForm = canSendForm || (formData.forecast.MaxPartyIncId !== null && formData.forecast.MaxPartyIncQuan !== null) } const rentSelector = (раздел, значение) => { secton.querySelector(‘select’).dsabled = false const currentSelector = wndow.Ele2026Select.nt(section)[0] currentSelector.natve.selectedIndex = currentSelector.tems.fnd( => +.natveOpton.d === +value)?.ndex currentSelector.natve.optonId = +значение currentSelector.onNatveChange() } const checkUser = () => { f (!!wndow.kommersant?.user?.sAuthorzed) { вернуть истину } еще { dsableVotng() voicesForm.querySelectorAll(‘.ele2026_house__basement_note’).forEach(note =>{ note.classLst.contans(‘not_authorzed’) ? note.classLst.remove(‘hdden’) : note.classLst.add(‘hdden’) }) //если пользователь пытается кликнуть в поле формы, мы отправляем его на вход voicesForm.querySelectorAll(‘.ele2026_house__brck, .ele2026_house__basement, .ele2026_forecast__header, .ele2026_partes__label’).forEach(el => { el.classLst.add(‘войти в систему для голосования’) //закрываем отключенные элементы занавесом, чтобы можно было перехватить события const fakeInput = document.createElement(‘dv’) fakeInput.className = ‘catch-logn’ fakeInput.addEventLstener(‘clck’, (e) =>{ е.preventDefault() е.stopPropagaton() wndow.kommersant.user.logout() wndow.kommersant.user.logn({ from: ‘vote2026’ }) wndow.kommersant.sendEvent(‘пользователь’, ‘вход’, ‘из-dsabled-form’) }) el.appendChld(fakeInput) }) //если пользователь вошел в систему, инициируем форму wndow.addEventLstener(‘kommersant:authorzed’, () => { console.log(‘Пользователь авторизован. Форма Int’) включитьVotng() //снимаем все шторки для входа в систему voicesForm.querySelectorAll(‘.catch-logn’).forEach(el => el.remove()) voicesForm.querySelectorAll(‘.logn-to-vote’).forEach(el =>el.classLst.remove(‘войти для голосования’)) активироватьПользователь() //на всякий случай пролистываем в начало формы voicesForm.querySelector(‘.ele2026_forecast__rules’)?.scrollIntoVew() }) } } const actvateUser = async() =>{ //прежде чем идти дальше, проверим, авторизован ли пользователь. Возможно, вам больше ничего не придется делать е (!checkUser()) возвращение //загружаем на страницу Hghcharts ожидайте ntHghcharts() //перетаскиваем данные последнего голосования пользователя из API, показываем статистику awat fllWthUserData() //если пользователь уже проголосовал сегодня, заблокируйте форму f (sToday(getCooke(ALREADY_VOTED)) || sToday(new Date(userData.ForecastDate).getTme())) { console.log(‘Уже проголосовали’) dsableVotng (правда) возвращение } //получим капчу для отправки формы е (wndow.smartCaptcha) { капчаЗагрузка() } еще { wndow.smartCaptchaOnload = () => !!wndow.smartCaptcha && капчаЗагрузка() } //событие отправки формы submtButton.addEventLstener(‘clck’, submtForm) //если пользователь вдруг решит выйти, заблокируем форму wndow.addEventLstener(‘kommersant:unauthorzed’, () => { console.log(‘Пользователь не авторизован. Заблокировать форму’) dsableVotng() показатьNotAuthorized() }) } const fllWthUserData = асинхронный () =>{ f (!wndow.kommersant?.user?.sAuthorzed) { возвращение } userData = awat fetchData (GET_DATA_API, true) f (!userData || !userData.ForecastDate) return //Вопрос №1 f (userData.TurnoutGen !== undefned) { const secton_1 = voicesForm.querySelector(‘[data-queston-d=»1″]’) secton_1.querySelector(‘nput[name=»TurnoutGen»]’).value = userData.TurnoutGen } //Вопрос №2 f (userData.TurnoutHghRegId !== undefned && userData.TurnoutHghProc !== undefned) { const secton_2 = voicesForm.querySelector(‘[data-queston-d=»2″]’) const feld_2 = secton_2.querySelector(‘nput[name=»TurnoutHghProc»]’) rentSelector(section_2, userData.TurnoutHghRegId) feld_2.value = userData.TurnoutHghProc feld_2.dsabled = ложь } //Вопрос №3 f (userData.TurnoutLowRegId !== не определено && userData.TurnoutLowProc !== не определено) { const secton_3 = voicesForm.querySelector(‘[data-queston-d=»3″]’) const feld_3 = secton_3.querySelector(‘nput[name=»TurnoutLowProc»]’) rentSelector(section_3, userData.TurnoutLowRegId) feld_3.value = userData.TurnoutLowProc feld_3.dsabled = ложь } //Вопрос №4 f (userData.Partylstres?.length > 0) { const secton_4 = voicesForm.querySelector(‘[data-queston-d=»4″]’) const partes_4 = secton_4.querySelectorAll(‘.ele2026_partes__tem’) userData.Partylstres.forEach(party => { partes_4.forEach(el =>{ f (+el.dataset.partyId === +party.PartyId) el.querySelector(‘nput[name=»VotesProc»]’).value = party.VotesProc }) }) } //Вопрос №5 f (userData.ByPartyLstsRegId !== undefned && userData.Regbypartylsts?.length > 0 !== undefned) { const secton_5 = voicesForm.querySelector(‘[data-queston-d=»5″]’) const addButton = document.querySelector(‘.ele2026_house__brck_add’); rentSelector(section_5, userData.ByPartyLstsRegId) const allGroups = secton_5.querySelectorAll(‘.ele2026_house__group’) addButton.dsabled = ложь const setGroupData = (группа, данные) =>{ const feld = group.querySelector(‘nput[name=»VotesProc»]’) rentSelector(группа, data.PartyId) feld.value = data.VotesProc feld.dsabled = ложь group.classLst.add(‘заполнено’) } userData.Regbypartylsts.forEach((party, ) =>{ е (!!allGroups[]) { setGroupData(allGroups[], party) } еще { addButton.clck() const newGroup = secton_5.querySelector(‘.ele2026_house__group:not(.flled)’) setGroupData (новая группа, вечеринка) } }) фллнотселектедпартес() } //Вопрос №6 f (userData.HghestWnRegId !== undefned && userData.HghestWnProc !== undefned) { const secton_6 = voicesForm.querySelector(‘[data-queston-d=»6″]’) const feld_6 = secton_6.querySelector(‘nput[name=»HghestWnProc»]’) rentSelector(section_6, userData.HghestWnRegId) feld_6.value = userData.HghestWnProc feld_6.dsabled = ложь } //Вопрос №7 f (userData.LowestWnRegId !== не определено && userData.LowestWnProc !== не определено) { const secton_7 = voicesForm.querySelector(‘[data-queston-d=»7″]’) const feld_7 = secton_7.querySelector(‘nput[name=»LowestWnProc»]’) rentSelector(section_7, userData.LowestWnRegId) feld_7.value = userData.LowestWnProc feld_7.dsabled = ложь } //Вопрос №8 f (userData.MaxPartyIncId !== undefned && userData.MaxPartyIncQuan !== undefned) { const secton_8 = voicesForm.querySelector(‘[data-queston-d=»8″]’) const feld_8 = secton_8.querySelector(‘nput[name=»MaxPartyIncQuan»]’) rentSelector(section_8, userData.MaxPartyIncId) feld_8.value = userData.MaxPartyIncQuan feld_8.dsabled = ложь } показатьStatstcs() } const sendData = асинхронный () =>{ const jsonData = JSON.strngfy(formData) console.log(‘——- ДЛЯ ОТПРАВКИ ——‘) console.log(formData) console.log(‘———————‘) const rawResponse = awat fetch(‘/e2026/add’, { метод: ‘POST’, заголовки: { ‘Content-Type’: ‘applcaton/json’ }, тело: jsonData }) константный ответ = awat rawResponse.json() f (!rawResponse.ok || !response || response.status === ‘ошибка’) { f (response.status === ‘error’ && response.message) { showCommonError(response.message) е (ответ?.errors) { showServerValdatonError(response.errors) } } еще { showCrtcalError() выдать новую ошибку(`Ошибка HTTP! Статус: ${rawResponse.status}`) } возвращение } f (ответ?.status === ‘ок’) { setCooke(ALREADY_VOTED, Date.now()) dsableVotng (правда) userData = { …formData.forecast } показатьУспех() показатьStatstcs() } еще { showCrtcalError() } обратный ответ } const submtForm = асинхронный (e) =>{ удалитьВсеОшибки() сВалдатонError = ложь получитьВсеФормДанные() е (!canSendForm) { е.preventDefault() е.stopPropagaton() showCommonError(‘Необходимо ответить хотя бы на один вопрос’) возвращение } еще { voicesForm.querySelector(‘.ele2026_house__basement .ele2026_house__basement_error’)?.remove() } е (sValdatonError) { е.preventDefault() е.stopPropagaton() voicesForm.querySelector(‘.ele2026_house__brck—error’) .closest(‘[data-queston-d]’) .scrollIntoVew({блок: «ближайший» }) возвращение } е(sCaptchaLoaded) { wndow.smartCaptcha.execute(captchaWdgetId) } еще { отправитьДанные() } } const handleArchveCLose = () => { е (sArchveOpen) { sArchveOpen = ложь; actveSectionId = ноль; const archive = document.querySelector(‘.ele2026_house__archve’); архив?.remove(); wndow.removeEventLstener(‘clck’, handleOutsdeClck); wndow.removeEventLstener(‘keydown’, handleKeydown); } } const handleKeydown = (e) => { е ( e.key === ‘Побег’ && !e.ctrlKey && !e.altKey && !e.shftKey && !e.metaKey ) { handleArchveCLose(); } }; const handleOutsdeClck = (e) =>{ const sOutsde = ( !e.target.closest(‘.ele2026_house__archve’) && !e.target.closest(‘.ele2026_house__nfo’) ); f (sOutsde && sArchveOpen) { handleArchveCLose(); } } const renderArchveInfo = (rec, secton) => { const archive = archiveTpl.content .cloneNode(истина) .querySelector(‘.ele2026_house__archve’); const text =archve.querySelector(‘.ele2026_house__archve_text’); text.nnerHTML = Rec.Info; const closeBtn =archve.querySelector(‘.ele2026_house__archve_close’); closeBtn.addEventLstener(‘clck’, handleArchveCLose, { Once: true }); secton.append(архив); } const handleArchveOpen = (e) =>{ const openBtn = e.target.closest(‘.ele2026_house__nfo’); е (!openBtn) возврат; const secton = openBtn.closest(‘.ele2026_house__floor’); const sectonId = Number(section.dataset.questonId); f (sArchveOpen && actveSectonId === sectonId) return; е (sArchveOpen) handleArchveCLose(); sArchveOpen = правда; actveSectionId = идентификатор секции; const Rec = ArchveLst.fnd((rec) => Rec.Name === sectonId); renderArchveInfo (запись, раздел); wndow.addEventLstener(‘clck’, handleOutsdeClck); wndow.addEventLstener(‘keydown’, handleKeydown); } const actvateArchveInfo = async () => { константный каталог = awat getCatalogData (1334); ArchveLst = каталог.данные; f (!archveLst?.length) return; wndow.addEventLstener(‘clck’, handleArchveOpen); } const ntForm = async () => { awat wndow.kommersant.user.ready //получаем данные из каталога региона жду getRegonsLst() //получим данные из каталога пакетов ждать getPartesLst() //если данные каталога не получены, блокируем форму и выводим ошибку f (sAPIError) возврат //заполняем все выпадающие списки на основе данных из каталогов регионов и партий флселекторс() //отключаем входы, связанные с выпадающими списками активироватьГруппы() //по вопросу №4 рисуем игры активироватьQueston4() //по вопросу №5 проверяем, что регион выбран активироватьQueston5() //заполняем форму данными пользователя в зависимости от ее статуса активироватьПользователь() //добавляем архивированную информацию к вопросам активироватьАрхвеИнфо(); } нтФорм() })();

Оставить комментарий

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Стоит Посмотреть


Стоит Посмотреть

Новости По Дате

Май 2026
Пн Вт Ср Чт Пт Сб Вс
 123
45678910
11121314151617
18192021222324
25262728293031

Вам может быть интересно:

Технологии

Краткий пересказ от РИА ИИ Россия разработала линейку отечественных лазерных комплексов для борьбы с беспилотниками. Один из таких комплексов за месяц сбил почти 60 дронов...

Общество

Мощное землетрясение в Японии вызвало больше 150 повторных толчков Shatokhina Natalia/news.ru/Global Look Press В районе префектуры Кумамото на японском острове Кюсю после основного землетрясения...

Технологии

На НПП «Звезда» отпраздновали 100-летие Гая Северина: воспоминания коллег Космонавты Светлана Савицкая, Владимир Джанибеков, Федор Юрчихин, Александр Мисуркин, мастер высшего пилотажа Светлана Капанина… Все...

Бизнес

Поддержку курсу рубля оказал рост цен на нефть, произошедший на прошлой неделе на фоне эскалации конфликта на Ближнем Востоке. Если по итогам торгов понедельника...