kazakhtelecom-ai-agent/index.html

1785 lines
141 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 name="viewport" content="width=device-width,initial-scale=1">
<title>QAZAQtelecom HSE — План ПБ 2026</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{font:14px/1.4 Arial,sans-serif;background:#F4F6F9;color:#1A1A2E;min-height:100vh}
input,select,textarea,button{font:inherit;outline:none}
.btn{background:#005BAA;color:#fff;padding:12px 24px;border-radius:8px;font-weight:600;font-size:14px;border:none;cursor:pointer;display:inline-block;text-align:center;transition:all 0.2s}.btn:hover{background:#004B8C;box-shadow:0 2px 8px rgba(0,91,170,0.3)}
.btn-sm{padding:7px 16px;font-size:12px}.btn-r{background:#E53935;color:#fff}.btn-g{background:#2E7D32;color:#fff}.btn-o{background:#F57C00;color:#fff}
#login{display:flex;align-items:center;justify-content:center;min-height:100vh;background:linear-gradient(135deg,#003D73,#005BAA,#0077CC)}
#login>div{background:#fff;border-radius:16px;padding:40px;width:400px;max-width:90vw;text-align:center;box-shadow:0 8px 32px rgba(0,0,0,0.15)}
#login h1{font-size:22px;font-weight:800;margin-bottom:4px}#login h1 span{color:#005BAA}
#login>div>p{color:#64748B;font-size:13px;margin-bottom:24px}
#login input{display:block;width:100%;padding:12px;border:2px solid #E2E8F0;border-radius:10px;font-size:14px;margin-bottom:12px;transition:border 0.2s}
#login input:focus{border-color:#005BAA}
#app{display:none;min-height:100vh}
#sidebar{position:fixed;left:0;top:0;bottom:0;width:220px;background:#0A1628;color:#fff;z-index:100;overflow-y:auto;box-shadow:2px 0 12px rgba(0,0,0,0.1)}
#sidebar .logo{padding:20px 16px 12px;font-size:16px;font-weight:800;border-bottom:1px solid rgba(255,255,255,.1);display:flex;align-items:center;gap:8px}
#sidebar .logo span{color:#005BAA}
#sidebar .user{font-size:11px;color:#94A3B8;padding:10px 16px;border-bottom:1px solid rgba(255,255,255,.05)}
#sidebar a{display:block;padding:12px 16px;color:#CBD5E1;text-decoration:none;font-size:13px;cursor:pointer;border-left:3px solid transparent;transition:all 0.15s}
#sidebar a:hover{background:rgba(0,91,170,.1);color:#fff}
#sidebar a.active{background:rgba(0,91,170,.2);color:#005BAA;border-left-color:#005BAA;font-weight:600}
#sidebar .logout{position:absolute;bottom:16px;left:16px;right:16px}
#main{margin-left:220px;padding:24px;min-height:100vh}
.top{display:flex;justify-content:space-between;align-items:center;padding:0 0 16px;border-bottom:2px solid #E2E8F0;margin-bottom:20px}
.top h2{font-size:20px;font-weight:700}
.card{background:#fff;border-radius:12px;padding:20px;margin-bottom:16px;border:1px solid #E8ECF1;overflow-x:auto;box-shadow:0 1px 4px rgba(0,0,0,0.04)}
.card h3{font-size:16px;font-weight:700;margin-bottom:12px}
table{width:100%;border-collapse:collapse}
th,td{padding:8px 10px;font-size:13px;text-align:left;border-bottom:1px solid #E2E8F0;vertical-align:top}
th{background:#F1F5F9;font-weight:600;font-size:11px;text-transform:uppercase;color:#64748B;white-space:nowrap}
tr:hover{background:#FAFBFC}
.badge{display:inline-block;padding:3px 8px;border-radius:100px;font-size:11px;font-weight:600;white-space:nowrap}
.badge.g{background:#E8F5E9;color:#2E7D32}.badge.a{background:#FFF3E0;color:#E65100}.badge.r{background:#FFEBEE;color:#C62828}.badge.b{background:#E3F2FD;color:#1565C0}.badge.w{background:#F5F5F5;color:#757575}
.fr{display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap;align-items:center}
.fr input,.fr select{padding:8px 12px;border:1px solid #E2E8F0;border-radius:8px;font-size:13px;background:#fff}.fr input{min-width:200px}
.tr-red{background:#FFF5F5}.tr-red td{border-bottom-color:#FECACA;color:#991B1B}
.tr-amber{background:#FFFBEB}.tr-amber td{border-bottom-color:#FDE68A;color:#92400E}
.tr-green{background:#F0FDF4}.tr-green td{border-bottom-color:#BBF7D0;color:#065F46}
.sec-h{background:#005BAA;color:#fff;padding:6px 12px;border-radius:6px;font-size:12px;font-weight:700;display:inline-block;margin:16px 0 8px}
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:20px}
.stat-card{background:#fff;border-radius:12px;padding:16px;border:1px solid #E2E8F0;text-align:center}
.stat-card .num{font-size:28px;font-weight:800;margin:4px 0}.stat-card .lb{font-size:12px;color:#64748B}
.stat-card.sg .num{color:#10B981}.stat-card.sr .num{color:#EF4444}.stat-card.sb .num{color:#00B4D8}.stat-card.sa .num{color:#F59E0B}
.chat-box{height:280px;overflow-y:auto;border:1px solid #E2E8F0;border-radius:10px;padding:12px;margin-bottom:12px;background:#FAFBFC}
.msg{padding:8px 12px;border-radius:10px;margin-bottom:8px;max-width:85%;font-size:13px;line-height:1.4}
.msg.u{margin-left:auto;background:#005BAA;color:#fff}.msg.b{background:#F1F5F9;color:#0B1A2E}
.msg .nm{font-size:10px;color:#94A3B8;margin-bottom:2px}
.chat-inp{display:flex;gap:8px}.chat-inp input{flex:1;padding:10px 14px;border:1px solid #E2E8F0;border-radius:8px;font-size:13px}
.chat-q{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}
.chat-q button{padding:6px 12px;border:1px solid #E2E8F0;border-radius:100px;font-size:11px;background:#fff;cursor:pointer;color:#0B1A2E}
.chat-q button:hover{background:#00B4D8;color:#fff;border-color:#00B4D8}
.rank-bar{height:8px;border-radius:4px;background:#E2E8F0;overflow:hidden;margin-top:4px}
.rank-bar>div{height:100%;border-radius:4px;transition:width .3s}
.sub-row{font-size:12px;color:#64748B;cursor:pointer;user-select:none}
.sub-row:hover{color:#00B4D8}.sub-row .arr{display:inline-block;width:16px;text-align:center}
.sub-items{padding-left:24px}.sub-item{font-size:12px;padding:4px 0;border-bottom:1px solid #F1F5F9}.sub-item:last-child{border:none}
.mod-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.5);z-index:1000;display:none;align-items:center;justify-content:center}
.mod-box{background:#fff;border-radius:16px;padding:28px;max-width:750px;width:90vw;max-height:85vh;overflow-y:auto;position:relative}
.file-item{display:flex;align-items:center;gap:8px;padding:6px 8px;background:#F8FAFC;border-radius:6px;margin:4px 0;border:1px solid #E2E8F0;flex-wrap:wrap}
.file-item .fn{font-size:12px;flex:1;min-width:80px}.file-item .fs{font-size:10px;color:#64748B}.file-item a{font-size:11px;color:#00B4D8;cursor:pointer;text-decoration:underline}
.stor-bar{font-size:11px;color:#64748B;padding:4px 0}
@media(max-width:768px){#sidebar{width:56px}#sidebar .logo span,#sidebar a span,#sidebar .user{display:none}#main{margin-left:56px}.stat-grid{grid-template-columns:repeat(2,1fr)}}
</style>
#toast{position:fixed;top:20px;right:20px;z-index:9999;background:#2E7D32;color:#fff;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:600;box-shadow:0 4px 12px rgba(0,0,0,0.2);display:none;transition:opacity 0.3s}
</head>
<body onload="init()" style="margin:0">
<div id="login"><div>
<h1><span>QAZAQtelecom</span> HSE</h1>
<p>План производственной безопасности 2026</p>
<input id="lem" placeholder="curator@telecom.kz">
<input id="lpw" type="password" placeholder="Пароль">
<p id="lerr" style="color:#EF4444;font-size:12px;display:none">Неверная почта</p>
<button class="btn" style="width:100%" onclick="doLogin()">Войти</button>
</div></div>
<div id="toast"></div>
<div id="app">
<div id="sidebar">
<div class="logo">QAZAQtelecom <span>HSE</span></div>
<div class="user" id="su_name"></div>
<a class=" active" id="snav_events" onclick="switchTab('events')"><span>Мероприятия</span></a>
<a class="" id="snav_analytics" onclick="switchTab('analytics')"><span>Аналитика</span></a>
<a class="" id="snav_reports" onclick="switchTab('reports')"><span>Отчётность</span></a>
<a class="" id="snav_ai" onclick="switchTab('ai')"><span>Джарвис</span></a>
<a class="" id="snav_hse" onclick="switchTab('hse')"><span>HSE.sk.kz</span></a>
<a class="" id="snav_users" onclick="switchTab('users')"><span>Учётные записи</span></a>
<div class="logout"><button class="btn btn-sm btn-r" style="width:100%" onclick="doLogout()">Выйти</button></div>
</div>
<div id="main">
<div class="top"><h2 id="page_title">Мероприятия</h2>
<div style="display:flex;gap:8px;align-items:center">
<span id="stor_ind" class="stor-bar"></span>
<button class="btn btn-sm btn-o" onclick="saveBackup()">Резерв</button>
<button class="btn btn-sm btn-g" onclick="document.getElementById('fu').click()">Восст.</button>
<input type="file" id="fu" accept=".json" style="display:none" onchange="loadBackup(this)">
</div></div>
<div id="tab_events">
<div class="fr">
<input id="sea" placeholder="Поиск..." oninput="renderEv()">
<select id="fs" onchange="renderEv()"><option value="">Все статусы</option><option value="warn">В процессе</option><option value="done">Исполнено</option><option value="late">Просрочено</option></select>
<select id="fb" onchange="renderEv()"><option value="">Все филиалы</option></select>
<span id="sc" style="font-size:12px;color:#64748B;margin-left:auto"></span>
</div>
<div class="card" id="ev_content"></div>
</div>
<div id="tab_analytics" style="display:none">
<div class="stat-grid" id="an_stats"></div>
<div class="card"><h3>TOP-10 проблемных мероприятий</h3><div id="an_top"></div></div>
<div class="card"><h3>Выполнение по разделам</h3><div id="an_sections"></div></div>
<div style="display:flex;gap:8px;margin-bottom:16px">
<button class="btn btn-sm btn-o" onclick="dlAnalyticsPPT()">Скачать PPT</button>
<button class="btn btn-sm btn-r" onclick="dlAnalyticsPDF()">Скачать PDF</button>
<button class="btn btn-sm" onclick="dlAnalyticsWord()">Скачать Word</button>
</div>
<div class="card" id="ltif_card"><h3>LTIF — Коэффициент частоты травм</h3>
<p style="font-size:12px;color:#64748B;margin-bottom:8px">LTIF = (A × 1 000 000) / Человеко-часы, где A — число пострадавших</p>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:end;margin-bottom:10px">
<div><span style="font-size:11px;color:#64748B">Месяц</span>
<select id="ltif_month" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px">
<option value="0">Январь</option><option value="1">Февраль</option><option value="2">Март</option>
<option value="3">Апрель</option><option value="4">Май</option><option value="5">Июнь</option>
<option value="6">Июль</option><option value="7">Август</option><option value="8">Сентябрь</option>
<option value="9">Октябрь</option><option value="10">Ноябрь</option><option value="11">Декабрь</option>
</select></div>
<div><span style="font-size:11px;color:#64748B">Человеко-часы</span>
<input id="ltif_hours" type="number" placeholder="0" style="width:130px;padding:6px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px"></div>
<div><span style="font-size:11px;color:#64748B">Пострадавших (A)</span>
<input id="ltif_inj" type="number" placeholder="0" style="width:80px;padding:6px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px"></div>
<button class="btn btn-sm btn-g" onclick="saveLTIF()">Сохранить</button>
<button class="btn btn-sm" onclick="loadLTIF()">Загрузить</button>
</div>
<div id="ltif_result" style="font-size:14px;padding:8px 0"></div>
<div id="ltif_table"></div>
<div id="ltif_corr_div"></div>
</div>
</div>
<div id="tab_reports" style="display:none">
<div class="card"><h3>Выгрузка сводного отчёта</h3>
<p style="font-size:13px;color:#64748B;margin-bottom:12px">Выберите период и формат для скачивания отчёта.</p>
<div class="fr">
<span style="font-size:13px;color:#64748B">Период:</span>
<select id="rp_period" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px" onchange="rpPeriodChange()">
<option value="year">Год</option>
<option value="month">Месяц</option>
<option value="q1">Январь-Март (Q1)</option>
<option value="q2">Апрель-Июнь (Q2)</option>
<option value="q3">Июль-Сентябрь (Q3)</option>
<option value="q4">Октябрь-Декабрь (Q4)</option>
<option value="h1">1-е полугодие</option>
<option value="h2">2-е полугодие</option>
</select>
<span style="font-size:12px;color:#64748B">Период:</span> <select id="rp_month_dd" onchange="rpDropdownChange()" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px;min-width:160px"></select>
<span style="font-size:12px;color:#64748B;display:none">с</span> <select id="rp_month_from" style="display:none" onchange="renderReports()" style="padding:6px 8px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px">
<option value="0">Январь</option><option value="1">Февраль</option><option value="2">Март</option>
<option value="3">Апрель</option><option value="4">Май</option><option value="5">Июнь</option>
<option value="6">Июль</option><option value="7">Август</option><option value="8">Сентябрь</option>
<option value="9">Октябрь</option><option value="10">Ноябрь</option><option value="11">Декабрь</option>
</select>
<span style="font-size:12px;color:#64748B;display:none">по</span> <select id="rp_month_to" style="display:none" onchange="renderReports()" style="padding:6px 8px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px">
<option value="0">Январь</option><option value="1">Февраль</option><option value="2">Март</option>
<option value="3">Апрель</option><option value="4">Май</option><option value="5">Июнь</option>
<option value="6">Июль</option><option value="7">Август</option><option value="8">Сентябрь</option>
<option value="9">Октябрь</option><option value="10">Ноябрь</option><option value="11" selected>Декабрь</option>
</select>
<select id="rp_year" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px">
<option>2026</option><option>2027</option>
</select>
<select id="rp_status" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px">
<option value="">Все статусы</option>
<option value="warn">В процессе</option>
<option value="done">Исполнено</option>
<option value="late">Просрочено</option>
</select>
</div>
<div style="display:flex;gap:8px;flex-wrap:wrap">
<button class="btn btn-sm btn-g" onclick="dlCSV()">CSV</button>
<button class="btn btn-sm" onclick="dlHTML()">HTML</button>
<button class="btn btn-sm btn-o" onclick="dlWord()">Word</button>
<button class="btn btn-sm" style="background:#7C3AED;color:#fff" onclick="dlZip()">ZIP</button>
<button class="btn btn-sm btn-r" onclick="dlPdf()">PDF</button>
</div>
<p id="rp_count" style="font-size:12px;color:#64748B;margin-top:8px"></p>
</div>
<div class="card" id="rp_preview"></div>
</div>
<div id="tab_users" style="display:none">
<div class="card"><h3>Учётные записи</h3>
<p style="font-size:13px;color:#64748B;margin-bottom:8px">Управление ответственными лицами по филиалам</p>
<button class="btn btn-sm btn-g" onclick="showRegModal()">+ Зарегистрировать</button>
<div id="users_list" style="margin-top:14px"></div>
</div></div>
<div id="tab_hse" style="display:none">
<div class="card"><h3>Интеграция с HSE.sk.kz</h3>
<p style="font-size:13px;color:#64748B;margin-bottom:16px">Направление подписанного сводного отчёта по месяцам в систему hse.sk.kz</p>
<div style="margin-bottom:12px"><strong>Месяц:</strong>
<input type="month" id="hse_month" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;margin-left:8px">
</div>
<div style="margin-bottom:12px"><strong>Формат:</strong>
<select id="hse_fmt" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;margin-left:8px">
<option value="word">Word (.docx)</option>
<option value="pdf">PDF</option>
</select>
</div>
<div style="margin-bottom:12px"><strong>API Ключ:</strong>
<input id="hse_key" type="password" placeholder="Ключ API HSE.sk.kz" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;margin-left:8px;width:300px">
</div>
<button class="btn btn-sm btn-g" onclick="hseSend()" id="hse_btn">Отправить отчёт в HSE.sk.kz</button>
<div id="hse_result" style="margin-top:12px;font-size:13px"></div>
</div></div>
<div id="tab_ai" style="display:none">
<div class="card">
<div class="chat-q">
<button onclick="aiAsk('сводка')">Сводка</button>
<button onclick="aiAsk('просроченные')">Просроченные</button>
<button onclick="aiAsk('риски')">Риски</button>
<button onclick="aiAsk('рейтинг')">Рейтинг</button>
<button onclick="aiAsk('прогноз')">Прогноз</button>
<button onclick="aiAsk('статус')">Статус</button>
<button onclick="aiAsk('план')">План действий</button>
</div>
<div class="chat-box" id="ai_chat"></div>
<div class="chat-inp"><input id="ai_inp" placeholder="Спроси про план ПБ..." onkeydown="if(event.key=='Enter')aiSend()">
<button class="btn btn-sm" onclick="aiSend()">Отправить</button></div>
</div></div>
</div></div>
<div id="modal" class="mod-overlay" onclick="if(event.target===this)closeModal()">
<div class="mod-box" id="modal_body"></div>
</div>
<div id="regModal" class="mod-overlay" onclick="if(event.target===this)closeRegModal()">
<div class="mod-box" style="max-width:500px">
<h3 style="margin-bottom:14px">Регистрация пользователя</h3>
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Email (логин)</label>
<input id="reg_email" placeholder="ivanov@telecom.kz" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">ФИО</label>
<input id="reg_name" placeholder="Иванов И.И." style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Телефон</label>
<input id="reg_phone" placeholder="+77001234567" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Роль</label>
<select id="reg_role" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></select></div>
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Филиал</label>
<select id="reg_branch" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></select></div>
<div style="margin-bottom:14px"><label style="font-size:12px;color:#64748B">Пароль</label>
<input id="reg_pass" type="password" placeholder="****" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
<div style="display:flex;gap:8px;justify-content:flex-end">
<button class="btn btn-sm" style="background:#E2E8F0;color:#0B1A2E" onclick="closeRegModal()">Отмена</button>
<button class="btn btn-sm btn-g" onclick="addUser()">Зарегистрировать</button>
<p style="font-size:11px;color:#64748B;margin-top:8px">На корпоративную почту придёт уведомление о регистрации и напоминания о необходимости представления отчёта</p>
</div></div></div>
<script>
var ALL_EVENTS=[
{
"id": 1,
"sec": 0,
"b": 6,
"s": "warn",
"p": 45,
"due": "31.12.2026",
"done": "—",
"dname": "Сертификаты, протоколы, электронная ведомость обучения",
"r": "Генеральный директор КУ\nГенеральные директора филиалов и ДАО",
"t": "Продолжить проведение обучения и повышения квалификации руководителей и работников компании в соответствии с лучшими международными практиками, ориентированными на специфику условий труда, работы повышенной опасности и требований промышленной безопасности, а также развитие культуры безопасности, включая обучение производственного персонала по курсу «Культура безопасного труда», в том числе с применением VR, AR технологий и цифровых симуляторов аварийных ситуаций по различным направлениям производственной безопасности (с правом выдачи сертификатов).",
"ai": "Обучение ведётся по графику. Охвачено 45% персонала.",
"h": [
"15.01 — Создано",
"01.03 — Запущено"
]
},
{
"id": 2,
"sec": 0,
"b": 0,
"s": "done",
"p": 100,
"due": "31.03.2026",
"done": "28.03.2026",
"dname": "Отчёт о проведённом анализе, утверждённый ВНД",
"r": "Директор ДПБ\nГенеральный директор ДИТ\nГенеральные директора филиалов и ДАО",
"t": "Провести анализ, в том числе с использованием аналитических платформ (Microsoft Teams, Power BI, Tableau, Qlik и др.), и в случае необходимости, осуществить пересмотр внутренних нормативных документов филиалов/ДАО Общества в соответствии со «Стратегией развития производственной безопасности АО «Самрук-Қазына» на 2024-2028 гг.», включая установку значений ключевых показателей производственной безопасности.",
"ai": "Анализ завершён в срок.",
"h": [
"10.01 — Создано",
"28.03 — Утверждён"
]
},
{
"id": 3,
"sec": 0,
"b": 0,
"s": "warn",
"p": 50,
"due": "31.12.2026",
"done": "—",
"dname": "Протоколы совещаний (a, b, c)",
"r": "а) Главный административный директор, Директор ДПБ\nГенеральные директора филиалов и ДАО\nb, c) Генеральные директора филиалов и ДАО",
"t": "Организовывать тематические совещания по вопросам производственной безопасности, в том числе с целью разъяснения внедряемых программ и инициатив:\na) руководство Общества с филиалами/ДАО Общества, не менее одного раза в квартал, в том числе с целью личного мониторинга показателей эффективности по производственной безопасности в рамках «Стратегии развития производственной безопасности АО «Самрук-Қазына» на 2024-2028 гг.» и статуса исполнения «Плана мероприятий по производственной безопасности АО «Самрук-Қазына» на 2026 год»;\nb) руководство филиалов/ДАО Общества со структурными подразделениями, не менее 1 раза в месяц;\nc) руководство региональных подразделений/филиалов/ДАО Общества с подрядными организациями, осуществляющими работы/предоставляющими услуги на объектах, не менее 1 раза в квартал.",
"ai": "Проведено 2 квартальных совещания.",
"h": [
"10.01 — Создано",
"15.02 — Q1",
"15.05 — Q2"
],
"sub": [
{
"l": "a",
"t": "Руководство Общества с филиалами/ДАО Общества, не менее одного раза в квартал, с личным мониторингом показателей эффективности"
},
{
"l": "b",
"t": "Руководство филиалов/ДАО Общества со структурными подразделениями, не менее 1 раза в месяц"
},
{
"l": "c",
"t": "Руководство региональных подразделений/филиалов/ДАО с подрядными организациями, не менее 1 раза в квартал"
}
]
},
{
"id": 4,
"sec": 0,
"b": 6,
"s": "warn",
"p": 55,
"due": "31.12.2026",
"done": "—",
"dname": "Отчёт о проделанной работе, тесты",
"r": "Генеральные директора филиалов и ДАО",
"t": "Продолжить практику проверки знаний в формате тестирования после проведения инструктажей по охране труда в филиалах/ДАО Общества.",
"ai": "Тестирование внедрено в 6 филиалах. Средний результат — 82%.",
"h": [
"01.02 — Создано"
]
},
{
"id": 5,
"sec": 0,
"b": 0,
"s": "done",
"p": 100,
"due": "31.03.2026",
"done": "25.03.2026",
"dname": "Информация о нематериальном поощрении",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Рассмотреть возможность нематериального поощрения филиалов и ДАО Общества, демонстрирующих устойчивое снижение количества несчастных случаев, пожаров и аварий по итогам нескольких и более лет.",
"ai": "Положение утверждено.",
"h": [
"15.01 — Проект",
"25.03 — Утверждено"
]
},
{
"id": 6,
"sec": 0,
"b": 6,
"s": "warn",
"p": 60,
"due": "30.06.2026",
"done": "—",
"dname": "Утверждённый ВНД, перечень внутренних тренеров",
"r": "Генеральный директор КУ\nУправляющий директор по персоналу\nГенеральные директора филиалов и ДАО",
"t": "Разработать/внести изменения в случае необходимости и утвердить внутренний нормативный документ, регламентирующий процедуру работы внутренних тренеров, в том числе по производственной безопасности, включая порядок их отбора, подготовки и привлечения, а также установление условий доплаты к основной заработной плате за выполнение тренерских функций.",
"ai": "Проект ВНД на финальном согласовании.",
"h": [
"01.03 — Создано"
]
},
{
"id": 7,
"sec": 0,
"b": 1,
"s": "warn",
"p": 40,
"due": "31.12.2026",
"done": "—",
"dname": "Материалы, рассмотренные в рамках обмена опытом",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Проводить мероприятия по обмену опытом в области производственной безопасности:\na) Продолжить практику обмена передовым опытом на площадке Комитета HSE, в том числе путем выездов на производственные объекты ПК, с целью последующего тиражирования успешных практик в ПК.\nb) Рассмотреть возможность организации обмена опытом в области производственной безопасности для работников ПК с иностранными и казахстанскими компаниями, соответствующих деятельности ПК, в том числе путем проведения онлайн-семинаров.",
"ai": "Проведён 1 выезд на KEGOC.",
"h": [
"15.02 — Создано",
"01.04 — Выезд"
],
"sub": [
{
"l": "a",
"t": "Продолжить практику обмена передовым опытом на площадке Комитета HSE, в том числе путем выездов на производственные объекты ПК"
},
{
"l": "b",
"t": "Рассмотреть возможность организации обмена опытом с иностранными и казахстанскими компаниями, в том числе путем проведения онлайн-семинаров"
}
]
},
{
"id": 8,
"sec": 0,
"b": 4,
"s": "wait",
"p": 15,
"due": "30.09.2026",
"done": "—",
"dname": "Заключительный Акт, программа Well-being, отчёт о скрининге, отчёт о микротравмах",
"r": "а) Директор ДПБ\nb) Генеральный директор КУ\nУправляющий директор по персоналу\nc) Управляющий директор по персоналу\nГенеральные директора филиалов и ДАО\nd) Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Провести анализ эффективности реализуемых мероприятий по охране здоровья:\na) организовать и обеспечить 100% прохождение обязательных периодических медицинских осмотров работниками, включая офисных работников;\nb) организовать ежегодную «Неделю благополучия» (Well-being Week) для работников всех уровней, предусматривая практические мероприятия по стресс-менеджменту, ментальному здоровью и физической активности;\nc) создать условия и обеспечить контроль за прохождением медицинского скрининга работников в соответствии с Приказом и.о. Министра Здравоохранения РК от 30 октября 2020 года №КР ДСМ-174/2020, в том числе в целях раннего диагностирования факторов риска сердечно-сосудистых заболеваний;\nd) внедрить алгоритм учета и расследования микротравм, а также фиксировать использование содержимого медицинских аптечек путем регистрации и расследования данных случаев.",
"ai": "Медосмотры — Q3. Well-being — сентябрь.",
"h": [
"01.04 — Создано"
],
"sub": [
{
"l": "a",
"t": "Организовать и обеспечить 100% прохождение обязательных периодических медицинских осмотров работниками, включая офисных работников"
},
{
"l": "b",
"t": "Организовать ежегодную «Неделю благополучия» (Well-being Week) для работников всех уровней"
},
{
"l": "c",
"t": "Создать условия и обеспечить контроль за прохождением медицинского скрининга работников"
},
{
"l": "d",
"t": "Внедрить алгоритм учета и расследования микротравм, фиксировать использование содержимого медицинских аптечек"
}
]
},
{
"id": 9,
"sec": 0,
"b": 6,
"s": "wait",
"p": 20,
"due": "31.12.2026",
"done": "—",
"dname": "Результаты конкурсов, пакет материалов",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Рассмотреть возможность участия ДПБ/филиалов/ДАО Общества в международных/национальных конкурсах и отраслевых соревнованиях профессионального мастерства в области производственной безопасности.",
"ai": "Определены 2 конкурса.",
"h": [
"01.05 — Создано"
]
},
{
"id": 10,
"sec": 1,
"b": 1,
"s": "warn",
"p": 55,
"due": "31.12.2026",
"done": "—",
"dname": "Аналитическая справка в разбивке по филиалам/ДАО",
"r": "Генеральный директор ОДС\nГенеральный директор СФ\nГенеральный директор ДУП\nГенеральный директор ДИТ",
"t": "Проводить работы по техническому перевооружению морально и физически изношенного оборудования, зданий и сооружений, эксплуатация которых из-за их технического состояния сопровождается повышенными рисками возникновения аварий и несчастных случаев с тяжёлыми и летальными исходами, в соответствии с ранее утвержденными Планами на 2024-2027 годы.",
"ai": "По плану 2024-2027. Заменено 55%.",
"h": [
"01.01 — Переходящее"
]
},
{
"id": 11,
"sec": 1,
"b": 1,
"s": "warn",
"p": 70,
"due": "30.06.2026",
"done": "—",
"dname": "Переутверждённая процедура, фотоотчёт, протоколы обучения",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Пересмотреть и актуализировать внутренний порядок выдачи нарядно-допускной системы, усилив законодательные требования Республики Казахстан путем внедрения в пилотном режиме практики применения сертификатов безопасности для одного из видов работ повышенной опасности. Указанные сертификаты должны содержать исчерпывающую информацию о потенциальных рисках и мерах безопасности перед началом работ, предусматривать обязательный замер газовоздушной среды при работах в замкнутом пространстве, анализ плана участка и исполнительных чертежей, установку защитных барьеров при проведении земляных работ, выполнение электрической изоляции источников опасности с обязательной проверкой отсутствия напряжения, а также меры безопасности при проведении радиографических работ.",
"ai": "Процедура пересмотрена. Пилот запущен.",
"h": [
"01.02 — Создано"
]
},
{
"id": 12,
"sec": 1,
"b": 8,
"s": "wait",
"p": 8,
"due": "30.09.2026",
"done": "—",
"dname": "Справка о внедрении, фотоотчёт",
"r": "Генеральные директора филиалов и ДАО",
"t": "Рассмотреть возможность внедрения системы цифровой маркировки опасных технических устройств, предусматривающей присвоение каждому устройству QR-кода для обеспечения быстрого доступа к паспорту, инструкции по эксплуатации и информации о проведенных технических освидетельствованиях, с учетом возможности использования мобильных телефонов на опасных производственных объектах.",
"ai": "Проект на стадии ТЭО.",
"h": [
"01.05 — Создано"
]
},
{
"id": 13,
"sec": 1,
"b": 0,
"s": "warn",
"p": 50,
"due": "31.12.2026",
"done": "—",
"dname": "Акты проверок и график",
"r": "Директор ДПБ",
"t": "Филиалам/ДАО Общества не реже 1 раза в квартал проводить проверку согласно адаптированным проверочным листам, в области БиОТ, промышленной и пожарной безопасности в соответствии с требованиями законодательства Республики Казахстан.",
"ai": "Q1 завершены. Q2 — по графику.",
"h": [
"01.01 — Создано"
]
},
{
"id": 14,
"sec": 1,
"b": 0,
"s": "warn",
"p": 40,
"due": "31.12.2026",
"done": "—",
"dname": "Письмо о предоставлении кандидата",
"r": "Директор ДПБ",
"t": "Продолжить практику участия в перекрёстных аудитах ПК, в том числе в соответствии с Планом-графиком проведения аудитов.",
"ai": "Назначены 4 аудитора.",
"h": [
"15.01 — Назначены"
]
},
{
"id": 15,
"sec": 1,
"b": 0,
"s": "warn",
"p": 48,
"due": "31.12.2026",
"done": "—",
"dname": "Аналитическая справка, Журнал «Опережающие индикаторы»",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Усилить контроль за применением проактивных инструментов:\nа) Продолжить мониторинг применения проактивных инструментов предотвращения аварий и несчастных случаев (проведение поведенческих аудитов/наблюдений безопасности, регистрация и расследование опасных условий, опасных действий и потенциально опасных происшествий Near Miss; право приостановки работы) с целью выработки корректирующих мероприятий, исключения формализма и занесения достоверных данных в Журнал «Опережающие индикаторы» Системы управления отчетности АО «Самрук-Қазына» и потенциально опасных происшествий Near Miss.",
"ai": "147 Near Miss. Аудиты — 320 шт.",
"h": [
"01.01 — Создано"
]
},
{
"id": 16,
"sec": 1,
"b": 1,
"s": "done",
"p": 85,
"due": "31.12.2026",
"done": "—",
"dname": "План-график аудитов, Акты, Протоколы совещаний",
"r": "Генеральные директора филиалов и ДАО",
"t": "Провести работу по повышению эффективности управления подрядными организациями, в том числе:\na) обеспечить проведение согласно типового чек-листа, разработанного Фондом, аудита подрядчиков внутри филиалов/ДАО Общества выборочных перекрёстных аудитов подрядных организаций, осуществляющих работы по договорам на оказание услуг сроком от 6 месяцев и более на объектах предприятий, преимущественно в которых произошли несчастные случаи со смертельным и тяжелым исходами, с участием специалистов службы производственной безопасности Общества и ДАО, не связанных с проверяемыми объектами;\nb) продолжить практику проведения стартовых/установочных совещаний с подрядными организациями перед допуском на территорию объекта филиалов/ДАО Общества с целью ознакомления с внутренними нормативными документами по производственной безопасности, а также информацией об опасных производственных объектах, оборудовании и (или) территории, создающих угрозу жизни и здоровью людей.",
"ai": "Q1 — 12 подрядчиков проверено.",
"h": [
"15.01 — План"
],
"sub": [
{
"l": "a",
"t": "Обеспечить проведение аудита подрядчиков согласно типового чек-листа Фонда"
},
{
"l": "b",
"t": "Продолжить практику проведения стартовых/установочных совещаний с подрядными организациями перед допуском на объект"
}
]
},
{
"id": 17,
"sec": 1,
"b": 0,
"s": "warn",
"p": 35,
"due": "31.12.2026",
"done": "—",
"dname": "Отчёты, график проверок, фотоотчёт",
"r": "а) Главный административный директор, Директор ДПБ\nb) Генеральные директора филиалов и ДАО",
"t": "Обеспечить контроль за состоянием производственной безопасности на производственных объектах:\nа) руководителям Общества уровня СЕО-1, курирующим вопросы производственной безопасности в Обществе, не реже одного раза в квартал лично проверять одно из филиалов Общества/подрядных организаций или участок, в зависимости от структуры и специфики Общества с обязательным представлением актов по результатам проверок в Фонд;\nb) первым руководителям и руководителям линейных подразделений филиалов Общества лично принимать участие во внутреннем производственном контроле с посещением производственных площадок не реже одного раза в квартал.",
"ai": "CEO-1: 2 филиала.",
"h": [
"01.02 — Создано"
],
"sub": [
{
"l": "a",
"t": "Руководителям уровня СЕО-1 не реже одного раза в квартал лично проверять филиал/подрядчика"
},
{
"l": "b",
"t": "Первым руководителям филиалов лично принимать участие в контроле с посещением площадок"
}
]
},
{
"id": 18,
"sec": 1,
"b": 1,
"s": "done",
"p": 90,
"due": "31.12.2026",
"done": "—",
"dname": "Ежемесячный сводный отчёт",
"r": "Генеральные директора филиалов и ДАО\nДиректор ДПБ",
"t": "Обеспечить контроль за состоянием транспортной безопасности, в том числе путем ежемесячного мониторинга нарушений требований транспортной безопасности со стороны штатных водителей и водителей подрядных организаций, оказывающих транспортные услуги по перевозке работников, с последующим применением предусмотренных договорами мер воздействия, включая штрафные санкции и ограничения на допуск к работам.",
"ai": "34 нарушения. Тренд — снижение.",
"h": [
"01.01 — Создано"
]
},
{
"id": 19,
"sec": 2,
"b": 1,
"s": "warn",
"p": 30,
"due": "31.12.2026",
"done": "—",
"dname": "Акты тренировок, пресс-релизы",
"r": "a) Управляющий директор по безопасности, Руководители ДАО\nb) Генеральный директор СФ, Руководители ДАО\nс) Управляющий директор по безопасности\nГенеральные директора филиалов и ДАО",
"t": "Обеспечить проведение:\nа) не менее одной учебной тревоги и/или противоаварийной тренировки по ликвидации крупной аварии, ЧС на опасном производственном объекте с привлечением Фонда и государственных органов;\nb) не менее двух тренировок по тушению пожара в административных зданиях (офисах) с привлечением государственных органов;\nc) не менее одного практического занятия по оказанию первой помощи с применением симуляционного оборудования в условиях ЧС техногенного и природного характера.",
"ai": "1 учение. Пожарные: 1 из 2.",
"h": [
"01.02 — Создано"
],
"sub": [
{
"l": "a",
"t": "Не менее одной учебной тревоги/противоаварийной тренировки"
},
{
"l": "b",
"t": "Не менее двух тренировок по тушению пожара"
},
{
"l": "c",
"t": "Не менее одного занятия по оказанию первой помощи"
}
]
},
{
"id": 20,
"sec": 2,
"b": 0,
"s": "warn",
"p": 65,
"due": "30.06.2026",
"done": "—",
"dname": "Приказ о внедрении, материалы обучения, акты штабов",
"r": "Управляющий директор по безопасности\nГенеральные директора филиалов и ДАО",
"t": "Усилить работу по реагированию на ЧС:\nа) внедрить процедуру «Crisis Management System» (Система управления кризисными ситуациями) для обеспечения своевременной и согласованной реакции на всех уровнях управления на кризисные события, а также сокращение ущерба для работников, активов, окружающей среды и репутации компании;\nb) рассмотреть возможность проведения обучения для ответственных работников филиалов/ДАО Общества по действиям в условиях ЧС;\nc) провести не менее двух заседаний штабов с целью отработки действий на практике.",
"ai": "CMS внедрена. Обучение — 60%.",
"h": [
"01.03 — Создано"
],
"sub": [
{
"l": "a",
"t": "Внедрить процедуру «Crisis Management System»"
},
{
"l": "b",
"t": "Провести обучение ответственных работников по действиям в условиях ЧС"
},
{
"l": "c",
"t": "Провести не менее двух заседаний штабов"
}
]
},
{
"id": 21,
"sec": 3,
"b": 0,
"s": "done",
"p": 100,
"due": "31.12.2026",
"done": "15.02.2026",
"dname": "Публикация на информационных порталах",
"r": "Директор ДПБ\nПресс-секретарь ЦА",
"t": "Обеспечить выпуск обращения от Председателя Правления ПК о важности соблюдения требований по производственной безопасности.",
"ai": "Опубликовано. Охват — 100%.",
"h": [
"15.02 — Публикация"
]
},
{
"id": 22,
"sec": 3,
"b": 0,
"s": "wait",
"p": 15,
"due": "31.12.2026",
"done": "—",
"dname": "Протоколы форумов, протоколы семинаров",
"r": "a) Директор ДПБ\nГенеральные директора филиалов и ДАО\nДепартамент по коммуникациям и продвижению бренда\nb) Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Проведение мероприятий по производственной безопасности:\na) в филиалах/ДАО Общества стратегических сессий/Форумов для первых руководителей филиалов/ДАО Общества;\nb) рассмотреть возможность проведения семинаров для подрядных организаций ПК на отдельных площадках филиалов/ДАО Общества.",
"ai": "Форум — октябрь.",
"h": [
"01.05 — Создано"
],
"sub": [
{
"l": "a",
"t": "В филиалах/ДАО стратегические сессии/Форумы для первых руководителей"
},
{
"l": "b",
"t": "Семинары для подрядных организаций ПК на отдельных площадках"
}
]
},
{
"id": 23,
"sec": 3,
"b": 6,
"s": "wait",
"p": 10,
"due": "30.09.2026",
"done": "—",
"dname": "Протокол итогов Олимпиады",
"r": "Директор ДПБ",
"t": "Проведение Олимпиады по производственной безопасности среди специалистов производственной безопасности Общества и подрядных организации на уровне Общества.",
"ai": "Положение на согласовании.",
"h": [
"01.05 — Создано"
]
},
{
"id": 24,
"sec": 3,
"b": 0,
"s": "done",
"p": 92,
"due": "31.12.2026",
"done": "—",
"dname": "Информационные бюллетени, листы ознакомления",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Обеспечить ознакомление всех работников филиалов/ДАО Общества с обстоятельствами несчастных случаев с тяжелым и летальным исходами, произошедших в ПК Фонда, и относящихся к специфике деятельности Общества, посредством направления информационных бюллетеней, в том числе с использованием цифровых решений либо в рамках внеплановых инструктажей.",
"ai": "3 бюллетеня, 92%.",
"h": [
"01.01 — Создано"
]
},
{
"id": 25,
"sec": 3,
"b": 6,
"s": "warn",
"p": 40,
"due": "31.12.2026",
"done": "—",
"dname": "Публикации в SK News, материалы мероприятий",
"r": "a) Управляющий директор по персоналу\nДепартамент по коммуникациям и продвижению бренда\nГенеральные директора филиалов и ДАО\nb) Директор ДПБ\nГенеральные директора филиалов и ДАО\nc) Директор ДПБ\nd) Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Проведение молодежных проектных инициатив в рамках работы Центра молодых работников по производственной безопасности группы компаний АО «Самрук-Қазына» с целью вовлечения молодых специалистов в вопросы производственной безопасности, в том числе:\na) публикация реальных историй из трудовой жизни работников в корпоративном журнале «SK News»;\nb) посещение рабочих мест, где в 2022-2025 годах произошли несчастные случаи с летальным или тяжелым исходом;\nc) привлечение молодых специалистов по производственной безопасности в перекрёстные аудиты состояния производственной безопасности ДЗО ПК АО «Самрук-Қазына»;\nd) онлайн-семинары/прямые эфиры на различные темы по вопросам производственной безопасности.",
"ai": "2 истории в SK News.",
"h": [
"01.02 — Создано"
],
"sub": [
{
"l": "a",
"t": "Публикация реальных историй из трудовой жизни работников в журнале «SK News»"
},
{
"l": "b",
"t": "Посещение рабочих мест, где в 2022-2025 годах произошли несчастные случаи"
},
{
"l": "c",
"t": "Привлечение молодых специалистов в перекрёстные аудиты"
},
{
"l": "d",
"t": "Онлайн-семинары/прямые эфиры на темы производственной безопасности"
}
]
},
{
"id": 26,
"sec": 3,
"b": 2,
"s": "warn",
"p": 50,
"due": "31.12.2026",
"done": "—",
"dname": "Видеоролики, постеры, брошюры",
"r": "а) Генеральные директора филиалов и ДАО\nb) и с) Директор ДПБ\nДепартамент по коммуникациям и продвижению бренда\nГенеральные директора филиалов и ДАО\nd) Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Усилить наглядную агитацию по производственной безопасности:\nа) Продолжить работы по разработке и использованию видеороликов/презентаций по производственной безопасности, в том числе:\n- с участием работников, получивших травму, а также членов семей работников (с их согласия);\n- с участием нарушителей требований безопасности и охраны труда, включая разбор ошибок и разработку мер по предотвращению аналогичных случаев в будущем (с их согласия).\nb) Разработать серии специализированных видеороликов:\n- в формате «Безопасность будущего», направленный на демонстрацию внедряемых цифровых и ИИ-решений в сфере производственной безопасности в группе Фонда;\n- по профилактике производственного травматизма с акцентом на наиболее опасные риски (ДТП, падения с высоты, работа с движущимися механизмами и т.д.).\nc) Рассмотреть возможность выпуска подкаста с участием трудовых династий о переходе от ручного труда к автоматизации и цифровизации, способствующем повышению уровня производственной безопасности.\nd) Продолжить работы по разработке и распространению постеров, брошюр, информационных рассылок на различные темы по соблюдению производственной безопасности.",
"ai": "2 видеоролика снято.",
"h": [
"01.02 — Создано"
],
"sub": [
{
"l": "a",
"t": "Разработка и использование видеороликов/презентаций по ПБ"
},
{
"l": "b",
"t": "Серии видеороликов «Безопасность будущего» и по профилактике травматизма"
},
{
"l": "c",
"t": "Выпуск подкаста с участием трудовых династий"
},
{
"l": "d",
"t": "Разработка и распространение постеров, брошюр, рассылок"
}
]
},
{
"id": 27,
"sec": 3,
"b": 3,
"s": "warn",
"p": 30,
"due": "31.12.2026",
"done": "—",
"dname": "Фотофиксация",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Рассмотрение возможности организации встреч коллектива с получившими производственные травмы работниками (с их согласия) с целью предупреждения аналогичных случаев травматизма.",
"ai": "1 встреча проведена.",
"h": [
"01.03 — Создано"
]
},
{
"id": 28,
"sec": 3,
"b": 0,
"s": "warn",
"p": 25,
"due": "31.12.2026",
"done": "—",
"dname": "Информационное письмо, пресс-релизы",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО\nДепартамент по коммуникациям и продвижению бренда",
"t": "Проведение мероприятий, направленных на пропаганду безопасного выполнения работ через семейные ценности:\nа) направление информационного письма членам семьи (супруг/а, родители) работника, положительно отличившегося в вопросах производственной безопасности;\nb) проведение Семейных дней охраны труда и дней открытых дверей для семей работников, в том числе на тему «Золотые правила безопасности для детей», с целью воспитания подрастающего поколения в традициях безопасности;\nc) проведение конкурса рисунков среди работников и их детей по безопасной работе и соблюдению правил на производстве на тему «Спецодежда будущего!».",
"ai": "5 писем семьям.",
"h": [
"01.04 — Создано"
],
"sub": [
{
"l": "a",
"t": "Направление письма членам семьи работника, отличившегося в вопросах ПБ"
},
{
"l": "b",
"t": "Проведение Семейных дней охраны труда и дней открытых дверей"
},
{
"l": "c",
"t": "Конкурс рисунков «Спецодежда будущего!»"
}
]
},
{
"id": 29,
"sec": 3,
"b": 6,
"s": "late",
"p": 40,
"due": "30.06.2026",
"done": "—",
"dname": "Корпоративный сборник лучших практик",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Разработать корпоративный сборник лучших практик по производственной безопасности в формате методического пособия или интерактивного PDF документа, отражающий меры по снижению производственного травматизма и управлению критическими рисками. В сборнике предусмотреть описание сути инициатив, перечень ключевых рисков (железнодорожные происшествия, ДТП, работы на высоте и др.), реализованные мероприятия, а также достигнутые результаты за последние пять лет.",
"ai": "Риск срыва Q2.",
"h": [
"01.03 — Создано"
]
},
{
"id": 30,
"sec": 3,
"b": 7,
"s": "warn",
"p": 60,
"due": "31.12.2026",
"done": "—",
"dname": "Предложения, план реализации",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Сбор предложений по совершенствованию системы управления производственной безопасности посредством применения цифровых решений с консолидацией в ДПБ.",
"ai": "18 предложений.",
"h": [
"01.01 — Создано"
]
},
{
"id": 31,
"sec": 3,
"b": 0,
"s": "warn",
"p": 75,
"due": "30.06.2026",
"done": "—",
"dname": "Видеообзор",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Разработка видеообзора кейсов происшествий в ПК с учетом специфики деятельности (из доступных на открытых медиа источниках) для наглядной демонстрации и разъяснения работникам о необходимости и важности соблюдения требований безопасности.",
"ai": "Монтаж 75%.",
"h": [
"01.03 — Создано"
]
},
{
"id": 32,
"sec": 4,
"b": 8,
"s": "warn",
"p": 70,
"due": "30.06.2026",
"done": "—",
"dname": "Справка, скриншоты чат-бота",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Обеспечить применение в филиалах/ДАО Общества чат-бот ИИ ассистент по производственной безопасности с целью упрощения доступа к нормативно-правовым актам Республики Казахстан и ВНД группы Фонда.",
"ai": "Чат-бот тестируется.",
"h": [
"01.02 — Создано"
]
},
{
"id": 33,
"sec": 4,
"b": 8,
"s": "wait",
"p": 15,
"due": "31.12.2026",
"done": "—",
"dname": "Справка, скриншоты системы",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Обеспечить применение в филиалах/ДАО Общества интегрированную систему анализа и предупреждения несчастных случаев и критических происшествий, а также платформу по идентификации и оценке рисков перед началом проведения работ на опасных производственных объектах.",
"ai": "ТЗ согласовывается.",
"h": [
"01.04 — Создано"
]
},
{
"id": 34,
"sec": 4,
"b": 8,
"s": "wait",
"p": 10,
"due": "31.12.2026",
"done": "—",
"dname": "Справка, скриншоты HSE паспорта",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Рассмотреть возможность запуска в филиалах/ДАО Общества электронного HSE паспорта на каждого работника с последующей интеграцией в корпоративную цифровую систему. Электронный HSE паспорт должен содержать сведения о прохождении инструктажей, обучения и проверок знаний, результаты медицинских осмотров, а также данные о выданных СИЗ, допусках к видам работ, стаже и квалификации.",
"ai": "Концепция утверждена.",
"h": [
"01.05 — Создано"
]
},
{
"id": 35,
"sec": 4,
"b": 5,
"s": "wait",
"p": 8,
"due": "31.12.2026",
"done": "—",
"dname": "Справка, скриншоты системы",
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
"t": "Рассмотреть возможность внедрения системы оформления нарядов-допусков на проведение работ повышенной опасности в электронном виде в филиалах/ДАО Общества.",
"ai": "Предпроект.",
"h": [
"01.05 — Создано"
]
}
];
var cu=null,evs=[],tab="events",curSub=null;
var secs=["Раздел I. Обучение, компетенции и культура безопасности","Раздел II. Техническая безопасность и надежность","Раздел III. Готовность к ЧС","Раздел IV. Коммуникации и вовлеченность","Раздел V. Цифровизация и инновации"];
var brs=["Дирекция производственной безопасности","Объединение «Дивизион «Сеть»","Дивизион по корпоративному бизнесу","Дивизион по розничному бизнесу","Сервисная фабрика","Дирекция «Телеком Комплект»","Корпоративный университет","Дирекция управления проектами","Дивизион цифрового бизнеса"];
var stn={warn:"В процессе",late:"Просрочено",done:"Исполнено"};
var stc={warn:"a",late:"r",done:"g"};
var USR={curator:{n:"Куратор ПБ",bg:0},admin:{n:"Администратор",bg:0},dpp:{n:"Директор ДПБ",bg:0},ivanov:{n:"Иванов Иван",bg:1},petrov:{n:"Петров Петр",bg:2},sidorov:{n:"Сидоров Сидор",bg:3},kozhin:{n:"Кожин А.М.",bg:4},ismailov:{n:"Исмаилов Р.К.",bg:1},nurpeisov:{n:"Нурпеисов Д.А.",bg:5},suleimenov:{n:"Сулейменов К.Т.",bg:6},kassenov:{n:"Касенов Б.Б.",bg:7},serikov:{n:"Сериков Е.С.",bg:8},zhunusov:{n:"Жунусов А.А.",bg:2},muratov:{n:"Муратов А.Т.",bg:3},bakirov:{n:"Бакиров Т.Н.",bg:4}};
function cleanTitle(e){if(!e||!e.t)return"";if(!e.sub||!e.sub.length)return e.t;var t=e.t;var nl=String.fromCharCode(10);var idx=-1;var ls=["a)","b)","c)","d)","e)","а)","б)","в)","г)","д)"];for(var i=0;i<ls.length;i++){var p=t.indexOf(nl+ls[i]);if(p>0&&(idx<0||p<idx))idx=p}if(idx<0){idx=t.indexOf(":"+nl+"a");if(idx>0)idx++}if(idx<0){var m=t.match(new RegExp(nl+"[a-zа-я]+[\)\u0029]"));if(m)idx=t.indexOf(m[0])}return idx>0?t.substring(0,idx).trim():t}
function esc(s){
return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")
}
function nl2c(s){
if(!s)return"";
return s.split(String.fromCharCode(10)).join(", ")
}
function subResp(r,letter){
if(!r)return"";
var parts=r.split(String.fromCharCode(10));
var cur="",found=false;
for(var i=0;i<parts.length;i++){
var p=parts[i].trim();
if(!p)continue;
var m=p.match(/^([a-z\u0430-\u044F]+)[\u0029\)]/);
if(m){
if(found)break;
var ids=m[1].split(",");
for(var j=0;j<ids.length;j++){
if(ids[j].trim()===letter){found=true;cur=p.replace(/^[a-z\u0430-\u044F,\s]+[\u0029\)]\s*/,"");break}
}
}else{
if(found)cur+=String.fromCharCode(10)+p
}
}
return cur||""
}
function init(){
try{
var su=localStorage.getItem("su");
if(su)cu=JSON.parse(su);
}catch(e){}
loadEv();
var fb=document.getElementById("fb");
if(fb){
for(var i=0;i<brs.length;i++){
var o=document.createElement("option");
o.value=i;o.textContent=brs[i];
fb.appendChild(o)
}
}
if(cu)showApp()
}
function doLogin(){
var e=document.getElementById("lem").value.trim().toLowerCase();
var k=e.split("@")[0];
var u=USR[k]||USR[e];
if(!u){var ex=localStorage.getItem("ext_users");if(ex){try{var eu=JSON.parse(ex);if(eu[k])u=eu[k];if(!u&&eu[e])u=eu[e]}catch(e){}}}
if(u){
cu={n:u.n,bg:u.bg,role:u.role!==undefined?u.role:(u.bg===0?0:1)};
localStorage.setItem("su",JSON.stringify(cu));
showApp()
}else{
document.getElementById("lerr").style.display="block"
}
}
function doLogout(){
localStorage.removeItem("su");
cu=null;
document.getElementById("login").style.display="flex";
document.getElementById("app").style.display="none"
}
function showApp(){
document.getElementById("login").style.display="none";
document.getElementById("app").style.display="block";
document.getElementById("su_name").textContent=cu?cu.n:"";
var unav=document.getElementById("snav_users");
if(unav)unav.style.display=cu&&cu.bg===0?"":"none";
var hsenav=document.getElementById("snav_hse");
if(hsenav)hsenav.style.display=cu&&cu.bg===0?"":"none";
if(cu&&cu.role===2){var anav=document.getElementById("snav_analytics");if(anav)anav.style.display="";var unav2=document.getElementById("snav_users");if(unav2)unav2.style.display="none"}
switchTab("events")
}
function loadEv(){
evs=[];
if(typeof ALL_EVENTS!=="undefined"&&ALL_EVENTS&&ALL_EVENTS.length){
var saved=localStorage.getItem("se5");
var smap={};
if(saved){
try{
var sd=JSON.parse(saved);
for(var i=0;i<sd.length;i++){
if(sd[i]&&sd[i].id)smap[sd[i].id]=sd[i]
}
}catch(e){}
}
for(var i=0;i<ALL_EVENTS.length;i++){
var e=ALL_EVENTS[i];
if(smap[e.id]){
e.s=smap[e.id].s||e.s;
if(smap[e.id].p!==undefined)e.p=smap[e.id].p;
if(smap[e.id].done)e.done=smap[e.id].done;
if(smap[e.id].h)e.h=smap[e.id].h;
if(smap[e.id].q!==undefined)e.q=smap[e.id].q;
if(smap[e.id].n!==undefined)e.n=smap[e.id].n
}
evs.push(e)
}
}
storCheck()
}
function saveEv(){
var out=[];
for(var i=0;i<evs.length;i++){
out.push({id:evs[i].id,s:evs[i].s,p:evs[i].p,done:evs[i].done,h:evs[i].h,q:evs[i].q,n:evs[i].n})
}
try{localStorage.setItem("se5",JSON.stringify(out))}catch(e){}
storCheck()
}
function switchTab(t){
tab=t;
var tabs=["events","analytics","reports","ai","users","hse"];
var tn={events:"Мероприятия",analytics:"Аналитика",reports:"Отчётность",ai:"Джарвис",users:"Учётные записи",hse:"HSE.sk.kz"};
for(var i=0;i<tabs.length;i++){
var el=document.getElementById("tab_"+tabs[i]);
if(el)el.style.display="none";
var nav=document.getElementById("snav_"+tabs[i]);
if(nav)nav.className=""
}
var sel=document.getElementById("tab_"+t);
if(sel)sel.style.display="block";
document.getElementById("page_title").textContent=tn[t];
if(t==="events")renderEv();
if(t==="analytics")renderAnalytics();
if(t==="reports")renderReports();
if(t==="ai")renderAI()
if(t==="hse"){var hm=document.getElementById("hse_month");if(hm&&!hm.value)hm.value=new Date().toISOString().slice(0,7)}
if(t==="users")renderUsers()
}
function daysRem(due){
if(!due||due==="\u2014")return 999;
var p=due.split(".");
if(p.length!==3)return 999;
var d=new Date(parseInt(p[2],10),parseInt(p[1],10)-1,parseInt(p[0],10));
var now=new Date();
now.setHours(0,0,0,0);
return Math.floor((d-now)/86400000)
}
function renderEv(){
var sea=document.getElementById("sea").value.toLowerCase().trim();
var fs=document.getElementById("fs").value;
var fb=document.getElementById("fb").value;
var fl=evs;
if(sea){
fl=fl.filter(function(e){
return e.t.toLowerCase().indexOf(sea)!==-1||
e.r.toLowerCase().indexOf(sea)!==-1||
e.dname.toLowerCase().indexOf(sea)!==-1||
String(e.id).indexOf(sea)!==-1
})
}
if(fs)fl=fl.filter(function(e){return e.s===fs});
if(fb!=="")fl=fl.filter(function(e){return String(e.b)===fb});
document.getElementById("sc").textContent="Показано: "+fl.length+" из "+evs.length;
var h="";
var lastSec=-1;
for(var i=0;i<fl.length;i++){
var e=fl[i];
if(e.sec!==lastSec){
if(lastSec!==-1)h+="<tr><td colspan='7' style='padding:4px;border:none'></td></tr>";
h+="<tr><td colspan='7' style='padding:0;border:none'><div class='sec-h'>"+esc(secs[e.sec])+"</div></td></tr>";
lastSec=e.sec
}
var dr=daysRem(e.due);
var rowCl=e.s==="done"?"tr-green":dr<=0&&e.s!=="done"?"tr-red":dr<=14?"tr-amber":"";
var cl=stc[e.s]||"w";
var drText=dr<=0&&e.s!=="done"?"Просрочено на "+Math.abs(dr)+" дн.":e.s==="done"?"Готово":dr===999?"\u2014":dr+" дн.";
var hasSub=e.sub&&e.sub.length>0;
h+="<tr class='"+rowCl+"'>";
h+="<td style='font-weight:700;font-size:12px'>"+e.id+"</td>";
h+="<td><div style='font-size:12px;line-height:1.3'>"+esc(e.t)+"</div><div style='font-size:10px;color:#64748B;margin-top:2px'>"+esc(e.dname)+"</div></td>";
h+="<td style='font-size:11px'>"+(e.sub&&e.sub.length?"\u0441\u043C. \u043F\u043E\u0434\u043F\u0443\u043D\u043A\u0442\u044B":esc(nl2c(e.r)))+"</td>";
h+="<td style='font-size:12px;white-space:nowrap'>"+e.due+" <span style='font-size:10px;color:#64748B'>("+drText+")</span></td>";
if(hasSub){h+="<td></td><td></td>"}
else{
h+="<td><span class='badge "+cl+"'>"+stn[e.s]+"</span></td>";
h+="<td><button class='btn btn-sm' style='padding:4px 12px;font-size:11px' onclick='openEv("+e.id+")'>Открыть</button></td>"
}
h+="</tr>";
if(hasSub){
for(var si=0;si<e.sub.length;si++){
var sr=subResp(e.r,e.sub[si].l)||nl2c(e.r);
var ss=e.s==="wait"?"warn":e.s;
var scl=stc[ss]||"a";
var subR=subResp(e.r,e.sub[si].l);if(!subR||subR.length<2)subR=nl2c(e.r);h+="<tr class='"+rowCl+" sub-item-row'><td style='padding-left:24px;font-size:11px;font-weight:600;color:#005BAA'>"+e.id+"."+esc(e.sub[si].l)+"</td>";
h+="<td style='font-size:11px'>"+esc(e.sub[si].t)+"</td>";
h+="<td style='font-size:11px'>"+esc(sr)+"</td>";
h+="<td style='font-size:11px'>"+e.due+"</td>";
h+="<td><span class='badge "+scl+"' style='font-size:10px'>"+stn[ss]+"</span></td>";
h+="<td><button class='btn btn-sm' style='padding:4px 10px;font-size:11px' onclick='openEv("+e.id+","+si+")'>Открыть</button></td></tr>"
}
}
}
if(!h)h="<p style='color:#64748B;padding:20px;text-align:center'>Нет мероприятий</p>";
document.getElementById("ev_content").innerHTML="<table><tr><th>N</th><th>Мероприятие</th><th>Ответственные</th><th>Срок</th><th>Статус</th><th></th></tr>"+h+"</table>"
}
function togSub(id){
var el=document.getElementById("sub_"+id);
if(!el)return;
var arr=document.getElementById("arr_"+id);
if(el.style.display==="none"){
el.style.display="block";
if(arr)arr.innerHTML="&#9660;"
}else{
el.style.display="none";
if(arr)arr.innerHTML="&#9656;"
}
}
function chkSub(id,idx,val){
var key="ss_"+id;
var ss=localStorage.getItem(key);
var arr=[];
if(ss){try{arr=JSON.parse(ss)}catch(e){}}
arr[idx]=val?true:false;
try{localStorage.setItem(key,JSON.stringify(arr))}catch(e){}
renderEv()
}
function openEv(id,subIdx){curSub=subIdx!==undefined?subIdx:null;var e=null;for(var i=0;i<evs.length;i++){if(evs[i].id===id){e=evs[i];break}}if(!e)return;var fk=subIdx!==undefined?"sf_"+id+"_s"+subIdx:"sf_"+id;var now=new Date();var curMonth=now.getMonth();var savedMonth=localStorage.getItem("evmonth_"+id);var selMonth=savedMonth!==null?parseInt(savedMonth,10):curMonth;var fkBase="sf_"+id+"_m"+selMonth+(subIdx!==undefined?"_s"+subIdx:"");var h="<div style='max-width:700px'>";var titlePre=subIdx!==undefined?"N"+id+"."+e.sub[subIdx].l+" ":"N"+id+". ";var titleText=subIdx!==undefined?e.sub[subIdx].t:e.t;h+="<h3 style='margin-bottom:8px;padding-right:30px'>"+titlePre+esc(titleText)+"</h3>";h+="<div style='font-size:12px;color:#64748B;margin-bottom:6px'><strong>\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439:</strong> "+esc(nl2c(e.r))+"</div>";h+="<div style='font-size:12px;color:#64748B;margin-bottom:6px'><strong>\u0424\u0438\u043B\u0438\u0430\u043B:</strong> "+brs[e.b]+" | <strong>\u0421\u0440\u043E\u043A:</strong> "+e.due;if(e.done&&e.done!="\u2014")h+=" | <strong>\u0418\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u043E:</strong> "+e.done;h+="</div>";h+="<div style='margin-bottom:12px'><strong>\u0421\u0442\u0430\u0442\u0443\u0441:</strong> <select id='evs_"+e.id+"' onchange='chgSt("+e.id+")'>";var sk=["warn","late","done"];for(var si=0;si<sk.length;si++){h+="<option value='"+sk[si]+"'";if(e.s===sk[si])h+=" selected";h+=">"+stn[sk[si]]+"</option>"}h+="</select></div>";if(e.h&&e.h.length){h+="<div style='margin-bottom:12px'><strong>\u0418\u0441\u0442\u043E\u0440\u0438\u044F:</strong><ul style='font-size:12px;margin:4px 0 0 16px'>";for(var hi=0;hi<e.h.length;hi++){h+="<li>"+esc(e.h[hi])+"</li>"}h+="</ul></div>"}h+="<div style='margin-bottom:12px'><strong>\u041E\u0442\u0447\u0451\u0442\u043D\u043E\u0441\u0442\u044C:</strong></div>";h+="<div style='margin-bottom:8px;display:flex;gap:3px;flex-wrap:wrap' id='evm_btns_"+e.id+"'>";var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];for(var mi=0;mi<12;mi++){h+="<button class='btn btn-sm' style='padding:5px 12px;font-size:12px;border-radius:6px;transition:all 0.15s;"+(mi===selMonth?"background:#005BAA;color:#fff;font-weight:700;border:2px solid #003D73;box-shadow:0 2px 6px rgba(0,91,170,0.4);transform:scale(1.05)":"")+"' onclick='switchEvMonthBtn("+e.id+","+mi+","+(subIdx!==undefined?subIdx:"null")+")'>"+mnames[mi]+"</button>"}h+="</div>";h+="<div style='margin-bottom:12px'><strong>\u0424\u0430\u0439\u043B\u044B \u0437\u0430 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043C\u0435\u0441\u044F\u0446:</strong><div id='fileList_"+e.id+"'>";if(cu&&cu.bg===0){for(var bi=0;bi<brs.length;bi++){var bk=fkBase+"_b"+bi;var fd=localStorage.getItem(bk);if(fd){try{var fa=JSON.parse(fd);if(fa.length)h+="<div style='font-size:11px;color:#64748B;margin-top:4px'><strong>"+esc(brs[bi])+":</strong></div>";for(var fi=0;fi<fa.length;fi++){var f=fa[fi];h+="<div class='file-item'><span class='fn'>"+esc(f.n)+"</span><span class='fs'>("+(f.s?Math.round(f.s/1024)+"KB":"")+", "+esc(f.u||"")+" "+esc(f.d||"")+")</span><a onclick='openFile("+e.id+","+fi+","+bi+")'>\u041E\u0442\u043A\u0440\u044B\u0442\u044C</a> <a onclick='dlFile("+e.id+","+fi+","+bi+")'>\u0421\u043A\u0430\u0447\u0430\u0442\u044C</a><a style='color:#EF4444;margin-left:4px' onclick='delFile("+e.id+","+fi+","+bi+")'>\u0423\u0434\u0430\u043B\u0438\u0442\u044C</a></div>"}}catch(ex){}}}}else{var bk=fkBase+"_b"+(cu?cu.bg:0);var fd=localStorage.getItem(bk);if(fd){try{var fa=JSON.parse(fd);for(var fi=0;fi<fa.length;fi++){var f=fa[fi];h+="<div class='file-item'><span class='fn'>"+esc(f.n)+"</span><span class='fs'>("+(f.s?Math.round(f.s/1024)+"KB":"")+", "+esc(f.u||"")+" "+esc(f.d||"")+")</span><a onclick='openFile("+e.id+","+fi+","+(cu?cu.bg:0)+")'>\u041E\u0442\u043A\u0440\u044B\u0442\u044C</a> <a onclick='dlFile("+e.id+","+fi+","+(cu?cu.bg:0)+")'>\u0421\u043A\u0430\u0447\u0430\u0442\u044C</a><a style='color:#EF4444;margin-left:4px' onclick='delFile("+e.id+","+fi+","+(cu?cu.bg:0)+")'>\u0423\u0434\u0430\u043B\u0438\u0442\u044C</a></div>"}}catch(ex){}}}h+="</div><div style='margin-top:6px'><input type='file' id='fu_"+e.id+"' style='font-size:12px' onchange='upFile("+e.id+(subIdx!==undefined?","+subIdx:"")+")'></div>";h+="<div style='margin-bottom:12px;margin-top:12px'><textarea id='evn_"+e.id+"' placeholder='\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 / \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F...' style='width:100%;padding:12px;border:1px solid #E2E8F0;border-radius:8px;font-size:13px;line-height:1.6;resize:vertical;min-height:120px;white-space:pre-wrap;overflow-y:auto' oninput='autoSaveNote("+e.id+")'>"+esc(subIdx!==undefined?((localStorage.getItem("sn_"+e.id+"_s"+subIdx+"_m"+selMonth)||"")):(localStorage.getItem("sn_"+e.id+"_m"+selMonth)||e.n||""))+"</textarea></div>";h+="</div>";if(subIdx===undefined&&e.sub&&e.sub.length>0){h+="<div style='margin-bottom:12px'><strong>\u041F\u043E\u0434\u043F\u0443\u043D\u043A\u0442\u044B:</strong>";var ss=localStorage.getItem("ss_"+e.id);for(var si=0;si<e.sub.length;si++){var checked="";if(ss){try{var sp=JSON.parse(ss);if(sp[si])checked="checked"}catch(ex){}}h+="<div style='font-size:12px;padding:4px 0'><input type='checkbox' "+checked+" onchange='chkSub("+e.id+","+si+",this.checked)'> "+esc(e.sub[si].l)+") "+esc(e.sub[si].t)+"</div>"}h+="</div>"}h+="<div style='margin-top:16px;text-align:right;border-top:1px solid #E2E8F0;padding-top:12px'><button class='btn btn-sm btn-g' onclick='saveEvModal("+e.id+")'>\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C</button>";h+="<button class='btn btn-sm' style='margin-left:8px;background:#E2E8F0;color:#0B1A2E' onclick='closeModal()'>\u041E\u0442\u043C\u0435\u043D\u0430</button></div>";h+="</div>";showModal(h)}
function showModal(html){
var mb=document.getElementById("modal_body");
var m=document.getElementById("modal");
if(!mb||!m)return;
mb.innerHTML=html;
m.style.display="flex"
}
var _ats={};function autoSaveNote(id){clearTimeout(_ats[id]);_ats[id]=setTimeout(function(){var inn=document.getElementById("evn_"+id);if(!inn)return;var mv2=localStorage.getItem("evmonth_"+id)||"0";var ss=curSub!==null?"_s"+curSub:"";try{localStorage.setItem("sn_"+id+ss+"_m"+mv2,inn.value.trim())}catch(e){}showToast("\u0410\u0432\u0442\u043E\u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u043E")},3000)}function showToast(msg){var t=document.getElementById("toast");if(!t)return;t.textContent=msg;t.style.display="block";t.style.opacity="1";clearTimeout(t._tid);t._tid=setTimeout(function(){t.style.opacity="0";setTimeout(function(){t.style.display="none"},300)},2000)}function closeModal(){
document.getElementById("modal").style.display="none"
}
function switchEvMonthBtn(id,m,subIdx){var inn=document.getElementById("evn_"+id);var curM=localStorage.getItem("evmonth_"+id)||"0";var subSuffix=curSub!==null?"_s"+curSub:"";if(inn)try{localStorage.setItem("sn_"+id+subSuffix+"_m"+curM,inn.value.trim())}catch(e){}try{localStorage.setItem("evmonth_"+id,m.toString())}catch(e){}openEv(id,subIdx!==null?subIdx:undefined)}
function switchEvMonth(id,subIdx){var inm=document.getElementById("evm_"+id);if(!inm)return;var mv=inm.value;var inn=document.getElementById("evn_"+id);var subSuffix=curSub!==null?"_s"+curSub:"";if(inn)try{localStorage.setItem("sn_"+id+subSuffix+"_m"+mv,inn.value.trim())}catch(e){}try{localStorage.setItem("evmonth_"+id,mv)}catch(e){}openEv(id,subIdx!==null?subIdx:undefined)}
function saveEvModal(id){var sel=document.getElementById("evs_"+id);for(var i=0;i<evs.length;i++){if(evs[i].id===id){if(sel)evs[i].s=sel.value;if(sel&&sel.value==="done"&&(evs[i].done==="\u2014"||!evs[i].done)){var d=new Date();evs[i].done=d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear()}break}}var inm=document.getElementById("evm_"+id);var mv=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");if(mv!=null){try{localStorage.setItem("evmonth_"+id,mv)}catch(e){};var inn=document.getElementById("evn_"+id);var subSuffix2=curSub!==null?"_s"+curSub:"";if(inn)try{localStorage.setItem("sn_"+id+subSuffix2+"_m"+mv,inn.value.trim())}catch(e){}}saveEv();showToast("\u0414\u0430\u043D\u043D\u044B\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u044B");renderEv()}
function chgSt(id){
var sel=document.getElementById("evs_"+id);
if(!sel)return;
for(var i=0;i<evs.length;i++){
if(evs[i].id===id){
evs[i].s=sel.value;
if(sel.value==="done"&&(evs[i].done==="\u2014"||!evs[i].done)){
var d=new Date();
evs[i].done=d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear()
}
break
}
}
}
function refreshFiles(id){var inm=document.getElementById("evm_"+id);var mv=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");var prefix="sf_"+id+"_m"+mv;var fdiv=document.getElementById("fileList_"+id);if(!fdiv)return;var groups={};var keys=[];for(var k in localStorage){if(localStorage.hasOwnProperty(k)&&k.indexOf(prefix)===0)keys.push(k)}for(var i=0;i<keys.length;i++){var fd=localStorage.getItem(keys[i]);if(fd){try{var arr=JSON.parse(fd);for(var j=0;j<arr.length;j++){var f=arr[j];var parts=keys[i].split("_b");var bi=parseInt(parts[parts.length-1])||0;if(!groups[bi])groups[bi]=[];groups[bi].push({n:f.n,s:f.s,d:f.d,u:f.u,bi:bi,idx:j,key:keys[i]})}}catch(e){}}}var fh="";for(var bi=0;bi<brs.length;bi++){if(!groups[bi]||!groups[bi].length)continue;if(cu&&cu.bg===0)fh+="<div style=\'font-size:11px;color:#64748B;margin-top:4px\'><strong>"+esc(brs[bi])+":</strong></div>";for(var j=0;j<groups[bi].length;j++){var f=groups[bi][j];fh+="<div class=\'file-item\'><span class=\'fn\'>"+esc(f.n)+"</span><span class=\'fs\'>("+(f.s?Math.round(f.s/1024)+"KB":"")+", "+esc(f.u||"")+" "+esc(f.d||"")+")</span><a onclick=\'openFile("+id+","+f.idx+","+f.bi+")\' style=\'cursor:pointer\'>\u041E\u0442\u043A\u0440\u044B\u0442\u044C</a> <a onclick=\'dlFile("+id+","+f.idx+","+f.bi+")\' style=\'cursor:pointer\'>\u0421\u043A\u0430\u0447\u0430\u0442\u044C</a><a style=\'color:#EF4444;margin-left:4px;cursor:pointer\' onclick=\'delFileRefresh("+id+","+f.idx+","+f.bi+")\'>>\u0423\u0434\u0430\u043B\u0438\u0442\u044C</a></div>"}}fdiv.innerHTML=fh||"\u041D\u0435\u0442 \u0444\u0430\u0439\u043B\u043E\u0432"}function delFileRefresh(id,idx,br){if(!confirm("\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0444\u0430\u0439\u043B?"))return;var mk=(localStorage.getItem("evmonth_"+id)||"0");var bk="_b"+(br!==undefined?br:(cu?cu.bg:0));var key="sf_"+id+"_m"+mk+(curSub!==null?"_s"+curSub:"")+bk;var ex=localStorage.getItem(key);if(!ex)return;try{var arr=JSON.parse(ex);arr.splice(idx,1);if(arr.length)localStorage.setItem(key,JSON.stringify(arr));else localStorage.removeItem(key);refreshFiles(id)}catch(e){}}
function upFile(id){var inp=document.getElementById("fu_"+id);if(!inp||!inp.files||!inp.files[0])return;var f=inp.files[0];if(f.size>2097152){alert("\u0424\u0430\u0439\u043B \u0431\u043E\u043B\u044C\u0448\u0435 2MB");return}var fr=new FileReader();var subKey=curSub!==null?"_s"+curSub:"";var inm=document.getElementById("evm_"+id);var mv2=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");var monthKey="_m"+mv2;var brKey="_b"+(cu?cu.bg:0);var fname=f.name;var fsize=f.size;fr.onload=function(){var key="sf_"+id+monthKey+subKey+brKey;var arr=[];var ex=localStorage.getItem(key);if(ex){try{arr=JSON.parse(ex)}catch(e){}}var d=new Date();arr.push({n:fname,s:fsize,d:d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear(),u:cu?cu.n:"",data:fr.result});try{localStorage.setItem(key,JSON.stringify(arr))}catch(e){alert("\u041E\u0448\u0438\u0431\u043A\u0430 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F. \u041E\u0447\u0438\u0441\u0442\u0438\u0442\u0435 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435.");return}showToast("\u0424\u0430\u0439\u043B \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D");refreshFiles(id)};fr.readAsDataURL(f)}
function openFile(id,idx,br){var inm=document.getElementById("evm_"+id);var mv3=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");var mk="_m"+mv3;var bk="_b"+(br!==undefined?br:(cu?cu.bg:0));var key="sf_"+id+mk+(curSub!==null?"_s"+curSub:"")+bk;var ex=localStorage.getItem(key);if(!ex)return;try{var arr=JSON.parse(ex);var f=arr[idx];if(f&&f.data){var w=window.open("","_blank");w.document.write("<iframe src='"+f.data+"' style='width:100%;height:100%;border:none'></iframe>")}}catch(e){}}
function dlFile(id,idx,br){
var inm=document.getElementById("evm_"+id);
var mv4=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");
var monthKey="_m"+mv4;
var key="sf_"+id+monthKey+(curSub!==null?"_s"+curSub:"")+"_b"+(cu?cu.bg:0);
var ex=localStorage.getItem(key);
if(!ex)return;
try{
var arr=JSON.parse(ex);
var f=arr[idx];
if(!f||!f.data)return;
var a=document.createElement("a");
a.href=f.data;
a.download=f.n;
document.body.appendChild(a);
a.click();
document.body.removeChild(a)
}catch(e){}
}
function delFile(id,idx,br){
if(!confirm("\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0444\u0430\u0439\u043B?"))return;
var inm=document.getElementById("evm_"+id);
var mv4=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");
var monthKey="_m"+mv4;
var brKey="_b"+(br!==undefined?br:(cu?cu.bg:0));
var key="sf_"+id+monthKey+(curSub!==null?"_s"+curSub:"")+brKey;
var ex=localStorage.getItem(key);
if(!ex)return;
try{
var arr=JSON.parse(ex);
arr.splice(idx,1);
if(arr.length){localStorage.setItem(key,JSON.stringify(arr))}
else{localStorage.removeItem(key)}
openEv(id,curSub!==null?curSub:undefined)
}catch(e){}
}
function saveBackup(){saveEv();var backup={events:evs.map(function(e){return{id:e.id,s:e.s,p:e.p,done:e.done,h:e.h,q:e.q,n:e.n}}),files:{}};var fkeys=[];for(var k in localStorage){if(localStorage.hasOwnProperty(k)&&k.indexOf("sf_")===0)fkeys.push(k)}for(var i=0;i<fkeys.length;i++){backup.files[fkeys[i]]=localStorage.getItem(fkeys[i])}var blob=new Blob([JSON.stringify(backup,null,2)],{type:"application/json"});var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="backup_"+new Date().toISOString().slice(0,10)+".json";a.click()}
function loadBackup(inp){if(!inp.files||!inp.files[0])return;var fr=new FileReader();fr.onload=function(){try{var d=JSON.parse(fr.result);if(!d||!d.events){alert("\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442");return}var out=[];for(var i=0;i<d.events.length;i++){out.push({id:d.events[i].id,s:d.events[i].s||"warn",p:d.events[i].p||0,done:d.events[i].done||"\u2014",h:d.events[i].h||[]})}localStorage.setItem("se5",JSON.stringify(out));if(d.files){var fk=Object.keys(d.files);for(var i=0;i<fk.length;i++){try{localStorage.setItem(fk[i],d.files[fk[i]])}catch(e){}}}loadEv();renderEv();var fc=d.files?Object.keys(d.files).length:0;alert("\u0412\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E "+out.length+" \u0437\u0430\u043F\u0438\u0441\u0435\u0439, "+fc+" \u0444\u0430\u0439\u043B\u043E\u0432")}catch(e){alert("\u041E\u0448\u0438\u0431\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438")}};fr.readAsText(inp.files[0])}
function storCheck(){
var el=document.getElementById("stor_ind");
if(!el)return;
try{
var used=0;
for(var k in localStorage){
if(localStorage.hasOwnProperty(k)){
used+=((localStorage[k].length||0)*2)
}
}
var max=5242880;
var pct=Math.round(used/max*100);
el.textContent="\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435: "+pct+"% ("+Math.round(used/1024)+"KB)"
}catch(e){el.textContent=""}
}
function renderAnalytics(){
if(cu&&cu.bg===0)loadLTIF();
var total=evs.length;
var done=0,late=0,warn=0;
for(var i=0;i<evs.length;i++){
var s=evs[i].s;
if(s==="done")done++;
else if(s==="late")late++;
else if(s==="warn")warn++
}
var html="";
html+="<div class='stat-card sb'><div class='lb'>\u0412\u0441\u0435\u0433\u043E \u043C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0439</div><div class='num'>"+total+"</div></div>";
html+="<div class='stat-card sg'><div class='lb'>\u0418\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u043E</div><div class='num'>"+done+"</div><div class='lb'>"+Math.round(done/total*100)+"%</div></div>";
html+="<div class='stat-card sr'><div class='lb'>\u041F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E</div><div class='num'>"+late+"</div></div>";
html+="<div class='stat-card'><div class='lb'>В процессе</div><div class='num'>"+warn+"</div></div>";
document.getElementById("an_stats").innerHTML=html;
var problem=[];
for(var i=0;i<evs.length;i++){
if(evs[i].s==="late"||evs[i].s==="warn"){
var dr=daysRem(evs[i].due);
problem.push({id:evs[i].id,t:evs[i].t,b:evs[i].b,s:evs[i].s,dr:dr,dn:evs[i].dname})
}
}
problem.sort(function(a,b){return a.dr-b.dr});
var pt=problem.slice(0,5);
if(pt.length){
var ph="<table><tr><th>N</th><th>\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0421\u0442\u0430\u0442\u0443\u0441</th><th>\u0414\u043D\u0435\u0439</th></tr>";
for(var i=0;i<pt.length;i++){
var pc=pt[i].s==="late"?"r":"w";
ph+="<tr><td>"+pt[i].id+"</td><td style='font-size:12px'>"+esc(pt[i].t)+"</td><td>"+brs[pt[i].b]+"</td><td><span class='badge "+pc+"'>"+stn[pt[i].s]+"</span></td><td>"+(pt[i].dr<=0?"\u041F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E":pt[i].dr+" \u0434\u043D.")+"</td></tr>"
}
ph+="</table>";
document.getElementById("an_top").innerHTML=ph;
var secData=[];for(var si=0;si<secs.length;si++){secData.push({n:secs[si].split(".")[1]||secs[si],t:0,d:0})}for(var i=0;i<evs.length;i++){var e=evs[i];secData[e.sec].t++;if(e.s==="done")secData[e.sec].d++}var sh="<table>";for(var i=0;i<secData.length;i++){var sp=secData[i].t?Math.round(secData[i].d/secData[i].t*100):0;sh+="<tr><td>"+esc(secData[i].n)+"</td><td>"+secData[i].d+"/"+secData[i].t+"</td><td><div class=\"rank-bar\"><div style=\"width:"+sp+"%;background:"+(sp>=70?"#10B981":sp>=40?"#F59E0B":"#EF4444")+"\"></div></div></td><td>"+sp+"%</td></tr>"}sh+="</table>";document.getElementById("an_sections").innerHTML=sh
}else{
document.getElementById("an_top").innerHTML="<p style='color:#64748B'>\u041F\u0440\u043E\u0431\u043B\u0435\u043C \u043D\u0435\u0442</p>"
}
}
function getFilteredEvs(){var statusF=document.getElementById("rp_status").value;var year=parseInt(document.getElementById("rp_year").value,10)||2026;var months=getReportMonths();var r=[];for(var i=0;i<evs.length;i++){var e=evs[i];if(statusF&&e.s!==statusF)continue;var dp=e.due.split(".");if(dp.length===3){var em=parseInt(dp[1],10)-1;var ey=parseInt(dp[2],10);if(ey===year&&months.indexOf(em)!==-1)r.push(e)}}return r}
function getReportPeriod(){
var period=document.getElementById("rp_period").value;
var year=document.getElementById("rp_year").value;
var month=parseInt(document.getElementById("rp_month").value,10)||0;
var mnames=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];
if(period==="month")return mnames[month]+" "+year;
if(period==="q1")return "I \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
if(period==="q2")return "II \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
if(period==="q3")return "III \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
if(period==="q4")return "IV \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
if(period==="h1")return "1-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;
if(period==="h2")return "2-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;
return year+" \u0433\u043E\u0434"
}
function rpPeriodChange(){}
function getReportPeriod(){
var period=document.getElementById("rp_period").value;var year=document.getElementById("rp_year").value;
var mFrom=parseInt(document.getElementById("rp_month_from").value,10)||0;var mTo=parseInt(document.getElementById("rp_month_to").value,10)||11;
var mn=["\u044F\u043D\u0432\u0430\u0440\u044C","\u0444\u0435\u0432\u0440\u0430\u043B\u044C","\u043C\u0430\u0440\u0442","\u0430\u043F\u0440\u0435\u043B\u044C","\u043C\u0430\u0439","\u0438\u044E\u043D\u044C","\u0438\u044E\u043B\u044C","\u0430\u0432\u0433\u0443\u0441\u0442","\u0441\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u043E\u043A\u0442\u044F\u0431\u0440\u044C","\u043D\u043E\u044F\u0431\u0440\u044C","\u0434\u0435\u043A\u0430\u0431\u0440\u044C"];
if(period==="year")return year+" \u0433\u043E\u0434";if(period==="q1")return "I \u043A\u0432. "+year;if(period==="q2")return "II \u043A\u0432. "+year;
if(period==="q3")return "III \u043A\u0432. "+year;if(period==="q4")return "IV \u043A\u0432. "+year;
if(period==="h1")return "1-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;if(period==="h2")return "2-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;
if(period==="month")return mn[mFrom]+" "+year;return mn[mFrom]+" \u2014 "+mn[mTo]+" "+year
}
function getReportMonths(){
var period=document.getElementById("rp_period").value;var mFrom=parseInt(document.getElementById("rp_month_from").value,10)||0;var mTo=parseInt(document.getElementById("rp_month_to").value,10)||11;
var months=[];if(period==="year"){for(var i=0;i<12;i++)months.push(i)}else if(period==="q1")months=[0,1,2];else if(period==="q2")months=[3,4,5];else if(period==="q3")months=[6,7,8];else if(period==="q4")months=[9,10,11];else if(period==="h1")months=[0,1,2,3,4,5];else if(period==="h2")months=[6,7,8,9,10,11];else if(period==="month")months=[mFrom];else{for(var i=mFrom;i<=mTo;i++)months.push(i)}return months
}
function rpDropdownChange(){var dd=document.getElementById("rp_month_dd");if(!dd)return;var v=dd.value.split("-");document.getElementById("rp_period").value="month";document.getElementById("rp_month_from").value=parseInt(v[1])-1;document.getElementById("rp_month_to").value=parseInt(v[1])-1;document.getElementById("rp_year").value=v[0];renderReports()}
function renderReports(){
var dd=document.getElementById("rp_month_dd");if(dd&&!dd.options.length){var mn=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];var now=new Date();var cm=now.getMonth();var cy=now.getFullYear();var h="";var sv=cy+"-"+String(cm+1).padStart(2,"0");for(var y=2026;y<=2027;y++){for(var m=0;m<12;m++){var val=y+"-"+String(m+1).padStart(2,"0");h+="<option value=\""+val+"\""+(val===sv?" selected":"")+">"+mn[m]+" "+y+"</option>"}}dd.innerHTML=h}
var fl=getFilteredEvs();
var cnt=document.getElementById("rp_count");
if(cnt)cnt.textContent="Выбрано мероприятий: "+fl.length;
document.getElementById("rp_preview").innerHTML=""
}
function dlCSV(){
var fl=getFilteredEvs();
var csv="\uFEFFN;\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435;\u0424\u0438\u043B\u0438\u0430\u043B;\u0421\u0440\u043E\u043A;\u0421\u0442\u0430\u0442\u0443\u0441;\u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441;\u041A\u043E\u043B-\u0432\u043E;\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435;\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439\n";
for(var i=0;i<fl.length;i++){
var e=fl[i];
csv+=e.id+";\""+esc(e.t)+"\";\""+brs[e.b]+"\";"+e.due+";"+stn[e.s]+";"+(e.p||0)+"%;"+(e.q||"")+";\""+esc(e.n||"")+"\";\""+esc(nl2c(e.r))+"\"\n"
}
var blob=new Blob([csv],{type:"text/csv;charset=utf-8"});
var a=document.createElement("a");
a.href=URL.createObjectURL(blob);
a.download="report_"+document.getElementById("rp_year").value+"_"+getReportPeriod().replace(/\s/g,"_")+".csv";
a.click()
}
function dlHTML(){var fl=getFilteredEvs();var periodLabel=getReportPeriod();var months=getReportMonths();var mn=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];var hh="<!DOCTYPE html><html><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 "+periodLabel+"</title><style>body{font:14px Arial;padding:30px;color:#1A1A2E}h3{font-size:14px;color:#005BAA;border-bottom:1px solid #ddd;padding-bottom:6px}.meta{font-size:12px;color:#1A1A2E;background:#F0F4FF;padding:6px 10px;border-radius:4px;margin:2px 0 6px}.desc{font-size:12px;padding:10px;background:#F0F4FF;border-left:4px solid #005BAA;border-radius:4px;margin:6px 0}.files{font-size:11px;margin:6px 0}.files .fg{margin:4px 0 8px;padding:4px 8px;background:#f9f9f9;border-radius:4px}.files .fgl{font-weight:600;color:#005BAA;font-size:11px}.files a{color:#005BAA;display:block;margin:2px 0 2px 8px}@media print{body{padding:10mm}}</style></head><body><h2>\u041F\u043B\u0430\u043D \u041F\u0411</h2><p>QAZAQtelecom HSE \u0437\u0430 "+periodLabel+"</p><p style='font-size:11px;color:#64748B'>"+new Date().toLocaleDateString("ru-RU")+"</p><br>";for(var i=0;i<fl.length;i++){var e=fl[i];var sn=secs[e.sec].split(". ")[1]||secs[e.sec];hh+="<h3>N"+e.id+". "+esc(e.t)+"</h3>";hh+="<div class='meta'>\u0420\u0430\u0437\u0434\u0435\u043B | "+esc(sn)+" | \u0421\u0440\u043E\u043A: "+e.due+" | "+stn[e.s]+"</div>";var rn="";for(var mi=0;mi<months.length;mi++){var nk="sn_"+e.id+"_m"+months[mi];var sv=localStorage.getItem(nk);if(sv){rn=sv;break}}if(!rn&&e.n)rn=e.n;if(rn)hh+="<div class='desc'><strong>\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435:</strong><br>"+esc(rn)+"</div>";var fhtml="";var hasAny=false;for(var mi=0;mi<months.length;mi++){var fg="";var mk="_m"+months[mi];for(var si=-1;si<(e.sub?e.sub.length:0);si++){var sk=si>=0?"_s"+si:"";for(var bk=0;bk<brs.length;bk++){var key="sf_"+e.id+mk+sk+"_b"+bk;var fd=localStorage.getItem(key);if(fd){try{var arr=JSON.parse(fd);for(var fi=0;fi<arr.length;fi++){var f=arr[fi];if(f&&f.n&&f.data)fg+="<a href='"+f.data+"' download='"+esc(f.n)+"'>\uD83D\uDCC4 "+esc(f.n)+" ("+Math.round((f.s||0)/1024)+" KB)</a>"}}catch(ex){}}}}if(fg){fhtml+="<div class='fg'><div class='fgl'>"+mn[months[mi]]+":</div>"+fg+"</div>";hasAny=true}}if(hasAny)hh+="<div class='files'><strong>\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E\u0449\u0438\u0435 \u0444\u0430\u0439\u043B\u044B:</strong>"+fhtml+"</div>"}hh+="<p style='font-size:11px;color:#64748B'><em>"+new Date().toLocaleDateString("ru-RU")+"</em></p></body></html>";var blob=new Blob([hh],{type:"text/html"});var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="report_pb_"+periodLabel.replace(/\s/g,"_")+".html";a.click()}
function dlWord(){var fl=getFilteredEvs();var periodLabel=getReportPeriod();var months=getReportMonths();var mn=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];var hh="<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word'><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 "+periodLabel+"</title><style>@page{size:A4;margin:20mm}body{font:12pt 'Times New Roman'}h2{font-size:16pt;text-align:center}h3{font-size:12pt;color:#005BAA;border-bottom:1px solid #ccc}.meta{font-size:10pt;color:#555}.desc{font-size:10pt;padding:6pt;background:#f9f9f9}.files{font-size:9pt}.files a{color:#005BAA;display:block}</style></head><body><h2>\u041F\u043B\u0430\u043D \u041F\u0411</h2><p style='text-align:center'>AO \u00AB\u041A\u0430\u0437\u0430\u0445\u0442\u0435\u043B\u0435\u043A\u043E\u043C\u00BB \u0437\u0430 "+periodLabel+"</p><br>";for(var i=0;i<fl.length;i++){var e=fl[i];var sn=secs[e.sec].split(". ")[1]||secs[e.sec];hh+="<h3>N"+e.id+". "+esc(e.t)+"</h3>";hh+="<p class='meta'>\u0420\u0430\u0437\u0434\u0435\u043B | "+esc(sn)+" | \u0421\u0440\u043E\u043A: "+e.due+" | "+stn[e.s]+"</p>";var rn="";for(var mi=0;mi<months.length;mi++){var nk="sn_"+e.id+"_m"+months[mi];var sv=localStorage.getItem(nk);if(sv){rn=sv;break}}if(!rn&&e.n)rn=e.n;if(rn)hh+="<p class='desc'><strong>\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435:</strong> "+esc(rn)+"</p>";var fhtml="";for(var mi=0;mi<months.length;mi++){var fg="";var mk="_m"+months[mi];for(var si=-1;si<(e.sub?e.sub.length:0);si++){var sk=si>=0?"_s"+si:"";for(var bk=0;bk<brs.length;bk++){var key="sf_"+e.id+mk+sk+"_b"+bk;var fd=localStorage.getItem(key);if(fd){try{var arr=JSON.parse(fd);for(var fi=0;fi<arr.length;fi++){var f=arr[fi];if(f&&f.n)fg+="<a href='"+f.data+"'>"+esc(f.n)+" ("+Math.round((f.s||0)/1024)+" KB)</a>"}}catch(ex){}}}}if(fg)fhtml+="<p><strong>"+mn[months[mi]]+":</strong><br>"+fg+"</p>"}if(fhtml)hh+="<div class='files'><strong>\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E\u0449\u0438\u0435 \u0444\u0430\u0439\u043B\u044B:</strong><br>"+fhtml+"</div>"}hh+="<p style='font-size:9pt;color:#888'>"+new Date().toLocaleDateString("ru-RU")+"</p></body></html>";var blob=new Blob([hh],{type:"application/msword"});var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="report_pb_"+periodLabel.replace(/\s/g,"_")+".doc";a.click()}
function dlPdf(){var fl=getFilteredEvs();var periodLabel=getReportPeriod();var hh="<!DOCTYPE html><html><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 "+periodLabel+"</title><style>body{font:14px Arial;padding:20px}table{border-collapse:collapse;width:100%}th,td{border:1px solid #ccc;padding:6px 10px;font-size:12px}th{background:#0A1628;color:#fff}@media print{body{padding:10mm}}</style></head><body><h2>\u041F\u043B\u0430\u043D \u041F\u0411</h2><p>QAZAQtelecom HSE \u0437\u0430 "+periodLabel+"</p><br><table><tr><th>N</th><th>\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0421\u0440\u043E\u043A</th><th>\u0421\u0442\u0430\u0442\u0443\u0441</th><th>%</th><th>\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435</th></tr>";for(var i=0;i<fl.length;i++){var e=fl[i];hh+="<tr><td>"+e.id+"</td><td>"+esc(e.t)+"</td><td>"+brs[e.b]+"</td><td>"+e.due+"</td><td>"+stn[e.s]+"</td><td>"+(e.p||0)+"%</td><td>"+esc(e.n||"")+"</td></tr>"}hh+="</table><p><em>"+new Date().toLocaleDateString("ru-RU")+"</em></p><script>window.onload=function(){window.print()}<\/script></body></html>";var w=window.open("","_blank","width=900,height=700");w.document.write(hh);w.document.close()}
function dlZip(){
var fl=getFilteredEvs();var periodLabel=getReportPeriod();var months=getReportMonths();
var zipParts=[];var offsets=[];var centralDir=[];var offset=0;
var mn=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];
function addFile(name,bytes){
var encoder=new TextEncoder();var data=typeof bytes==="string"?encoder.encode(bytes):new Uint8Array(bytes);
var nameBytes=encoder.encode(name);var crc=crc32(data);
var lh=new Uint8Array(30+nameBytes.length);var v=new DataView(lh.buffer);
v.setUint32(0,0x04034b50,true);v.setUint16(8,0,true);v.setUint16(10,0,true);v.setUint16(26,nameBytes.length,true);
v.setUint32(14,crc,true);v.setUint32(18,data.length,true);v.setUint32(22,data.length,true);lh.set(nameBytes,30);
zipParts.push(lh);zipParts.push(data);
var cd=new Uint8Array(46+nameBytes.length);var cv=new DataView(cd.buffer);
cv.setUint32(0,0x02014b50,true);cv.setUint16(8,0,true);cv.setUint16(10,0,true);cv.setUint16(28,nameBytes.length,true);
cv.setUint32(16,crc,true);cv.setUint32(20,data.length,true);cv.setUint32(24,data.length,true);cv.setUint32(42,offset,true);cd.set(nameBytes,46);
centralDir.push(cd);offset+=30+nameBytes.length+data.length
}
function crc32(data){var c=0xffffffff;for(var i=0;i<data.length;i++){c^=data[i];for(var j=0;j<8;j++){if(c&1)c=(c>>>1)^0xedb88320;else c>>>=1}}return(c^0xffffffff)>>>0}
var html='<!DOCTYPE html><html><head><meta charset="utf-8"><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 '+periodLabel+'</title><style>body{font:14px Arial;padding:20px}h2{font-size:20px}h3{font-size:14px;color:#005BAA;border-bottom:1px solid #ccc}.meta{font-size:12px;color:#555}.desc{font-size:12px;padding:8px;background:#f9f9f9;margin:6px 0}</style></head><body><h2>\u041F\u043B\u0430\u043D \u041F\u0411 \u2014 QAZAQtelecom HSE</h2><p>\u041F\u0435\u0440\u0438\u043E\u0434: '+periodLabel+'</p><p>\u0414\u0430\u0442\u0430: '+new Date().toLocaleDateString("ru-RU")+'</p><br>';
for(var i=0;i<fl.length;i++){var e=fl[i];var sn=secs[e.sec].split(". ")[1]||secs[e.sec];
html+='<h3>N'+e.id+'. '+esc(e.t)+'</h3><div class="meta">\u0420\u0430\u0437\u0434\u0435\u043B | '+esc(sn)+' | \u0421\u0440\u043E\u043A: '+e.due+' | '+stn[e.s]+'</div>';
var rn="";for(var mi=0;mi<months.length;mi++){var nk="sn_"+e.id+"_m"+months[mi];var sv=localStorage.getItem(nk);if(sv){rn=sv;break}}if(!rn&&e.n)rn=e.n;if(rn)html+='<div class="desc"><strong>\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435:</strong><br>'+esc(rn)+'</div>'
}
html+='<p><em>'+new Date().toLocaleDateString("ru-RU")+'</em></p></body></html>';
addFile("report.html",html);
for(var i=0;i<fl.length;i++){var e=fl[i];
for(var mi=0;mi<12;mi++){var mk="_m"+mi;
for(var si=-1;si<(e.sub?e.sub.length:0);si++){var sk=si>=0?"_s"+si:"";
for(var bk=0;bk<brs.length;bk++){var key="sf_"+e.id+mk+sk+"_b"+bk;var fd=localStorage.getItem(key);
if(fd){try{var arr=JSON.parse(fd);for(var fi=0;fi<arr.length;fi++){var f=arr[fi];if(f&&f.n&&f.data){var b64=f.data.split(",")[1];if(b64){var bin=Uint8Array.from(atob(b64),function(c){return c.charCodeAt(0)});addFile("event_"+e.id+"/"+esc(f.n),bin)}}}}catch(ex){}}
}
}
}
}
var cdOff=offset;for(var i=0;i<centralDir.length;i++)zipParts.push(centralDir[i]);
var cdSz=zipParts.reduce(function(s,p){return s+p.length},0)-cdOff;
var eocd=new Uint8Array(22);var ev=new DataView(eocd.buffer);
ev.setUint32(0,0x06054b50,true);ev.setUint16(8,centralDir.length,true);ev.setUint16(10,centralDir.length,true);
ev.setUint32(12,cdSz,true);ev.setUint32(16,cdOff,true);zipParts.push(eocd);
var blob=new Blob(zipParts,{type:"application/zip"});var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="report_pb_"+periodLabel.replace(/\s/g,"_")+".zip";a.click()
}
function hseSend(){
var btn=document.getElementById("hse_btn");
var result=document.getElementById("hse_result");
btn.disabled=true;btn.textContent="Отправка...";result.innerHTML="";
var month=document.getElementById("hse_month").value;
var fmt=document.getElementById("hse_fmt").value;
var apiKey=document.getElementById("hse_key").value;
if(!month){result.innerHTML="<span style='color:#EF4444'>Выберите месяц</span>";btn.disabled=false;btn.textContent="Отправить отчёт в HSE.sk.kz";return}
if(!apiKey){result.innerHTML="<span style='color:#EF4444'>Введите API ключ</span>";btn.disabled=false;btn.textContent="Отправить отчёт в HSE.sk.kz";return}
var fl=getFilteredEvs();
var total=fl.length;
var done=0;for(var i=0;i<fl.length;i++){if(fl[i].s==="done")done++}
var pct=total?Math.round(done/total*100):0;
var payload={month:month,events:fl.map(function(e){return{id:e.id,title:e.t,branch:brs[e.b],deadline:e.due,status:e.s,progress:e.p||0,quantity:e.q||"",note:e.n||""}}),summary:{total:total,done:done,pct:pct}};
try{
fetch("http://localhost:5000/api/hse/send",{method:"POST",headers:{"Content-Type":"application/json","Authorization":"Bearer hse-integration"},body:JSON.stringify({month:month,api_key:apiKey,format:fmt,report:payload})}).then(function(r){return r.json()}).then(function(d){
if(d.ok){result.innerHTML="<span style='color:#10B981'>Отчёт за "+month+" отправлен в HSE.sk.kz</span>"}
else{result.innerHTML="<span style='color:#EF4444'>Ошибка: "+(d.error||"соединение")+"</span>"}
}).catch(function(e){result.innerHTML="<span style='color:#EF4444'>Сервер не запущен. Запустите <code>python3 server.py</code></span>"}).finally(function(){btn.disabled=false;btn.textContent="Отправить отчёт в HSE.sk.kz"})
}catch(e){}
}
var aiGreeted=false;
function renderAI(){
if(!aiGreeted){
aiGreeted=true;
var box=document.getElementById("ai_chat");
if(box){
box.innerHTML="";
addMsg("b","Джарвис к вашим услугам. Я анализирую 35 мероприятий ПБ по 9 филиалам. Спросите: сводка, просроченные, риски, рейтинг, аудит, прогноз, советник.","Джарвис")
}
}
}
function addMsg(role,text,name){
var box=document.getElementById("ai_chat");
if(!box)return;
var nm=role==="u"?"\u0412\u044B":(name||"\u0411\u043E\u0442");
box.innerHTML+="<div class='msg "+role+"'><div class='nm'>"+esc(nm)+"</div><div>"+esc(text)+"</div></div>";
box.scrollTop=box.scrollHeight
}
function aiAsk(q){
addMsg("u",q,"\u0412\u044B");
setTimeout(function(){aiResp(q)},300)
}
function aiSend(){
var inp=document.getElementById("ai_inp");
if(!inp||!inp.value.trim())return;
var q=inp.value.trim();
inp.value="";
aiAsk(q)
}
function aiResp(q){
var total=evs.length;
var done=0,late=0,warn=0;
for(var i=0;i<evs.length;i++){
var s=evs[i].s;
if(s==="done")done++;
else if(s==="late")late++;
else if(s==="warn")warn++
}
var ql=q.toLowerCase();
var ans="";
if(ql.indexOf("свод")!==-1||ql.indexOf("общ")!==-1||ql.indexOf("статус")!==-1||ql.indexOf("все")!==-1){
ans="Общая сводка по плану ПБ:";
ans+="\n- Всего: "+total+" мероприятий";
ans+="\n- Исполнено: "+done+" ("+Math.round(done/total*100)+"%)";
ans+="\n- В процессе: "+warn;
ans+="\n- Просрочено: "+late
}else if(ql.indexOf("просроч")!==-1||ql.indexOf("срочн")!==-1||ql.indexOf("критич")!==-1){
var lateList=[];
for(var i=0;i<evs.length;i++){if(evs[i].s==="late"){lateList.push(evs[i])}}
if(lateList.length){
ans="Просроченные мероприятия ("+lateList.length+"):";
for(var i=0;i<lateList.length;i++){
ans+="\nN"+lateList[i].id+" - "+lateList[i].t.slice(0,80)+"... ("+lateList[i].due+", "+brs[lateList[i].b]+")"
}
}else{ans="Просроченных нет"}
}else if(ql.indexOf("рик")!==-1||ql.indexOf("risk")!==-1||ql.indexOf("пробл")!==-1||ql.indexOf("срыв")!==-1){
var risk=[];
for(var i=0;i<evs.length;i++){
var dr=daysRem(evs[i].due);
if(evs[i].s!=="done"&&dr<=30&&dr>0){risk.push(evs[i])}
}
if(risk.length){
ans="Менее 30 дней до срока ("+risk.length+"):";
for(var i=0;i<risk.length;i++){
ans+="\nN"+risk[i].id+" - "+risk[i].t.slice(0,60)+"... ("+daysRem(risk[i].due)+" дн.)"
}
}else{ans="Рисков нет"}
}else if(ql.indexOf("рейт")!==-1||ql.indexOf("филиал")!==-1||ql.indexOf("лучш")!==-1||ql.indexOf("худш")!==-1){
var brd=[];
for(var i=0;i<brs.length;i++){brd.push({n:brs[i],t:0,d:0})}
for(var i=0;i<evs.length;i++){var e=evs[i];brd[e.b].t++;if(e.s==="done")brd[e.b].d++}
brd.sort(function(a,b){return(b.d/b.t||0)-(a.d/a.t||0)});
ans="Рейтинг филиалов:";
for(var i=0;i<brd.length;i++){
var pct=brd[i].t?Math.round(brd[i].d/brd[i].t*100):0;
ans+="\n"+(i+1)+". "+brd[i].n+": "+brd[i].d+"/"+brd[i].t+" ("+pct+"%)"
}
}else if(ql.indexOf("прогноз")!==-1||ql.indexOf("прогн")!==-1){
var atRisk=0,crit=0,onTrack=0;
for(var i=0;i<evs.length;i++){
var dr=daysRem(evs[i].due);
if(evs[i].s==="done")onTrack++;
else if(dr<=0)crit++;
else if(dr<=30)atRisk++;
else onTrack++
}
ans="Прогноз выполнения плана ПБ:\n- Выполнено: "+onTrack+"\n- В зоне риска (<30 дн): "+atRisk+"\n- Критические (просрочено): "+crit;
ans+="\n\nПрогнозируемый % выполнения к концу года: "+Math.round((onTrack+atRisk*0.5)/evs.length*100)+"%";
if(crit>3)ans+="\n\nРекомендация: срочный штаб по "+crit+" просроченным пунктам."
}else if(ql.indexOf("статус")!==-1||ql.indexOf("состоян")!==-1||ql.indexOf("обстан")!==-1){
var bySec=[];
for(var si=0;si<secs.length;si++){bySec.push({n:secs[si].split(".")[0],t:0,d:0,l:0})}
for(var i=0;i<evs.length;i++){
var e=evs[i];bySec[e.sec].t++;
if(e.s==="done")bySec[e.sec].d++;
else if(e.s==="late")bySec[e.sec].l++
}
ans="Состояние по разделам:";
for(var i=0;i<bySec.length;i++){
ans+="\n"+bySec[i].n+": "+bySec[i].d+"/"+bySec[i].t+" ("+Math.round(bySec[i].d/bySec[i].t*100)+"%)"+(bySec[i].l?" просрочено:"+bySec[i].l:"")
}
}else if(ql.indexOf("план")!==-1||ql.indexOf("действ")!==-1||ql.indexOf("рекоменд")!==-1||ql.indexOf("совет")!==-1){
var pct=Math.round(done/total*100);
if(pct<30)ans="Рекомендация: выполнено менее 30%. Рекомендуется усилить контроль за просроченными и провести штаб с ответственными лицами";
else if(pct<60)ans="Рекомендация: выполнено "+pct+"%. Обратить внимание на процент выполнения в филиалах с низким показателем";
else ans="Хороший прогресс: "+pct+"%. Рекомендуется продолжать работу в том же темпе"
}else if(ql.indexOf("аудит")!==-1||ql.indexOf("провер")!==-1||ql.indexOf("контрол")!==-1){
ans="Аудит плана ПБ:";
ans+="\n- выполнено: "+done+"/"+total+" ("+Math.round(done/total*100)+"%)";
ans+="\n- просрочено: "+late;
var riskCount=0;
for(var i=0;i<evs.length;i++){var dr=daysRem(evs[i].due);if(evs[i].s!=="done"&&dr<=30&&dr>0)riskCount++}
ans+="\n- в риске (<30 дней): "+riskCount;
if(done/total>0.7)ans+="\nОбщая оценка: хорошо";
else if(done/total>0.4)ans+="\nОбщая оценка: удовлетворительно";
else ans+="\nОбщая оценка: требует внимания"
}else if(ql.indexOf("пункт")!==-1||ql.indexOf("номер")!==-1){
var match=ql.match(/\d+/);
if(match){
var num=parseInt(match[0],10);
var found=null;
for(var i=0;i<evs.length;i++){if(evs[i].id===num){found=evs[i];break}}
if(found){
ans="N"+found.id+" "+found.t.slice(0,80)+"...";
ans+="\nСтатус: "+stn[found.s];
ans+="\nФилиал: "+brs[found.b];
ans+="\nСрок: "+found.due;
ans+="\nПрогресс: "+(found.p||0)+"%"
}else{ans="Пункт N"+num+" не найден"}
}else{ans="Напиши номер пункта, например: пункт 5"}
}else{
ans="Я — Джарвис, ваш аналитический ассистент. Могу ответить:\n\n• сводка — общая статистика\n• просроченные — список просрочек\n• риски — зона риска (<30 дней)\n• рейтинг — рейтинг филиалов\n• аудит — полный аудит\n• прогноз — прогноз исполнения\n• статус — состояние по разделам\n• план — план действий и рекомендации\n• пункт N — детали конкретного мероприятия"
}
addMsg("b",ans,"Джарвис")
}
function renderUsers(){
if(!cu||cu.bg!==0){document.getElementById("tab_users").innerHTML="<div class='card'><p style='color:#EF4444'>\u0414\u043E\u0441\u0442\u0443\u043F \u0437\u0430\u043F\u0440\u0435\u0449\u0451\u043D</p></div>";return}
var ex=localStorage.getItem("ext_users");
if(ex){try{var eu=JSON.parse(ex);for(var k in eu){if(eu.hasOwnProperty(k)&&!USR[k])USR[k]=eu[k]}}catch(e){}}
var rn={0:"\u041A\u0443\u0440\u0430\u0442\u043E\u0440",1:"\u041E\u0442\u0432. \u043B\u0438\u0446\u043E",2:"\u0420\u0443\u043A. \u0444\u0438\u043B\u0438\u0430\u043B\u0430"};
var h="<table><tr><th>\u041B\u043E\u0433\u0438\u043D</th><th>\u0424\u0418\u041E</th><th>\u0422\u0435\u043B\u0435\u0444\u043E\u043D</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0420\u043E\u043B\u044C</th><th></th></tr>";
for(var k in USR){
if(!USR.hasOwnProperty(k))continue;
var u=USR[k];
h+="<tr><td>"+esc(k)+(k.indexOf("@")===-1?"@telecom.kz":"")+"</td><td>"+esc(u.n)+"</td><td>"+esc(u.ph||"")+"</td><td>"+esc(brs[u.bg]||"")+"</td><td>"+esc(rn[u.role]||(u.bg===0?"\u041A\u0443\u0440\u0430\u0442\u043E\u0440":"\u041E\u0442\u0432. \u043B\u0438\u0446\u043E"))+"</td>";
h+="<td><button class='btn btn-sm btn-o' style='padding:3px 8px;margin-right:4px' onclick=\"resetPw('"+esc(k)+"')\">\u0421\u0431\u0440\u043E\u0441</button><button class='btn btn-sm btn-r' style='padding:3px 10px' onclick=\"delUser('"+esc(k)+"')\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button></td></tr>"
}
h+="</table>";
document.getElementById("users_list").innerHTML=h
}
function resetPw(k){
var np=prompt("Новый пароль для "+k+":","0000");
if(np&&USR[k]){USR[k].pw=np;saveUsers();renderUsers()}
}
function addUser(){
var em=document.getElementById("reg_email").value.trim().toLowerCase();
var k=em.split("@")[0];
var nm=document.getElementById("reg_name").value.trim();
var ph=document.getElementById("reg_phone").value.trim();
var bg=parseInt(document.getElementById("reg_branch").value,10);
var pw=document.getElementById("reg_pass").value.trim();
var rlSel=document.getElementById("reg_role");
var rl=rlSel?parseInt(rlSel.value,10):1;
if(!em||!nm){alert("\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u043B\u043E\u0433\u0438\u043D \u0438 \u0424\u0418\u041E");return}
if(USR[k]){alert("\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442");return}
USR[k]={n:nm,bg:bg,ph:ph,role:rl};
if(pw)USR[k].pw=pw;
saveUsers();
closeRegModal();
renderUsers()
}
function showRegModal(){
var rb=document.getElementById("reg_branch");
if(rb&&!rb.options.length){
for(var i=0;i<brs.length;i++){
var o=document.createElement("option");
o.value=i;o.textContent=brs[i];
rb.appendChild(o)
}
}
var rr=document.getElementById("reg_role");
if(rr&&!rr.options.length){
var roles=[{v:0,t:"\u041A\u0443\u0440\u0430\u0442\u043E\u0440 \u041F\u0411"},{v:1,t:"\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u043E\u0435 \u043B\u0438\u0446\u043E"},{v:2,t:"\u0420\u0443\u043A\u043E\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C \u0444\u0438\u043B\u0438\u0430\u043B\u0430"}];
for(var j=0;j<roles.length;j++){
var o2=document.createElement("option");
o2.value=roles[j].v;o2.textContent=roles[j].t;
rr.appendChild(o2)
}
}
document.getElementById("regModal").style.display="flex"
}
function closeRegModal(){
document.getElementById("regModal").style.display="none";
document.getElementById("reg_email").value="";
document.getElementById("reg_name").value="";
document.getElementById("reg_phone").value="";
document.getElementById("reg_pass").value=""
}
function delUser(k){
if(!confirm("Удалить "+k+"?"))return;
delete USR[k];
saveUsers();
renderUsers()
}
function saveLTIF(){
if(!cu||cu.bg!==0){alert("\u0422\u043E\u043B\u044C\u043A\u043E \u043A\u0443\u0440\u0430\u0442\u043E\u0440 \u043C\u043E\u0436\u0435\u0442 \u0432\u043D\u043E\u0441\u0438\u0442\u044C \u0434\u0430\u043D\u043D\u044B\u0435 LTIF");return}
var m=parseInt(document.getElementById("ltif_month").value,10);
var h=parseFloat(document.getElementById("ltif_hours").value)||0;
var a=parseInt(document.getElementById("ltif_inj").value)||0;
if(!h){alert("\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u043E-\u0447\u0430\u0441\u044B");return}
var data=localStorage.getItem("ltif_data");
var ltif=[];
if(data){try{ltif=JSON.parse(data)}catch(e){}}
if(ltif[m]&&ltif[m].h){
var co=localStorage.getItem("ltif_corrections");
var corr=[];
if(co){try{corr=JSON.parse(co)}catch(e){}}
var d=new Date();
corr.push({month:m,oldH:ltif[m].h,oldA:ltif[m].a,newH:h,newA:a,comment:"\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u0431\u0435\u0437 \u043A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u044F",date:d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear(),user:cu?cu.n:""});
try{localStorage.setItem("ltif_corrections",JSON.stringify(corr))}catch(e){}
}
ltif[m]={h:h,a:a};
try{localStorage.setItem("ltif_data",JSON.stringify(ltif))}catch(e){}
loadLTIF()
}
function saveLtifCorrection(m){
if(!cu||cu.bg!==0)return;
var nh=parseFloat(document.getElementById("ltifc_h_"+m).value)||0;
var na=parseInt(document.getElementById("ltifc_a_"+m).value)||0;
var nc=document.getElementById("ltifc_c_"+m).value.trim()||"\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430";
if(!nh){alert("\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u043E-\u0447\u0430\u0441\u044B");return}
var data=localStorage.getItem("ltif_data");
var ltif=[];
if(data){try{ltif=JSON.parse(data)}catch(e){}}
var oh=ltif[m]?ltif[m].h:0;
var oa=ltif[m]?ltif[m].a:0;
var co=localStorage.getItem("ltif_corrections");
var corr=[];
if(co){try{corr=JSON.parse(co)}catch(e){}}
var d=new Date();
corr.push({month:m,oldH:oh,oldA:oa,newH:nh,newA:na,comment:nc,date:d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear(),user:cu?cu.n:""});
try{localStorage.setItem("ltif_corrections",JSON.stringify(corr))}catch(e){}
ltif[m]={h:nh,a:na};
try{localStorage.setItem("ltif_data",JSON.stringify(ltif))}catch(e){}
loadLTIF()
}
function loadLTIF(){
var data=localStorage.getItem("ltif_data");
var ltif=[];
if(data){try{ltif=JSON.parse(data)}catch(e){}}
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
var m=parseInt(document.getElementById("ltif_month").value,10);
var cur=ltif[m];
if(cur){document.getElementById("ltif_hours").value=cur.h;document.getElementById("ltif_inj").value=cur.a}
else{document.getElementById("ltif_hours").value="";document.getElementById("ltif_inj").value=""}
var res=document.getElementById("ltif_result");
var totalH=0,totalA=0;
var isCurator=cu&&cu.bg===0;
var tbl="<table><tr><th>\u041C\u0435\u0441\u044F\u0446</th><th>\u0427\u0435\u043B-\u0447\u0430\u0441\u044B</th><th>\u041F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0435</th><th>LTIF</th>"+(isCurator?"<th>\u041A\u043E\u0440\u0440.</th>":"")+"</tr>";
for(var i=0;i<12;i++){
if(ltif[i]&&ltif[i].h){
totalH+=ltif[i].h;totalA+=ltif[i].a;
var lt=ltif[i].a*1000000/ltif[i].h;
tbl+="<tr><td>"+mnames[i]+"</td><td>"+ltif[i].h.toLocaleString()+"</td><td>"+ltif[i].a+"</td><td>"+lt.toFixed(2)+"</td>";
if(isCurator)tbl+="<td><button class='btn btn-sm btn-o' style='padding:2px 6px;font-size:10px' onclick=\"showLtifCorr("+i+")\">\u041A\u043E\u0440\u0440.</button></td>";
tbl+="</tr>"
}
}
tbl+="</table>";
if(totalH>0){
var totalLT=totalA*1000000/totalH;
res.innerHTML="<strong>\u0413\u043E\u0434\u043E\u0432\u043E\u0439 LTIF: "+totalLT.toFixed(2)+"</strong> (\u043F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0445: "+totalA+", \u0447\u0435\u043B-\u0447\u0430\u0441\u043E\u0432: "+totalH.toLocaleString()+")"
}else{res.innerHTML=""}
document.getElementById("ltif_table").innerHTML=tbl;
document.getElementById("ltif_corr_div").innerHTML="";
document.getElementById("ltif_card").style.display=cu&&cu.bg===0?"":"none";
renderLtifCorrections()
}
function showLtifCorr(m){
if(!cu||cu.bg!==0)return;
var data=localStorage.getItem("ltif_data");
var ltif=[];
if(data){try{ltif=JSON.parse(data)}catch(e){}}
var cur=ltif[m];
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
var h="<div style='margin-top:8px;padding:8px;background:#FFF3E0;border-radius:6px;font-size:12px'>";
h+="<strong>\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u0437\u0430 "+esc(mnames[m])+":</strong><br>";
h+="\u0427\u0435\u043B-\u0447\u0430\u0441\u044B: <input id='ltifc_h_"+m+"' type='number' value='"+(cur?cur.h:"")+"' style='width:120px;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'> ";
h+="\u041F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0445: <input id='ltifc_a_"+m+"' type='number' value='"+(cur?cur.a:"0")+"' style='width:60px;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'><br>";
h+="\u041F\u0440\u0438\u0447\u0438\u043D\u0430: <input id='ltifc_c_"+m+"' placeholder='\u041F\u0440\u0438\u0447\u0438\u043D\u0430 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0438' style='width:100%;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'><br>";
h+="<button class='btn btn-sm btn-g' style='margin-top:4px;padding:3px 10px;font-size:11px' onclick='saveLtifCorrection("+m+")'>\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C</button> ";
h+="<button class='btn btn-sm' style='margin-top:4px;padding:3px 10px;font-size:11px;background:#E2E8F0;color:#0B1A2E' onclick='document.getElementById(\"ltif_corr_div\").innerHTML=\"\"'>\u041E\u0442\u043C\u0435\u043D\u0430</button></div>";
document.getElementById("ltif_corr_div").innerHTML=h
}
function renderLtifCorrections(){
var co=localStorage.getItem("ltif_corrections");
if(!co)return;
try{
var corr=JSON.parse(co);
if(!corr||!corr.length)return;
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
corr.sort(function(a,b){return b.month-a.month});
var h="<div style='margin-top:12px'><strong>\u0418\u0441\u0442\u043E\u0440\u0438\u044F \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043E\u043A:</strong><table style='font-size:11px'><tr><th>\u041C\u0435\u0441\u044F\u0446</th><th>\u0411\u044B\u043B\u043E \u0447-\u0447/\u043F</th><th>\u0421\u0442\u0430\u043B\u043E \u0447-\u0447/\u043F</th><th>\u041F\u0440\u0438\u0447\u0438\u043D\u0430</th><th>\u0414\u0430\u0442\u0430</th><th>\u041A\u0442\u043E</th></tr>";
for(var i=0;i<corr.length;i++){
var c=corr[i];
h+="<tr><td>"+mnames[c.month]+"</td><td>"+(c.oldH||0)+"/"+(c.oldA||0)+"</td><td>"+c.newH+"/"+c.newA+"</td><td style='font-size:10px'>"+esc(c.comment||"")+"</td><td>"+esc(c.date||"")+"</td><td>"+esc(c.user||"")+"</td></tr>"
}
h+="</table></div>";
document.getElementById("ltif_corr_div").innerHTML+=h
}catch(e){}
}
function saveUsers(){
var ex={};
for(var k in USR){
if(!USR.hasOwnProperty(k))continue;
if(k!=="curator"&&k!=="admin"&&k!=="dpp")ex[k]=USR[k]
}
try{localStorage.setItem("ext_users",JSON.stringify(ex))}catch(e){}
}
function dlAnalyticsPPT(){
var total=evs.length;var done=0,late=0,warn=0;
for(var i=0;i<evs.length;i++){if(evs[i].s==="done")done++;else if(evs[i].s==="late")late++;else warn++}
var pct=total?Math.round(done/total*100):0;
var brd=[];for(var i=0;i<brs.length;i++){brd.push({n:brs[i],t:0,d:0})}
for(var i=0;i<evs.length;i++){var e=evs[i];brd[e.b].t++;if(e.s==="done")brd[e.b].d++}
brd.sort(function(a,b){return(b.d/b.t||0)-(a.d/a.t||0)});
var h="<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:p='urn:schemas-microsoft-com:office:powerpoint'><head><meta charset='utf-8'><title>\u0410\u043D\u0430\u043B\u0438\u0442\u0438\u043A\u0430 HSE</title><style>body{font:18px Arial;padding:30px}@page{size:A4 landscape;margin:15mm}h1{color:#005BAA;font-size:28px}.num{font-size:48px;font-weight:800;color:#005BAA}.pct{font-size:72px;font-weight:800;color:"+(pct>=70?"#10B981":pct>=40?"#F59E0B":"#EF4444")+"}.bar{height:28px;background:#005BAA;border-radius:6px;margin:8px 0}.slide{page-break-after:always;min-height:350px}table{border-collapse:collapse;width:100%}td{padding:12px 20px;border:1px solid #ddd;font-size:16px}th{background:#0A1628;color:#fff;padding:10px 14px;font-size:13px}</style></head><body><div class='slide'><h1>QAZAQtelecom HSE \u2014 \u0410\u043D\u0430\u043B\u0438\u0442\u0438\u043A\u0430 \u041F\u0411</h1><p>\u0414\u0430\u0442\u0430: "+new Date().toLocaleDateString("ru-RU")+"</p><br><div style='text-align:center'><div class='pct'>"+pct+"%</div><p style='font-size:20px;color:#64748B'>\u041E\u0431\u0449\u0438\u0439 \u043F\u0440\u043E\u0446\u0435\u043D\u0442 \u0438\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F</p></div><br><table><tr><td style='text-align:center'><div class='num'>"+total+"</div>\u0412\u0441\u0435\u0433\u043E</td><td style='text-align:center'><div class='num'>"+done+"</div>\u0418\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u043E</td><td style='text-align:center'><div class='num'>"+warn+"</div>\u0412 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0435</td><td style='text-align:center'><div class='num' style='color:#EF4444'>"+late+"</div>\u041F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E</td></tr></table><div class='bar' style='width:"+Math.round(pct*5)+"px'></div></div><div class='slide'><h2>\u0420\u0435\u0439\u0442\u0438\u043D\u0433 \u0444\u0438\u043B\u0438\u0430\u043B\u043E\u0432</h2><table><tr><th>\u2116</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u043E</th><th>%</th></tr>";
for(var i=0;i<brd.length;i++){var bp=brd[i].t?Math.round(brd[i].d/brd[i].t*100):0;h+="<tr><td>"+(i+1)+"</td><td>"+esc(brd[i].n)+"</td><td>"+brd[i].d+"/"+brd[i].t+"</td><td><div class='bar' style='width:"+(bp*2)+"px'></div> "+bp+"%</td></tr>"}
h+="</table></div></body></html>";
var blob=new Blob([h],{type:"application/vnd.ms-powerpoint"});
var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="analytics_"+new Date().toISOString().slice(0,10)+".ppt";a.click()
}
function dlAnalyticsPDF(){
var h=document.getElementById("tab_analytics").innerHTML;
var w=window.open("","_blank","width=900,height=700");
w.document.write("<!DOCTYPE html><html><head><meta charset='utf-8'><title>Аналитика</title><style>body{font:14px Arial;padding:20px}@media print{body{padding:10mm}}.card{background:#fff;border:1px solid #E8ECF1;border-radius:12px;padding:16px;margin-bottom:12px}.num{font-size:28px;font-weight:800}</style></head><body><h2>QAZAQtelecom HSE — Аналитика</h2><p>"+new Date().toLocaleDateString("ru-RU")+"</p><br>"+h+"<script>window.onload=function(){window.print()}<\/script></body></html>");
w.document.close()
}
function dlAnalyticsWord(){
var total=evs.length;
var done=0,late=0,warn=0;
for(var i=0;i<evs.length;i++){
if(evs[i].s==="done")done++;else if(evs[i].s==="late")late++;else warn++
}
var h="<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word'><head><meta charset='utf-8'><title>Аналитика HSE</title><style>@page{size:A4;margin:20mm}body{font:14pt 'Times New Roman'}h1{color:#005BAA}table{border-collapse:collapse}td{border:1px solid #000;padding:12px 20px;font-size:20pt;font-weight:700}</style></head><body><h1>QAZAQtelecom HSE — Аналитика</h1><p>Дата: "+new Date().toLocaleDateString("ru-RU")+"</p><br><table><tr><td>Всего<br><span style='font-size:28pt'>"+total+"</span></td><td>Исполнено<br><span style='font-size:28pt'>"+done+" ("+Math.round(done/total*100)+"%)</span></td><td>В процессе<br><span style='font-size:28pt'>"+warn+"</span></td><td>Просрочено<br><span style='font-size:28pt;color:red'>"+late+"</span></td></tr></table></body></html>";
var blob=new Blob([h],{type:"application/msword"});
var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="analytics.doc";a.click()
}
</script></script></script></script></script></script></script></script></script></script></script></script>
</body>
</html>