Base_of_lessons / index.html
AnnLior's picture
Update index.html
528b1fe verified
Raw History Blame Contribute Delete
51.1 kB
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Уроки Т</title>
<style>
:root{--bg:#ffffff;--sand:#F8FAFC;--ink:#696969;--text:#4a3a31;--dim:#8a7a6e;--chip:#696969;--chipt:#fff;--card:#F8FAFC;
--pray:#7fbab4;--word:#2f8a6c;--dream:#b08a4f;--digest:#925727;--mark:#f1dfa6;
padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}
body.dark{--bg:#171412;--sand:#262120;--ink:#f5f4f0;--text:#d8cfc6;--dim:#9a8d82;--chip:#2f2926;--chipt:#f5f4f0;--card:#211c1a;--mark:#8a6a1e}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);font-family:system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;padding-left:46px;min-height:100vh;transition:background .25s}
button{font:inherit;cursor:pointer;border:none;color:inherit}
/* ВЕРХНИЙ БЛОК — СПЛОШНАЯ ЗАЛИВКА */
.hero{position:relative;margin-left:-46px;background:#185a4f;padding:calc(14px + env(safe-area-inset-top,0px)) 18px 22px}
.hero-top{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-start;margin-bottom:14px}
.hbtn{background:rgba(255,255,255,.14);color:#fff;border-radius:12px;padding:8px 13px;font-size:12.5px;backdrop-filter:blur(6px)}
.hbtn:hover{background:rgba(255,255,255,.24)}
/* календарь на зелёном */
#cal{margin:0 auto;text-align:center;color:#fff}
.cal-h{display:flex;justify-content:center;align-items:center;gap:10px;font-size:12.5px;margin-bottom:9px;color:#dff0ea}
.cal-h button{background:rgba(255,255,255,.18);color:#fff;border-radius:8px;width:24px;height:24px}
.cal-g{display:grid;grid-template-columns:repeat(7,28px);gap:4px;justify-content:center}
.cd{width:28px;height:28px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:11px;background:rgba(255,255,255,.12);color:#cfe6df}
.cd.l{background:#fff;color:#0a322b;font-weight:700;box-shadow:0 2px 8px rgba(0,0,0,.3)}
.cd.cur{outline:2px solid #f1dfa6}
.cd.e{background:none}
.cal-wd{width:28px;height:14px;font-size:9px;text-align:center;color:#a9ccc3}
.wrap{
max-width: 900px;
margin: 0 auto;
padding: 24px 56px 80px 18px;
}
@media(min-width:761px){
.wrap{
max-width: 800px;
margin: 0 auto;
transform: translateX(-23px);
padding-left: 70px;
padding-right: 70px;
box-sizing: border-box;
}
}
.sub{text-align:center;font-size:13px;color:var(--dim);margin-bottom:20px}
.row{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-bottom:18px;align-items:center}
.search{flex:0 1 340px;display:flex;background:var(--sand);border-radius:14px;padding:10px 15px}
.search input{flex:1;border:none;outline:none;background:none;font:inherit;font-size:14.5px;color:var(--ink);min-width:0}
.pill{background:var(--chip);color:var(--chipt);border-radius:12px;padding:10px 16px;font-size:13.5px}
.pill.off{background:var(--sand);color:var(--text)}
.cloud{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-bottom:22px}
.tag{background:var(--chip);color:var(--chipt);border-radius:9px;padding:5px 11px;font-size:12px;display:inline-flex;gap:6px;align-items:center}
.tag i{font-style:normal;opacity:.55;font-size:10.5px}
.tag.dim{background:var(--sand);color:var(--dim)}
.tag.act{outline:2px solid var(--ink);outline-offset:1px}
.tag.act.pray{background:var(--pray);color:#141210}.tag.act.word{background:var(--word);color:#fff}.tag.act.dream{background:var(--dream);color:#fff}.tag.act.digest{background:var(--digest);color:#fff}
.col{
max-width: 700px;
width: 100%;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.sum{text-align:center;font-size:12.5px;color:var(--dim)}
.sum b{color:var(--ink)}
.sum button{margin-left:8px;padding:4px 12px;font-size:12px}
.empty{text-align:center;color:var(--dim);padding:40px 16px;line-height:1.7;font-size:14px}
.note{background:var(--card);border-radius:16px;padding:16px 18px 12px;border-left:2px solid var(--c,var(--pray))}
.nh{display:flex;justify-content:space-between;gap:12px;margin-bottom:8px}
.nt{font-weight:600;color:var(--ink);font-size:15.5px}
.nd{font-size:11.5px;color:var(--dim);white-space:nowrap}
.snip{font-size:11px;font-weight:600;color:var(--dim);text-transform:uppercase;margin-bottom:6px}
.nb{font-size:14.5px;line-height:1.6;white-space:pre-wrap;word-break:break-word}
.nb p{margin:0 0 .6em}
.nb mark{background:var(--mark);border-radius:4px;padding:0 3px;color:inherit}
.nt2{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
.nt2 .tag{font-size:11.5px;padding:4px 10px}
.acts{display:flex;gap:8px;justify-content:flex-end;margin-top:10px}
.ib{background:var(--chip);color:var(--chipt);border-radius:10px;width:32px;height:32px;font-size:13px}
.tabs{position:fixed;left:0;top:50%;transform:translateY(-50%);z-index:30;display:flex;flex-direction:column;gap:8px}
.tb{writing-mode:vertical-rl;transform:rotate(180deg);width:32px;padding:12px 0;border-radius:12px 0 0 12px;background:var(--sand);color:var(--text);font-size:12px;font-weight:600;letter-spacing:.4px;display:flex;align-items:center;justify-content:center;gap:8px;white-space:nowrap;transition:width .15s}
.tb:hover{width:32px}
.tb.on{background:var(--chip);color:var(--chipt);width:32px}
.tb b{width:9px;height:9px;border-radius:50%;background:var(--c)}
.tb small{opacity:.6;font-weight:400}
.tb small.fnd{opacity:1;font-weight:700;background:rgba(128,128,128,.28);border-radius:8px;padding:5px 1px}
.ov{position:fixed;inset:0;background:rgba(20,18,16,.55);backdrop-filter:blur(3px);display:none;align-items:center;justify-content:center;padding:18px;z-index:60}
.ov.open{display:flex}
.modal{background:var(--bg);border-radius:20px;padding:22px;width:100%;max-width:520px;max-height:90vh;overflow:auto}
.modal h2{margin:0 0 14px;font-size:18px;color:var(--ink)}
.f{margin-bottom:14px}.f label{display:block;font-size:12.5px;color:var(--dim);margin-bottom:6px}
.f input[type=text],.f textarea{width:100%;border:none;outline:none;background:var(--sand);border-radius:12px;padding:11px 13px;font:inherit;font-size:14.5px;color:var(--ink)}
.f textarea{min-height:140px;resize:vertical;line-height:1.55}
.mdb{display:flex;align-items:center;gap:6px;margin-bottom:6px}
.mdb button{width:30px;height:30px;border-radius:9px;background:var(--sand);color:var(--ink);font-size:13px}
.mdb .hint{margin-left:4px}
.sugs{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.sugs .tag{cursor:pointer;font-size:11.5px;padding:3px 10px}
.mact{display:flex;gap:10px;justify-content:flex-end;margin-top:16px}
.lrow{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:7px 2px;font-size:13px;color:var(--ink)}
.lrow .tag{padding:3px 9px}
input[type=file]{display:none}
.ib.on{outline:2px solid var(--digest)}
.dot{width:9px;height:9px;border-radius:50%;display:inline-block;flex:0 0 auto}
.dgb{line-height:var(--dg-line,1.45);font-size:14px}
.dgb p{position:relative;margin:0 0 var(--dg-gap,.5em);padding-left:44px}
.pbm,.ped{position:absolute;top:.1em;width:18px;background:none;font-size:12px;line-height:1;padding:0;opacity:.18;text-align:center}
.pbm{left:0}.ped{left:22px}
.pbm,.ped,.dopen{-webkit-user-select:none;user-select:none}
.dgb p:hover .pbm,.dgb p:hover .ped{opacity:.9}
@media(hover:none){.pbm,.ped{opacity:.5}}
.dgb p.bmp{background:rgba(128,52,24,.1);border-radius:8px}.bmp .pbm{opacity:1}
.dgb p.dq{background:rgba(175, 80, 113,.34);border-radius:8px;padding-top:4px;padding-bottom:4px}
.dgb p.editing{padding-left:0}
.pe{width:100%;font:inherit;font-size:14px;line-height:1.5;color:var(--ink);background:var(--sand);border:none;border-radius:10px;padding:8px 10px;resize:vertical;outline:none;min-height:60px}
.peb{display:flex;gap:8px;align-items:center;margin-top:6px;flex-wrap:wrap}.hint{font-size:11px;color:var(--dim)}
.dopen{border:none;width:17px;height:17px;border-radius:50%;font-size:9px;padding:0;margin:0 3px;vertical-align:middle;color:#fff}
.rcol{position:fixed;top:calc(12px + env(safe-area-inset-top,0px));right:14px;z-index:46;display:flex;flex-direction:column;gap:6px;align-items:flex-end}
.bmw{display:flex;align-items:center;gap:7px;background:rgba(20,18,16,.78);color:#fff;border-radius:12px;padding:6px 10px;font-size:12px;cursor:pointer;backdrop-filter:blur(6px)}
.bmw em{font-style:normal;opacity:.7}.bmx{display:none;background:none;color:#fff;padding:0 2px}.bmw:hover .bmx{display:inline}
.stabs{position:fixed;right:18px;bottom:calc(84px + env(safe-area-inset-bottom,0px));z-index:40;display:flex;flex-direction:column;gap:8px;align-items:flex-end}
.sw{position:relative}
.st{writing-mode:vertical-rl;background:var(--chip);color:var(--chipt);font-size:12px;font-weight:600;width:32px;padding:12px 0;display:flex;align-items:center;justify-content:center;border-radius:12px 0 0 12px}
.hbtn, .bmw{min-height:34px;box-sizing:border-box}
.sp{
position:absolute;right:100%;bottom:0;transform:translateX(12px);
width:210px;background:var(--bg);border-radius:16px;padding:14px;
opacity:0;pointer-events:none;
transition:opacity .18s, transform .18s;
box-shadow:0 8px 30px rgba(0,0,0,.25);
color:var(--text);z-index:80;
}
.sw:hover .sp{opacity:1;pointer-events:auto;transform:none}
.sp.scr{
max-height:320px;overflow-y:auto;
scrollbar-width:none;-ms-overflow-style:none;
}
.sp.scr::-webkit-scrollbar{display:none;width:0;height:0}
body.dark .sp{background:var(--card);box-shadow:0 8px 30px rgba(0,0,0,.55)}
.spt{font-size:11px;font-weight:600;color:var(--dim);text-transform:uppercase;margin-bottom:10px;text-align:center}
.tsr{display:flex;align-items:center;gap:6px;padding:4px 2px;font-size:12.5px;color:var(--ink)}
.hit{display:flex;gap:8px;padding:7px;border-radius:12px;cursor:pointer;font-size:12px;color:var(--text)}.hit:hover{background:var(--sand)}.hit small{display:block;color:var(--dim);font-size:10px}
.he{text-align:center;color:var(--dim);font-size:12px;padding:12px}
.vr{margin-bottom:12px;font-size:12px}.vr label{display:flex;justify-content:space-between;margin-bottom:6px}.vr input{width:100%;accent-color:var(--digest)}
.sab{position:fixed;z-index:70;display:none;background:var(--digest);color:#fff;border-radius:12px;padding:9px 14px;font-size:12.5px;font-weight:600}
.stop{position:fixed;right:18px;bottom:calc(22px + env(safe-area-inset-bottom,0px));width:48px;height:48px;border-radius:50%;background:var(--chip);color:var(--chipt);font-size:18px;opacity:0;pointer-events:none;transition:opacity .2s;z-index:45;display:flex;align-items:center;justify-content:center;padding:0}.stop.v{opacity:1;pointer-events:auto}
.stop svg{position:absolute;inset:0;width:100%;height:100%}
.stop .ar{position:relative;z-index:1;font-weight:600;line-height:1}
/* НОВАЯ ОРАНЖЕВАЯ КНОПКА */
.fab{position:fixed;left:0;top:0;width:46px;height:46px;border-radius:50%;background:#f08a24;color:#fff;font-size:28px;line-height:1;padding:0;display:none;align-items:center;justify-content:center;z-index:55;box-shadow:0 4px 14px rgba(0,0,0,.35)}
.fab.v{display:flex}
@media(max-width:760px){
html,body{overflow-x:hidden}
body{padding-left:0}
.hero{margin-left:0}
.hbtn{padding:6px 9px;font-size:11.5px}
.rcol{top:calc(14px + env(safe-area-inset-top,0px));bottom:auto;right:8px;flex-direction:row;gap:6px;align-items:flex-start;max-width:calc(100vw - 90px);overflow-x:auto;overflow-y:hidden;pointer-events:none}
.rcol .bmw{pointer-events:auto;flex-shrink:0;white-space:nowrap;padding:0 4px 0 11px;font-size:11.5px;min-height:34px;border-radius:12px;gap:6px}
.rcol .bmw em{display:none}
.rcol .bmw b{display:inline;font-weight:600}
.rcol .bmw .bmx{display:inline;opacity:.85;min-width:32px;height:34px;margin-left:2px;font-size:14px;border-left:1px solid rgba(255,255,255,.22)}
/* контент по центру, поля чуть шире узких ярлыков */
.wrap{padding:16px 0 80px}
.row,.cloud,.sub{padding:0 30px}
.col{max-width:100%;width:100%;padding:0;margin:0 auto}
.note{margin:0 30px;padding:14px 14px 10px}
/* левые ярлыки: узкие, полупрозрачные, скругления развернуты */
.tabs{left:0;gap:6px}
.tb,.tb:hover,.tb.on{width:24px}
.tb{padding:10px 0;font-size:11.5px;gap:5px;border-radius:10px 0 0 10px;opacity:.45;transition:opacity .25s}
.tb b{width:7px;height:7px}
.tb small{font-size:10px}
.tb.on{opacity:.8}
.tb:active{opacity:1}
/* правые ярлыки: так же */
.stabs{right:0;gap:6px;pointer-events:none}
.sw{pointer-events:auto}
.stabs .st{width:24px;padding:10px 0;font-size:11px;border-radius:10px 0 0 10px;opacity:.45;transition:opacity .25s}
.sw:hover .st,.sw:active .st{opacity:1}
}
/* узкое окно на компьютере: отодвигаем правые ярлыки от полосы прокрутки */
@media(max-width:760px) and (hover:hover){
.stabs{right:22px}
.row,.cloud,.sub{padding:0 54px 0 32px}
.note{margin:0 54px 0 32px}
}
</style>
</head>
<body>
<!-- ВЕРХНИЙ БЛОК: ЗЕЛЁНАЯ ЗАЛИВКА + КАЛЕНДАРЬ -->
<div class="hero" id="hero">
<div class="hero-top">
<button class="hbtn" id="exportBtn" title="Скачать все заметки в файл">⬇ Экспорт</button>
<button class="hbtn" id="importBtn" title="Загрузить заметки из файла">⬆ Импорт</button>
<button class="hbtn" id="themeBtn" title="Переключить тему">☾ Тема</button>
<input type="file" id="importFile" accept=".json,application/json">
</div>
<div id="cal"></div>
</div>
<div class="wrap">
<div class="row">
<div class="search"><input type="text" id="search" placeholder="Поиск по заметкам…"></div>
<button class="pill off" id="clearBtn" title="Сбросить поиск и теги">✕</button>
<button class="pill off" id="onlyBtn" title="Если включено, поиск и теги ищут только среди конспектов">Только конспекты</button>
<button class="pill" id="lessonsBtn">Уроки</button>
<button class="pill" id="addBtn" title="Добавить заметку">+ Заметка</button>
</div>
<div class="cloud" id="cloud"></div>
<div class="col" id="content"></div>
</div>
<div class="rcol" id="bmWidget"></div>
<div class="stabs">
<div class="sw"><div class="st">Теги</div><div class="sp scr"><div class="spt">Все теги · по популярности</div><div id="tagsPanel"></div></div></div>
<div class="sw"><div class="st">База</div><div class="sp"><div class="spt">Статистика</div><div id="statsBox"></div></div></div>
<div class="sw"><div class="st">Вид</div><div class="sp"><div class="spt">Вид конспектов</div>
<div class="vr"><label><span>Строки в абзаце</span><b id="vLineV"></b></label><input type="range" id="vLine" min="0.8" max="1.8" step="0.05"></div>
<div class="vr"><label><span>Между абзацами</span><b id="vGapV"></b></label><input type="range" id="vGap" min="0" max="1.2" step="0.05"></div></div></div>
<div class="sw"><div class="st">История</div><div class="sp"><div class="spt">Последние 5 добавленных</div><div id="historyList"></div></div></div>
</div>
<button class="stop" id="stop" title="Наверх">
<svg viewBox="0 0 50 50"><circle cx="25" cy="25" r="21" fill="none" stroke="rgba(128,128,128,.35)" stroke-width="3"/><circle id="ringP" cx="25" cy="25" r="21" fill="none" stroke="#e8c97a" stroke-width="3" stroke-linecap="round" transform="rotate(-90 25 25)"/></svg>
<span class="ar">↑</span>
</button>
<div class="tabs" id="tabs"></div>
<div class="ov" id="ov"><div class="modal" id="modal"></div></div>
<script>
(function(){
'use strict';
var KEY='my_notes_v1',TYPES=['pray','word','dream','digest'],NAMES={pray:'Молитва',word:'Слово',dream:'Сны',digest:'Конспекты'};
var notes=[],tab='pray',q='',sel=[],only=false,focus=null,cal=null;
var $=function(i){return document.getElementById(i)};
function ls(k,v){try{if(v===undefined)return localStorage.getItem(k);localStorage.setItem(k,v)}catch(e){return null}}
function esc(s){return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}
function md(h){return h.replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>').replace(/__(.+?)__/g,'<u>$1</u>').replace(/\*(.+?)\*/g,'<em>$1</em>')}
function hl(t){var s=esc(t);if(!q)return s;var r=esc(q).replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return s.replace(new RegExp('('+r+')','gi'),'<mark>$1</mark>')}
function el(t,c,x){var e=document.createElement(t);if(c)e.className=c;if(x!=null)e.textContent=x;return e}
function uid(){return Date.now().toString(36)+Math.random().toString(36).slice(2,7)}
function fd(ts){var d=new Date(ts),p=function(n){return n<10?'0'+n:n};return p(d.getDate())+'.'+p(d.getMonth()+1)+'.'+d.getFullYear()+' '+p(d.getHours())+':'+p(d.getMinutes())}
function dom(n){for(var i=0;i<4;i++)if((n.types||[]).indexOf(TYPES[i])>-1)return TYPES[i];return 'pray'}
function save(){ls(KEY,JSON.stringify(notes))}
function load(){try{notes=JSON.parse(ls(KEY)||'[]');if(!Array.isArray(notes))notes=[]}catch(e){notes=[]}}
var LRE=/урок\s*№/i;
function lessonTags(n){return (n.tags||[]).filter(function(t){return LRE.test(t)})}
function pdate(t){var m=/^\s*(\d{4})[-.\/](\d{2})[-.\/](\d{2})/.exec(t||'');return m?{y:+m[1],m:+m[2]-1,d:+m[3]}:null}
function partNo(t){var m=/\((\d+)\s*ч\)/i.exec(t||'');return m?+m[1]:0}
function dlg(text,btns){var o=el('div','ov open'),b=el('div','modal');b.style.maxWidth='380px';var p=el('div','',text);p.style.cssText='white-space:pre-line;color:var(--ink);line-height:1.6;margin-bottom:16px';b.appendChild(p);var a=el('div','mact');btns.forEach(function(x){var k=el('button','pill'+(x.p?'':' off'),x.l);k.onclick=function(){document.body.removeChild(o);x.f&&x.f()};a.appendChild(k)});b.appendChild(a);o.appendChild(b);document.body.appendChild(o)}
function alertM(t){dlg(t,[{l:'ОК',p:1}])}
function theme(d){document.body.classList.toggle('dark',d);ls('uroki_theme',d?'dark':'light')}
$('themeBtn').onclick=function(){theme(!document.body.classList.contains('dark'))};
theme(ls('uroki_theme')==='dark'||(ls('uroki_theme')===null&&window.matchMedia&&matchMedia('(prefers-color-scheme: dark)').matches));
$('exportBtn').onclick=function(){if(!notes.length){alertM('Нет заметок для экспорта.');return}
var b=new Blob([JSON.stringify({app:'uroki-t',version:1,exportedAt:new Date().toISOString(),count:notes.length,notes:notes,bookmarks:bm},null,2)],{type:'application/json;charset=utf-8'});var a=document.createElement('a');a.href=URL.createObjectURL(b);a.download='uroki-t.json';document.body.appendChild(a);a.click();document.body.removeChild(a);setTimeout(function(){URL.revokeObjectURL(a.href)},1000)};
$('importBtn').onclick=function(){$('importFile').value='';$('importFile').click()};
$('importFile').onchange=function(e){var f=e.target.files&&e.target.files[0];if(!f)return;var r=new FileReader();r.onload=function(ev){var p;try{p=JSON.parse(ev.target.result)}catch(x){alertM('Не удалось прочитать файл: это не корректный JSON.');return}
var inc=Array.isArray(p)?p:(p&&p.notes);if(!Array.isArray(inc)||!inc.length){alertM('В файле не найдено ни одной заметки.');return}
var cl=inc.filter(function(n){return n&&typeof n==='object'}).map(function(n){return{id:n.id||uid(),title:String(n.title||''),body:String(n.body||''),tags:Array.isArray(n.tags)?n.tags.map(String):[],types:Array.isArray(n.types)?n.types.filter(function(t){return TYPES.indexOf(t)>-1}):[],read:!!n.read,created:typeof n.created==='number'?n.created:Date.now()}}).filter(function(n){return n.types.length});
if(!cl.length){alertM('В файле не найдено корректных заметок.');return}
var ib=(p&&!Array.isArray(p)&&p.bookmarks&&typeof p.bookmarks==='object')?p.bookmarks:{};
dlg('Найдено заметок: '+cl.length+'.\n\nЗаменить все текущие заметки или добавить их к существующим?',[
{l:'Добавить',f:function(){var ids={};notes.forEach(function(n){ids[n.id]=1});cl.forEach(function(n){if(ids[n.id])n.id=uid();else if(Object.prototype.hasOwnProperty.call(ib,n.id)&&!hasBm(n.id))bm[n.id]=ib[n.id];notes.push(n)});saveBm();save();render();alertM('Импорт завершён. Всего заметок: '+notes.length)}},
{l:'Заменить',p:1,f:function(){notes=cl;bm={};cl.forEach(function(n){if(Object.prototype.hasOwnProperty.call(ib,n.id))bm[n.id]=ib[n.id]});saveBm();save();render();alertM('Импорт завершён. Всего заметок: '+notes.length)}}])};
r.onerror=function(){alertM('Ошибка чтения файла.')};r.readAsText(f,'utf-8')};
function tagStats(){var c={};notes.forEach(function(n){(n.tags||[]).forEach(function(t){var k=t.trim();if(!k||/^\d{4}[-./]\d{2}[-./]\d{2}/.test(k))return;var l=k.toLowerCase();if(!c[l])c[l]={label:k,n:0,t:{pray:0,word:0,dream:0,digest:0}};c[l].n++;(n.types||[]).forEach(function(x){if(c[l].t[x]!==undefined)c[l].t[x]++})})});return c}
function domTag(s){var b='pray';TYPES.forEach(function(t){if(s.t[t]>s.t[b])b=t});return b}
function tagMatch(n){var l=(n.tags||[]).map(function(t){return t.toLowerCase()});return sel.filter(function(s){return l.indexOf(s.toLowerCase())>-1}).length}
function pass(n){if(sel.length&&!tagMatch(n))return false;if(q){var s=((n.title||'')+' '+(n.body||'')+' '+(n.tags||[]).join(' ')).toLowerCase();if(s.indexOf(q.toLowerCase())<0)return false}return true}
function renderCloud(){var c=$('cloud');c.innerHTML='';var st=tagStats();Object.keys(st).sort().forEach(function(k){var s=st[k],cls=domTag(s),a=sel.some(function(t){return t.toLowerCase()===k});
var b=el('button','tag '+cls+(a?' act':'')+(s.t[tab]>0?'':' dim'));b.appendChild(document.createTextNode(s.label));b.appendChild(el('i','','('+s.n+')'));
b.onclick=function(){focus=null;if(a)sel=sel.filter(function(t){return t.toLowerCase()!==k});else sel.push(s.label);render()};c.appendChild(b)})}
function renderTabs(res){var t=$('tabs');t.innerHTML='';['pray','word','dream'].forEach(function(x){var n=notes.filter(function(m){return(m.types||[]).indexOf(x)>-1}).length;
var b=el('button','tb'+(tab===x?' on':''));b.style.setProperty('--c','var(--'+x+')');b.appendChild(el('b'));b.appendChild(document.createTextNode(NAMES[x]+' '));b.appendChild(el('small','','('+n+')'));
if(res&&!only){var fn=res.filter(function(m){return(m.types||[]).indexOf(x)>-1}).length;if(fn){b.appendChild(el('small','fnd',String(fn)));b.title='Найдено: '+fn}}
b.onclick=function(){tab=x;focus=null;render()};t.appendChild(b)})}
function renderCal(){var box=$('cal');box.innerHTML='';var tag=null,fn=focus&&notes.filter(function(n){return n.id===focus})[0];
if(fn)tag=lessonTags(fn).filter(pdate)[0];if(!tag)tag=sel.filter(function(t){return LRE.test(t)&&pdate(t)})[0];if(!tag){cal=null;return}
var d0=pdate(tag);if(!cal||cal.tag!==tag)cal={tag:tag,y:d0.y,m:d0.m};
var days={};notes.forEach(function(n){lessonTags(n).forEach(function(t){var p=pdate(t);if(p&&p.y===cal.y&&p.m===cal.m){(days[p.d]=days[p.d]||[]);if(days[p.d].indexOf(t)<0)days[p.d].push(t)}})});
var MN=['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'];
var h=el('div','cal-h'),pr=el('button','','‹'),nx=el('button','','›');
pr.onclick=function(){cal.m--;if(cal.m<0){cal.m=11;cal.y--}renderCal()};nx.onclick=function(){cal.m++;if(cal.m>11){cal.m=0;cal.y++}renderCal()};
h.appendChild(pr);h.appendChild(el('span','',MN[cal.m]+' '+cal.y+' · уроков: '+Object.keys(days).length));h.appendChild(nx);box.appendChild(h);
var g=el('div','cal-g'),first=(new Date(cal.y,cal.m,1).getDay()+6)%7,dim=new Date(cal.y,cal.m+1,0).getDate();
['Пн','Вт','Ср','Чт','Пт','Сб','Вс'].forEach(function(w){g.appendChild(el('div','cal-wd',w))});
for(var i=0;i<first;i++)g.appendChild(el('div','cd e'));
for(var d=1;d<=dim;d++){(function(d){var l=days[d],c=el(l?'button':'div','cd'+(l?' l':'')+(l&&d0.y===cal.y&&d0.m===cal.m&&d0.d===d?' cur':''),d);
if(l){c.title=l.join('\n');c.onclick=function(){openLesson(l)}}g.appendChild(c)})(d)}
box.appendChild(g)}
function openLesson(tags){q='';$('search').value='';focus=null;sel=tags.slice();only=notes.some(function(n){return(n.types||[]).indexOf('digest')>-1&&(n.tags||[]).some(function(t){return tags.indexOf(t)>-1})});$('onlyBtn').classList.toggle('off',!only);render();window.scrollTo({top:0,behavior:'smooth'})}
function card(n,ty){var t=ty||dom(n),e=el('div','note');e.setAttribute('data-id',n.id);e.style.setProperty('--c','var(--'+t+')');
var h=el('div','nh');if((n.title||'').trim()){var tt=el('div','nt');tt.innerHTML=md(hl(n.title));h.appendChild(tt)}else h.appendChild(el('div'));
h.appendChild(el('div','nd',(n.read?'✓ вычитано · ':'')+fd(n.created)));e.appendChild(h);
var b=el('div','nb');
if(t==='digest'&&focus===n.id){digestBody(b,n)}
else if(t==='digest'&&focus!==n.id){e.appendChild(el('div','snip','Фрагмент конспекта'));var s=n.body||'',i=q?s.toLowerCase().indexOf(q.toLowerCase()):-1,st=Math.max(0,i-160);b.innerHTML=hl((st>0?'…':'')+s.slice(st,st+360)+(s.length>st+360?'…':''))}
else b.innerHTML=md(hl(n.body||''));
e.appendChild(b);
if((n.tags||[]).length){var tg=el('div','nt2'),sl=sel.map(function(x){return x.toLowerCase()});n.tags.slice().sort(function(a,b){return a.toLowerCase().localeCompare(b.toLowerCase(),'ru')}).forEach(function(x){var s=el('span','tag'+(sl.indexOf(x.toLowerCase())>-1?' act '+t:''));s.innerHTML=hl(x);tg.appendChild(s)});e.appendChild(tg)}
var a=el('div','acts');
if(t==='digest'){var o=el('button','ib',focus===n.id?'⤡':'⤢');o.title='Открыть / свернуть';o.onclick=function(){focus=focus===n.id?null:n.id;render()};a.appendChild(o);if(focus===n.id){var bk=el('button','ib'+(hasBm(n.id)?' on':''),'🔖');bk.title='Закладка в начало (для места — 🔖 у абзаца)';bk.onclick=function(){if(hasBm(n.id))clearBm(n.id);else setBm(n.id,null);render()};a.appendChild(bk)}}
var ed=el('button','ib','✎');ed.title='Редактировать';ed.onclick=function(){openModal(n)};a.appendChild(ed);
var dl=el('button','ib','🗑');dl.title='Удалить';dl.onclick=function(){dlg('Удалить эту заметку?',[{l:'Отмена'},{l:'Удалить',p:1,f:function(){notes=notes.filter(function(x){return x.id!==n.id});save();render()}}])};a.appendChild(dl);
e.appendChild(a);return e}
var PS=20,cur=[],rl=PS,rfn=null,io=null;
if(window.IntersectionObserver)io=new IntersectionObserver(function(es){es.forEach(function(x){if(x.isIntersecting)more()})},{rootMargin:'300px'});
function mk(n){return card(n,rfn(n))}
function status(){var s=$('loadStatus');if(!s)return;s.textContent=!cur.length?'':(rl<cur.length?'Показано '+rl+' из '+cur.length+' · прокрутите вниз, чтобы увидеть ещё':'Показаны все заметки: '+cur.length)}
function sentinel(c){var s=el('div');s.id='loadSentinel';s.style.height='1px';c.appendChild(s);if(io)io.observe(s)}
function more(){if(rl>=cur.length)return;var c=$('content'),o=$('loadSentinel');if(o){if(io)io.unobserve(o);o.remove()}var st=$('loadStatus'),p=rl;rl=Math.min(rl+PS,cur.length);cur.slice(p,rl).forEach(function(n){var e=mk(n);if(st)c.insertBefore(e,st);else c.appendChild(e)});status();if(rl<cur.length)sentinel(c)}
function paged(c,list,fn){if(io)io.disconnect();cur=list;rfn=fn;rl=io?Math.min(PS,cur.length):cur.length;cur.slice(0,rl).forEach(function(n){c.appendChild(mk(n))});var s=el('div','sum');s.id='loadStatus';c.appendChild(s);status();if(rl<cur.length)sentinel(c)}
function filtered(){var dm=only?['digest']:['pray','word','dream'];
return notes.filter(function(n){return(n.types||[]).some(function(t){return dm.indexOf(t)>-1})&&pass(n)}).sort(function(a,b){var d=tagMatch(b)-tagMatch(a);if(d)return d;if(sel.some(function(t){return LRE.test(t)})){var p=partNo(lessonTags(a).join(' '))-partNo(lessonTags(b).join(' '));if(p)return p}return b.created-a.created})}
function render(){var filt=!!(q||sel.length),res=filt?filtered():[];
renderTabs(filt?res:null);renderCloud();renderCal();renderPanels();renderBm();
var c=$('content');c.innerHTML='';if(io)io.disconnect();
if(focus){var f=notes.filter(function(n){return n.id===focus})[0];if(f){var sm0=el('div','sum','Показана одна запись.'),bk0=el('button','pill off','Показать список');bk0.onclick=function(){focus=null;render()};sm0.appendChild(bk0);c.appendChild(sm0);c.appendChild(card(f));return}focus=null}
if(filt){
if(!res.length){c.appendChild(el('div','empty','Ничего не найдено.'));return}
var sm=el('div','sum');
if(sel.length>=2&&!sel.every(function(t){return LRE.test(t)})){var an=res.filter(function(n){return tagMatch(n)===sel.length}).length;sm.innerHTML='Найдено: '+res.length+' заметок, <b>'+an+' с тегами: '+esc(sel.join(', '))+'.</b>'}
else sm.textContent='Найдено: '+res.length+' заметок'+(only?'':' (по всем вкладкам)');
c.appendChild(sm);paged(c,res,function(n){return dom(n)});return}
if(tab==='digest'){c.appendChild(el('div','empty','Конспекты длинные, поэтому полным списком не выводятся.\nОткройте урок кнопкой «Уроки» или днём в календаре, либо включите «Только конспекты» и используйте поиск или теги.'));c.firstChild.style.whiteSpace='pre-line';return}
var list=notes.filter(function(n){return(n.types||[]).indexOf(tab)>-1}).sort(function(a,b){return b.created-a.created});
if(!list.length){c.appendChild(el('div','empty','Пока нет материалов в этом разделе.'));return}
var tt=tab;paged(c,list,function(){return tt})}
function lessonsList(){var m={};notes.forEach(function(n){lessonTags(n).forEach(function(t){var k=t.trim().toLowerCase();if(!m[k]){var x=/урок\s*№\s*(\d+)/i.exec(t);m[k]={l:t.trim(),n:x?+x[1]:1e9,p:partNo(t),c:0,dg:false}}if((n.types||[]).some(function(x){return x!=='digest'}))m[k].c++;if((n.types||[]).indexOf('digest')>-1){m[k].dg=true;if(n.read)m[k].rd=true}})});
return Object.keys(m).map(function(k){return m[k]}).sort(function(a,b){return a.n-b.n||a.p-b.p})}
$('lessonsBtn').onclick=function(){var M=$('modal');M.innerHTML='';M.appendChild(el('h2','','Уроки по порядку'));var L=lessonsList();
if(!L.length)M.appendChild(el('div','empty','Пока нет уроков'));
L.forEach(function(x){var r=el('div','lrow');r.appendChild(el('span','',x.l));var rt=el('span');rt.style.cssText='display:flex;gap:8px;align-items:center';var bmid=null;Object.keys(bm).forEach(function(id){var bn=notes.filter(function(n){return n.id===id})[0];if(bn&&(bn.tags||[]).some(function(t){return t.toLowerCase()===x.l.toLowerCase()}))bmid=id});if(bmid){var bb=el('button','tag','🔖');bb.title='Закладка — вернуться в это место';bb.onclick=function(){$('ov').classList.remove('open');goBm(bmid)};rt.appendChild(bb)}var ad=el('button','tag','+');ad.title='Добавить заметку с тегом «'+x.l+'»';ad.onclick=function(){openModal(null,{tags:[x.l],title:x.l,types:['digest']})};rt.appendChild(ad);var cs=el('span','',String(x.c));if(x.rd){cs.title='Конспект вычитан';cs.style.cssText='border:2px solid var(--word);border-radius:11px;padding:0 6px'}rt.appendChild(cs);
var b=el('button','tag',x.dg?'к · открыть':'открыть');b.onclick=function(){$('ov').classList.remove('open');openLesson([x.l])};rt.appendChild(b);r.appendChild(rt);M.appendChild(r)});
var a=el('div','mact'),c=el('button','pill off','Закрыть');c.onclick=function(){$('ov').classList.remove('open')};a.appendChild(c);M.appendChild(a);$('ov').classList.add('open')};
var edId=null,mTags=[],mTypes=[];
function openModal(n,pre){pre=pre||{};edId=n?n.id:null;mTags=n&&n.tags?n.tags.slice():(pre.tags||[]).slice();mTypes=n?(n.types||[]).slice():(pre.types||[]).slice();var M=$('modal');M.innerHTML='';M.appendChild(el('h2','',n?'Редактировать заметку':'Новая заметка'));
function fld(lbl,inp){var f=el('div','f');f.appendChild(el('label','',lbl));f.appendChild(inp);M.appendChild(f);return f}
var ti=el('input');ti.type='text';ti.value=n?n.title||'':(pre.title||'');fld('Заголовок',ti);
var bo=el('textarea');bo.value=n?n.body||'':(pre.body||'');
var mb=el('div','mdb');[['Ж','**','**','Жирный'],['К','*','*','Курсив'],['Ч','__','__','Подчёркнутый']].forEach(function(x){var b=el('button','',x[0]);b.type='button';b.title=x[3];if(x[0]==='Ж')b.style.fontWeight='700';if(x[0]==='К')b.style.fontStyle='italic';if(x[0]==='Ч')b.style.textDecoration='underline';
b.onclick=function(){var s=bo.selectionStart,e2=bo.selectionEnd,v=bo.value;bo.value=v.slice(0,s)+x[1]+v.slice(s,e2)+x[2]+v.slice(e2);bo.focus();bo.setSelectionRange(s+x[1].length,s+x[1].length+(e2-s))};mb.appendChild(b)});
mb.appendChild(el('span','hint','выделите текст и нажмите значок'));
var bw=el('div');bw.appendChild(mb);bw.appendChild(bo);fld('Текст',bw);
var tg=el('div'),chips=el('div','nt2'),ni=el('input'),sg=el('div','sugs');ni.type='text';ni.placeholder='Новый тег и Enter…';chips.style.margin='0 0 8px';tg.appendChild(chips);tg.appendChild(ni);tg.appendChild(sg);fld('Теги',tg);
function drawChips(){chips.innerHTML='';mTags.forEach(function(t){var s=el('span','tag',t+' ');var x=el('button','','×');x.type='button';x.style.cssText='background:none;padding:0;font-size:14px';x.onclick=function(){mTags=mTags.filter(function(y){return y!==t});drawChips()};s.appendChild(x);chips.appendChild(s)});
sg.innerHTML='';var st=tagStats(),low=mTags.map(function(x){return x.toLowerCase()});Object.keys(st).sort().forEach(function(k){if(low.indexOf(k)>-1)return;var b=el('button','tag dim',st[k].label);b.type='button';b.onclick=function(){mTags.push(st[k].label);drawChips()};sg.appendChild(b)})}
drawChips();function addT(){var v=ni.value.trim().replace(/,$/,'');if(v&&mTags.map(function(x){return x.toLowerCase()}).indexOf(v.toLowerCase())<0)mTags.push(v);ni.value='';drawChips()}
ni.onkeydown=function(e){if(e.key==='Enter'||e.key===','){e.preventDefault();addT()}};
var tp=el('div','nt2');tp.style.margin='0';TYPES.forEach(function(x){var b=el('button','pill'+(mTypes.indexOf(x)>-1?'':' off'),NAMES[x]);b.type='button';var d=el('i','dot');d.style.background='var(--'+x+')';d.style.marginRight='7px';b.insertBefore(d,b.firstChild);b.onclick=function(){var i=mTypes.indexOf(x);if(i>-1)mTypes.splice(i,1);else mTypes.push(x);b.classList.toggle('off',mTypes.indexOf(x)<0)};tp.appendChild(b)});fld('Тип материала (можно несколько)',tp);
var rd=el('input');rd.type='checkbox';rd.checked=n?!!n.read:false;var rl2=el('label','','');rl2.style.cssText='display:flex;gap:8px;align-items:center;color:var(--ink)';rl2.appendChild(rd);rl2.appendChild(document.createTextNode('✓ Вычитано (конспект разобран на цитаты)'));M.appendChild(rl2);
var a=el('div','mact'),c=el('button','pill off','Отмена'),s=el('button','pill','Сохранить');c.onclick=function(){$('ov').classList.remove('open')};
s.onclick=function(){if(!mTypes.length){alertM('Отметьте хотя бы один тип.');return}var t=ti.value.trim(),b=bo.value.trim();if(!t&&!b){alertM('Введите заголовок или текст.');return}if(ni.value.trim())addT();
if(edId){var x=notes.filter(function(m){return m.id===edId})[0];if(x){x.title=t;x.body=b;x.tags=mTags.slice();x.types=mTypes.slice();x.read=rd.checked}}else notes.push({id:uid(),title:t,body:b,tags:mTags.slice(),types:mTypes.slice(),read:rd.checked,created:Date.now()});
save();$('ov').classList.remove('open');render()};
a.appendChild(c);a.appendChild(s);M.appendChild(a);$('ov').classList.add('open');setTimeout(function(){ti.focus()},30)}
$('addBtn').onclick=function(){openModal(null)};
$('ov').onclick=function(e){if(e.target===$('ov'))$('ov').classList.remove('open')};
document.addEventListener('keydown',function(e){if(e.key==='Escape'&&$('ov').classList.contains('open'))$('ov').classList.remove('open')});
var tm;$('search').oninput=function(){clearTimeout(tm);var v=this.value;tm=setTimeout(function(){q=v.trim();focus=null;render()},160)};
$('clearBtn').onclick=function(){$('search').value='';q='';sel=[];focus=null;only=false;$('onlyBtn').classList.add('off');render();$('search').focus()};
$('onlyBtn').onclick=function(){only=!only;this.classList.toggle('off',!only);focus=null;render()};
var bm={};try{var sv0=JSON.parse(ls('uroki_bookmarks')||'null');if(sv0&&typeof sv0==='object')bm=sv0;else{var ob=JSON.parse(ls('uroki_bookmark')||'null');if(ob&&ob.id)bm[ob.id]=(typeof ob.para==='number')?ob.para:null}}catch(e){bm={}}
function saveBm(){ls('uroki_bookmarks',JSON.stringify(bm))}
function hasBm(id){return Object.prototype.hasOwnProperty.call(bm,id)}
function lkey(n){var t=(n.tags||[]).filter(function(x){return /урок\s*№/i.test(x)})[0];return t?t.trim().toLowerCase():null}
function setBm(id,p){var cur2=notes.filter(function(n){return n.id===id})[0],k=cur2?lkey(cur2):null;if(k)Object.keys(bm).forEach(function(o){if(o===id)return;var x=notes.filter(function(n){return n.id===o})[0];if(x&&lkey(x)===k)delete bm[o]});bm[id]=typeof p==='number'?p:null;saveBm()}
function clearBm(id){delete bm[id];saveBm()}
function shortL(n){var lt=(n.tags||[]).filter(function(t){return /урок\s*№/i.test(t)})[0];if(lt){var m=/урок\s*№\s*(\d+)/i.exec(lt);if(m){var p=/\((\d+)\s*ч\)/i.exec(lt);return 'Урок '+m[1]+(p?' ('+p[1]+' ч)':'')}return lt.trim()}return (n.title||'').trim()||'Конспект'}
function goBm(id){var n=notes.filter(function(x){return x.id===id})[0];if(!n)return;focus=id;q='';sel=[];only=false;$('onlyBtn').classList.add('off');$('search').value='';render();setTimeout(function(){var t=document.querySelector('.bmp')||document.querySelector('.note');if(t)t.scrollIntoView({behavior:'smooth',block:'center'})},60)}
function renderBm(){var s=$('bmWidget');s.innerHTML='';var it=[];Object.keys(bm).forEach(function(id){var n=notes.filter(function(x){return x.id===id})[0];if(n)it.push(n)});
function lno(n){var m=/урок\s*№\s*(\d+)/i.exec(lkey(n)||'');return m?+m[1]:1e9}it.sort(function(a,b){return lno(a)-lno(b)});
it.forEach(function(n){var raw=(n.body||'').replace(/\n+/g,'\n\n'),tot=splitP(raw,names(raw)).filter(function(p){return p.s<p.e}).length,p=bm[n.id],box=el('div','bmw');
box.innerHTML='<span>🔖</span><b>'+esc(shortL(n))+'</b><em>'+(typeof p==='number'?'абзац '+(p+1)+'/'+tot:'начало')+'</em><button type="button" class="bmx" title="Убрать">✕</button>';
box.onclick=function(e){if(e.target.closest('.bmx')){e.stopPropagation();clearBm(n.id);render();return}goBm(n.id)};s.appendChild(box)})}
function tok(t){var r=[],re=/[\p{L}\p{N}]+/gu,m;while((m=re.exec(t))!==null)r.push({n:m[0].toLowerCase(),s:m.index,e:m.index+m[0].length});return r}
function align(A,B){var m=A.length,n=B.length;if(!m||!n)return null;var W=n+1,sc=new Int16Array((m+1)*W),dr=new Uint8Array((m+1)*W),mx=0,mi=0,mj=0;
for(var i=1;i<=m;i++)for(var j=1;j<=n;j++){var d=sc[(i-1)*W+j-1]+(A[i-1].n===B[j-1].n?2:-1),u=sc[(i-1)*W+j]-1,l=sc[i*W+j-1]-1,b=0,x=0;if(d>b){b=d;x=1}if(u>b){b=u;x=2}if(l>b){b=l;x=3}sc[i*W+j]=b;dr[i*W+j]=x;if(b>mx){mx=b;mi=i;mj=j}}
if(mx<=0)return null;var i2=mi,j2=mj,ix=[],c=0;while(i2>0&&j2>0&&sc[i2*W+j2]>0){var x2=dr[i2*W+j2];if(x2===1){if(A[i2-1].n===B[j2-1].n){c++;ix.push(j2-1)}i2--;j2--}else if(x2===2)i2--;else if(x2===3)j2--;else break}
if(!ix.length)return null;return{a:Math.min.apply(null,ix),b:Math.max.apply(null,ix),r:c/m}}
function derived(dn,raw){var T=tok(raw);if(!T.length)return [];var dt=(dn.tags||[]).map(function(t){return t.toLowerCase()}),res=[];
notes.forEach(function(c){if(c.id===dn.id)return;if(!(c.types||[]).some(function(t){return t==='pray'||t==='word'||t==='dream'}))return;if(!(c.tags||[]).some(function(t){return dt.indexOf(t.toLowerCase())>-1}))return;
var A=tok(c.body||'');if(A.length<4)return;var r=align(A,T);if(!r||r.r<.55)return;res.push({note:c,type:dom(c),s:T[r.a].s,e:T[r.b].e,r:r.r})});
res.sort(function(a,b){return b.r-a.r});var ok=[];res.forEach(function(r){if(!ok.some(function(a){return !(r.e<=a.s||r.s>=a.e)}))ok.push(r)});ok.sort(function(a,b){return a.s-b.s});return ok}
function names(t){var r=[],m,re=/^([ \t]*)(Уззия)(\s*:)/gim;while((m=re.exec(t))!==null){var s=m.index+m[1].length;r.push({s:s,e:s+m[2].length+m[3].length,c:'#7e2625'})}
re=/^([ \t]*)(?!Уззия\s*:)([А-ЯЁA-Z][А-Яа-яЁёA-Za-z\-]{1,24}(?:\s[А-ЯЁA-Z][А-Яа-яЁёA-Za-z\-]{1,24})?)(\s*:)/gm;while((m=re.exec(t))!==null){var s2=m.index+m[1].length;r.push({s:s2,e:s2+m[2].length+m[3].length,c:'#2f6a80'})}
r.sort(function(a,b){return a.s-b.s});return r}
function splitP(t,nr){var act={},re=/\n(?:[ \t]*\n)+/g,m;while((m=re.exec(t))!==null)act[m.index]=1;var ns={};nr.forEach(function(r){ns[r.s]=1});
for(var i=0;i<t.length;i++){if(t.charAt(i)!=='\n'||act[i])continue;var k=i+1;while(k<t.length&&(t.charAt(k)===' '||t.charAt(k)==='\t'))k++;if(ns[k])act[i]=1}
var ps=[],st=0;for(var j=0;j<=t.length;j++){if(j===t.length||act[j]){ps.push({s:st,e:j});var x=j+1;while(x<t.length&&/[\n \t]/.test(t.charAt(x)))x++;st=x;j=x-1}}return ps}
function digestBody(b,n){var raw=(n.body||'').replace(/\n+/g,'\n\n'),nr=names(raw),dr=derived(n,raw),ps=splitP(raw,nr),bi=hasBm(n.id)?bm[n.id]:undefined,out='',k=0,qo=false,ql=0;
ps.forEach(function(p){if(p.s>=p.e)return;var my=k++,pt=raw.slice(p.s,p.e).trim(),qOp=(pt.match(/«/g)||[]).length,qCl=(pt.match(/»/g)||[]).length,sq=/^[*_\s]*[«"„“]/.test(pt),eq=/[»"”“][*_\s]*[.!?…,;:\-–—]*[*_\s]*$/.test(pt),isq=false;
if(qo){isq=true;ql--;if(qCl>qOp||ql<=0)qo=false}else if(sq&&eq)isq=true;else if(sq&&qOp>qCl){isq=true;qo=true;ql=10}
var bd=[p.s,p.e];dr.concat(nr.map(function(r){return{s:r.s,e:r.e}})).forEach(function(r){if(r.s>p.s&&r.s<p.e)bd.push(r.s);if(r.e>p.s&&r.e<p.e)bd.push(r.e)});
bd=Array.from(new Set(bd)).sort(function(a,b){return a-b});var po='';
for(var i=0;i<bd.length-1;i++){var f=bd[i],t=bd[i+1];if(f>=t)continue;var h=md(hl(raw.slice(f,t))),nh=nr.filter(function(r){return r.s<=f&&r.e>=t})[0];if(nh)h='<b style="color:'+nh.c+';font-weight:800">'+h+'</b>';
var dh=dr.filter(function(r){return r.s<=f&&r.e>=t})[0];if(dh){var col='var(--'+dh.type+')',inf=[];if((dh.note.title||'').trim())inf.push('Заметка: '+dh.note.title.trim());inf.push('Теги: '+((dh.note.tags||[]).join(', ')||'—'));
h='<span title="'+esc(inf.join('\n')).replace(/"/g,'&quot;')+'" style="border-bottom:2px solid '+col+'">'+h+'</span>';if(t>=dh.e)h+='<button type="button" class="dopen" data-id="'+dh.note.id+'" style="background:'+col+'" title="Открыть заметку">✎</button>'}po+=h}
out+='<p class="'+(bi===my?'bmp':'')+(isq?' dq':'')+'"><button type="button" class="pbm" data-p="'+my+'" title="Закладка">🔖</button><button type="button" class="ped" data-p="'+my+'" title="Исправить абзац">✎</button>'+po+'</p>'});
b.innerHTML=out;b.classList.add('dgb');
b.onclick=function(e){var ed=e.target.closest('.ped');if(ed){e.stopPropagation();paraEdit(n,+ed.getAttribute('data-p'),ed.closest('p'));return}var op=e.target.closest('.dopen');if(op){e.stopPropagation();notePopup(op.getAttribute('data-id'));return}var bt=e.target.closest('.pbm');if(!bt)return;e.stopPropagation();var ix=+bt.getAttribute('data-p');if(hasBm(n.id)&&bm[n.id]===ix)clearBm(n.id);else setBm(n.id,ix);render()}}
function nmap(t){t=t||'';var o=[],m=[];for(var i=0;i<t.length;i++){var c=t.charAt(i);if(c==='\n'){var j=i;while(j<t.length&&t.charAt(j)==='\n')j++;o.push('\n','\n');m.push(i,i);i=j-1}else{o.push(c);m.push(i)}}return{t:o.join(''),m:m}}
function paraEdit(n,idx,pe){if(!pe||pe.classList.contains('editing'))return;var body=n.body||'',nm=nmap(body),pp=splitP(nm.t,names(nm.t)).filter(function(p){return p.s<p.e}),pr=pp[idx];if(!pr)return;var rs=nm.m[pr.s],re=nm.m[pr.e-1]+1;pe.classList.add('editing');pe.innerHTML='';var ta=el('textarea','pe');ta.value=body.slice(rs,re);
function au(){ta.style.height='auto';ta.style.height=(ta.scrollHeight+2)+'px'}function cm(){n.body=body.slice(0,rs)+ta.value+body.slice(re);save();render()}
ta.oninput=au;ta.onkeydown=function(e){if(e.key==='Escape'){e.preventDefault();render()}else if(e.key==='Enter'&&(e.ctrlKey||e.metaKey)){e.preventDefault();cm()}};
var bar=el('div','peb'),ok=el('button','pill','Сохранить'),cn=el('button','pill off','Отмена');ok.onclick=cm;cn.onclick=function(){render()};bar.appendChild(ok);bar.appendChild(cn);bar.appendChild(el('span','hint','Ctrl+Enter — сохранить, Esc — отмена'));pe.appendChild(ta);pe.appendChild(bar);au();ta.focus()}
function notePopup(id){var n=notes.filter(function(x){return x.id===id})[0];if(!n)return;var o=el('div','ov open'),b=el('div','modal');b.style.maxWidth='480px';
if((n.title||'').trim()){var h=el('div','nt');h.innerHTML=md(esc(n.title));h.style.marginBottom='10px';b.appendChild(h)}
var p=el('div','nb');p.innerHTML=md(esc(n.body||''));b.appendChild(p);
if((n.tags||[]).length){var tg=el('div','nt2');n.tags.slice().sort(function(a,b){return a.toLowerCase().localeCompare(b.toLowerCase(),'ru')}).forEach(function(t){tg.appendChild(el('span','tag',t))});b.appendChild(tg)}
var a=el('div','mact'),c=el('button','pill off','Закрыть'),e=el('button','pill','✎ Редактировать');c.onclick=function(){document.body.removeChild(o)};e.onclick=function(){document.body.removeChild(o);openModal(n)};
a.appendChild(c);a.appendChild(e);b.appendChild(a);o.onclick=function(ev){if(ev.target===o)document.body.removeChild(o)};o.appendChild(b);document.body.appendChild(o)}
function renderPanels(){
var st=tagStats(),arr=Object.keys(st).map(function(k){return st[k]}).sort(function(a,b){return b.n-a.n}),tp=$('tagsPanel');tp.innerHTML=arr.length?'':'<div class="he">Пока нет тегов</div>';
arr.forEach(function(s){var r=el('div','tsr'),d=el('i','dot'),l=el('span','',s.label);d.style.background='var(--'+domTag(s)+')';l.style.cssText='flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap';r.appendChild(d);r.appendChild(l);r.appendChild(el('b','',s.n));tp.appendChild(r)});
var ln={},dl={},by={pray:0,word:0,dream:0,digest:0};notes.forEach(function(n){var dg=(n.types||[]).indexOf('digest')>-1;(n.tags||[]).forEach(function(t){var m=/урок\s*№\s*(\d+)/i.exec(t);if(m){ln[m[1]]=1;if(dg)dl[m[1]]=1}});(n.types||[]).forEach(function(t){if(by[t]!==undefined)by[t]++})});
function row(c,l,v){return '<div class="tsr">'+(c?'<i class="dot" style="background:var(--'+c+')"></i>':'')+'<span style="flex:1">'+l+'</span><b>'+v+'</b></div>'}
$('statsBox').innerHTML=row('','Всего заметок',notes.length)+row('','Уроков (по тегам)',Object.keys(ln).length)+row('pray','Молитва',by.pray)+row('word','Слово',by.word)+row('dream','Сны',by.dream)+row('digest','Конспекты',Object.keys(dl).length+' ('+by.digest+')');
var hb=$('historyList');hb.innerHTML=notes.length?'':'<div class="he">Пока пусто</div>';
notes.slice().sort(function(a,b){return b.created-a.created}).slice(0,5).forEach(function(n){var t=dom(n),it=el('div','hit'),pv=(n.body||'').trim();if(pv.length>80)pv=pv.slice(0,80)+'…';if(!pv)pv=n.title||'(без текста)';
it.innerHTML='<i class="dot" style="background:var(--'+t+');margin-top:4px"></i><span><small>'+fd(n.created)+'</small>'+esc(pv)+'</span>';
it.onclick=function(){focus=n.id;if(t!=='digest')tab=t;q='';sel=[];$('search').value='';render()};hb.appendChild(it)})}
var vs={line:1.45,gap:.5};try{var sv=JSON.parse(ls('uroki_view')||'null');if(sv&&typeof sv.line==='number'&&typeof sv.gap==='number')vs=sv}catch(e){}
function applyView(){var r=document.documentElement.style;r.setProperty('--dg-line',vs.line);r.setProperty('--dg-gap',vs.gap+'em');$('vLine').value=vs.line;$('vGap').value=vs.gap;$('vLineV').textContent=vs.line.toFixed(2);$('vGapV').textContent=vs.gap.toFixed(2)}
function onView(){vs={line:parseFloat($('vLine').value),gap:parseFloat($('vGap').value)};applyView();ls('uroki_view',JSON.stringify(vs))}
$('vLine').oninput=onView;$('vGap').oninput=onView;applyView();
/* НОВАЯ ЛОГИКА ВЫДЕЛЕНИЯ С ОРАНЖЕВОЙ КНОПКОЙ */
var sb=el('button','sab','+ Заметка из выделения'),fab=el('button','fab','+'),pend=null,touch=!!(window.matchMedia&&matchMedia('(hover:none)').matches);
fab.type='button';fab.title='Заметка из выделения';document.body.appendChild(sb);document.body.appendChild(fab);
function hsb(){sb.style.display='none';fab.classList.remove('v');pend=null}
function chk(){var s=getSelection();if(!s||s.isCollapsed||!s.toString().trim()){hsb();return}
var an=s.anchorNode,e2=an&&an.nodeType===1?an:(an?an.parentElement:null),bd=e2?e2.closest('.dgb'):null,ne=bd?bd.closest('.note'):null;if(!ne){hsb();return}
var sn=notes.filter(function(n){return n.id===ne.getAttribute('data-id')})[0];if(!sn){hsb();return}
pend={text:s.toString(),tags:lessonTags(sn)};
if(touch){
var rg=s.getRangeAt(0),rs=rg.getClientRects(),lr=rs.length?rs[rs.length-1]:rg.getBoundingClientRect();
var x=Math.max(8,Math.min(lr.left+lr.width/2-23,innerWidth-54)),y=lr.bottom+38;
if(y>innerHeight-60)y=innerHeight-60;
fab.style.left=x+'px';fab.style.top=y+'px';fab.classList.add('v');
}else{
var r=s.getRangeAt(0).getBoundingClientRect();sb.style.left=Math.max(8,Math.min(r.left,innerWidth-200))+'px';sb.style.top=Math.max(8,r.top-44)+'px';sb.style.display='inline-flex';
}}
function take(){if(!pend)return;var d=pend;hsb();getSelection().removeAllRanges();openModal(null,{tags:d.tags,body:d.text.trim()})}
document.addEventListener('mouseup',function(e){if(e.target===sb)return;setTimeout(chk,0)});
var st2;document.addEventListener('selectionchange',function(){if(!touch)return;clearTimeout(st2);st2=setTimeout(chk,200)});
sb.onclick=take;fab.onclick=take;
fab.addEventListener('touchstart',function(e){e.preventDefault();take()},{passive:false});
var ring=$('ringP'),RC=2*Math.PI*21;ring.style.strokeDasharray=String(RC);
function upr(){var t=window.scrollY||document.documentElement.scrollTop||0,h=document.documentElement.scrollHeight-innerHeight,f=h>0?Math.min(1,Math.max(0,t/h)):0;ring.style.strokeDashoffset=String(RC*(1-f));$('stop').classList.toggle('v',t>220)}
window.addEventListener('scroll',function(){upr();if(touch){if(pend)chk()}else hsb()},{passive:true});
window.addEventListener('resize',upr);
$('stop').onclick=function(){window.scrollTo({top:0,behavior:'smooth'})};
load();render();upr();
})();
</script>
</body>
</html>