function esc(s){return String(s==null?'':s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"')} function fmt(d){return d?d.split('-').reverse().join('.'):'весь период'} function showImg(src){document.getElementById('lightboxImg').src=src;document.getElementById('lightbox').classList.add('open')} function isImageFile(name){return /\.(jpe?g|png|gif|webp|bmp|avif|svg|ico)$/i.test(name||'')} function fileType(name){ if(/\.(jpe?g|png|gif|webp|bmp|avif|svg|ico)$/i.test(name||'')) return 'image'; if(/\.(mp3|wav|ogg|flac|m4a|aac|opus)$/i.test(name||'')) return 'music'; if(/\.(pptx?|odp|key)$/i.test(name||'')) return 'presentation'; if(/\.(pdf|docx?|xlsx?|txt|rtf|odt|ods|csv|md)$/i.test(name||'')) return 'document'; return 'other'; } function fileIcon(t){ const icons = {image:'🖼️',music:'🎵',presentation:'📊',document:'📄',other:'📁'}; return icons[t]||icons.other; } function filesHTML(files, password, shareToken){ if(!files||!files.length)return ''; const pw = password ? `?password=${encodeURIComponent(password)}` : ''; return `