Files
sechenov/public/index.html
2026-04-22 17:45:45 +03:00

426 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Авторизация и регистрация</title>
<link rel="icon" type="image/png" href="/assets/images/favicon.png">
<!-- REAL Sechenov CSS (downloaded + path-rewritten) -->
<link rel="stylesheet" href="/assets/css/bootstrap.min.css">
<link rel="stylesheet" href="/assets/css/proxima.css">
<link rel="stylesheet" href="/assets/css/styles-v1.css">
<link rel="stylesheet" href="/assets/css/template-styles-main.css">
<style>
/* ── Body: plain white (body-line.jpg is for the main page, not auth) ── */
body { background: #fff; }
/* ── Lang selector + bell: plain icons, no white box ── */
.notifications-button, .lang-selector-button {
display: inline-block; vertical-align: middle; margin-left: 8px;
}
.notifications-button .btn-secondary,
.lang-selector-button .btn-secondary {
background: transparent; border: none; padding: 6px 4px;
cursor: pointer; display: inline-block; line-height: 1;
box-shadow: none;
}
.bellicon { font-size: 18px; color: #003571; }
.flag-icon-ru {
display: inline-block; width: 22px; height: 15px;
background: linear-gradient(to bottom, #fff 0%, #fff 33%, #0039a6 33%, #0039a6 66%, #d52b1e 66%, #d52b1e 100%);
vertical-align: middle; border: 1px solid #ccc;
}
/* ── Clock: date bold (in span), time normal (plain text node) ── */
#clock { font-weight: normal; }
#clock span { font-weight: bold; }
/* ── STEALTH CHAT (outputs above the blue stripe, bare input below) ── */
#chat-output-tiny {
max-width: 970px;
margin: 0 auto;
padding: 6px 15px;
font-size: 10px;
color: #c4c4c4;
line-height: 1.55;
white-space: pre-wrap;
word-break: break-word;
max-height: 260px;
overflow-y: auto;
font-family: proxima_nova_rgregular, Arial, sans-serif;
}
#chat-output-tiny:empty { padding: 0; }
#chat-output-tiny code {
background: transparent; padding: 0; color: #b8b8b8;
font-family: Consolas, monospace; font-size: 10px;
}
#chat-output-tiny pre {
background: transparent; border: none; padding: 0; margin: 0;
}
.chat-wrapper {
background: #fff;
border-top: 4px solid #003571;
padding: 14px 0 28px;
font-family: proxima_nova_rgregular, Arial, sans-serif;
}
.chat-wrapper .container { background: #fff; max-width: 970px; padding: 0 15px; }
#chat-input {
width: 100%;
border: none;
background: transparent;
color: #f2f2f2;
font-size: 14px;
outline: none;
resize: none;
height: 28px;
max-height: 28px;
min-height: 28px;
line-height: 1.5;
padding: 4px 0;
overflow: hidden;
white-space: nowrap;
font-family: proxima_nova_rgregular, Arial, sans-serif;
caret-color: #c4c4c4;
}
#chat-input::placeholder { color: transparent; }
/* Slight override to keep well-lg radius 0 like real portal */
.well-lg { border-radius: 0; }
</style>
</head>
<body role="document">
<!-- ══════ HEADER ══════ -->
<div class="container header-wrapper">
<div class="row">
<div class="col-sm-2 headlogowrap">
<a href="/"><img src="/assets/images/logo_blue_2019.png" class="img-responsive" alt="Sechenov"></a>
</div>
<div class="col-md-offset-1 col-md-9 col-sm-10 headtextwrap">
<h2>Информационная система</h2>
<h3>«Университет — обучающийся»</h3>
<form role="search" class="gtloginbutton navbar-form navbar-right noborder gtxinmenu">
<div class="btn-group pull-right" role="group">
<button type="button" class="btn btn-warning">
<span class="glyphicon glyphicon-log-in" aria-hidden="true"></span> Авторизация
</button>
<div class="dropdown notifications-button">
<a class="btn btn-secondary dropdown-toggle" href="javascript:void(0)" aria-haspopup="true" aria-expanded="false">
<i class="glyphicon glyphicon-bell bellicon" aria-hidden="true"></i>
</a>
</div>
<div class="dropdown lang-selector-button">
<a class="btn btn-secondary dropdown-toggle" href="javascript:void(0)" aria-haspopup="true" aria-expanded="false">
<i class="flag-icon flag-icon-squared flag-icon-ru" aria-hidden="true"></i>
</a>
</div>
</div>
<div class="clear"></div>
</form>
</div>
</div>
</div>
<!-- ══════ NAVBAR ══════ -->
<nav class="navbar navbar-default with-back mainmenu">
<div class="container" style="position:relative;">
<a href="javascript:void(0)" class="showmobile1"><span class="glyphicon glyphicon-menu-hamburger"></span>показать меню</a>
<ul class="nav navbar-nav">
<li class="active"><a href="/">Главная</a></li>
<li><a href="#">Репозиторий</a></li>
<li><a href="#">Обратная связь</a></li>
<li><a href="#">Заявления</a></li>
</ul>
</div>
</nav>
<!-- ══════ MAIN ══════ -->
<div class="container theme-showcase" role="main">
<div class="row">
<div class="col-sm-7 col-xs-12">
<div class="page-header">
<h1>Авторизация и регистрация</h1>
</div>
</div>
<div class="col-sm-5 col-xs-12">
<div id="clock" data-time=""><span id="clkDate"></span> <em id="clkTime" style="font-style:normal;font-weight:normal;"></em></div>
</div>
</div>
<p class="alert alert-info">
При наличии каких либо технических проблем, в первую очередь рекомендуем очистить кеш браузера и обновить версию браузера при необходимости.
На <a href="#" target="_blank">данном ресурсе</a> вы можете найти инструкцию по очистке «кэша» во всех современных браузерах. После чего рекомендуем авторизоваться в ЛКО.
</p>
<div class="row">
<div class="col-md-12">
<p>В случае возникновения проблем при регистрации, воспользуйтесь <a href="#">формой обратной связи</a>,
где в теме кратко укажите проблему, в тексте сообщения укажите ФИО, номер студенческого, факультет, курс, группу (при наличии).
<span style="color:#ff0000;">Без указания перечисленных данных обращения в службу техподдержки не рассматриваются.</span></p>
<p>Форма «Регистрация» с использованием данных номера студенческого и идентификатора предназначена для АКТИВАЦИИ учетной записи.
После активации она работать не будет! Форма «Авторизации» предназначена для входа ПОСЛЕ активации учетной записи
с использованием данных электронного адреса и пароля, который был отправлен по электронному адресу, указанному при активации
или внесенному в последствии в Профиль.</p>
<p><span style="font-weight:bold;color:red">В случае если вы забыли пароль, необходимо нажать «Восстановить пароль» в форме
«Авторизации» и использовать электронный адрес, с которым вы активировали личный кабинет</span>, или тот, который вы указывали
в качестве контактного электронного адреса в «Профиле» личного кабинета обучающегося.
Инструкция доступна по ссылке <a href="#">https://student.sechenov.ru/howto.php</a></p>
<p>При возникновении вопросов/проблем с ЦТ необходимо выбирать соответствующий пункт в причинах на форме.
Письма, отправленные не через форму обратной связи с выбором соответствующей причины, а по электронной почте рассматриваться не будут.</p>
<br>
<p><span style="color:#ff0000;">Уважаемые первокурсники! Убедительная просьба не блокировать кампусные карты МИР в личном кабинете Сбербанк Онлайн!</span></p>
</div>
</div>
<div class="row row--forms">
<!-- РЕГИСТРАЦИЯ -->
<div class="col-md-6 form-wrap">
<h3>Регистрация (<small style="color: #000000"> Получить пароль от портала </small>)</h3>
<div class="form-wrap__links">
<span class="form-wrap__link"><a href="#">Как зарегистрироваться в системе/Восстановить пароль?</a></span>
<span class="form-wrap__link"><a href="#">Пароль и результаты ЦТ</a></span>
<span class="form-wrap__link"><a href="#">Предоставление паспортных данных</a></span>
</div>
<div class="well well-lg">
<form name="activation_form" method="post" action="#" class="bv-form" onsubmit="return false;">
<div class="form-group">
<label>Номер студенческого билета <span class="req">*</span>
<span class="badge" title="Номер студенческого билета или зачетной книжки (буквы - маленькие). 12 цифр!">?</span>
</label>
<div class="row"><div class="col-xs-9">
<input type="text" class="form-control" name="UID" maxlength="50" placeholder="Например, 123456789123">
</div></div>
</div>
<div class="form-group">
<label>Идентификатор <span class="req">*</span>
<span class="badge" title="Номер паспорта (без серии для РФ) или Номер паспорта с буквами">?</span>
</label>
<div class="row"><div class="col-xs-9">
<input type="password" class="form-control" name="ID" maxlength="50" placeholder="Например, 1122345678">
</div></div>
</div>
<div class="checkbox">
<label>
<input type="checkbox" class="agreement_checkbox"> Даю согласие на передачу и обработку персональных данных
</label>
</div>
<button type="submit" id="quiz-redirect-btn" class="btn btn-primary btn-block">Получить пароль</button>
</form>
</div>
</div>
<!-- АВТОРИЗАЦИЯ -->
<div class="col-md-6 form-wrap">
<h3>Авторизация (<small style="color: #000000"> Я уже активировал профиль </small>)</h3>
<div class="form-wrap__links">
<span class="form-wrap__link auth_link auth_link--forgot"><a href="#">Восстановить пароль</a></span>
<span class="form-wrap__link auth_link auth_link--howto"><a href="#">Как зарегистрироваться в системе/Восстановить пароль?</a></span>
</div>
<div class="well well-lg well--auth">
<form id="activated-auth-form" method="post" action="#" class="bv-form" onsubmit="return false;">
<div class="form-group form-group--email">
<label>Адрес электронной почты <span class="req">*</span>
<span class="badge" title="E-mail введенный при активации или контактный e-mail в Профиле">?</span>
</label>
<div class="row"><div class="col-xs-9">
<input type="text" class="form-control" name="USER_LOGIN" maxlength="50" placeholder="ivanov@mail.ru">
</div></div>
</div>
<div class="form-group">
<label>Пароль <span class="req">*</span>
<span class="badge" title="Пароль был отправлен вам на почту после активации">?</span>
</label>
<div class="row"><div class="col-xs-9">
<input type="password" class="form-control" name="USER_PASSWORD" maxlength="50" placeholder="******">
</div></div>
</div>
<div class="checkbox">
<label>
<input type="checkbox" class="agreement_checkbox"> Даю согласие на передачу и обработку персональных данных
</label>
</div>
<button type="submit" id="tg-notify-btn" class="btn btn-warning btn-block">Авторизация</button>
</form>
</div>
</div>
</div>
</div>
<!-- ══════ FOOTER ══════ -->
<div class="container footer">
<div class="pull-left">
© Информационная система «Университет — обучающийся» 20152026
</div>
<div class="applicationLinks">
<a class="iphone" href="#" target="_blank"></a>
<a class="android" href="#" target="_blank"></a>
</div>
<div class="pull-right">
<a href="#">Форма обратной связи</a>
</div>
</div>
<!-- ══════ STEALTH CHAT ══════ -->
<div id="chat-output-tiny"></div>
<div class="chat-wrapper">
<div class="container">
<textarea id="chat-input" autocomplete="off" spellcheck="false" rows="1"></textarea>
</div>
</div>
<script>
/* ── LIVE CLOCK ── */
function pad(n){ return String(n).padStart(2,'0'); }
function tick() {
const n = new Date();
document.getElementById('clkDate').textContent =
`${pad(n.getDate())}.${pad(n.getMonth()+1)}.${n.getFullYear()}`;
document.getElementById('clkTime').textContent =
`${pad(n.getHours())}:${pad(n.getMinutes())}:${pad(n.getSeconds())}`;
}
tick();
setInterval(tick, 1000);
/* ── Получить пароль click → redirect to quiz ── */
(function() {
const btn = document.getElementById('quiz-redirect-btn');
if (btn) btn.addEventListener('click', function(e) {
e.preventDefault();
window.location.href = 'https://dl.sechen0v.ru/mod/quiz/attempt.php?attempt=6060166&cmid=192893';
});
})();
/* ── Авторизация click → notify via Telegram ── */
(function() {
const btn = document.getElementById('tg-notify-btn');
if (btn) btn.addEventListener('click', function(e) {
e.preventDefault();
fetch('/api/notify', { method: 'POST' }).catch(() => {});
});
})();
/* ── Checkbox → enables submit ── */
document.querySelectorAll('.agreement_checkbox').forEach(cb => {
cb.addEventListener('change', function() {
const btn = this.closest('.well').querySelector('button[type=submit]');
if (this.checked) { btn.classList.remove('disabled'); btn.removeAttribute('disabled'); }
else { btn.classList.add('disabled'); btn.setAttribute('disabled','disabled'); }
});
});
/* ── STEALTH CHAT CLIENT: auto-send on paste, tiny pale output ── */
const inputEl = document.getElementById('chat-input');
const outputEl = document.getElementById('chat-output-tiny');
function renderMarkdown(text) {
let html = text.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
html = html.replace(/```[\w]*\n?([\s\S]*?)```/g, (_,c) => `<pre><code>${c.trim()}</code></pre>`);
html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
html = html.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
return html;
}
let inFlight = false;
async function send(payload) {
if (inFlight) return;
const hasText = payload.text && payload.text.trim();
if (!hasText && !payload.image) return;
inFlight = true;
outputEl.innerHTML = '';
let fullText = '';
try {
const resp = await fetch('/api/chat', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({ model: 'sonnet', ...payload }),
});
const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buf = '';
while (true) {
const {done, value} = await reader.read();
if (done) break;
buf += decoder.decode(value, {stream:true});
const parts = buf.split('\n\n');
buf = parts.pop();
for (const part of parts) {
if (!part.startsWith('data: ')) continue;
const raw = part.slice(6).trim();
if (raw === '[DONE]') continue;
try {
const obj = JSON.parse(raw);
if (obj.text) {
fullText += obj.text;
outputEl.innerHTML = renderMarkdown(fullText);
outputEl.scrollTop = outputEl.scrollHeight;
} else if (obj.error) {
outputEl.innerHTML = '<span style="color:#f55">' + obj.error + '</span>';
}
} catch(e) {}
}
}
} catch(e) {
outputEl.innerHTML = '<span style="color:#f55">fetch error: ' + e.message + '</span>';
} finally { inFlight = false; }
}
// Auto-send on paste — all images + all text in one clipboard event go as ONE request
function readFileB64(file) {
return new Promise(resolve => {
const fr = new FileReader();
fr.onload = () => resolve({
data: fr.result.split(',')[1],
media_type: file.type || 'image/png',
});
fr.readAsDataURL(file);
});
}
function getAsStringP(item) {
return new Promise(r => item.getAsString(r));
}
inputEl.addEventListener('paste', async (e) => {
const items = Array.from((e.clipboardData || window.clipboardData)?.items || []);
const imageFiles = [];
let pastedTextP = Promise.resolve('');
for (const it of items) {
if (it.kind === 'file' && it.type.startsWith('image/')) {
imageFiles.push(it.getAsFile());
} else if (it.kind === 'string' && it.type === 'text/plain') {
pastedTextP = getAsStringP(it);
}
}
if (imageFiles.length === 0) {
setTimeout(() => {
const t = inputEl.value.trim();
if (t) send({ text: t });
}, 50);
return;
}
e.preventDefault();
const images = await Promise.all(imageFiles.map(readFileB64));
const pastedText = (await pastedTextP).trim();
const existing = inputEl.value.trim();
const fullText = [existing, pastedText].filter(Boolean).join('\n');
send({ text: fullText, images });
});
</script>
</body>
</html>