window.COMMUNITY_INDEX_SOURCE_LOCK_R10F15=true;
/* V249432_FEED_COMMENTS_MESH_ONE_GROUP_SPACE_CREATE_READY */
/* OK ITHAKI V249432 synchronized server/APK asset */
/* V249430_PLUS_TEXT_GOLD_CARD_READY */
/* OK ITHAKI V249430 synchronized server/APK asset */
// V249357: canonical feed ownership is decided before legacy patch layers execute.
window.__ITHAKI_CANONICAL_FEED_ONLY_V249357__=1;
// V249234 server-api-clean-notifications compatible
/* OK ITHAKI V249208 stable connection + Greek UI clean start: remove stale connection and unstable first-run flags before app boots. */
(function(){try{
  var q='';try{q=new URL(location.href).searchParams.get('lang')||''}catch(e){}
  var manual=false;try{manual=localStorage.getItem('ith_ui_lang_manual')==='1'||localStorage.getItem('ith_ui_lang_manual_v249141')==='1'}catch(e){}
  var qcode=String(q||'').toLowerCase().split('-')[0];
  var supported=['el','en','bg','hr','cs','da','nl','et','fi','fr','de','hu','ga','it','lv','lt','mt','pl','pt','ro','sk','sl','es','sv','sq','bs','ca','eu','gl','is','lb','mk','no','sr','tr','uk','cy','be'];
  if(supported.indexOf(qcode)>=0){
    localStorage.setItem('ith_global_language_r10f7',qcode);
    localStorage.setItem('ith_global_language_selected_r10f7','1');
    localStorage.setItem('ith_ui_lang_v249141',qcode);
    localStorage.setItem('ith_ui_lang',qcode);
    localStorage.setItem('ith_ui_lang_manual','1');
    localStorage.setItem('ith_ui_lang_manual_v249141','1');
  }
  if(localStorage.getItem('ith_v249169_fresh_avatar_cleanup_done')!=='1'){
    var kill=[];
    for(var i=0;i<localStorage.length;i++){
      var k=localStorage.key(i)||'';
      if(/ith_people_cache|ith_people_cache_from_server|ith_entry_choice_v24915[48]|ith_registered_member_v24915[48]|ith_auto_reconnect_v249154|ith_lang_menu_open_v249154|ith_home_protection_open_v249154|ith_home_protection_open_v249158|ith_profile_language_open_v249158|ith_saved_api_base|ith_server_base/i.test(k))kill.push(k);
    }
    kill.forEach(function(k){try{localStorage.removeItem(k)}catch(e){}});
    localStorage.setItem('ith_v249169_fresh_avatar_cleanup_done','1');
  }
}catch(e){}})();
/* OK ITHAKI V249158 ANDROID NETWORK PERMISSIONS ALERTS */
(() => {
'use strict';
const ITHAKI_BUILD_249318='249470';
try{const oldBuild=localStorage.getItem('ith_frontend_build');if(oldBuild!==ITHAKI_BUILD_249318){['ith_feed_last_html','ith_feed_cache','ith_last_feed_etag'].forEach(k=>{try{localStorage.removeItem(k)}catch(e){}});localStorage.setItem('ith_frontend_build',ITHAKI_BUILD_249318);if(window.caches&&caches.keys)caches.keys().then(keys=>keys.forEach(k=>{try{caches.delete(k)}catch(e){}}));}}catch(e){}
const VERSION='2.4.9.470-mobile-video-bil-onboarding-avatar-notices';
const TOKEN='OKITHAKI_PUBLIC_BETA_TOKEN_SERVER_ONLY_2026';
const ITH_DOMAIN_BASE='https://ok-ithaki.gr';
const TEST_TUNNEL_BASE=ITH_DOMAIN_BASE; // V249469 compatibility alias; no ngrok fallback
function cleanBaseUrl(x){x=String(x||'').trim();if(!x)return'';try{x=decodeURIComponent(x)}catch{}if(x.endsWith('/'))x=x.slice(0,-1);return x}
function queryParam(name){try{return new URL(location.href).searchParams.get(name)||''}catch{return''}}
function requestedServerBase(){return cleanBaseUrl(queryParam('server')||queryParam('api')||queryParam('base'))}
function androidBridgeServerBase(){try{if(window.OKITHAKI_ANDROID&&typeof window.OKITHAKI_ANDROID.getServerBase==='function')return cleanBaseUrl(window.OKITHAKI_ANDROID.getServerBase()||'');}catch(e){}try{if(window.AndroidBridge&&typeof window.AndroidBridge.getServerBase==='function')return cleanBaseUrl(window.AndroidBridge.getServerBase()||'');}catch(e){}return ''}
function isLocalhostBase(b){b=String(b||'').toLowerCase();return b.includes('127.0.0.1')||b.includes('localhost')}
function isPrivateLanBaseJs(b){b=String(b||'').toLowerCase();return /^http:\/\/(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/.test(b)}
function isTestTunnelBase(b){b=String(b||'').toLowerCase();return b.includes('.ngrok-free.dev')||b.includes('.ngrok-free.app')}
function isDomainReadyBase(b){b=String(b||'').toLowerCase().replace(/\/$/,'');return b==='https://ok-ithaki.gr'||b==='https://www.ok-ithaki.gr'}
function isForbiddenTestRemote(b){b=String(b||'').toLowerCase();return b.includes('185.185.80.71')}
function isAndroidAssetOriginV249470(b){b=String(b||'').toLowerCase();return b.includes('appassets.androidplatform.net')||b.startsWith('file:')}
function isAllowedTestBase(b){b=cleanBaseUrl(b);if(!b)return false;if(isForbiddenTestRemote(b)||isAndroidAssetOriginV249470(b))return false;if(isPrivateLanBaseJs(b)||isTestTunnelBase(b)||isDomainReadyBase(b))return true;if(location.protocol.startsWith('http')&&cleanBaseUrl(location.origin)===b&&!isAndroidAssetOriginV249470(b))return true;if(isLocalhostBase(b)&&location.protocol.startsWith('http')&&isLocalhostBase(location.origin))return true;return false}
function forgetOldConnectionBases(){try{['ith_api_base','ith_saved_api_base','ith_server_base'].forEach(k=>{const v=localStorage.getItem(k);if(v&&!isAllowedTestBase(v))localStorage.removeItem(k)})}catch{}}
forgetOldConnectionBases();
const $=id=>document.getElementById(id);
const esc=s=>String(s??'').replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]));
const escJs=s=>String(s??'').replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/\n/g,'\\n').replace(/\r/g,'');

/* V249469 production-domain migration: remove only stale automatic connection choices once. */
try{if(localStorage.getItem('ith_v249469_public_domain_migration')!=='1'){['ith_api_base','ith_saved_api_base','ith_server_base','ith_lan_api_url','ith_saved_local_base','ith_last_detected_lan_url'].forEach(function(k){try{localStorage.removeItem(k)}catch(e){}});localStorage.setItem('ith_v249469_public_domain_migration','1')}}catch(e){}
const ITH_PUBLIC_SITE='https://ok-ithaki.gr';
function shareSiteBase(){try{const o=String(location.origin||'');if(/^https?:\/\//.test(o)&&!isPrivateLanBaseJs(o)&&!isLocalhostBase(o)&&!isTestTunnelBase(o))return o}catch{}return ITH_PUBLIC_SITE}
const now=()=>Date.now()/1000;
const state={api:(requestedServerBase()||androidBridgeServerBase()||((location.protocol.startsWith('http')&&!isAndroidAssetOriginV249470(location.origin))?location.origin:ITH_DOMAIN_BASE)),token:TOKEN,room:localStorage.getItem('ith_room')||'ithaki-phone-test',device:localStorage.getItem('ith_device')||('dev_'+Math.random().toString(36).slice(2)+Date.now().toString(36)),name:localStorage.getItem('ith_name')||'Μέλος',avatar:localStorage.getItem('ith_avatar')||'',animal:localStorage.getItem('ith_animal')||'🦉',age16:localStorage.getItem('ith_age16')==='1',policyOk:localStorage.getItem('ith_policy_ok')==='1',people:new Map(),page:'home',activePeer:'',activeChannel:'',lastMsgIds:new Set(),messagesSince:0,preview:{},spaces:[],currentSpace:'',currentSpaceChannel:'',sending:false,replyTo:null,autoTranslate:localStorage.getItem('ith_auto_translate')==='1',contentTarget:'auto',ws:null,wsReady:false,wsReconnect:0,wsChannels:new Set(),commentChannel:'',commentPostId:'',call:null,audioRecorder:null,audioStream:null,audioChunks:[],audioContext:null,screenTheme:'auto'};
localStorage.setItem('ith_device',state.device);
window.__ITHAKI_CORE_STATE__=state;window.state=state;window.ITH=window.ITH||{};window.ITH.state=state;

const animals=['🦉','🐬','🦋','🦊','🐢','🐶','🐱','🦁','🐼','🦄'];
const wisdoms=['We speak clearly, listen humanly and keep respect.','ITHAKI is clean communication with minimal data.','One kind word can become a bridge.'];
const UI_LANG_KEY='ith_ui_lang_v249141';const UI_LANG_MANUAL_KEY='ith_ui_lang_manual_v249141';try{localStorage.removeItem('ith_target_lang');const q=new URL(location.href).searchParams.get('lang');if(q==='el'||q==='en'){localStorage.setItem(UI_LANG_KEY,q);localStorage.setItem('ith_ui_lang',q);localStorage.setItem(UI_LANG_MANUAL_KEY,'1');localStorage.setItem('ith_ui_lang_manual','1')}else if(!localStorage.getItem(UI_LANG_KEY)){const old=localStorage.getItem('ith_ui_lang');localStorage.setItem(UI_LANG_KEY,(old==='el'||old==='en')?old:'el');localStorage.setItem('ith_ui_lang',(old==='el'||old==='en')?old:'el')}}catch{}
function api(p){return state.api.replace(/\/$/,'')+p}
function connectionCandidates(){
  forgetOldConnectionBases();
  const arr=[];
  const add=(name,base)=>{base=cleanBaseUrl(base);if(base)arr.push({name,base})};
  const req=requestedServerBase();
  const abr=androidBridgeServerBase();
  // V249158: Toner/Hotspot first. This is the quick pass for tether/hotspot/Wi-Fi.
  try{const savedCfg=cleanBaseUrl(localStorage.getItem('ith_lan_api_url')||localStorage.getItem('ith_last_detected_lan_url')||localStorage.getItem('ith_saved_local_base'));if(savedCfg)add('Saved toner/hotspot IP',savedCfg)}catch{}
  try{const manualLocal=savedLocalBase();const mode=localMode();if(manualLocal&&(mode==='hotspot'||mode==='wifi'))add('Saved local '+mode,manualLocal)}catch{}
  if(req&&isAllowedTestBase(req))add('APK selected server',req);
  if(abr&&isAllowedTestBase(abr))add('Android selected server',abr);
  try{const current=cleanBaseUrl(state&&state.api);if(current&&isAllowedTestBase(current))add('Current active server',current)}catch{}
  const cur=(location.protocol.startsWith('http'))?cleanBaseUrl(location.origin):'';
  if(cur&&isPrivateLanBaseJs(cur))add('Same tether/hotspot/Wi-Fi first',cur);
  try{const saved=cleanBaseUrl(localStorage.getItem('ith_api_base'));if(saved&&isAllowedTestBase(saved)&&isPrivateLanBaseJs(saved))add('Saved hotspot/Wi-Fi second',saved)}catch{}
  try{const lan=cleanBaseUrl(localStorage.getItem('ith_lan_api_url')||localStorage.getItem('ith_last_detected_lan_url'));if(lan&&isAllowedTestBase(lan))add('Saved hotspot/Wi-Fi second',lan)}catch{}
  // V249158: ngrok only for tests after IP/LAN.
  add('Production domain',ITH_DOMAIN_BASE);
  if(req&&!isPrivateLanBaseJs(req)&&isTestTunnelBase(req))add('APK ngrok fallback',req);
  if(abr&&!isPrivateLanBaseJs(abr)&&isTestTunnelBase(abr))add('Android ngrok fallback',abr);
  try{const saved=cleanBaseUrl(localStorage.getItem('ith_api_base'));if(saved&&isAllowedTestBase(saved)&&isTestTunnelBase(saved))add('Saved ngrok fallback',saved)}catch{}
  if(cur&&isTestTunnelBase(cur))add('Current ngrok page fallback',cur);
  // Domain is present but not connected yet, so it stays last.
  add('Production domain',ITH_DOMAIN_BASE);
  if(cur&&isLocalhostBase(cur))add('Laptop local server',cur);
  if(location.protocol.startsWith('http')&&isLocalhostBase(cur))add('Local laptop fallback','http://127.0.0.1:8010');
  return arr.map(x=>Object.assign({},x,{base:cleanBaseUrl(x.base)})).filter((x,i,a)=>isAllowedTestBase(x.base)&&a.findIndex(y=>y.base===x.base)===i)
}
async function checkConnections(){
  const old=state.api;
  setDoveStatus('connecting');
  const quickFetch=async(url)=>{
    const ctrl=('AbortController' in window)?new AbortController():null;
    const timer=ctrl?setTimeout(()=>ctrl.abort(),4200):null;
    try{return await fetch(url,{cache:'no-store',signal:ctrl?ctrl.signal:undefined})}
    finally{if(timer)clearTimeout(timer)}
  };
  for(const c of connectionCandidates()){
    try{
      state.api=c.base.replace(/\/$/,'');
      setDoveStatus('connecting');
      if($('subStatus'))$('subStatus').textContent='Έλεγχος σύνδεσης: '+c.name;
      const r=await quickFetch(api('/health'));
      if(r.ok){
        localStorage.setItem('ith_api_base',state.api);
        try{if(window.AndroidBridge&&AndroidBridge.saveServerBase)AndroidBridge.saveServerBase(state.api)}catch(e){}
        setConnectionGreen('Σύνδεση ενεργή: '+c.name+' · '+connectionLabel());
        return true;
      }
    }catch(e){}
  }
  state.api=old;
  if(state.wsReady){setConnectionGreen('Realtime WebSocket ενεργό');return true}
  setConnectionOffline('Δεν υπάρχει σύνδεση με server · άνοιξε START, έλεγξε hotspot/Wi‑Fi ή tunnel');
  return false;
}
function localMode(){try{return localStorage.getItem('ith_local_mode')||'hotspot'}catch{return'hotspot'}}
function savedLocalBase(){try{return cleanBaseUrl(localStorage.getItem('ith_lan_api_url')||localStorage.getItem('ith_saved_local_base')||localStorage.getItem('ith_last_detected_lan_url')||'')}catch{return''}}
function saveLocalBase(base,mode='hotspot'){base=cleanBaseUrl(base);if(!base)return'';try{localStorage.setItem('ith_lan_api_url',base);localStorage.setItem('ith_saved_local_base',base);localStorage.setItem('ith_local_mode',mode);localStorage.setItem('ith_api_base',base);if(window.AndroidBridge&&AndroidBridge.saveServerBase)AndroidBridge.saveServerBase(base)}catch{}return base}
function buildLocalBaseFromInput(v){v=String(v||'').trim();if(!v)return'';if(/^https?:\/\//i.test(v))return cleanBaseUrl(v);v=v.replace(/\s+/g,'').replace(/^\/+|\/+$/g,'');if(!/:\d+$/.test(v))v+=':8010';return cleanBaseUrl('http://'+v)}
async function connectToLocalBase(base,mode='hotspot'){base=saveLocalBase(base,mode);if(!base)return toast(uiText('Write the laptop/server Toner/Hotspot first.'));state.api=base;setDoveStatus('connecting',mode,base);if($('subStatus'))$('subStatus').textContent='local '+mode+': '+base;try{if(window.AndroidBridge&&AndroidBridge.setServerAndReload){AndroidBridge.setServerAndReload(base);toast(uiText('Local connection saved. Reloading...'));return true}}catch{}const ok=await checkConnections();setDoveStatus(ok?'connected':'offline',mode,base);toast(ok?uiText('Local connection OK'):uiText('Local connection failed. Check hotspot/Wi‑Fi and firewall.'));return ok}
function activeConnectionKind(){const b=String(state.api||'');if(isPrivateLanBaseJs(b))return 'local';if(isTestTunnelBase(b))return 'tunnel';if(isLocalhostBase(b))return 'laptop';return b?'normal':'offline'}
function connectionLabel(){const b=String(state.api||'');const k=activeConnectionKind();if(k==='local')return uiText('Local hotspot/Wi‑Fi')+' · '+b;if(k==='tunnel')return uiText('EU tunnel')+' · '+b;if(k==='laptop')return uiText('Laptop local')+' · '+b;if(k==='normal')return uiText('Normal connection')+' · '+b;return uiText('Offline')}
function setDoveStatus(status='',mode='',base=''){try{const btn=$('localDoveBtn');if(!btn)return;const k=activeConnectionKind();btn.classList.remove('connected','connecting','offline','local','tunnel','normal');if(status)btn.classList.add(status);else btn.classList.add(k==='offline'?'offline':'connected');btn.classList.add(k);btn.title='🕊️ '+connectionLabel();btn.setAttribute('aria-label',btn.title);let mark=btn.querySelector('.doveMark');if(!mark){btn.innerHTML='<span class="doveIcon">🕊️</span><span class="doveMark"></span>';mark=btn.querySelector('.doveMark')}mark.textContent=k==='local'?'L':k==='tunnel'?'T':k==='laptop'?'P':k==='normal'?'N':'!';const dot=$('netDot');if(dot){dot.classList.toggle('on',status==='connected'||(status===''&&k!=='offline'));dot.classList.toggle('warn',status==='connecting');}}catch(e){}}
async function switchToNormalConnection(){try{['ith_lan_api_url','ith_saved_local_base','ith_last_detected_lan_url'].forEach(k=>localStorage.removeItem(k));}catch{}state.api=ITH_DOMAIN_BASE;setDoveStatus('connecting','normal',state.api);const ok=await checkConnections();setDoveStatus(ok?'connected':'offline','normal',state.api);toast(ok?uiText('Normal production connection active'):uiText('Normal connection failed'));return false}
function setLocalMode(mode){mode=(mode==='wifi'||mode==='hotspot')?mode:'hotspot';try{localStorage.setItem('ith_local_mode',mode)}catch{}openLocalConnection();return false}
function useCurrentLocal(){const cur=cleanBaseUrl(location.origin);if(isPrivateLanBaseJs(cur))return connectToLocalBase(cur,localMode());toast(uiText('Open the app from the laptop IP, not 127.0.0.1, then press this.'));return false}
function saveLocalIpAndConnect(){const v=$('localIpInput')?.value||'';return connectToLocalBase(buildLocalBaseFromInput(v),localMode())}
function clearLocalConnection(){try{['ith_lan_api_url','ith_saved_local_base','ith_last_detected_lan_url','ith_api_base'].forEach(k=>localStorage.removeItem(k));if(window.AndroidBridge&&AndroidBridge.clearServerBase)AndroidBridge.clearServerBase()}catch{}toast(uiText('Local saved IP cleared.'));setDoveStatus('connecting','normal',TEST_TUNNEL_BASE);openLocalConnection();return false}

function closeMemberMenu(){const m=$('memberMenu');if(m){m.classList.remove('show','localPanel','legalPanel','themePanel');m.innerHTML=''}return false}
function enableButtonFeedback(){try{if(window.__ithButtonFeedback)return;window.__ithButtonFeedback=1;document.addEventListener('click',ev=>{const b=ev.target&&ev.target.closest?ev.target.closest('button,.btn,.tile,.actionIcon'):null;if(!b)return;b.classList.add('tapSelected');setTimeout(()=>{try{b.classList.remove('tapSelected')}catch{}},900);if(b.closest&&b.closest('.localConnGrid')){b.closest('.localConnGrid').querySelectorAll('.btn').forEach(x=>x.classList.remove('selected'));b.classList.add('selected')}})}catch(e){console.warn('button feedback',e)}}
const MEDIA_STATUS_POLLING=new Set();
function mediaProcessingId(metaId){return 'processing_media_'+safeDomId(metaId||'none')}
function processingMediaHtml(m,tools=true){const meta=String(m.meta_id||m.media_id||'');if(meta)scheduleProcessingMedia(meta);const up=m.uploaded_mb||m.size_mb||(m.size?Math.round((+m.size/1024/1024)*10)/10:0);const upText=up?`${uiText('Uploaded')}: ${up} MB · `:'';return `<div class="processingMediaCard" data-processing-media="${esc(meta)}" id="${mediaProcessingId(meta)}"><div class="spinner">⏳</div><b>${uiText('Video uploaded to server. It will appear here when ready.')}</b><div class="date">${upText}${uiText('The post is visible now; server is preparing the video.')}</div><div class="progress processing"><span style="width:70%"></span></div><button class="btn green" onclick="ITH.refreshProcessingMedia('${escJs(meta)}')">${uiText('Check video status')}</button></div>`}
function scheduleProcessingMedia(meta){meta=String(meta||'');if(!meta||MEDIA_STATUS_POLLING.has(meta))return;MEDIA_STATUS_POLLING.add(meta);let tries=0;const loop=async()=>{tries++;const done=await refreshProcessingMedia(meta,false);if(done||tries>600){MEDIA_STATUS_POLLING.delete(meta);return}setTimeout(loop,3000)};setTimeout(loop,1200)}
async function refreshProcessingMedia(meta,showToast=true){meta=String(meta||'');if(!meta)return true;try{const st=await fetchJson('/api/media/status/'+encodeURIComponent(meta));const els=[...document.querySelectorAll('[data-processing-media="'+meta.replace(/"/g,'')+'"]')];if(st.ready){const mm={kind:st.kind||st.media_kind||'video',url:st.url||st.file_url,filename:st.filename||'video.mp4',mime_type:st.mime_type||'video/mp4',size:st.size_bytes||0};els.forEach(el=>{el.outerHTML=mediaHtml(mm,true)});if(showToast)toast(st.message||uiText('Video is ready'));return true}if(st.failed||st.ok===false){els.forEach(el=>{el.classList.add('failed');el.innerHTML=`<b>⚠️ ${uiText('Video failed')}</b><div class="date">${esc(st.message||st.reason||'processing failed')}</div>`});if(showToast)toast(st.message||uiText('Video failed'),7000);return true}els.forEach(el=>{const d=el.querySelector('.date');if(d)d.textContent=((st.uploaded_mb?uiText('Uploaded')+': '+st.uploaded_mb+' MB · ':'')+(st.message||uiText('Still processing...')))});if(showToast)toast(st.message||uiText('Still processing...'));return false}catch(e){if(showToast)toast('Video status: '+(e.message||e));return false}}


try{if(!document.getElementById('ithV249141Css')){const st=document.createElement('style');st.id='ithV249141Css';st.textContent='.homeProtectionPro .shipMini{width:34px;height:34px;object-fit:contain;border-radius:10px;background:rgba(255,255,255,.10);padding:4px;margin-right:8px}.homeProtectionPro .proPanelIcon.shipWrap{display:flex;align-items:center;justify-content:center}.protectList{display:grid;gap:8px;margin-top:8px}.protectList div{padding:8px 10px;border-radius:14px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.10)}.anonymousRow{justify-content:center;margin-top:10px}.anonBadge{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:6px 10px;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.12)}.post.anonymousPost .postHead .avatar,.post.anonymousPost .feedAvatarOverlay .avatar{filter:grayscale(.2);opacity:.72}.mediaCenterGrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.mediaCenterGrid .tile{min-height:94px}.mediaCenterStats{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.mediaCenterStats span{display:block;text-align:center;border-radius:14px;background:rgba(255,255,255,.08);padding:10px}.mediaCenterStats b{display:block;font-size:20px}';document.head.appendChild(st)}}catch{}
try{if(!document.getElementById('ithMeshCss')){const st=document.createElement('style');st.id='ithMeshCss';st.textContent='.meshBox{margin-top:8px}.meshPeer{display:grid;grid-template-columns:auto 1fr auto auto;gap:8px;align-items:center;padding:8px;border-radius:14px;background:rgba(255,255,255,.08);margin:6px 0}.meshPeer .avatar{width:38px;height:38px}.localConnGrid .active{outline:2px solid rgba(255,215,0,.75)}';document.head.appendChild(st)}}catch{}
try{if(!document.getElementById('ithV249200Css')){const st=document.createElement('style');st.id='ithV249200Css';st.textContent='.feedGoldPollCard .feedGoldLogo{display:none!important}.feedGoldPollCard .feedGoldCardInner{padding-top:8px!important}.msgMediaTools{display:flex!important;gap:6px!important;flex-wrap:wrap!important;margin-top:7px!important}.msgMediaWrap{max-width:100%!important}.msgVideoShell{position:relative!important;background:#000!important;border-radius:16px!important;overflow:hidden!important}.msgVideo{display:block!important;width:min(100%,620px)!important;max-height:52dvh!important;object-fit:contain!important;background:#000!important}.msgImage{display:block!important;max-width:100%!important;max-height:52dvh!important;object-fit:contain!important;border-radius:15px!important}.fullMediaAudio{width:min(92vw,720px)!important}.mediaViewerTop{gap:7px!important;align-items:center!important}.mediaViewerTop>b{max-width:42vw!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.msgMediaTools .icon.small,.msgMediaTools .btn.mini{min-width:38px!important;min-height:34px!important}.msgOfficeFileCard .fileTools{display:flex!important;gap:6px!important;flex-wrap:wrap!important}.callActions{display:flex!important;justify-content:center!important;gap:8px!important;flex-wrap:wrap!important}.callControlBtn{min-width:52px!important}.callControlBtn.off{opacity:.55!important;filter:grayscale(1)!important}.callBox .callStage{position:relative!important}.callLocal{border:2px solid rgba(255,215,0,.75)!important}';document.head.appendChild(st)}}catch{}
function bridgeObj(){return window.AndroidBridge||window.OKITHAKI_ANDROID||null}
function bridgeHas(name){try{const b=bridgeObj();return !!(b&&typeof b[name]==='function')}catch{return false}}
function bridgeCall(name,...args){try{const b=bridgeObj();if(b&&typeof b[name]==='function')return b[name](...args)}catch(e){toast('Android bridge: '+(e.message||e))}return''}
let ALERT_AUDIO_CTX=null;
function unlockAlertAudio(){try{if(!ALERT_AUDIO_CTX){const C=window.AudioContext||window.webkitAudioContext;if(C)ALERT_AUDIO_CTX=new C()}if(ALERT_AUDIO_CTX&&ALERT_AUDIO_CTX.state==='suspended')ALERT_AUDIO_CTX.resume()}catch{}}
function playWebAlert(kind='message'){try{unlockAlertAudio();if(ALERT_AUDIO_CTX){const osc=ALERT_AUDIO_CTX.createOscillator();const gain=ALERT_AUDIO_CTX.createGain();const t=ALERT_AUDIO_CTX.currentTime;osc.type='sine';osc.frequency.setValueAtTime(kind==='call'?720:880,t);gain.gain.setValueAtTime(0.0001,t);gain.gain.exponentialRampToValueAtTime(kind==='call'?0.18:0.10,t+0.025);gain.gain.exponentialRampToValueAtTime(0.0001,t+(kind==='call'?0.55:0.16));osc.connect(gain);gain.connect(ALERT_AUDIO_CTX.destination);osc.start(t);osc.stop(t+(kind==='call'?0.62:0.20))}}catch{}try{if(navigator.vibrate)navigator.vibrate(kind==='call'?[260,120,260,120,380]:[120])}catch{}}
function playAppAlert(kind='message'){if(bridgeHas('playAlertSound')){bridgeCall('playAlertSound',kind);return}playWebAlert(kind)}
function notifyAppEvent(title,body,kind='message'){let native=false;try{if(bridgeHas('notifyInAppEvent')){bridgeCall('notifyInAppEvent',title||'OK ITHAKI',body||'',kind);native=true}else if(kind==='call'&&bridgeHas('notifyCall')){bridgeCall('notifyCall',title||'OK ITHAKI call',body||'Incoming call');native=true}else if(bridgeHas('notifyMessage')){bridgeCall('notifyMessage',title||'OK ITHAKI',body||'New message');native=true}}catch{}if(!native)playWebAlert(kind);try{if(!native&&'Notification'in window&&Notification.permission==='granted')new Notification(title||'OK ITHAKI',{body:body||''})}catch{}}
function notifyIncomingMessage(m,body=''){if(state.suppressMessageAlerts)return;if(!m||String(m.sender_id)===String(state.device))return;const title=m.nickname||m.from_name||uiText('New message');const txt=String(body||m.text||uiText('New message')).slice(0,140);notifyAppEvent(title,txt,'message')}
function startupAndroidWarmup(){return true}
try{document.addEventListener('pointerdown',unlockAlertAudio,{once:true,passive:true});document.addEventListener('keydown',unlockAlertAudio,{once:true,passive:true})}catch{}
function meshConsentOn(){try{return localStorage.getItem('ith_mesh_consent')==='1'}catch{return false}}
function setMeshConsent(v){try{localStorage.setItem('ith_mesh_consent',v?'1':'0')}catch{}meshAnnounce();toast(v?uiText('Emergency relay consent ON'):uiText('Emergency relay consent OFF'));openLocalConnection();return false}
function meshMode(){try{return localStorage.getItem('ith_mesh_mode')||localMode()||'hotspot'}catch{return'hotspot'}}
function setMeshMode(m){m=(m==='wifi_direct'||m==='router'||m==='hotspot')?m:'hotspot';try{localStorage.setItem('ith_mesh_mode',m);localStorage.setItem('ith_local_mode',m==='router'?'wifi':m)}catch{}openLocalConnection();return false}
function meshNativeSummary(){let s='';try{s=bridgeCall('getMeshNetworkSummary')||''}catch{}return s}
function meshRequestPermissions(){const r=bridgeCall('requestEmergencyMeshPermissions')||'';toast(r||uiText('Permission request opened.'));return false}
function meshOpenHotspot(){bridgeCall('openHotspotSettings');toast(uiText('Open hotspot/settings and enable it only if you agree.'));return false}
function meshOpenWifi(){bridgeCall('openWifiSettings');return false}
async function meshAnnounce(){try{const body={room_id:state.room,device_id:state.device,nickname:state.name,avatar:avatarValue(),mode:meshMode(),consent:meshConsentOn(),base_url:state.api,capabilities:['web-local-server','message-relay','file-relay-ready','native-wifi-direct-ready','phone-microserver-8099']};const r=await fetchJson('/api/mesh/announce',{method:'POST',body:JSON.stringify(body)});return r}catch(e){return {ok:false,error:e.message}}}
async function meshRadar(){await meshAnnounce();let r={peers:[]};try{r=await fetchJson('/api/mesh/radar?room_id='+encodeURIComponent(state.room)+'&device_id='+encodeURIComponent(state.device))}catch(e){r={ok:false,error:e.message,peers:[]}}const box=$('meshRadarBox');if(box){const peers=(r.peers||[]).filter(Boolean);box.innerHTML=peers.length?peers.map(p=>`<div class="meshPeer"><span>${avatarHtml({nickname:p.nickname||'Peer',avatar:p.avatar||''})}</span><b>${esc(p.nickname||'Peer')}</b><span class="date">${esc(p.mode||'local')} · ${p.consent?'relay OK':'needs consent'} · ${Math.round((Date.now()/1000-(+p.last_seen||0)))}s</span><button class="btn mini" onclick="ITH.meshSendTest('${esc(p.device_id||'')}')">${uiText('Send test')}</button></div>`).join(''):`<div class="date">${uiText('No nearby ITHAKI devices found yet. Keep both devices on the same hotspot/Wi‑Fi and press Announce/Radar.')}</div>`}toast((r.peers||[]).length+' '+uiText('devices found'));return r}
async function meshSendTest(to){if(!to)return toast('No target');const text=prompt(uiText('Emergency message'), 'OK ITHAKI emergency test')||'';if(!text.trim())return;try{await fetchJson('/api/mesh/packet',{method:'POST',body:JSON.stringify({room_id:state.room,from_id:state.device,to_id:to,nickname:state.name,kind:'text',text,consent:meshConsentOn()})});toast(uiText('Emergency packet stored for relay.'))}catch(e){toast('Mesh send failed: '+e.message)}}
async function meshInbox(){try{const r=await fetchJson('/api/mesh/inbox?room_id='+encodeURIComponent(state.room)+'&device_id='+encodeURIComponent(state.device));const box=$('meshInboxBox');if(box){const arr=r.packets||[];box.innerHTML=arr.length?arr.map(x=>`<div class="bubble"><b>${esc(x.nickname||x.from_id||'Peer')}</b><div>${esc(x.text||'')}</div><div class="date">${fmt(x.created_at)}</div></div>`).join(''):`<div class="date">${uiText('No emergency relay messages.')}</div>`}toast((r.packets||[]).length+' '+uiText('inbox packets'))}catch(e){toast('Mesh inbox failed: '+e.message)}}

function parseBridgeJson(raw){try{return JSON.parse(raw||'{}')}catch(e){return {ok:false,error:e.message,raw:String(raw||'')}}}
function phoneNodeStart(){const r=parseBridgeJson(bridgeCall('startPhoneMicroServer')||'{}');toast(r.ok?uiText('Phone microserver started')+': '+(r.url||'8099'):uiText('Phone microserver not available in browser'));openLocalConnection();return false}
function phoneNodeInfo(){return parseBridgeJson(bridgeCall('getPhoneNodeInfo')||'{}')}
function phoneNodeScan(){const r=parseBridgeJson(bridgeCall('scanPhoneNodes')||'{}');const box=$('phoneNodeRadarBox');if(box){const nodes=(r.nodes||[]).filter(n=>n&&n.node_id!==state.device);const status=`<div class="localScanStatus date">${esc(((r.nodes||[]).length||0)+' '+uiText('phone nodes found'))}</div>`;box.innerHTML=status+(nodes.length?nodes.map(n=>`<div class="meshPeer"><span>📱</span><b>${esc(n.nickname||n.node_id||'ITHAKI node')}</b><span class="date">${esc(n.ip||'')} · ${esc(n.url||n.base||'')} · ${esc(n.transport||'wifi')}</span><button class="btn mini" onclick="ITH.phoneNodeSend('${esc(n.url||n.base||'')}','${esc(n.node_id||'')}')">${uiText('Send message')}</button></div>`).join(''):`<div class="date">${uiText('No phone microservers found. Open hotspot/Wi‑Fi, start microserver on each APK, then scan again.')}</div>`)}return r}
function phoneNodeSend(base,to){const text=prompt(uiText('Message to phone node'), 'OK ITHAKI local message')||'';if(!text.trim())return false;const r=parseBridgeJson(bridgeCall('sendPhoneNodeMessage',base,text,to||'')||'{}');toast(r.ok?uiText('Message sent to local phone node'):('Send failed: '+(r.error||'')));return false}
function phoneNodeInbox(){const r=parseBridgeJson(bridgeCall('getPhoneNodeInbox')||'{}');const box=$('phoneNodeInboxBox');if(box){const arr=r.packets||[];box.innerHTML=arr.length?arr.slice().reverse().map(x=>`<div class="bubble"><b>${esc(x.nickname||x.from_id||'Phone node')}</b><div>${esc(x.text||'')}</div><div class="date">${fmt(x.created_at)}</div></div>`).join(''):`<div class="date">${uiText('No direct phone-node messages.')}</div>`}toast(((r.packets||[]).length||0)+' '+uiText('phone-node inbox'));return r}


function doveIsolated(){try{return localStorage.getItem('ith_dove_isolated')==='1'}catch{return false}}
function setDoveIsolated(v){try{localStorage.setItem('ith_dove_isolated',v?'1':'0')}catch{};setDoveStatus(v?'offline':'connecting');toast(v?uiText('Local connection panel isolated. It will not auto-scan or reconnect.'):uiText('Local connection panel active.'));openLocalConnection();return false}
function closeDovePanel(){try{localStorage.setItem('ith_dove_panel_closed','1')}catch{};return closeMemberMenu()}
function defaultPermissionPrefs(){return {camera:true,microphone:true,notifications:true,nearby_wifi:true,local_hotspot:true,video_call:true,media:true,accepted:true}}
function permissionPrefs(){try{const raw=localStorage.getItem('ith_permission_prefs');if(!raw)return defaultPermissionPrefs();return Object.assign(defaultPermissionPrefs(),JSON.parse(raw||'{}')||{})}catch{return defaultPermissionPrefs()}}
function setPermissionPref(k,v){const p=permissionPrefs();p[k]=!!v;p.accepted=true;try{localStorage.setItem('ith_permission_prefs',JSON.stringify(p))}catch{};toast(uiText('Permission choice saved'));return false}
function acceptProfilePermissions(){const p=defaultPermissionPrefs();try{localStorage.setItem('ith_permission_prefs',JSON.stringify(p));bridgeCall('requestAllProfilePermissions')}catch{}toast(uiText('Permissions saved'));openPermissionsPanel();return false}
function openPermissionsPanel(){const p=permissionPrefs();const row=(k,label,note)=>`<label class="card row permRow checkedPerm"><input type="checkbox" ${p[k]?'checked':''} onchange="ITH.setPermissionPref('${escJs(k)}',this.checked)"><span><b>${uiText(label)}</b><br><small class="date">${uiText(note)}</small></span><i>✓</i></label>`;let android='';try{android=bridgeCall('getPermissionState')||''}catch{}$('memberMenu').innerHTML=`<div class="row localPanelHeader"><b>🔔 ${uiText('Permissions')}</b><button class="icon localCloseBtn danger" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><b>✅ ${uiText('Keep my choices')}</b><div class="localConnNote">${uiText('These are your app choices. Android may still ask system permission the first time camera, microphone, notifications or local Wi‑Fi are used.')}</div>${android?`<div class="date" style="margin-top:8px">Android: ${esc(android)}</div>`:''}</div>${row('camera','Camera permission','Ask only when I open camera/photo.')}${row('microphone','Microphone permission','Ask only when I start audio/video call.')}${row('video_call','Video call permissions','Camera and microphone before video call.')}${row('media','Media permissions','Photos, videos, audio and files.')}${row('notifications','Notification permission','Ask only when I enable notifications.')}${row('nearby_wifi','Nearby Wi‑Fi permission','Ask only for local radar / hotspot / Wi‑Fi Direct features.')}${row('local_hotspot','Hotspot / local network','Remember that I prefer local hotspot/Wi‑Fi mode.')}<div class="row" style="margin-top:10px"><button class="btn green" onclick="ITH.acceptProfilePermissions()">✅ ${uiText('Accept and save')}</button><button class="btn" onclick="try{bridgeCall('requestVideoCallPermissions')}catch{};toast(uiText('Video call permissions checked'))">📹 ${uiText('Check video call permissions')}</button></div>`;$('memberMenu').classList.add('show','localPanel');return false}
function legalPolicyHtml(lang=uiLang()){const el=lang==='el';return el?`
<div class="legalDoc">
  <div class="legalIntro card"><b>OK ITHAKI · Πολιτική & Όροι</b><p>Σύντομη έκδοση μέσα στην εφαρμογή. Είναι γραμμένη για να καταλαβαίνει ο χρήστης τι αποδέχεται, αλλά πριν από δημόσια εμπορική χρήση θέλει τελικό έλεγχο δικηγόρου και συμπλήρωση υπευθύνου/επικοινωνίας.</p></div>
  <section><h3>1. Τι είναι η υπηρεσία</h3><p>Η ΙΘΑΚΗ είναι εφαρμογή επικοινωνίας με Ροή, μηνύματα, δωμάτια/κοινότητες, φωτογραφίες, βίντεο, ηχογραφήσεις, ψηφοφορίες, φωνητικές/βιντεοκλήσεις και τοπική/offline μετάφραση όπου είναι διαθέσιμη.</p></section>
  <section><h3>2. Προφίλ και ηλικία</h3><p>Δεν απαιτείται υποχρεωτικά τηλέφωνο ή email. Ο χρήστης μπορεί να λειτουργεί με ψευδώνυμο, avatar και τεχνικό αναγνωριστικό συσκευής. Η εφαρμογή προορίζεται για άτομα 16+ ή για μικρότερους μόνο με γονική συναίνεση όπου απαιτείται.</p></section>
  <section><h3>3. Τι επιτρέπεται και τι απαγορεύεται</h3><ul><li>Μίλα με σεβασμό, χωρίς παρενόχληση, απειλές, απάτες ή spam.</li><li>Μην ανεβάζεις παράνομο, βίαιο, κακοποιητικό ή μισαλλόδοξο περιεχόμενο.</li><li>Μην παραβιάζεις ιδιωτικότητα, πνευματικά δικαιώματα ή δικαιώματα τρίτων.</li><li>Μην χρησιμοποιείς bots ή μαζική κατάχρηση που χαλάει την υπηρεσία.</li></ul></section>
  <section><h3>4. Περιεχόμενο και media</h3><p>Το περιεχόμενο παραμένει δικό σου. Δίνεις στην εφαρμογή την αναγκαία άδεια να το αποθηκεύει, να το εμφανίζει, να το συμπιέζει και να το στέλνει στους προορισμούς που επιλέγεις. Τα βίντεο μπορούν να συμπιεστούν στον server και τα πρωτότυπα να διαγραφούν μετά από επιτυχημένη συμπίεση.</p></section>
  <section><h3>5. Τι δεδομένα κρατάμε</h3><div class="legalGrid"><span>Λογαριασμός</span><b>device id, ψευδώνυμο, avatar, ρυθμίσεις</b><span>Περιεχόμενο</span><b>δημοσιεύσεις, μηνύματα, σχόλια, δωμάτια</b><span>Media</span><b>αρχεία, τύπος, μέγεθος, τεχνικά μεταδεδομένα</b><span>Ασφάλεια</span><b>IP, χρόνοι, όρια χρήσης, αναφορές</b><span>Ειδοποιήσεις</span><b>push token μόνο αν ενεργοποιηθεί</b></div></section>
  <section><h3>6. Τι δεν ζητάμε υποχρεωτικά</h3><p>Δεν ζητάμε υποχρεωτικά αριθμό τηλεφώνου, email, λίστα επαφών κινητού, ακριβή GPS θέση ή πλήρες ιδιωτικό αρχείο ανάκτησης. Η τοπική αποθήκευση της συσκευής χρησιμοποιείται για λειτουργικές ρυθμίσεις όπως γλώσσα, θέμα, προφίλ και αποδοχή πολιτικής.</p></section>
  <section><h3>7. Νομικές βάσεις και δικαιώματα</h3><p>Η επεξεργασία γίνεται για παροχή υπηρεσίας, ασφάλεια/αντιμετώπιση κατάχρησης, νόμιμες υποχρεώσεις και, όπου χρειάζεται, συγκατάθεση. Μπορείς να ζητήσεις πρόσβαση, διόρθωση, διαγραφή, περιορισμό, φορητότητα, εναντίωση ή ανάκληση συγκατάθεσης. Η εφαρμογή έχει επιλογή διαγραφής δεδομένων στο προφίλ.</p></section>
  <section><h3>8. Κλήσεις, κρυπτογράφηση και μετάφραση</h3><p>Οι κλήσεις χρησιμοποιούν WebRTC. Τα προσωπικά/ομαδικά μηνύματα μπορούν να έχουν προαιρετική κρυπτογράφηση ανά κανάλι με κοινό κλειδί. Η μετάφραση προτιμά τοπική/offline λειτουργία ώστε να μειώνεται η εξωτερική μεταφορά δεδομένων.</p></section>
  <section><h3>9. Αναφορές, DSA και ePrivacy</h3><p>Παράνομο ή επικίνδυνο περιεχόμενο μπορεί να αναφερθεί μέσα από την εφαρμογή ή στο κανάλι Host. Αν υπάρξει περιορισμός περιεχομένου, πρέπει να υπάρχει καθαρή αιτιολόγηση και δυνατότητα ένστασης. Οι ειδοποιήσεις push και μη αναγκαία αποθήκευση στη συσκευή χρειάζονται επιλογή/άδεια και μπορούν να ανακληθούν.</p></section>
  <section><h3>10. Δήλωση αποδοχής</h3><p>Πατώντας αποδοχή δηλώνεις ότι διάβασες και αποδέχεσαι τους Όρους Χρήσης, την Πολιτική Απορρήτου και τους κανόνες συμμόρφωσης ΕΕ της OK ITHAKI.</p></section>
</div>`:`
<div class="legalDoc">
  <div class="legalIntro card"><b>OK ITHAKI · Policy & Terms</b><p>Short in-app version. It is written so users understand what they accept. Before public commercial launch, the controller/contact details must be completed and the text should be reviewed by a lawyer.</p></div>
  <section><h3>1. The service</h3><p>ITHAKI is a communication app with Feed, messages, rooms/communities, photos, videos, audio recordings, polls, voice/video calls and local/offline translation where available.</p></section>
  <section><h3>2. Profile and age</h3><p>A phone number or email is not mandatory. Users may use a nickname, avatar and technical device identifier. The app is intended for users aged 16+ or younger users with parental consent where required.</p></section>
  <section><h3>3. Acceptable use</h3><ul><li>Communicate respectfully, without harassment, threats, fraud or spam.</li><li>Do not upload illegal, violent, abusive or hateful content.</li><li>Do not violate privacy, intellectual property or third-party rights.</li><li>Do not use bots or mass abuse that disrupts the service.</li></ul></section>
  <section><h3>4. Content and media</h3><p>Your content remains yours. You give the app the licence needed to store, display, compress and deliver it to the destinations you choose. Videos may be compressed on the server and originals deleted after successful compression.</p></section>
  <section><h3>5. Data we keep</h3><div class="legalGrid"><span>Account</span><b>device id, nickname, avatar, settings</b><span>Content</span><b>posts, messages, comments, spaces</b><span>Media</span><b>files, type, size, technical metadata</b><span>Safety</span><b>IP, timestamps, usage limits, reports</b><span>Notifications</span><b>push token only if enabled</b></div></section>
  <section><h3>6. Data we do not require</h3><p>We do not require a phone number, email, mobile contacts list, precise GPS location or full private recovery file. Local device storage is used for functional choices such as language, theme, profile and policy acceptance.</p></section>
  <section><h3>7. Legal bases and rights</h3><p>Processing is used to provide the service, protect security, prevent abuse, comply with legal duties and, where required, rely on consent. You may request access, correction, erasure, restriction, portability, objection or consent withdrawal. The profile includes a data deletion option.</p></section>
  <section><h3>8. Calls, encryption and translation</h3><p>Calls use WebRTC. Direct and room messages can use optional per-channel encryption with a shared key. Translation prefers local/offline processing to reduce unnecessary external data transfers.</p></section>
  <section><h3>9. Reports, DSA and ePrivacy</h3><p>Illegal or dangerous content can be reported in-app or through the Host channel. If content is restricted, a clear reason and complaint route should be available. Push notifications and non-essential device storage require a user choice/permission and can be withdrawn.</p></section>
  <section><h3>10. Acceptance statement</h3><p>By accepting, you confirm that you read and accept OK ITHAKI's Terms of Use, Privacy Policy and EU compliance rules.</p></section>
</div>`}
function openLegalPolicy(lang=uiLang()){lang=lang==='en'?'en':'el';$('memberMenu').innerHTML=`<div class="row localPanelHeader legalHeader"><b>📜 ${uiText('Policy & terms')}</b><button class="btn ${lang==='el'?'green':''}" onclick="ITH.openLegalPolicy('el')">EL</button><button class="btn ${lang==='en'?'green':''}" onclick="ITH.openLegalPolicy('en')">EN</button><button class="icon localCloseBtn danger" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="legalScroll">${legalPolicyHtml(lang)}</div><div class="legalActions row"><button class="btn green" onclick="ITH.acceptLegalPolicy()">${uiText('Accept policy')}</button><button class="btn" onclick="ITH.closeMember()">${uiText('Close')}</button></div>`;$('memberMenu').classList.add('show','localPanel','legalPanel');return false}
function acceptLegalPolicy(){state.policyOk=true;try{localStorage.setItem('ith_policy_ok','1');localStorage.setItem('ith_policy_accepted_version','249163');localStorage.setItem('ith_policy_accepted_at',new Date().toISOString())}catch{}closeMemberMenu();renderProfile();toast(uiText('Policy accepted'));return false}
function serverDataCountsHtml(counts){counts=counts||{};const labels={messages:'Μηνύματα',flow_posts:'Δημοσιεύσεις Ροής',people:'Παρουσία/online',user_profiles:'Προφίλ',fcm_tokens:'Push tokens',push_subscriptions:'Συνδρομές ειδοποιήσεων',member_quota_overrides:'Όρια μέλους',media_usage:'Χρήση media',media_metadata:'Μεταδεδομένα media',optional_identities:'Προαιρετική ταυτότητα hash',reports:'Αναφορές'};return Object.keys(labels).map(k=>`<div class="serverDataLine"><span>${uiText(labels[k])}</span><b>${esc(counts[k]??0)}</b></div>`).join('')}
async function openServerDataPanel(){const base=`room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`;$('memberMenu').innerHTML=`<div class="row localPanelHeader"><b>🗄️ ${uiText('What the server keeps')}</b><button class="icon localCloseBtn danger" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><b>${uiText('What the server really keeps')}</b><div class="localConnNote">${uiText('The server keeps only operational data needed for Feed, messages, contacts, notifications, media, limits, reports and safety. It does not require email or phone. It does not keep a full account recovery secret.')}</div></div><div class="card"><b>${uiText('What the server does not keep')}</b><div class="localConnNote">${uiText('No mandatory phone number, no mandatory email, no plain password, no full private recovery file, no phone contacts list, no exact GPS location. Original videos are deleted after successful FFmpeg compression when that path is used.')}</div></div><div id="serverDataSnapshot" class="card"><b>${uiText('Real data now')}</b><div class="date">${uiText('Loading...')}</div></div><div class="grid"><button class="tile" onclick="ITH.openSavedPostsPanel()"><b>💾</b>${uiText('My saved items')}</button><button class="tile" onclick="ITH.clearSavedPosts()"><b>🧹</b>${uiText('Delete saved items')}</button><button class="tile danger" onclick="ITH.deleteAccountData()"><b>🗑️</b>${uiText('Delete account')}</button></div>`;$('memberMenu').classList.add('show','localPanel');try{const r=await fetchJson('/api/privacy/profile_server_snapshot?'+base);const box=$('serverDataSnapshot');if(box)box.innerHTML=`<b>${uiText('Real data now')}</b><div class="serverDataGrid">${serverDataCountsHtml(r.counts||{})}</div><div class="localConnNote">${uiText('Recent media metadata')}: ${(r.recent_media_metadata||[]).length} · ${uiText('Recent message headers')}: ${(r.recent_message_headers||[]).length}</div>`}catch(e){const box=$('serverDataSnapshot');if(box)box.innerHTML=`<b>${uiText('Real data now')}</b><div class="date">${uiText('Could not load server snapshot.')}</div>`}return false}
async function openSavedPostsPanel(){let ids=[];try{ids=JSON.parse(localStorage.getItem('ith_saved_posts')||'[]')||[]}catch{};$('memberMenu').innerHTML=`<div class="row localPanelHeader"><b>💾 ${uiText('My saved items')}</b><button class="icon localCloseBtn danger" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><b>${ids.length}</b> ${uiText('saved items on this device')}</div><div id="savedItemsBox" class="savedItemsBox">${ids.length?ids.map(id=>`<div class="card savedItem"><b>${esc(id)}</b><button class="btn danger" onclick="ITH.removeSavedPost('${escJs(id)}')">${uiText('Delete')}</button></div>`).join(''):`<div class="card date">${uiText('No saved items.')}</div>`}</div><div class="row" style="margin-top:10px"><button class="btn danger" onclick="ITH.clearSavedPosts()">${uiText('Delete saved items')}</button><button class="btn" onclick="ITH.openServerDataPanel()">${uiText('Back')}</button></div>`;$('memberMenu').classList.add('show','localPanel');return false}

function openMemberMediaCenter(){let saved=[];try{saved=JSON.parse(localStorage.getItem('ith_saved_posts')||'[]')||[]}catch{}const pCount=document.querySelectorAll('.postMediaWrap img').length;const vCount=document.querySelectorAll('.postMediaWrap video').length;$('memberMenu').innerHTML=`<div class="row localPanelHeader"><b>🎞️ ${uiText('Member media center')}</b><button class="icon localCloseBtn danger" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><b>${uiText('My media and files')}</b><div class="localConnNote">${uiText('Upload, open saved items and manage your local member media from one active center.')}</div></div><div class="mediaCenterStats"><span><b>${saved.length}</b>${uiText('Saved')}</span><span><b>${pCount}</b>${uiText('Photos on screen')}</span><span><b>${vCount}</b>${uiText('Videos on screen')}</span></div><div class="mediaCenterGrid" style="margin-top:12px"><button class="tile" onclick="ITH.chooseFile('feed','photo');ITH.closeMember()"><b>📷</b>${uiText('Upload photo')}</button><button class="tile" onclick="ITH.chooseFile('feed','video');ITH.closeMember()"><b>📹</b>${uiText('Upload video')}</button><button class="tile" onclick="ITH.chooseFile('feed','file');ITH.closeMember()"><b>📎</b>${uiText('Upload file')}</button><button class="tile" onclick="ITH.openSavedPostsPanel()"><b>💾</b>${uiText('My saved items')}</button></div>`;$('memberMenu').classList.add('show','localPanel');return false}
function removeSavedPost(id){let a=[];try{a=JSON.parse(localStorage.getItem('ith_saved_posts')||'[]')||[]}catch{};a=a.filter(x=>String(x)!==String(id));localStorage.setItem('ith_saved_posts',JSON.stringify(a));toast(uiText('Deleted'));openSavedPostsPanel();return false}
function clearSavedPosts(){if(!confirm(uiText('Delete saved items from this device?')))return false;try{localStorage.setItem('ith_saved_posts','[]')}catch{};toast(uiText('Saved items deleted'));openSavedPostsPanel();return false}
async function deleteAccountData(){if(!confirm(uiText('Delete account data from this server and this device?')))return false;try{await fetchJson('/api/privacy/delete_device_data',{method:'POST',body:JSON.stringify({room_id:state.room,device_id:state.device,confirm:true})})}catch(e){toast(uiText('Server deletion failed or was partial. Local data will still be cleared.'),4500)}try{const keepLang=localStorage.getItem(UI_LANG_KEY)||localStorage.getItem('ith_ui_lang')||'el';['ith_name','ith_avatar','ith_animal','ith_age16','ith_policy_ok','ith_saved_posts','ith_permission_prefs','ith_following','ith_blocked','ith_contacts','ith_notices'].forEach(k=>localStorage.removeItem(k));localStorage.setItem(UI_LANG_KEY,keepLang);localStorage.setItem('ith_ui_lang',keepLang)}catch{};toast(uiText('Account deletion request completed. Restart the app.'),5000);setTimeout(()=>location.reload(),900);return false}
function openLocalConnection(){const saved=savedLocalBase();const mm=meshMode();const iso=doveIsolated();const hot=mm==='hotspot'?' active selected':'';const wifi=mm==='router'?' active selected':'';const wd=mm==='wifi_direct'?' active selected':'';const node=phoneNodeInfo();const nodeUrl=esc(node.url||uiText('APK only / press Start microserver'));const native=esc(meshNativeSummary()||uiText('Native network info is available only inside the APK.'));const menu=$('memberMenu');menu.classList.add('localPanel');menu.innerHTML=`<div class="row localPanelHeader"><b>🕊️ ${uiText('Emergency local network')}</b><label class="doveIsoSwitch"><span>${uiText('Isolate panel')}</span><button class="btn mini ${iso?'green':'ghost'}" onclick="ITH.setDoveIsolated(true)">${uiText('Yes')}</button><button class="btn mini ${!iso?'green':'ghost'}" onclick="ITH.setDoveIsolated(false)">${uiText('No')}</button></label><button class="icon localCloseBtn danger" style="margin-left:auto" onclick="ITH.closeDovePanel()" title="${uiText('Close local network')}">×</button></div><div class="card"><b>${uiText('No internet / no provider mode')}</b><div class="localConnNote">${uiText('Each phone becomes a small local ITHAKI node. One phone/laptop opens hotspot or a battery router creates Wi‑Fi. Other phones join, start their microserver, scan the radar and exchange messages. A middle phone can store and forward packets when it meets the next phone.')}</div>${iso?`<div class="card warnCard"><b>⏸️ ${uiText('Panel isolated')}</b><div class="date">${uiText('Automatic scan/reconnect is stopped. You can still press buttons manually.')}</div></div>`:''}<div class="localConnGrid"><button class="btn${hot}" onclick="ITH.setMeshMode('hotspot')">📶 <b>${uiText('Hotspot default')}</b><br><span class="date">${uiText('One phone/laptop opens hotspot; others join. Best first emergency mode.')}</span></button><button class="btn${wifi}" onclick="ITH.setMeshMode('router')">🛜 <b>${uiText('Same Wi‑Fi / router repeater')}</b><br><span class="date">${uiText('A battery router can become a repeater/access point without internet.')}</span></button><button class="btn${wd}" onclick="ITH.setMeshMode('wifi_direct')">📡 <b>${uiText('Wi‑Fi Direct ready')}</b><br><span class="date">${uiText('Native APK Wi‑Fi Direct mode for phone-to-phone discovery and longer range.')}</span></button></div><div class="row" style="margin-top:8px;flex-wrap:wrap"><button class="btn green" onclick="ITH.phoneNodeStart()">📱 ${uiText('Start phone microserver')}</button><button class="btn" onclick="ITH.phoneNodeScan()">📡 ${uiText('Radar phone nodes')}</button><button class="btn" onclick="ITH.phoneNodeInbox()">📥 ${uiText('Direct inbox')}</button><button class="btn" onclick="ITH.meshOpenHotspot()">📶 ${uiText('Open hotspot settings')}</button><button class="btn" onclick="ITH.meshOpenWifi()">🛜 ${uiText('Open Wi‑Fi settings')}</button><button class="btn" onclick="ITH.meshRequestPermissions()">🔐 ${uiText('Ask nearby Wi‑Fi permission')}</button></div><div class="localConnStatus"><b>🕊️ ${uiText('Current connection')}: ${esc(connectionLabel())}</b><br>${uiText('Phone node')}: ${nodeUrl}<br>${uiText('Current server')}: ${esc(state.api||'')}<br>${uiText('Saved local')}: ${esc(saved||uiText('none'))}<br>${uiText('Native status')}: ${native}</div><div class="row" style="margin-top:8px;flex-wrap:wrap"><button class="btn green" onclick="ITH.checkConnections()">${uiText('Check connection')}</button><button class="btn gold" onclick="ITH.switchToNormalConnection()">${uiText('Return to production server')}</button></div></div><div class="card"><b>📡 ${uiText('Phone microserver radar')}</b><div class="localConnNote">${uiText('This radar scans the local Wi‑Fi/hotspot for OK ITHAKI phone microservers on port 8099. Only Wi‑Fi/Hotspot/Wi‑Fi Direct is used.')}</div><div id="phoneNodeRadarBox" class="meshBox"><div class="date">${uiText('Press Start phone microserver, then Radar phone nodes.')}</div></div><div id="phoneNodeInboxBox" class="meshBox"></div></div><div class="card"><div class="row" style="justify-content:space-between"><b>🧭 ${uiText('Local server relay fallback')}</b><label class="row"><input type="checkbox" ${meshConsentOn()?'checked':''} onchange="ITH.setMeshConsent(this.checked)"><span>${uiText('Allow this device to relay')}</span></label></div><div class="localConnInput"><input id="localIpInput" value="${esc(saved||'')}" placeholder="192.168.43.123 or http://192.168.43.123:8010"><button class="btn green" onclick="ITH.saveLocalIpAndConnect()">${uiText('Save IP & connect')}</button></div><div class="row" style="margin:8px 0;flex-wrap:wrap"><button class="btn" onclick="ITH.checkConnections()">${uiText('Test auto connection')}</button><button class="btn" onclick="ITH.meshAnnounce().then(()=>ITH.meshRadar())">📍 ${uiText('Announce to local server')}</button><button class="btn" onclick="ITH.meshRadar()">🔄 ${uiText('Local server radar')}</button><button class="btn" onclick="ITH.meshInbox()">📥 ${uiText('Relay inbox')}</button><button class="btn danger" onclick="ITH.clearLocalConnection()">${uiText('Clear saved IP')}</button></div><div id="meshRadarBox" class="meshBox"><div class="date">${uiText('Optional: use this when there is one laptop/router local server on 8010.')}</div></div><div id="meshInboxBox" class="meshBox"></div></div><div class="card"><b>⚠️ ${uiText('Reality check')}</b><div class="localConnNote">${uiText('Phone-to-phone without provider needs all phones on the same hotspot/Wi‑Fi island or native Wi‑Fi Direct groups. This version uses Wi‑Fi/Hotspot/Wi‑Fi Direct only and adds a real APK microserver base on port 8099 for local tests.')}</div></div>`;$('memberMenu').classList.add('show');return false}

function headers(json=true){const h={'X-ITHAKI-TOKEN':state.token};if(json)h['Content-Type']='application/json';return h}
async function fetchJson(p,o={}){const opt=Object.assign({headers:headers(!o.body||typeof o.body==='string')},o);if(o.form){opt.body=o.form;opt.headers={'X-ITHAKI-TOKEN':state.token};delete opt.form}const r=await fetch(api(p),opt);if(!r.ok)throw new Error(p+' '+r.status);return r.json()}
function toast(m,ms=2800){const t=$('toast');if(!t)return; t.textContent=m;t.classList.add('show');clearTimeout(toast.t);toast.t=setTimeout(()=>t.classList.remove('show'),ms)}
function fmt(ts){try{return new Date((+ts||now())*1000).toLocaleString('en-GB',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'})}catch{return''}}
function mb(n){return ((+n||0)/1048576).toFixed((+n||0)>10485760?1:2)+' MB'}
function blocked(){try{return JSON.parse(localStorage.getItem('ith_blocked')||'[]').map(String)}catch{return[]}}
function isBlocked(id){return blocked().includes(String(id))}
function saveBlocked(a){localStorage.setItem('ith_blocked',JSON.stringify([...new Set(a.map(String))]))}
function uniqBy(arr,keyFn){const seen=new Set();return (arr||[]).filter((x,i)=>{let k='';try{k=String(keyFn(x,i)||'')}catch(e){k=String(i)};if(seen.has(k))return false;seen.add(k);return true})}
function uniquePosts(arr){const seenId=new Set(),seenSig=new Set();return (arr||[]).filter((p,i)=>{const id=String(p?.post_id||'').trim();if(id){if(seenId.has(id))return false;seenId.add(id)}let body='';let media='';try{const t=(typeof parseText==='function')?parseText(p?.text):{body:String(p?.text||''),media:null};body=String(t.body||'').replace(/\s+/g,' ').trim().toLowerCase().slice(0,260);const m=t.media||{};media=String(m.url||m.file_url||m.media_url||m.meta_id||m.kind||'').trim().toLowerCase()}catch(e){body=String(p?.text||'').replace(/\s+/g,' ').trim().toLowerCase().slice(0,260)}const minute=Math.floor((+(p?.created_at||0)||0)/60);const sig=[p?.sender_id||'',body,media,minute].join('|');if(sig.replace(/\|/g,'').length>8){if(seenSig.has(sig))return false;seenSig.add(sig)}return true})}
function uniqueMessages(arr){return uniqBy(arr,m=>m?.message_id||((m?.sender_id||'')+'|'+(m?.created_at||'')+'|'+String(m?.text||'').slice(0,180)))}
function uniqueNotices(arr){return uniqBy(arr,n=>n?.id||((n?.type||'')+'|'+(n?.from_id||'')+'|'+(n?.to_id||'')+'|'+(n?.text||'')+'|'+(n?.created_at||'')))}
function unreadFrom(id){try{return localNotices().some(n=>!n.read&&n.type==='message'&&String(n.from_id)===String(id))}catch{return false}}
function avatarDotClass(p){return unreadFrom(p.id)?'red':(p.online?'on':'')}

function avatarValue(){return state.avatar||('animal:'+state.animal)}
function avatarAssetV249502(value){let v=String(value||'').trim();if(!v)return'';if(v.startsWith('animal:'))return'';if(/^(data:image|blob:|https?:|file:)/i.test(v))return v;const base=String(state&&state.api||ITH_DOMAIN_BASE||location.origin||'').replace(/\/$/,'');if(v.startsWith('/'))return base+v;if(/^(api|uploads?|media|files?|assets?)\//i.test(v)||/\.(png|jpe?g|webp|gif|svg)(?:[?#].*)?$/i.test(v))return base+'/'+v.replace(/^\/+/, '');return''}
function avatarHtml(p={}){const a=String(p.avatar||p.photo||p.animal||'').trim(),fallback=esc((p.nickname||p.name||'M')[0]||'M');if(a.startsWith('animal:'))return `<span class="avatar">${esc(a.replace('animal:',''))}</span>`;if(animals.includes(a))return `<span class="avatar">${esc(a)}</span>`;const src=avatarAssetV249502(a);if(src)return `<span class="avatar"><img src="${esc(src)}" alt="" loading="lazy" onerror="this.remove();this.parentElement.textContent='${fallback}'"></span>`;return `<span class="avatar">${fallback}</span>`}
function norm(x){const id=String(x?.device_id||x?.id||x?.sender_id||'').trim();if(!id||id===state.device||isBlocked(id))return null;return{id,device_id:id,nickname:String(x?.nickname||x?.name||id||'Member'),avatar:String(x?.avatar||x?.photo||''),online:!!x?.online,last_seen:+(x?.last_seen||0)}}
function v249231PersonById(id){id=String(id||'').trim();if(!id)return {id:'',device_id:'',nickname:'Μέλος',avatar:'',online:false,last_seen:0};let p=null;try{p=state.people.get(id)||null}catch(e){}if(!p){try{for(const v of state.people.values()){if(String(v?.device_id||v?.id||'')===id){p=v;break}}}catch(e){}}p=p||{id,device_id:id,nickname:'Μέλος',avatar:'',online:false,last_seen:0};if(!p.id)p.id=id;if(!p.device_id)p.device_id=id;if(!p.nickname)p.nickname='Μέλος';if(typeof p.online==='undefined')p.online=!!(p.last_seen&&(+p.last_seen)>=now()-180);return p}
function mergePerson(x){const p=norm(x);if(!p)return;const old=state.people.get(p.id)||{};state.people.set(p.id,Object.assign({},old,p,{online:p.online||old.online,avatar:p.avatar||old.avatar||''}))}
function peopleArray(){return [...state.people.values()].filter(p=>!isBlocked(p.id)).sort((a,b)=>(b.online-a.online)||((b.last_seen||0)-(a.last_seen||0))||a.nickname.localeCompare(b.nickname,'en'))}
function loadPeopleLocal(){/* V249169: avatars start fresh from server only; no old cached avatar strip. */}
async function loadConfig(){try{const c=await (await fetch(api('/app_connection_config.json'),{cache:'no-store'})).json();state.token=c.public_app_token||state.token;state.room=c.default_room_id||state.room}catch{}try{const b=await fetchJson('/api/app/bootstrap');state.token=b.public_app_token||state.token;state.room=b.default_room_id||b.room_id||state.room}catch{}localStorage.setItem('ith_room',state.room)}
async function heartbeat(){
  try{
    await fetchJson('/api/people/heartbeat',{method:'POST',body:JSON.stringify({room_id:state.room,device_id:state.device,nickname:state.name||'Μέλος',language:(typeof uiLang==='function'?uiLang():'el'),avatar:avatarValue()})});
    setConnectionGreen('Σύνδεση server ενεργή');
    return true;
  }catch(e){
    if(state.wsReady){setConnectionGreen('Realtime WebSocket ενεργό · αναμονή ελέγχου προφίλ');return false}
    setConnectionOffline('Δεν υπάρχει σύνδεση με server');
    try{if(window.ITH&&ITH.checkConnections)ITH.checkConnections()}catch(_){}
    return false;
  }
}
async function loadPeople(){try{const k=await fetchJson(`/api/people/known?room_id=${encodeURIComponent(state.room)}&limit=800`);(k.people||[]).forEach(mergePerson)}catch{}try{const o=await fetchJson(`/api/people/online?room_id=${encodeURIComponent(state.room)}`);(o.people||[]).forEach(x=>mergePerson(Object.assign({},x,{online:true})))}catch{}try{const f=await fetchJson(`/api/flow?room_id=${encodeURIComponent(state.room)}&visibility=public&limit=200&lite=1&viewer_id=${encodeURIComponent(state.device)}`);(f.posts||[]).forEach(p=>mergePerson({device_id:p.sender_id,nickname:p.nickname,avatar:p.avatar,last_seen:p.created_at}))}catch{}try{localStorage.setItem('ith_people_cache_from_server_v249169','1');localStorage.setItem('ith_people_cache_v249169',JSON.stringify(peopleArray().slice(0,400)))}catch{}if(state.page==='home')refreshHomeStoriesV249407();if(state.page==='dm'||document.getElementById('dmPage')?.classList.contains('active'))renderPeople()}



const ITH_FALLBACK_DICT={"γεια": "hello", "καλημέρα": "good morning", "καλησπέρα": "good evening", "καληνύχτα": "good night", "ευχαριστώ": "thank you", "παρακαλώ": "please", "ναι": "yes", "όχι": "no", "οχι": "no", "άνθρωπος": "person", "ανθρωπος": "person", "άνθρωποι": "people", "φιλος": "friend", "φίλος": "friend", "φίλη": "friend", "φίλοι": "friends", "κόσμος": "world", "κοσμος": "world", "καρδιά": "heart", "καρδια": "heart", "σεβασμός": "respect", "σεβασμος": "respect", "αγάπη": "love", "αγαπη": "love", "σκέψη": "thought", "σκεψη": "thought", "φωνή": "sound", "φωνη": "sound", "λόγος": "word", "λογος": "word", "λέξη": "word", "λεξη": "word", "μήνυμα": "message", "μηνυμα": "message", "μηνύματα": "messages", "μηνυματα": "messages", "σχόλιο": "comment", "σχολιο": "comment", "δημοσίευση": "post", "δημοσιευση": "post", "ροή": "feed", "ροη": "feed", "community": "community", "κοινοτητα": "community", "κοινότητες": "communities", "κοινοτητες": "communities", "room": "room", "δωματιο": "room", "δωμάτια": "rooms", "δωματια": "rooms", "ψηφοφορία": "poll", "ψηφοφορια": "poll", "επιλογή": "choice", "επιλογη": "choice", "options": "choices", "επιλογες": "choices", "προφίλ": "profile", "προφιλ": "profile", "μέλος": "member", "μελος": "member", "members": "members", "μελη": "members", "φωτογραφία": "photo", "φωτογραφια": "photo", "βίντεο": "video", "βιντεο": "video", "file": "file", "αρχειο": "file", "αρχεία": "files", "αρχεια": "files", "άνοιγμα": "open", "ανοιγμα": "open", "λήψη": "download", "ληψη": "download", "κοινοποίηση": "share", "κοινοποιηση": "share", "αποστολή": "send", "αποστολη": "send", "γράφω": "write", "γραφω": "write", "γράψε": "write", "γραψε": "write", "διαγραφή": "delete", "διαγραφη": "delete", "απάντηση": "reply", "απαντηση": "reply", "μετάφραση": "translation", "μεταφραση": "translation", "μετάφρασε": "translate", "μεταφρασε": "translate", "ελληνικά": "Greek", "ελληνικα": "Greek", "αγγλικά": "English", "αγγλικα": "English", "προστασία": "protection", "προστασια": "protection", "βοτ": "bot", "spam": "spam", "καθαρή": "clean", "καθαρη": "clean", "επικοινωνία": "communication", "επικοινωνια": "communication", "ελεύθερα": "freely", "ελευθερα": "freely", "ανώνυμα": "anonymously", "ανωνυμα": "anonymously", "ανθρώπινα": "humanly", "ανθρωπινα": "humanly", "ωραία": "nice", "ωραια": "nice", "καλό": "good", "καλο": "good", "καλή": "good", "καλη": "good", "καλά": "well", "καλα": "well", "κακό": "bad", "κακο": "bad", "άσχημο": "bad", "ασχημο": "bad", "θέλω": "I want", "θελω": "I want", "μπορώ": "I can", "μπορω": "I can", "μπορείς": "can you", "μπορεις": "can you", "είμαι": "I am", "ειμαι": "I am", "είσαι": "you are", "εισαι": "you are", "είναι": "is", "ειναι": "is", "έχω": "I have", "εχω": "I have", "έχεις": "you have", "εχεις": "you have", "κάνω": "I do", "κανω": "I do", "κάνεις": "you do", "κανεις": "you do", "φτιάξε": "fix", "φτιαξε": "fix", "διόρθωσε": "fix", "διορθωσε": "fix", "τώρα": "now", "τωρα": "now", "πάνω": "up", "πανω": "up", "κάτω": "down", "κατω": "down", "μέσα": "inside", "μεσα": "inside", "έξω": "outside", "εξω": "outside", "αρχική": "home", "αρχικη": "home", "οθόνη": "screen", "οθονη": "screen", "κουμπί": "button", "κουμπι": "button", "κουμπιά": "buttons", "κουμπια": "buttons", "μπάρα": "bar", "μπαρα": "bar", "ήχος": "sound", "ηχος": "sound", "κλείνει": "closes", "κλεινει": "closes", "ανοίγει": "opens", "ανοιγει": "opens", "φορτώνει": "loads", "φορτωνει": "loads", "λειτουργεί": "works", "λειτουργει": "works", "σφάλμα": "error", "σφαλμα": "error", "σωστό": "correct", "σωστο": "correct", "λάθος": "wrong", "λαθος": "wrong", "γρήγορα": "fast", "γρηγορα": "fast", "αργά": "slow", "αργα": "slow", "σύνδεση": "connection", "συνδεση": "connection", "wifi": "wifi", "τόνερ": "tether", "τονερ": "tether", "κινητό": "mobile", "κινητο": "mobile", "υπολογιστής": "computer", "υπολογιστης": "computer", "hello": "γεια", "good": "καλό", "morning": "καλημέρα", "evening": "καλησπέρα", "night": "νύχτα", "thank": "ευχαριστώ", "you": "εσύ", "please": "παρακαλώ", "yes": "ναι", "no": "όχι", "person": "άνθρωπος", "people": "άνθρωποι", "friend": "φίλος", "friends": "φίλοι", "world": "κόσμος", "heart": "καρδιά", "respect": "σεβασμός", "love": "αγάπη", "thought": "σκέψη", "voice": "φωνή", "word": "λέξη", "message": "μήνυμα", "messages": "μηνύματα", "comment": "σχόλιο", "post": "δημοσίευση", "feed": "ροή", "community": "community", "communities": "κοινότητες", "room": "room", "rooms": "δωμάτια", "poll": "ψηφοφορία", "choice": "επιλογή", "choices": "options", "profile": "προφίλ", "member": "μέλος", "members": "members", "photo": "φωτογραφία", "video": "βίντεο", "file": "file", "files": "αρχεία", "open": "άνοιγμα", "download": "λήψη", "share": "κοινοποίηση", "send": "αποστολή", "write": "γράφω", "delete": "διαγραφή", "reply": "απάντηση", "translation": "μετάφραση", "translate": "μετάφραση", "greek": "ελληνικά", "english": "αγγλικά", "protection": "προστασία", "bot": "βοτ", "clean": "καθαρή", "communication": "επικοινωνία", "freely": "ελεύθερα", "anonymously": "ανώνυμα", "humanly": "ανθρώπινα", "nice": "ωραία", "bad": "κακό", "now": "τώρα", "up": "πάνω", "down": "κάτω", "inside": "μέσα", "outside": "έξω", "home": "αρχική", "screen": "οθόνη", "button": "κουμπί", "buttons": "κουμπιά", "bar": "μπάρα", "sound": "ήχος", "closes": "κλείνει", "opens": "ανοίγει", "loads": "φορτώνει", "works": "λειτουργεί", "error": "σφάλμα", "correct": "σωστό", "wrong": "λάθος", "fast": "γρήγορα", "slow": "αργά", "connection": "σύνδεση", "tether": "τόνερ", "mobile": "κινητό", "computer": "υπολογιστής"};
const ITH_UI_EN={
  "Αρχική":"Home","Ροή":"Feed","Μηνύματα":"Messages","Συνομιλίες":"Chats","Χώροι":"Spaces","Προφίλ":"Profile","Φωτογραφία":"Photo","Βίντεο":"Video","Αρχείο":"File","Κείμενο":"Text","Ψηφοφορία":"Poll","Ειδοποιήσεις":"Notifications","Διαχείριση":"Admin","Επικοινωνία":"Contact","Αποθήκευση":"Save","Ανάκτηση":"Recovery","Διαγραφή":"Delete","Άνοιγμα":"Open","Λήψη":"Download","Κοινοποίηση":"Share","Αποστολή":"Send","Ελληνικά":"Greek","Αγγλικά":"English",
  "Home":"Home","Feed":"Feed","Messages":"Messages","Spaces":"Spaces","Profile":"Profile","Photo":"Photo","Video":"Video","File":"File","Text":"Text","Poll":"Poll","Notifications":"Notifications","Admin":"Admin","ITHAKI Host":"ITHAKI Host","Welcome to":"Welcome to","Communicate freely, humanly and anonymously.":"Communicate freely, humanly and anonymously.","Wise words":"Wise words","Protection and clean communication":"Protection and clean communication","Communication builds bridges where silence left distance.":"Communication builds bridges where silence left distance.","A person is heard better when speaking with respect.":"A person is heard better when speaking with respect.","A clear conversation can become the beginning of a better world.":"A clean conversation can be the beginning of a better world.","There is protection from bots, spam and malicious mass behavior.":"There is protection from bots, spam and malicious mass behavior.","Live translation works internally/offline, without unnecessary external data transfer.":"Live translation works internally/offline, without unnecessary external data transfer.","Post":"Post","Rooms / communities":"Rooms / communities","Notification center":"Notification center","Translate":"Translate","Greek":"Greek","English":"English","Save":"Save","Open contact":"Open contact","Choose a contact":"Choose a contact","Choose a contact to message.":"Choose a contact to message.","Write a message...":"Write a message...","No contacts yet.":"No contacts yet.","Rooms":"Rooms","Communities":"Communities","Create":"Create","Choose a space.":"Choose a space.","Message this space...":"Message this space...","Contact server":"Contact server","Member code":"Member code","Contact the server":"Contact the server"
};
const ITH_UI_EL={
  "Home":"Αρχική","Feed":"Ροή","Messages":"Μηνύματα","Spaces":"Χώροι","Profile":"Προφίλ","Photo":"Φωτογραφία","Video":"Βίντεο","File":"Αρχείο","Text":"Κείμενο","Poll":"Ψηφοφορία","Notifications":"Ειδοποιήσεις","Admin":"Διαχείριση","ITHAKI Host":"ΙΘΑΚΗ Host","Welcome to":"Καλώς ήρθες στο","Communicate freely, humanly and anonymously.":"Επικοινώνησε ελεύθερα, ανθρώπινα και ανώνυμα.","Wise words":"Σοφά λόγια","Protection and clean communication":"Προστασία και καθαρή επικοινωνία","Communication builds bridges where silence left distance.":"Η επικοινωνία χτίζει γέφυρες εκεί όπου η σιωπή άφησε απόσταση.","A person is heard better when speaking with respect.":"Ο άνθρωπος ακούγεται καλύτερα όταν μιλά με σεβασμό.","A clear conversation can become the beginning of a better world.":"Μια καθαρή συζήτηση μπορεί να γίνει αρχή για έναν καλύτερο κόσμο.","There is protection from bots, spam and malicious mass behavior.":"Υπάρχει προστασία από bots, spam και κακόβουλη μαζική συμπεριφορά.","Live translation works internally/offline, without unnecessary external data transfer.":"Η ζωντανή μετάφραση λειτουργεί εσωτερικά/offline, χωρίς περιττή εξωτερική μεταφορά δεδομένων.","Post":"Δημοσίευση","Rooms / communities":"Δωμάτια / κοινότητες","Notification center":"Κέντρο ειδοποιήσεων","Translate":"Μετάφραση","Greek":"Ελληνικά","English":"Αγγλικά","Save":"Αποθήκευση","Open contact":"Άνοιγμα επικοινωνίας","ITHAKI uses internal offline translation so people can communicate without unnecessary external data transfer.":"Η ΙΘΑΚΗ χρησιμοποιεί εσωτερική offline μετάφραση ώστε οι άνθρωποι να επικοινωνούν χωρίς περιττή εξωτερική μεταφορά δεδομένων.","There is protection from bots, spam and malicious mass behavior that distorts dialogue and tires members.":"Υπάρχει προστασία από bots, spam και κακόβουλη μαζική συμπεριφορά που χαλάει τον διάλογο και κουράζει τα μέλη.","The goal is a simple, decent and human environment: speak freely, with respect.":"Στόχος είναι ένα απλό, αξιοπρεπές και ανθρώπινο περιβάλλον: μίλα ελεύθερα, με σεβασμό.","Videos, photos, text":"Βίντεο, φωτογραφίες, κείμενο","Text, photo, video, file":"Κείμενο, φωτογραφία, βίντεο, αρχείο","Chats, files, replies":"Συνομιλίες, αρχεία, απαντήσεις","Anonymous or profile":"Ανώνυμα ή με προφίλ","Invites / approvals":"Προσκλήσεις / αποδοχές","Member code":"Κωδικός μέλους","Contact server":"Επικοινωνία με server","Contact the server":"Επικοινωνία με τον server","We are happy to hear your thoughts, observations and advice.":"Θέλουμε να ακούμε τις σκέψεις, τις παρατηρήσεις και τις συμβουλές σου.","Choose a contact":"Επίλεξε επαφή","Choose a contact to message.":"Επίλεξε επαφή για μήνυμα.","Write a message...":"Γράψε μήνυμα...","No contacts yet.":"Δεν υπάρχουν επαφές ακόμα.","Rooms":"Δωμάτια","Communities":"Κοινότητες","Create":"Δημιουργία","Choose a space":"Επίλεξε χώρο","Choose a space.":"Επίλεξε χώρο.","Message this space...":"Μήνυμα σε αυτόν τον χώρο...","New poll":"Νέα ψηφοφορία","Poll type":"Τύπος ψηφοφορίας","My choices":"Δικές μου επιλογές","Yes / No":"Ναι / Όχι","Ready question list":"Έτοιμη λίστα ερωτήσεων","Poll topic":"Θέμα ψηφοφορίας","Question":"Ερώτηση","Poll options":"Επιλογές ψηφοφορίας","Post poll":"Δημοσίευση ψηφοφορίας","Statistics":"Στατιστικά","Profile":"Προφίλ","Name":"Όνομα","Avatar / policy / recovery":"Avatar / πολιτική / ανάκτηση","Translation":"Μετάφραση","Chat translation":"Μετάφραση συνομιλίας","Save account":"Αποθήκευση λογαριασμού","Recovery":"Ανάκτηση","What the server keeps":"Τι κρατά ο server","Permissions":"Άδειες","Blocked":"Μπλοκαρισμένοι","No blocked members.":"Δεν υπάρχουν μπλοκαρισμένα μέλη.","Loading...":"Φόρτωση...","No posts yet.":"Δεν υπάρχουν ακόμη δημοσιεύσεις.","Contact ITHAKI Host":"Επικοινωνία με ΙΘΑΚΗ Host","Write thoughts, observations or advice. The message stays internally in ITHAKI.":"Γράψε σκέψεις, παρατηρήσεις ή συμβουλές. Το μήνυμα μένει εσωτερικά στην ΙΘΑΚΗ.","My message to ITHAKI Host...":"Το μήνυμά μου προς ΙΘΑΚΗ Host...","Anonymous contact":"Ανώνυμη επικοινωνία","Send to Host":"Αποστολή στον Host"
};


Object.assign(ITH_UI_EN,{
  'Καλώς ήρθες στην':'Welcome to',
  'ΙΘΑΚΗ':'ITHAKI',
  'Ανθρώπινη επικοινωνία, καθαρή ροή, σεβασμός και ανωνυμία.':'Human communication, a clean feed, respect and anonymity.',
  'Διάλεξε πού θέλεις να πας.':'Choose where you want to go.',
  'Σοφός λόγος':'Wise words',
  'Ροή':'Feed',
  'Βίντεο, φωτογραφίες και λόγια':'Videos, photos and words',
  'Δημοσίευση':'Post',
  'Κείμενο, φωτογραφία, βίντεο ή αρχείο':'Text, photo, video or file',
  'Μηνύματα':'Messages',
  'Συνομιλίες και αρχεία':'Chats and files',
  'Δωμάτια / Κοινότητες':'Rooms / Communities',
  'Ομάδες και χώροι συζήτησης':'Groups and discussion spaces',
  'Ψηφοφορία':'Poll',
  'Ρώτα γνώμη με καθαρή κάρτα':'Ask for opinions with a clean card',
  'Προφίλ':'Profile',
  'Όνομα, avatar, προστασία και ειδοποιήσεις':'Name, avatar, protection and notifications',
  'Προστασία':'Protection',
  'Η ΙΘΑΚΗ κρατά την επικοινωνία καθαρή, ανθρώπινη και αξιοπρεπή.':'ITHAKI keeps communication clean, human and respectful.',
  'Υπάρχουν όρια κατά spam, bots και κακόβουλης μαζικής συμπεριφοράς.':'There are limits against spam, bots and malicious mass behaviour.',
  'Δεν ζητάμε υποχρεωτικά τηλέφωνο, email ή ιδιωτική λίστα επαφών.':'We do not require a phone number, email or private contact list.',
  'Οι ειδοποιήσεις FCM είναι προαιρετικές και ενεργοποιούνται μόνο αν το επιλέξεις.':'FCM notifications are optional and enabled only if you choose them.',
  'Το προφίλ αποθηκεύεται πρώτα στη συσκευή και μετά συγχρονίζεται με τον server.':'The profile is saved on the device first and then synced with the server.',
  'Me':'Me',
  'Avatar μελών':'Member avatars',
  'Τα avatar θα εμφανίζονται από τον server όταν ενεργοποιηθούν νέα προφίλ.':'Avatars will appear from the server when new profiles are activated.'
});
Object.assign(ITH_UI_EL,{
  'Welcome to':'Καλώς ήρθες στην',
  'Human communication, a clean feed, respect and anonymity.':'Ανθρώπινη επικοινωνία, καθαρή ροή, σεβασμός και ανωνυμία.',
  'Choose where you want to go.':'Διάλεξε πού θέλεις να πας.',
  'Me':'Εγώ',
  'Member avatars':'Avatar μελών',
  'Avatars will appear from the server when new profiles are activated.':'Τα avatar θα εμφανίζονται από τον server όταν ενεργοποιηθούν νέα προφίλ.'
});

Object.assign(ITH_UI_EN,{
  'Current connection':'Current connection','Local hotspot/Wi‑Fi':'Local hotspot/Wi‑Fi','EU tunnel':'EU tunnel','Laptop local':'Laptop local','Normal connection':'Normal connection','Offline':'Offline','Return to normal/tunnel':'Return to normal/tunnel','Check connection':'Check connection','Normal/tunnel connection active':'Normal/tunnel connection active','Normal connection failed':'Normal connection failed','Uploaded':'Uploaded','Direct small/pre-compressed video':'Direct small/pre-compressed video','Published immediately under 100MB without waiting for FFmpeg.':'Published immediately under 100MB without waiting for FFmpeg.',
  'Back':'Back','Close':'Close','Open full screen':'Open full screen','Exit full screen':'Exit full screen','Only this member':'Only this member','Small view':'Small view','Member menu':'Member menu','New message':'New message','Open site link':'Open site link','Copy link':'Copy link','Link copied':'Link copied','If the app is not installed, the link opens on the OK ITHAKI site.':'If the app is not installed, the link opens on the OK ITHAKI site.','Choose a contact':'Choose a contact','No contacts yet.':'No contacts yet.','Start the conversation.':'Start the conversation.','Messages are not loading':'Messages are not loading','Delete post?':'Delete post?','Cannot delete':'Cannot delete','Deleted':'Deleted','Message':'Message','Posts':'Posts','Contact invite':'Contact invite','Follow':'Follow','Block':'Block','Report':'Report','Online':'Online','Offline':'Offline','Notification center':'Notification center','Contact accepted':'Contact accepted','Reject':'Reject','Open message':'Open message','Outside the app':'Outside the app','Connect Push / FCM':'Connect Push / FCM','Post comments':'Post comments','Loading comments...':'Loading comments...','No comments yet. Write the first one.':'No comments yet. Write the first one.','Comments are not loading.':'Comments are not loading.','Write a comment or reply...':'Write a comment or reply...','Reply':'Reply','Loading member feed...':'Loading member feed...','Member feed is not loading.':'Member feed is not loading.','No posts found.':'No posts found.','Loading short videos...':'Loading short videos...','Member posts are not loading.':'Member posts are not loading.','All':'All','Open':'Open','Download':'Download','Share':'Share','Vote:':'Vote:','Anonymous':'Anonymous','With profile':'With profile','Total votes':'Total votes','Suggested communities':'Suggested communities','Suggested rooms':'Suggested rooms','New community':'New community','New room':'New room','Title':'Title','Description / rules':'Description / rules','Access':'Access','Open access':'Open','By invitation/approval':'By invitation/approval','With member code':'With member code','Member code':'Member code','Admin code':'Admin code','Create':'Create','Code/QR':'Code/QR','Enter a title':'Enter a title','Not created':'Not created','Created':'Created','Choose a space':'Choose a space','Choose a space.':'Choose a space.','Message this space...':'Message this space...','Spaces are not loading.':'Spaces are not loading.','Auto Greek ↔ English':'Auto Greek ↔ English','Content translation is automatic: Greek ↔ English':'Content translation is automatic: Greek ↔ English'
});
Object.assign(ITH_UI_EL,{
  'Current connection':'Τρέχουσα σύνδεση','Local hotspot/Wi‑Fi':'Τοπικό hotspot/Wi‑Fi','EU tunnel':'Ευρωπαϊκό tunnel','Laptop local':'Τοπικό laptop','Normal connection':'Κανονική σύνδεση','Offline':'Εκτός σύνδεσης','Return to normal/tunnel':'Επιστροφή σε κανονική/tunnel','Check connection':'Έλεγχος σύνδεσης','Normal/tunnel connection active':'Ενεργή κανονική/tunnel σύνδεση','Normal connection failed':'Απέτυχε η κανονική σύνδεση','Uploaded':'Ανέβηκε','Direct small/pre-compressed video':'Μικρό/ήδη συμπιεσμένο βίντεο','Published immediately under 100MB without waiting for FFmpeg.':'Δημοσιεύτηκε αμέσως κάτω από 100MB χωρίς αναμονή FFmpeg.',
  'Back':'Πίσω','Close':'Κλείσιμο','Open full screen':'Άνοιγμα πλήρους οθόνης','Exit full screen':'Έξοδος πλήρους οθόνης','Only this member':'Μόνο αυτό το μέλος','Small view':'Μικρή προβολή','Member menu':'Μενού μέλους','New message':'Νέο μήνυμα','Open site link':'Άνοιγμα συνδέσμου site','Copy link':'Αντιγραφή συνδέσμου','Link copied':'Ο σύνδεσμος αντιγράφηκε','If the app is not installed, the link opens on the OK ITHAKI site.':'Αν δεν υπάρχει η εφαρμογή, ο σύνδεσμος ανοίγει στο site OK ITHAKI.','Choose a contact':'Διάλεξε επαφή','No contacts yet.':'Δεν υπάρχουν ακόμη επαφές.','Start the conversation.':'Ξεκίνα τη συζήτηση.','Messages are not loading':'Τα μηνύματα δεν φορτώνουν','Delete post?':'Διαγραφή δημοσίευσης;','Cannot delete':'Δεν γίνεται διαγραφή','Deleted':'Διαγράφηκε','Message':'Μήνυμα','Posts':'Δημοσιεύσεις','Contact invite':'Πρόσκληση επαφής','Follow':'Ακολούθηση','Block':'Μπλοκάρισμα','Report':'Αναφορά','Online':'Συνδεδεμένος','Offline':'Εκτός σύνδεσης','Notification center':'Κέντρο ειδοποιήσεων','Contact accepted':'Η επαφή έγινε αποδεκτή','Reject':'Απόρριψη','Open message':'Άνοιγμα μηνύματος','Outside the app':'Εκτός εφαρμογής','Connect Push / FCM':'Σύνδεση Push / FCM','Post comments':'Σχόλια δημοσίευσης','Loading comments...':'Φόρτωση σχολίων...','No comments yet. Write the first one.':'Δεν υπάρχουν σχόλια ακόμη. Γράψε το πρώτο.','Comments are not loading.':'Τα σχόλια δεν φορτώνουν.','Write a comment or reply...':'Γράψε σχόλιο ή απάντηση...','Reply':'Απάντηση','Loading member feed...':'Φόρτωση ροής μέλους...','Member feed is not loading.':'Η ροή μέλους δεν φορτώνει.','No posts found.':'Δεν βρέθηκαν δημοσιεύσεις.','Loading short videos...':'Φόρτωση σύντομων βίντεο...','Member posts are not loading.':'Οι δημοσιεύσεις μέλους δεν φορτώνουν.','All':'Όλα','Open':'Άνοιγμα','Download':'Λήψη','Share':'Κοινοποίηση','Vote:':'Ψήφος:','Anonymous':'Ανώνυμα','With profile':'Με προφίλ','Total votes':'Σύνολο ψήφων','Suggested communities':'Προτεινόμενες κοινότητες','Suggested rooms':'Προτεινόμενα δωμάτια','New community':'Νέα κοινότητα','New room':'Νέο δωμάτιο','Title':'Τίτλος','Description / rules':'Περιγραφή / κανόνες','Access':'Πρόσβαση','Open access':'Ανοιχτό','By invitation/approval':'Με πρόσκληση/έγκριση','With member code':'Με κωδικό μέλους','Member code':'Κωδικός μέλους','Admin code':'Κωδικός διαχειριστή','Create':'Δημιουργία','Code/QR':'Κωδικός/QR','Enter a title':'Βάλε τίτλο','Not created':'Δεν δημιουργήθηκε','Created':'Δημιουργήθηκε','Choose a space':'Διάλεξε χώρο','Choose a space.':'Διάλεξε χώρο.','Message this space...':'Μήνυμα σε αυτόν τον χώρο...','Spaces are not loading.':'Οι χώροι δεν φορτώνουν.','Auto Greek ↔ English':'Αυτόματα Ελληνικά ↔ Αγγλικά','Content translation is automatic: Greek ↔ English':'Η μετάφραση περιεχομένου είναι αυτόματη: Ελληνικά ↔ Αγγλικά'
});

Object.assign(ITH_UI_EL,{
  'Local connection':'Τοπική σύνδεση','Connection philosophy':'Φιλοσοφία σύνδεσης','For tests: 1) EU tunnel when internet exists. 2) Local Hotspot/Wi‑Fi when phones and laptop are on the same network. Local mode can work without provider internet, as long as all devices see the laptop/server IP.':'Για δοκιμές: 1) Ευρωπαϊκό tunnel όταν υπάρχει internet. 2) Τοπικό Hotspot/Wi‑Fi όταν κινητά και laptop είναι στο ίδιο δίκτυο. Η τοπική λειτουργία δουλεύει χωρίς πάροχο, αρκεί οι συσκευές να βλέπουν την IP του laptop/server.',
  'Phone hotspot or laptop hotspot, no provider internet needed.':'Hotspot κινητού ή laptop, χωρίς ανάγκη internet παρόχου.','All devices on the same router/Wi‑Fi.':'Όλες οι συσκευές στο ίδιο router/Wi‑Fi.','Prepared option. Real Wi‑Fi local transfer needs native APK module.':'Έτοιμη επιλογή. Η πραγματική μεταφορά Wi‑Fi local χρειάζεται native APK module.','Only if opened from 192.168.x.x / 10.x.x.x':'Μόνο αν άνοιξε από 192.168.x.x / 10.x.x.x','Save IP & connect':'Αποθήκευση IP & σύνδεση','Test auto connection':'Δοκιμή αυτόματης σύνδεσης','Clear saved IP':'Καθαρισμός αποθηκευμένης IP','Current server':'Τρέχων server','Saved local':'Αποθηκευμένο τοπικό','none':'κανένα','Mesh note':'Σημείωση mesh','Phone-to-phone relay at 30–80 meters is a future native mode with Wi‑Fi Direct relay. Browser/WebView alone cannot reliably create a true mesh network. This version prepares the menu and saves the local route.':'Η αναμετάδοση από κινητό σε κινητό στα 30–80 μέτρα είναι μελλοντική native λειτουργία με Wi‑Fi Direct relay. Μόνο Browser/WebView δεν φτιάχνει αξιόπιστο πραγματικό mesh. Αυτή η έκδοση ετοιμάζει το μενού και αποθηκεύει την τοπική διαδρομή.',
  'Write the laptop/server Toner/Hotspot first.':'Γράψε πρώτα την IP του laptop/server.','Local connection saved. Reloading...':'Η τοπική σύνδεση αποθηκεύτηκε. Γίνεται επαναφόρτωση...','Local connection OK':'Η τοπική σύνδεση είναι OK','Local connection failed. Check hotspot/Wi‑Fi and firewall.':'Η τοπική σύνδεση απέτυχε. Έλεγξε hotspot/Wi‑Fi και firewall.','Wi‑Fi local needs native Android/Wi‑Fi Direct module. Use Hotspot or Wi‑Fi now.':'Το Wi‑Fi local χρειάζεται native Android/Wi‑Fi Direct module. Χρησιμοποίησε τώρα Hotspot ή Wi‑Fi.','Open the app from the laptop IP, not 127.0.0.1, then press this.':'Άνοιξε την εφαρμογή από την IP του laptop, όχι 127.0.0.1, και μετά πάτησέ το.','Local saved IP cleared.':'Η αποθηκευμένη τοπική IP καθαρίστηκε.'
});

Object.assign(ITH_UI_EN,{
  'Preview':'Preview','Cancel':'Cancel','Upload / Send':'Upload / Send','Ready':'Ready','Sending...':'Sending...','Uploading':'Uploading','Compressing video...':'Compressing video...','Video processing...':'Video processing...','Video ready.':'Video ready.','Sent':'Sent','Send again':'Send again','Not sent':'Not sent','FFmpeg missing on this laptop/server. Install FFmpeg and restart.':'FFmpeg missing on this laptop/server. Install FFmpeg and restart.','Offline translation model missing on this laptop. Run 02_INSTALL_ARGOS_EN_EL_OFFLINE_MODEL.cmd and restart.':'Offline translation model missing on this laptop. Run 02_INSTALL_ARGOS_EN_EL_OFFLINE_MODEL.cmd and restart.','Translation system OK':'Translation system OK','Server tools':'Server tools','Check FFmpeg / video':'Check FFmpeg / video','Add any caption you want...':'Add any caption you want...','to Feed':'to Feed','to Messages':'to Messages','to Community / Room':'to Community / Room','here':'here','It will appear as a card and open externally.':'It will appear as a card and open externally.','App language: English':'App language: English','Γλώσσα εφαρμογής: Ελληνικά':'App language: Greek','Content translation is automatic: Greek ↔ English':'Content translation is automatic: Greek ↔ English'
});
Object.assign(ITH_UI_EL,{
  'Preview':'Προεπισκόπηση','Cancel':'Άκυρο','Upload / Send':'Ανέβασμα / Αποστολή','Ready':'Έτοιμο','Sending...':'Αποστολή...','Uploading':'Ανέβασμα','Compressing video...':'Συμπίεση βίντεο...','Video processing...':'Επεξεργασία βίντεο...','Video ready.':'Το βίντεο είναι έτοιμο.','Sent':'Στάλθηκε','Send again':'Στείλε ξανά','Not sent':'Δεν στάλθηκε','FFmpeg missing on this laptop/server. Install FFmpeg and restart.':'Λείπει το FFmpeg από το laptop/server. Εγκατέστησέ το και κάνε restart.','Offline translation model missing on this laptop. Run 02_INSTALL_ARGOS_EN_EL_OFFLINE_MODEL.cmd and restart.':'Λείπει το offline μοντέλο μετάφρασης Argos στο laptop. Τρέξε 02_INSTALL_ARGOS_EN_EL_OFFLINE_MODEL.cmd και κάνε restart.','Translation system OK':'Το σύστημα μετάφρασης είναι OK','Server tools':'Εργαλεία server','Check FFmpeg / video':'Έλεγχος FFmpeg / βίντεο','Add any caption you want...':'Γράψε λεζάντα αν θέλεις...','to Feed':'στη Ροή','to Messages':'στα Μηνύματα','to Community / Room':'στην Κοινότητα / Δωμάτιο','here':'εδώ','It will appear as a card and open externally.':'Θα εμφανιστεί σαν κάρτα και θα ανοίγει εξωτερικά.','App language: English':'Γλώσσα εφαρμογής: Αγγλικά','Γλώσσα εφαρμογής: Ελληνικά':'Γλώσσα εφαρμογής: Ελληνικά','Content translation is automatic: Greek ↔ English':'Η μετάφραση περιεχομένου είναι αυτόματη: Ελληνικά ↔ Αγγλικά','Home':'Αρχική','Feed':'Ροή','Messages':'Μηνύματα','Spaces':'Χώροι','Profile':'Προφίλ','Photo':'Φωτογραφία','Video':'Βίντεο','File':'Αρχείο','Text':'Κείμενο','Poll':'Ψηφοφορία','Notifications':'Ειδοποιήσεις','Name':'Όνομα','Save':'Αποθήκευση','Blocked':'Μπλοκαρισμένοι','No blocked members.':'Δεν υπάρχουν μπλοκαρισμένοι.'
});


// V249141 UI dictionary hard split: menu/app language does NOT use Argos/content translation.
const ITH_UI_PATCH_V249141 = {en:{"Αρχική":"Home","Ροή":"Feed","Μηνύματα":"Messages","Συνομιλίες":"Chats","Χώροι":"Spaces","Προφίλ":"Profile","Φωτογραφία":"Photo","Βίντεο":"Video","Αρχείο":"File","Κείμενο":"Text","Ψηφοφορία":"Poll","Ειδοποιήσεις":"Notifications","Διαχείριση":"Admin","Επικοινωνία":"Communication","Αποθήκευση":"Save","Ανάκτηση":"Recovery","Διαγραφή":"Delete","Άνοιγμα":"Open","Λήψη":"Download","Κοινοποίηση":"Share","Αποστολή":"Send","Ελληνικά":"Greek","Αγγλικά":"English","Πίσω":"Back","Κλείσιμο":"Close","Άκυρο":"Cancel","Έτοιμο":"Ready","Όλα":"All","Όνομα":"Name","Πρόσβαση":"Access","Στατιστικά":"Statistics","Αναφορά":"Report","Απάντηση":"Reply","Μπλοκάρισμα":"Block","Ακολούθηση":"Follow","Δημιουργία":"Create","Δημιουργήθηκε":"Created","Διαγράφηκε":"Deleted","Στάλθηκε":"Sent","Δεν στάλθηκε":"Not sent","Στείλε ξανά":"Send again","Ανοιχτό":"Open","Εκτός σύνδεσης":"Offline","Συνδεδεμένος":"Connected","Καλώς ήρθες στο":"Welcome to","Επικοινώνησε ελεύθερα, ανθρώπινα και ανώνυμα.":"Communicate freely, humanly and anonymously.","Σοφά λόγια":"Wise words","Προστασία και καθαρή επικοινωνία":"Protection and clean communication","Η επικοινωνία χτίζει γέφυρες εκεί όπου η σιωπή άφησε απόσταση.":"Communication builds bridges where silence left distance.","Ο άνθρωπος ακούγεται καλύτερα όταν μιλά με σεβασμό.":"A person is heard better when speaking with respect.","Μια καθαρή συζήτηση μπορεί να γίνει αρχή για έναν καλύτερο κόσμο.":"A clear conversation can become the beginning of a better world.","Υπάρχει προστασία από bots, spam και κακόβουλη μαζική συμπεριφορά.":"There is protection from bots, spam and malicious mass behavior.","Υπάρχει προστασία από bots, spam και κακόβουλη μαζική συμπεριφορά που χαλάει τον διάλογο και κουράζει τα μέλη.":"There is protection from bots, spam and malicious mass behavior that harms dialogue and tires members.","Στόχος είναι ένα απλό, αξιοπρεπές και ανθρώπινο περιβάλλον: μίλα ελεύθερα, με σεβασμό.":"The goal is a simple, decent and human environment: speak freely, with respect.","Γλώσσα εφαρμογής: Αγγλικά":"App language: English","Γλώσσα εφαρμογής: Ελληνικά":"App language: Greek","Αυτόματα Ελληνικά ↔ Αγγλικά":"Auto Greek ↔ English","Η μετάφραση περιεχομένου είναι αυτόματη: Ελληνικά ↔ Αγγλικά":"Content translation is automatic: Greek ↔ English","Μετάφραση":"Translation","Μετάφραση συνομιλίας":"Conversation translation","Η ζωντανή μετάφραση λειτουργεί εσωτερικά/offline, χωρίς περιττή εξωτερική μεταφορά δεδομένων.":"Live translation works internally/offline, without unnecessary external data transfer.","Η ΙΘΑΚΗ χρησιμοποιεί εσωτερική offline μετάφραση ώστε οι άνθρωποι να επικοινωνούν χωρίς περιττή εξωτερική μεταφορά δεδομένων.":"ITHAKI uses internal offline translation so people can communicate without unnecessary external data transfer.","Η γλώσσα των μενού αλλάζει από εσωτερικό λεξικό UI και δεν χρειάζεται Argos.":"Menu language changes from the built-in UI dictionary and does not need Argos.","Μετάφραση περιεχομένου":"Content translation","Γλώσσα μενού":"Menu language","Εσωτερικό λεξικό UI":"Built-in UI dictionary","Δεν χρειάζεται Argos για τα μενού.":"Argos is not needed for menus.","Εργαλεία server":"Server tools","Έλεγχος FFmpeg / βίντεο":"Check FFmpeg / video","Λείπει το FFmpeg από το laptop/server. Εγκατέστησέ το και κάνε restart.":"FFmpeg is missing from the laptop/server. Install it and restart.","Το FFmpeg είναι OK. Τα βίντεο μπορούν να συμπιεστούν.":"FFmpeg is OK. Videos can be compressed.","Συμπίεση βίντεο...":"Compressing video...","Επεξεργασία βίντεο...":"Video processing...","Το βίντεο είναι έτοιμο.":"Video ready.","Ανέβασμα":"Uploading","Ανέβασμα / Αποστολή":"Upload / Send","Αποστολή...":"Sending...","Προεπισκόπηση":"Preview","Γράψε λεζάντα αν θέλεις...":"Add any caption you want...","Θα εμφανιστεί σαν κάρτα και θα ανοίγει εξωτερικά.":"It will appear as a card and open externally.","στη Ροή":"to Feed","στα Μηνύματα":"to Messages","στην Κοινότητα / Δωμάτιο":"to Community / Room","εδώ":"here","Το βίντεο δεν φορτώνει χωρίς FFmpeg. Βάλε ffmpeg.exe στο server ή στο PATH.":"Video cannot be published without FFmpeg. Put ffmpeg.exe in server or PATH.","Τοπική σύνδεση":"Local connection","Φιλοσοφία σύνδεσης":"Connection philosophy","Επικοινωνία με server":"Server communication","Επικοινωνία με τον server":"Server communication","Ευρωπαϊκό tunnel όταν υπάρχει internet.":"European tunnel when internet exists.","Τοπικό Hotspot/Wi‑Fi όταν κινητά και laptop είναι στο ίδιο δίκτυο.":"Local Hotspot/Wi‑Fi when phones and laptop are on the same network.","Για δοκιμές: 1) Ευρωπαϊκό tunnel όταν υπάρχει internet. 2) Τοπικό Hotspot/Wi‑Fi όταν κινητά και laptop είναι στο ίδιο δίκτυο. Η τοπική λειτουργία δουλεύει χωρίς πάροχο, αρκεί οι συσκευές να είναι στο ίδιο δίκτυο.":"For tests: 1) European tunnel when internet exists. 2) Local Hotspot/Wi‑Fi when phones and laptop are on the same network. Local mode works without a provider as long as devices are on the same network.","Γράψε πρώτα την IP του laptop/server.":"Write the laptop/server Toner/Hotspot first.","Αποθήκευση IP & σύνδεση":"Save IP & connect","Η τοπική σύνδεση αποθηκεύτηκε. Γίνεται επαναφόρτωση...":"Local connection saved. Reloading...","Η τοπική σύνδεση είναι OK":"Local connection OK","Η τοπική σύνδεση απέτυχε. Έλεγξε hotspot/Wi‑Fi και firewall.":"Local connection failed. Check hotspot/Wi‑Fi and firewall.","Η αποθηκευμένη τοπική IP καθαρίστηκε.":"Local saved IP cleared.","Καθαρισμός αποθηκευμένης IP":"Clear saved IP","Δοκιμή αυτόματης σύνδεσης":"Test auto connection","Τρέχων server":"Current server","Αποθηκευμένο τοπικό":"Saved local","Μόνο αν άνοιξε από 192.168.x.x / 10.x.x.x":"Only if opened from 192.168.x.x / 10.x.x.x","Hotspot κινητού ή laptop, χωρίς ανάγκη internet παρόχου.":"Phone or laptop hotspot, no provider internet required.","Όλες οι συσκευές στο ίδιο router/Wi‑Fi.":"All devices on the same router/Wi‑Fi.","Το Wi‑Fi local χρειάζεται native Android/Wi‑Fi Direct module. Χρησιμοποίησε τώρα Hotspot ή Wi‑Fi.":"Wi‑Fi local needs a native Android/Wi‑Fi Direct module. Use Hotspot or Wi‑Fi now.","Σημείωση mesh":"Mesh note","Η αναμετάδοση από κινητό σε κινητό στα 30–80 μέτρα είναι μελλοντική native λειτουργία με Wi‑Fi Direct relay. Μόνο Browser/WebView δεν φτιάχνει αξιόπιστο πραγματικό mesh. Αυτή η έκδοση βάζει τη σωστή βάση.":"Phone-to-phone relay at 30–80 meters is a future native feature with Wi‑Fi Direct relay. Browser/WebView alone cannot build a reliable real mesh. This version builds the correct base.","Δημοσίευση":"Post","Δημοσιεύσεις":"Posts","Νέο μήνυμα":"New message","Μήνυμα":"Message","Γράψε μήνυμα...":"Write a message...","Γράψε σχόλιο ή απάντηση...":"Write a comment or reply...","Γράψε σκέψεις, παρατηρήσεις ή συμβουλές. Το μήνυμα μένει εσωτερικά στην ΙΘΑΚΗ.":"Write thoughts, observations or advice. The message stays internally in ITHAKI.","Το μήνυμά μου προς ΙΘΑΚΗ Host...":"My message to ITHAKI Host...","Αποστολή στον Host":"Send to Host","Επικοινωνία με ΙΘΑΚΗ Host":"Contact ITHAKI Host","Θέλουμε να ακούμε τις σκέψεις, τις παρατηρήσεις και τις συμβουλές σου.":"We want to hear your thoughts, observations and advice.","Κέντρο ειδοποιήσεων":"Notification center","Δεν υπάρχουν ακόμη δημοσιεύσεις.":"No posts yet.","Δεν βρέθηκαν δημοσιεύσεις.":"No posts found.","Φόρτωση σύντομων βίντεο...":"Loading short videos...","Φόρτωση...":"Loading...","Φόρτωση σχολίων...":"Loading comments...","Φόρτωση ροής μέλους...":"Loading member feed...","Τα σχόλια δεν φορτώνουν.":"Comments do not load.","Τα μηνύματα δεν φορτώνουν":"Messages do not load","Η ροή μέλους δεν φορτώνει.":"Member feed does not load.","Οι δημοσιεύσεις μέλους δεν φορτώνουν.":"Member posts do not load.","Οι χώροι δεν φορτώνουν.":"Spaces do not load.","Δεν υπάρχουν σχόλια ακόμη. Γράψε το πρώτο.":"No comments yet. Write the first one.","Σχόλια δημοσίευσης":"Post comments","Διαγραφή δημοσίευσης;":"Delete post?","Δεν γίνεται διαγραφή":"Cannot delete","Άνοιγμα πλήρους οθόνης":"Open full screen","Έξοδος πλήρους οθόνης":"Exit full screen","Μικρή προβολή":"Small view","Άνοιγμα συνδέσμου site":"Open site link","Ο σύνδεσμος αντιγράφηκε":"Link copied","Αντιγραφή συνδέσμου":"Copy link","Αν δεν υπάρχει η εφαρμογή, ο σύνδεσμος ανοίγει στο site OK ITHAKI.":"If the app is not installed, the link opens on the OK ITHAKI site.","Εκτός εφαρμογής":"Outside the app","Ανώνυμη επικοινωνία":"Anonymous communication","Ανώνυμα":"Anonymous","Ανώνυμα ή με προφίλ":"Anonymous or with profile","Με προφίλ":"With profile","Με κωδικό μέλους":"With member code","Με πρόσκληση/έγκριση":"With invitation/approval","Πρόσκληση επαφής":"Contact invitation","Προσκλήσεις / αποδοχές":"Invitations / approvals","Η επαφή έγινε αποδεκτή":"Contact accepted","Απόρριψη":"Reject","Επίλεξε επαφή":"Choose a contact","Επίλεξε επαφή για μήνυμα.":"Choose a contact to message.","Δεν υπάρχουν ακόμη επαφές.":"No contacts yet.","Δεν υπάρχουν επαφές ακόμα.":"No contacts yet.","Διάλεξε επαφή":"Choose a contact","Ξεκίνα τη συζήτηση.":"Start the conversation.","Μενού μέλους":"Member menu","Μόνο αυτό το μέλος":"Only this member","Κοινότητες":"Communities","Δωμάτια":"Rooms","Δωμάτια / κοινότητες":"Rooms / communities","Προτεινόμενα δωμάτια":"Suggested rooms","Προτεινόμενες κοινότητες":"Suggested communities","Νέο δωμάτιο":"New room","Νέα κοινότητα":"New community","Διάλεξε χώρο":"Choose a space","Διάλεξε χώρο.":"Choose a space.","Επίλεξε χώρο":"Choose a space","Επίλεξε χώρο.":"Choose a space.","Μήνυμα σε αυτόν τον χώρο...":"Message this space...","Συνομιλίες, αρχεία, απαντήσεις":"Chats, files, replies","Βίντεο, φωτογραφίες, κείμενο":"Videos, photos, text","Κείμενο, φωτογραφία, βίντεο, αρχείο":"Text, photo, video, file","Νέα ψηφοφορία":"New poll","Δημοσίευση ψηφοφορίας":"Post poll","Ερώτηση":"Question","Θέμα ψηφοφορίας":"Poll topic","Τύπος ψηφοφορίας":"Poll type","Ναι / Όχι":"Yes / No","Δικές μου επιλογές":"My choices","Επιλογές ψηφοφορίας":"Poll options","Έτοιμη λίστα ερωτήσεων":"Ready question list","Βάλε τίτλο":"Add a title","Σύνολο ψήφων":"Total votes","Ψήφος:":"Vote:","Κωδικός διαχειριστή":"Admin code","Κωδικός μέλους":"Member code","Κωδικός/QR":"Code/QR","Άνοιγμα επικοινωνίας":"Open contact","Άδειες":"Permissions","Τι κρατά ο server":"What the server keeps","Αποθήκευση λογαριασμού":"Save account","Avatar / πολιτική / ανάκτηση":"Avatar / policy / recovery","Δεν υπάρχουν μπλοκαρισμένα μέλη.":"No blocked members.","Δεν υπάρχουν μπλοκαρισμένοι.":"No blocked members.","Μπλοκαρισμένοι":"Blocked","Σύνδεση Push / FCM":"Connect Push / FCM","Περιγραφή / κανόνες":"Description / rules","English":"English","Greek":"Greek","OK ITHAKI":"OK ITHAKI","QR":"QR","Auto: ON":"Auto: ON","Auto: OFF":"Auto: OFF","UI English":"UI English","UI Ελληνικά":"UI Ελληνικά","FFmpeg OK":"FFmpeg OK"},el:{"App language: Greek":"Γλώσσα εφαρμογής: Ελληνικά","App language: English":"Γλώσσα εφαρμογής: Αγγλικά","Menu language changes from the built-in UI dictionary and does not need Argos.":"Η γλώσσα των μενού αλλάζει από εσωτερικό λεξικό UI και δεν χρειάζεται Argos.","Argos is not needed for menus.":"Δεν χρειάζεται Argos για τα μενού.","Check FFmpeg / video":"Έλεγχος FFmpeg / βίντεο","FFmpeg missing on this laptop/server. Install FFmpeg and restart.":"Λείπει το FFmpeg από το laptop/server. Εγκατέστησέ το και κάνε restart.","FFmpeg is OK. Videos can be compressed.":"Το FFmpeg είναι OK. Τα βίντεο μπορούν να συμπιεστούν.","Video cannot be published without FFmpeg. Put ffmpeg.exe in server or PATH.":"Το βίντεο δεν φορτώνει χωρίς FFmpeg. Βάλε ffmpeg.exe στο server ή στο PATH.","Start phone microserver":"Έναρξη μικροserver κινητού","Radar phone nodes":"Ραντάρ κόμβων κινητών","Direct inbox":"Άμεσο inbox","Open hotspot settings":"Άνοιγμα ρυθμίσεων hotspot","Open Wi‑Fi settings":"Άνοιγμα ρυθμίσεων Wi‑Fi","Ask nearby Wi‑Fi permission":"Άδεια κοντινού Wi‑Fi","Phone node":"Κόμβος κινητού","Phone microserver radar":"Ραντάρ μικροserver κινητού","No phone microservers found. Open hotspot/Wi‑Fi, start microserver on each APK, then scan again.":"Δεν βρέθηκαν μικροserver κινητών. Άνοιξε hotspot/Wi‑Fi, ξεκίνα μικροserver σε κάθε APK και ξανακάνε radar.","Message to phone node":"Μήνυμα σε κόμβο κινητού","Message sent to local phone node":"Το μήνυμα στάλθηκε στον τοπικό κόμβο κινητού","No direct phone-node messages.":"Δεν υπάρχουν άμεσα μηνύματα κόμβου κινητού.","phone nodes found":"κόμβοι κινητών βρέθηκαν","phone-node inbox":"inbox κόμβου κινητού","Native status":"Κατάσταση native","Current server":"Τρέχων server","Saved local":"Αποθηκευμένο τοπικό","none":"κανένα","Emergency local network":"Τοπικό δίκτυο ανάγκης","No internet / no provider mode":"Λειτουργία χωρίς internet / πάροχο","Each phone becomes a small local ITHAKI node. One phone/laptop opens hotspot or a battery router creates Wi‑Fi. Other phones join, start their microserver, scan the radar and exchange messages. A middle phone can store and forward packets when it meets the next phone.":"Κάθε κινητό γίνεται μικρός τοπικός κόμβος ΙΘΑΚΗ. Ένα κινητό/laptop ανοίγει hotspot ή ένα battery router δημιουργεί Wi‑Fi. Τα άλλα κινητά μπαίνουν, ξεκινούν μικροserver, σαρώνουν το ραντάρ και ανταλλάσσουν μηνύματα. Ένα ενδιάμεσο κινητό μπορεί να κρατήσει και να προωθήσει πακέτα όταν συναντήσει το επόμενο κινητό.","Home":"Αρχική","Feed":"Ροή","Messages":"Μηνύματα","Chats":"Συνομιλίες","Spaces":"Χώροι","Profile":"Προφίλ","Photo":"Φωτογραφία","Video":"Βίντεο","File":"Αρχείο","Text":"Κείμενο","Poll":"Ψηφοφορία","Notifications":"Ειδοποιήσεις","Admin":"Διαχείριση","ITHAKI Host":"ΙΘΑΚΗ Host","Welcome to":"Καλώς ήρθες στο","Communicate freely, humanly and anonymously.":"Επικοινώνησε ελεύθερα, ανθρώπινα και ανώνυμα.","Wise words":"Σοφά λόγια","Protection and clean communication":"Προστασία και καθαρή επικοινωνία","Contact":"Επικοινωνία","Save":"Αποθήκευση","Recovery":"Ανάκτηση","Delete":"Διαγραφή","Open":"Άνοιγμα","Download":"Λήψη","Share":"Κοινοποίηση","Send":"Αποστολή","Back":"Πίσω","Close":"Κλείσιμο","Cancel":"Άκυρο","Ready":"Έτοιμο","Loading...":"Φόρτωση...","Post":"Δημοσίευση","Posts":"Δημοσιεύσεις","Write text...":"Γράψε κείμενο...","Write a message...":"Γράψε μήνυμα...","Choose a contact":"Διάλεξε επαφή","Choose a contact to message.":"Επίλεξε επαφή για μήνυμα.","Choose a space":"Διάλεξε χώρο","Choose a space.":"Διάλεξε χώρο.","Message this space...":"Μήνυμα σε αυτόν τον χώρο...","Rooms":"Δωμάτια","Communities":"Κοινότητες","Create":"Δημιουργία","Question":"Ερώτηση","Vote:":"Ψήφος:","Total votes":"Σύνολο ψήφων","Upload / Send":"Ανέβασμα / Αποστολή","Preview":"Προεπισκόπηση","Sending...":"Αποστολή...","Uploading":"Ανέβασμα","Compressing video...":"Συμπίεση βίντεο...","Video processing...":"Επεξεργασία βίντεο...","Video ready.":"Το βίντεο είναι έτοιμο.","Sent":"Στάλθηκε","Send again":"Στείλε ξανά","Not sent":"Δεν στάλθηκε","Add any caption you want...":"Γράψε λεζάντα αν θέλεις...","It will appear as a card and open externally.":"Θα εμφανιστεί σαν κάρτα και θα ανοίγει εξωτερικά.","to Feed":"στη Ροή","to Messages":"στα Μηνύματα","to Community / Room":"στην Κοινότητα / Δωμάτιο","here":"εδώ","Name":"Όνομα","Blocked":"Μπλοκαρισμένοι","No blocked members.":"Δεν υπάρχουν μπλοκαρισμένοι.","Save account":"Αποθήκευση λογαριασμού","What the server keeps":"Τι κρατά ο server","Permissions":"Άδειες","Translation":"Μετάφραση","Auto Greek ↔ English":"Αυτόματα Ελληνικά ↔ Αγγλικά","Menu language":"Γλώσσα μενού","Content translation":"Μετάφραση περιεχομένου","English":"English","Greek":"Greek","OK ITHAKI":"OK ITHAKI","QR":"QR","Auto: ON":"Auto: ON","Auto: OFF":"Auto: OFF","UI English":"UI English","UI Ελληνικά":"UI Ελληνικά","FFmpeg OK":"FFmpeg OK"}};

const ITH_UI_PATCH_V249141_PRIVACY={en:{
'Απομόνωση καρτέλας':'Isolate panel','Ναι':'Yes','Όχι':'No','Isolate panel':'Απομόνωση καρτέλας','Yes':'Ναι','No':'Όχι','Panel isolated':'Καρτέλα απομονωμένη','Automatic scan/reconnect is stopped. You can still press buttons manually.':'Η αυτόματη σάρωση/επανασύνδεση σταμάτησε. Μπορείς να πατάς τα κουμπιά χειροκίνητα.','Local connection panel isolated. It will not auto-scan or reconnect.':'Η καρτέλα τοπικής σύνδεσης απομονώθηκε. Δεν θα σκανάρει ούτε θα επανασυνδέεται μόνη της.','Local connection panel active.':'Η καρτέλα τοπικής σύνδεσης ενεργοποιήθηκε.','Hotspot default':'Hotspot default','Same Wi‑Fi / router repeater':'Same Wi‑Fi / router repeater','Wi‑Fi Direct ready':'Wi‑Fi Direct ready','What the server really keeps':'What the server really keeps','What the server does not keep':'What the server does not keep','Real data now':'Real data now','The server keeps only operational data needed for Feed, messages, contacts, notifications, media, limits, reports and safety. It does not require email or phone. It does not keep a full account recovery secret.':'The server keeps only operational data needed for Feed, messages, contacts, notifications, media, limits, reports and safety. It does not require email or phone. It does not keep a full account recovery secret.','No mandatory phone number, no mandatory email, no plain password, no full private recovery file, no phone contacts list, no exact GPS location. Original videos are deleted after successful FFmpeg compression when that path is used.':'No mandatory phone number, no mandatory email, no plain password, no full private recovery file, no phone contacts list, no exact GPS location. Original videos are deleted after successful FFmpeg compression when that path is used.','Could not load server snapshot.':'Could not load server snapshot.','Recent media metadata':'Recent media metadata','Recent message headers':'Recent message headers','My saved items':'My saved items','Delete saved items':'Delete saved items','Delete saved items from this device?':'Delete saved items from this device?','Saved items deleted':'Saved items deleted','No saved items.':'No saved items.','saved items on this device':'saved items on this device','Delete account':'Delete account','Delete account data from this server and this device?':'Delete account data from this server and this device?','Account deletion request completed. Restart the app.':'Account deletion request completed. Restart the app.','Server deletion failed or was partial. Local data will still be cleared.':'Server deletion failed or was partial. Local data will still be cleared.','Keep my choices':'Keep my choices','Clear choices':'Clear choices','Permission choice saved':'Permission choice saved','These are your app choices. Android may still ask system permission the first time camera, microphone, notifications or local Wi‑Fi are used.':'These are your app choices. Android may still ask system permission the first time camera, microphone, notifications or local Wi‑Fi are used.','Camera permission':'Camera permission','Ask only when I open camera/photo.':'Ask only when I open camera/photo.','Microphone permission':'Microphone permission','Ask only when I start audio/video call.':'Ask only when I start audio/video call.','Notification permission':'Notification permission','Ask only when I enable notifications.':'Ask only when I enable notifications.','Nearby Wi‑Fi permission':'Nearby Wi‑Fi permission','Ask only for local radar / hotspot / Wi‑Fi Direct features.':'Ask only for local radar / hotspot / Wi‑Fi Direct features.','Hotspot / local network':'Hotspot / local network','Remember that I prefer local hotspot/Wi‑Fi mode.':'Remember that I prefer local hotspot/Wi‑Fi mode.','Μηνύματα':'Messages','Δημοσιεύσεις Ροής':'Feed posts','Παρουσία/online':'Presence/online','Προφίλ':'Profile','Συνδρομές ειδοποιήσεων':'Notification subscriptions','Όρια μέλους':'Member limits','Χρήση media':'Media usage','Μεταδεδομένα media':'Media metadata','Προαιρετική ταυτότητα hash':'Optional identity hash','Αναφορές':'Reports'},el:{
'Isolate panel':'Απομόνωση καρτέλας','Yes':'Ναι','No':'Όχι','Panel isolated':'Καρτέλα απομονωμένη','Automatic scan/reconnect is stopped. You can still press buttons manually.':'Η αυτόματη σάρωση/επανασύνδεση σταμάτησε. Μπορείς να πατάς τα κουμπιά χειροκίνητα.','Local connection panel isolated. It will not auto-scan or reconnect.':'Η καρτέλα τοπικής σύνδεσης απομονώθηκε. Δεν θα σκανάρει ούτε θα επανασυνδέεται μόνη της.','Local connection panel active.':'Η καρτέλα τοπικής σύνδεσης ενεργοποιήθηκε.','Hotspot default':'Προεπιλογή hotspot','Same Wi‑Fi / router repeater':'Ίδιο Wi‑Fi / router αναμεταδότης','Wi‑Fi Direct ready':'Έτοιμο Wi‑Fi Direct','What the server really keeps':'Τι πραγματικά κρατά ο server','What the server does not keep':'Τι δεν κρατά ο server','Real data now':'Πραγματικά δεδομένα τώρα','The server keeps only operational data needed for Feed, messages, contacts, notifications, media, limits, reports and safety. It does not require email or phone. It does not keep a full account recovery secret.':'Ο server κρατά μόνο λειτουργικά δεδομένα που χρειάζονται για Ροή, μηνύματα, επαφές, ειδοποιήσεις, media, όρια, αναφορές και ασφάλεια. Δεν απαιτεί email ή τηλέφωνο. Δεν κρατά πλήρες μυστικό αρχείο ανάκτησης λογαριασμού.','No mandatory phone number, no mandatory email, no plain password, no full private recovery file, no phone contacts list, no exact GPS location. Original videos are deleted after successful FFmpeg compression when that path is used.':'Δεν κρατά υποχρεωτικό τηλέφωνο, υποχρεωτικό email, απλό κωδικό, πλήρες ιδιωτικό αρχείο ανάκτησης, λίστα επαφών κινητού ή ακριβή GPS θέση. Τα original βίντεο σβήνονται μετά από επιτυχημένη συμπίεση FFmpeg όταν χρησιμοποιείται αυτή η διαδρομή.','Could not load server snapshot.':'Δεν φορτώθηκε η εικόνα δεδομένων του server.','Recent media metadata':'Πρόσφατα μεταδεδομένα media','Recent message headers':'Πρόσφατες κεφαλίδες μηνυμάτων','My saved items':'Τα αποθηκευμένα μου','Delete saved items':'Διαγραφή αποθηκευμένων','Delete saved items from this device?':'Να διαγραφούν τα αποθηκευμένα από αυτή τη συσκευή;','Saved items deleted':'Τα αποθηκευμένα διαγράφηκαν','No saved items.':'Δεν υπάρχουν αποθηκευμένα.','saved items on this device':'αποθηκευμένα σε αυτή τη συσκευή','Delete account':'Διαγραφή λογαριασμού','Delete account data from this server and this device?':'Να διαγραφούν τα δεδομένα λογαριασμού από αυτόν τον server και αυτή τη συσκευή;','Account deletion request completed. Restart the app.':'Η αίτηση διαγραφής λογαριασμού ολοκληρώθηκε. Κάνε επανεκκίνηση την εφαρμογή.','Server deletion failed or was partial. Local data will still be cleared.':'Η διαγραφή στον server απέτυχε ή ήταν μερική. Τα τοπικά δεδομένα θα καθαριστούν.','Keep my choices':'Να κρατά τις επιλογές μου','Clear choices':'Καθαρισμός επιλογών','Permission choice saved':'Η επιλογή άδειας αποθηκεύτηκε','These are your app choices. Android may still ask system permission the first time camera, microphone, notifications or local Wi‑Fi are used.':'Αυτές είναι οι επιλογές της εφαρμογής. Το Android μπορεί ακόμη να ζητήσει άδεια συστήματος την πρώτη φορά που θα χρησιμοποιηθεί κάμερα, μικρόφωνο, ειδοποιήσεις ή τοπικό Wi‑Fi.','Camera permission':'Άδεια κάμερας','Ask only when I open camera/photo.':'Να ζητείται μόνο όταν ανοίγω κάμερα/φωτογραφία.','Microphone permission':'Άδεια μικροφώνου','Ask only when I start audio/video call.':'Να ζητείται μόνο όταν ξεκινώ ήχο/βιντεοκλήση.','Notification permission':'Άδεια ειδοποιήσεων','Ask only when I enable notifications.':'Να ζητείται μόνο όταν ενεργοποιώ ειδοποιήσεις.','Nearby Wi‑Fi permission':'Άδεια κοντινού Wi‑Fi','Ask only for local radar / hotspot / Wi‑Fi Direct features.':'Να ζητείται μόνο για ραντάρ τοπικού δικτύου / hotspot / Wi‑Fi Direct.','Hotspot / local network':'Hotspot / τοπικό δίκτυο','Remember that I prefer local hotspot/Wi‑Fi mode.':'Να θυμάται ότι προτιμώ τοπικό hotspot/Wi‑Fi.','Messages':'Μηνύματα','Feed posts':'Δημοσιεύσεις Ροής','Presence/online':'Παρουσία/online','Profile':'Προφίλ','Notification subscriptions':'Συνδρομές ειδοποιήσεων','Member limits':'Όρια μέλους','Media usage':'Χρήση media','Media metadata':'Μεταδεδομένα media','Optional identity hash':'Προαιρετική ταυτότητα hash','Reports':'Αναφορές'}};
Object.assign(ITH_UI_EN, ITH_UI_PATCH_V249141_PRIVACY.en);
Object.assign(ITH_UI_EL, ITH_UI_PATCH_V249141_PRIVACY.el);
Object.assign(ITH_UI_EN,{'Answer':'Answer','End call':'End call','Incoming call':'Incoming call','Calling...':'Calling...','Connecting...':'Connecting...','Connected':'Connected','Call ended':'Call ended','Call connection failed':'Call connection failed','Call disconnected':'Call disconnected','Call not accepted':'Call not accepted','A call is already active.':'A call is already active.'});
Object.assign(ITH_UI_EL,{'Answer':'Απάντηση','End call':'Τερματισμός κλήσης','Incoming call':'Εισερχόμενη κλήση','Calling...':'Κλήση...','Connecting...':'Σύνδεση...','Connected':'Συνδέθηκε','Call ended':'Η κλήση τερματίστηκε','Call connection failed':'Η σύνδεση κλήσης απέτυχε','Call disconnected':'Η κλήση αποσυνδέθηκε','Call not accepted':'Η κλήση δεν έγινε αποδεκτή','A call is already active.':'Υπάρχει ήδη ενεργή κλήση.'});
Object.assign(ITH_UI_EN,{'Record audio':'Record audio','Stop recording':'Stop recording','Cancel recording':'Cancel recording','Recording audio...':'Recording audio...','Take photo':'Take photo','Record video':'Record video','Choose destination first.':'Choose a conversation, room or community first.'});
Object.assign(ITH_UI_EL,{'Record audio':'Εγγραφή ήχου','Stop recording':'Τέλος εγγραφής','Cancel recording':'Ακύρωση εγγραφής','Recording audio...':'Γίνεται εγγραφή ήχου...','Take photo':'Λήψη φωτογραφίας','Record video':'Εγγραφή βίντεο','Choose destination first.':'Επίλεξε πρώτα συνομιλία, δωμάτιο ή κοινότητα.'});
Object.assign(ITH_UI_EN, ITH_UI_PATCH_V249141.en);
Object.assign(ITH_UI_EL, ITH_UI_PATCH_V249141.el);

Object.assign(ITH_UI_EN,{
  'Video uploaded. Processing on server.':'Video uploaded. Processing on server.','Video uploaded. Waiting for final video URL before publishing.':'Video uploaded. Waiting for final video URL before publishing.',
  'Video uploaded to server. It will appear here when ready.':'Video uploaded to server. It will appear here when ready.',
  'The post is visible now; server is preparing the video.':'The post is visible now; server is preparing the video.',
  'Check video status':'Check video status',
  'Still processing...':'Still processing...',
  'Video is ready':'Video is ready',
  'Video failed':'Video failed',
  'Small fallback video published without compression.':'Small fallback video published without compression.',
  'Close local network':'Close local network',
  'Selected':'Selected'
});
Object.assign(ITH_UI_EL,{
  'Video uploaded. Processing on server.':'Το βίντεο ανέβηκε. Ο server το ετοιμάζει.',
  'Video uploaded to server. It will appear here when ready.':'Το βίντεο ανέβηκε στον server. Θα εμφανιστεί εδώ όταν ετοιμαστεί.',
  'The post is visible now; server is preparing the video.':'Η δημοσίευση φαίνεται τώρα· ο server ετοιμάζει το βίντεο.',
  'Check video status':'Έλεγχος κατάστασης βίντεο',
  'Still processing...':'Ακόμη γίνεται επεξεργασία...',
  'Video is ready':'Το βίντεο είναι έτοιμο',
  'Video failed':'Το βίντεο απέτυχε',
  'Small fallback video published without compression.':'Μικρό βίντεο δημοσιεύτηκε χωρίς συμπίεση.',
  'Close local network':'Κλείσιμο τοπικού δικτύου',
  'Selected':'Επιλεγμένο'
});

Object.assign(ITH_UI_EN,{
  "Travel freely.":"Travel with us, humanly, freely, anonymously.",
  "One wise word for this hour":"One wise word for this hour",
  "People meet more honestly when the path is simple and respectful.":"People meet more honestly when the path is simple and respectful.",
  "Good communication does not shout; it opens a safe road.":"Good communication does not shout; it opens a safe road.",
  "Freedom needs respect, patience and a clear way back.":"Freedom needs respect, patience and a clear way back.",
  "A message can travel farther when people become bridges.":"A message can travel farther when people become bridges.",
  "Protection panel":"Protection panel",
  "Professional protection for clean communication":"Professional protection for clean communication",
  "BotGuard, rate limits and local privacy tools protect the conversation without asking for phone or email.":"BotGuard, rate limits and local privacy tools protect the conversation without asking for phone or email.",
  "The server keeps only what the app needs for feed, messages, media, safety and moderation.":"The server keeps only what the app needs for feed, messages, media, safety and moderation.",
  "Professional poll":"Professional poll",
  "Quick community question":"Quick community question",
  "What should ITHAKI improve first today?":"What should ITHAKI improve first today?",
  "Better video feed":"Better video feed",
  "Cleaner messages":"Cleaner messages",
  "More local network tools":"More local network tools",
  "Better privacy controls":"Better privacy controls",
  "Professional thought":"Professional thought",
  "This card appears after videos only once per day, so it does not cover the feed again and again.":"This card appears after videos only once per day, so it does not cover the feed again and again.",
  "Hide this card":"Hide this card",
  "Voice call":"Voice call",
  "Video call":"Video call",
  "Camera message":"Camera message",
  "Private lock":"Private lock",
  "Choose a contact first.":"Choose a contact first.",
  "Voice call request sent.":"Voice call request sent.",
  "Video call request sent.":"Video call request sent.",
  "Secure key panel opened.":"Secure key panel opened.",
  "Call request":"Call request",
  "wants to call you":"wants to call you",
  "Video call started on the server.":"Video call started on the server.",
  "If the full call screen is not ready on this device, the other member still receives a clear call request message.":"If the full call screen is not ready on this device, the other member still receives a clear call request message.",
  "Poll type":"Poll type",
  "My choices":"My choices",
  "Yes / No":"Yes / No",
  "Ready question list":"Ready question list",
  "Poll topic":"Poll topic",
  "Question":"Question",
  "Write the question clearly...":"Write the question clearly...",
  "Poll options":"Poll options",
  "option":"option",
  "Write option":"Write option",
  "Anonymous":"Anonymous",
  "With profile":"With profile",
  "Post to Feed":"Post to Feed",
  "Post poll":"Post poll",
  "members voted":"members voted",
  "Percentages will appear after posting and voting.":"Percentages will appear after posting and voting.",
  "Use the same shared key on both devices to decrypt private messages.":"Use the same shared key on both devices to decrypt private messages.",
  "Shared secret key":"Shared secret key",
  "Enable E2E":"Enable E2E",
  "Turn off E2E":"Turn off E2E",
  "Server test OK":"Server test OK",
  "server test failed":"server test failed"
});
Object.assign(ITH_UI_EL,{
  "Travel freely.":"Ταξιδέψτε μαζί μας ανθρώπινα, ελεύθερα, ανώνυμα.",
  "One wise word for this hour":"Ένας σοφός λόγος για αυτή την ώρα",
  "People meet more honestly when the path is simple and respectful.":"Οι άνθρωποι συναντιούνται πιο αληθινά όταν ο δρόμος είναι απλός και με σεβασμό.",
  "Good communication does not shout; it opens a safe road.":"Η καλή επικοινωνία δεν φωνάζει· ανοίγει έναν ασφαλή δρόμο.",
  "Freedom needs respect, patience and a clear way back.":"Η ελευθερία θέλει σεβασμό, υπομονή και καθαρό δρόμο επιστροφής.",
  "A message can travel farther when people become bridges.":"Ένα μήνυμα ταξιδεύει πιο μακριά όταν οι άνθρωποι γίνονται γέφυρες.",
  "Protection panel":"Πάνελ προστασίας",
  "Professional protection for clean communication":"Επαγγελματική προστασία για καθαρή επικοινωνία",
  "BotGuard, rate limits and local privacy tools protect the conversation without asking for phone or email.":"BotGuard, όρια ασφαλείας και τοπικά εργαλεία ιδιωτικότητας προστατεύουν τη συζήτηση χωρίς να ζητούν τηλέφωνο ή email.",
  "The server keeps only what the app needs for feed, messages, media, safety and moderation.":"Ο server κρατά μόνο ό,τι χρειάζεται η εφαρμογή για ροή, μηνύματα, media, ασφάλεια και διαχείριση.",
  "Professional poll":"Επαγγελματική ψηφοφορία",
  "Quick community question":"Γρήγορη ερώτηση κοινότητας",
  "What should ITHAKI improve first today?":"Τι πρέπει να βελτιώσει πρώτη σήμερα η ΙΘΑΚΗ;",
  "Better video feed":"Καλύτερη ροή βίντεο",
  "Cleaner messages":"Καθαρότερα μηνύματα",
  "More local network tools":"Περισσότερα εργαλεία τοπικού δικτύου",
  "Better privacy controls":"Καλύτεροι έλεγχοι ιδιωτικότητας",
  "Professional thought":"Επαγγελματικός στοχασμός",
  "This card appears after videos only once per day, so it does not cover the feed again and again.":"Αυτή η κάρτα εμφανίζεται μετά από βίντεο μόνο μία φορά την ημέρα, για να μη σκεπάζει ξανά και ξανά τη ροή.",
  "Hide this card":"Απόκρυψη κάρτας",
  "Voice call":"Κλήση φωνής",
  "Video call":"Βιντεοκλήση",
  "Camera message":"Μήνυμα κάμερας",
  "Private lock":"Ιδιωτική κλειδαριά",
  "Choose a contact first.":"Διάλεξε πρώτα μία επαφή.",
  "Voice call request sent.":"Στάλθηκε αίτημα κλήσης φωνής.",
  "Video call request sent.":"Στάλθηκε αίτημα βιντεοκλήσης.",
  "Secure key panel opened.":"Άνοιξε η καρτέλα ασφαλούς κλειδιού.",
  "Call request":"Αίτημα κλήσης",
  "wants to call you":"θέλει να σε καλέσει",
  "Video call started on the server.":"Η βιντεοκλήση ξεκίνησε στον server.",
  "If the full call screen is not ready on this device, the other member still receives a clear call request message.":"Αν η πλήρης οθόνη κλήσης δεν είναι έτοιμη σε αυτή τη συσκευή, το άλλο μέλος λαμβάνει καθαρό μήνυμα αιτήματος κλήσης.",
  "Poll type":"Τύπος ψηφοφορίας",
  "My choices":"Οι επιλογές μου",
  "Yes / No":"Ναι / Όχι",
  "Ready question list":"Έτοιμη λίστα ερωτήσεων",
  "Poll topic":"Θέμα ψηφοφορίας",
  "Question":"Ερώτηση",
  "Write the question clearly...":"Γράψε καθαρά την ερώτηση...",
  "Poll options":"Επιλογές ψηφοφορίας",
  "option":"επιλογή",
  "Write option":"Γράψε επιλογή",
  "Anonymous":"Ανώνυμα",
  "With profile":"Με προφίλ",
  "Post to Feed":"Δημοσίευση στη Ροή",
  "Post poll":"Δημοσίευση ψηφοφορίας",
  "members voted":"μέλη ψήφισαν",
  "Percentages will appear after posting and voting.":"Τα ποσοστά θα εμφανιστούν μετά τη δημοσίευση και την ψήφο.",
  "Use the same shared key on both devices to decrypt private messages.":"Χρησιμοποίησε το ίδιο κοινό κλειδί και στις δύο συσκευές για αποκρυπτογράφηση ιδιωτικών μηνυμάτων.",
  "Shared secret key":"Κοινό μυστικό κλειδί",
  "Enable E2E":"Ενεργοποίηση E2E",
  "Turn off E2E":"Απενεργοποίηση E2E",
  "Server test OK":"Έλεγχος server OK",
  "server test failed":"ο έλεγχος server απέτυχε"
});

function shouldSkipUiI18nNode(n){try{const e=n&&n.nodeType===3?n.parentElement:n;if(!e)return true;if(e.closest('#feedPage .textClamp,#feedPage .translatedText,#feedPage .commentText,#messages .bubble,#spaceMsgs .bubble,#memberMenu .bubble,#phoneNodeInboxBox .bubble,#meshInboxBox .bubble,textarea,input,script,style'))return true;return false}catch{return true}}
function trUiString(raw){const s=String(raw??'');const trimmed=s.trim();if(!trimmed)return s;const map=uiLang()==='el'?ITH_UI_EL:ITH_UI_EN;let out=map[trimmed];if(!out){out=map[s]}
  if(!out){return s}
  const lead=(s.match(/^\s*/)||[''])[0], tail=(s.match(/\s*$/)||[''])[0];return lead+out+tail}
function translateUiTextNodes(root){try{const roots=[];if(root&&root.nodeType===1)roots.push(root);['top','nav','plusSheet','memberMenu','homePage','createPage','profilePage','spacesPage','dmPage','previewModal','toast'].forEach(id=>{const el=$(id);if(el)roots.push(el)});const seen=new Set();for(const r of roots){if(!r||seen.has(r))continue;seen.add(r);const w=document.createTreeWalker(r,NodeFilter.SHOW_TEXT,{acceptNode:n=>shouldSkipUiI18nNode(n)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT});let n;while((n=w.nextNode())){const old=n.nodeValue;const neu=trUiString(old);if(neu!==old)n.nodeValue=neu}}}catch(e){console.warn('ui text node patch',e)}}
function scheduleUiLanguagePatch(){try{clearTimeout(window.__ithUiLangPatchTimer);window.__ithUiLangPatchTimer=setTimeout(()=>applyUiLanguagePatch(),60)}catch{}}
function startUiLanguageObserver(){try{if(window.__ithUiLangObserver)return;window.__ithUiLangObserver=new MutationObserver(()=>scheduleUiLanguagePatch());window.__ithUiLangObserver.observe(document.body,{childList:true,subtree:true,characterData:false});}catch(e){console.warn('ui observer',e)}}

function readRequestedUiLang(){try{const q=new URL(location.href).searchParams.get('lang');if(q==='el'||q==='en')return q}catch{}return''}
function uiLang(){try{const q=readRequestedUiLang();if(q)return q;return localStorage.getItem(UI_LANG_KEY)==='el'?'el':'en'}catch{return'en'}}
function renderTopLang(){try{const lang=uiLang();document.documentElement.lang=lang;if(document.body)document.body.setAttribute('data-ui-lang',lang);const box=$('topLangSwitch');if(box){box.querySelectorAll('button[data-lang]').forEach(b=>b.classList.toggle('active',b.dataset.lang===lang));const en=box.querySelector('[data-lang="en"]');const el=box.querySelector('[data-lang="el"]');if(en)en.textContent='English';if(el)el.textContent='Ελληνικά'}applyUiLanguagePatch()}catch{}}
function setUiLang(lang){const next=lang==='el'?'el':'en';try{localStorage.setItem(UI_LANG_KEY,next);localStorage.setItem(UI_LANG_MANUAL_KEY,'1');localStorage.setItem('ith_ui_lang',next);localStorage.setItem('ith_ui_lang_manual','1');localStorage.removeItem('ith_target_lang');const u=new URL(location.href);u.searchParams.set('lang',next);u.searchParams.set('v',(window.ITHAKI_ACTIVE_VERSION||'249526r10f38'));u.searchParams.delete('_');history.replaceState(null,'',u.toString())}catch{}renderTopLang();renderNav();applyScreenTheme();rerenderCurrentPage();setTimeout(applyUiLanguagePatch,40);toast(next==='el'?'Γλώσσα εφαρμογής: Ελληνικά':'App language: English');return false}
function rerenderCurrentPage(){const p=state.page||'home';try{if(p==='home')renderHome();else if(p==='create')renderCreate();else if(p==='dm')openDM();else if(p==='spaces'){const f=window.ITH&&ITH.activateSpacesPageV249516;if(typeof f==='function')f();else if(window.__ITHAKI_V249517_COMMUNITY_SINGLE_OWNER__){document.documentElement.setAttribute('data-ithaki-community-r7-pending','1');const e=$('spacesPage');if(e)e.innerHTML='<div class="card">Φόρτωση κοινοτήτων…</div>'}else renderSpaces();}else if(p==='profile')renderProfile();else if(p==='feed')loadFeed()}catch(e){console.warn('rerender language',e)}}
function applyUiLanguagePatch(){try{const lang=uiLang();const map=lang==='el'?ITH_UI_EL:ITH_UI_EN;document.documentElement.lang=lang;if(document.body)document.body.setAttribute('data-ui-lang',lang);document.querySelectorAll('input[placeholder],textarea[placeholder]').forEach(el=>{if(shouldSkipUiI18nNode(el))return;const raw=el.getAttribute('placeholder')||'';const tr=map[raw]||map[raw.trim()];if(tr)el.setAttribute('placeholder',tr)});document.querySelectorAll('[data-i18n]').forEach(el=>{const k=el.getAttribute('data-i18n')||'';if(map[k])el.textContent=map[k]});document.querySelectorAll('button,small,label,span,b,h1,h2,h3,div.date,div.proFooter,.btn,.tile').forEach(el=>{try{if(shouldSkipUiI18nNode(el))return;if(el.children&&el.children.length>2)return;const raw=(el.textContent||'').trim();if(!raw||raw.length>260)return;const tr=map[raw];if(tr&&tr!==raw)el.textContent=tr}catch(e){}});translateUiTextNodes(document.body)}catch(e){console.warn('applyUiLanguagePatch',e)}}
function uiText(s){const key=String(s??'');return uiLang()==='el'?(ITH_UI_EL[key]||key):(ITH_UI_EN[key]||key)}
const SCREEN_THEME_KEY='ith_screen_theme_v249145';
const SCREEN_THEME_META={auto:{icon:'◐',label:'Automatic'},mountain:{icon:'🏔️',label:'Morning · Mountain'},sea:{icon:'🌊',label:'Midday · Sea'},sunset:{icon:'🌅',label:'Afternoon · Sunset'},night:{icon:'🌙',label:'Night'}};
function automaticScreenTheme(hour=(new Date()).getHours()){if(hour>=5&&hour<11)return'mountain';if(hour>=11&&hour<17)return'sea';if(hour>=17&&hour<21)return'sunset';return'night'}
function selectedScreenTheme(){try{const v=localStorage.getItem(SCREEN_THEME_KEY)||'auto';return SCREEN_THEME_META[v]?v:'auto'}catch{return'auto'}}
function applyScreenTheme(mode=selectedScreenTheme()){mode=SCREEN_THEME_META[mode]?mode:'auto';state.screenTheme=mode;const actual=mode==='auto'?automaticScreenTheme():mode;if(document.body){document.body.dataset.screenTheme=actual;document.body.dataset.screenThemeMode=mode}const b=$('screenThemeBtn');if(b){b.textContent=SCREEN_THEME_META[actual].icon;b.title=uiText(mode==='auto'?'Automatic screen theme':SCREEN_THEME_META[mode].label);b.setAttribute('aria-label',b.title)}const meta=document.querySelector('meta[name="theme-color"]');if(meta)meta.content=actual==='mountain'?'#253f50':actual==='sea'?'#075b78':actual==='sunset'?'#5a274d':'#071321';return actual}
function setScreenTheme(mode){if(!SCREEN_THEME_META[mode])mode='auto';try{localStorage.setItem(SCREEN_THEME_KEY,mode)}catch{}applyScreenTheme(mode);openScreenThemePanel();toast(mode==='auto'?uiText('Automatic screen theme')+': '+uiText(SCREEN_THEME_META[automaticScreenTheme()].label):uiText(SCREEN_THEME_META[mode].label));return false}
function openScreenThemePanel(){const selected=selectedScreenTheme();const item=(key,sub)=>`<button class="themeChoice ${selected===key?'active':''}" onclick="ITH.setScreenTheme('${key}')"><span class="themeChoiceIcon">${SCREEN_THEME_META[key].icon}</span><span><b>${uiText(SCREEN_THEME_META[key].label)}</b><small>${uiText(sub)}</small></span><i>${selected===key?'✓':''}</i></button>`;$('memberMenu').innerHTML=`<div class="row themePanelHead"><b>🎨 ${uiText('Screen appearance')}</b><button class="icon localCloseBtn" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card themeAutoNote">${uiText('Automatic changes the screen by local time without changing any app function.')}</div><div class="themeChoiceList">${item('auto','Changes automatically by time')}${item('mountain','05:00–10:59')}${item('sea','11:00–16:59')}${item('sunset','17:00–20:59')}${item('night','21:00–04:59')}</div>`;$('memberMenu').classList.add('show','themePanel');applyUiLanguagePatch();return false}
function targetLang(text=''){const src=detectLangSmart(text);return src==='el'?'en':'el'}
function autoTranslateOn(){return localStorage.getItem('ith_auto_translate')==='1'}
function stripAccentsEl(s){return String(s||'').normalize('NFD').replace(/[\u0300-\u036f]/g,'')}
function looseGreekKey(s){let v=stripAccentsEl(String(s||'').toLowerCase()).replace(/ς/g,'σ');[['ει','ι'],['οι','ι'],['υι','ι'],['η','ι'],['υ','ι'],['ω','ο'],['αι','ε']].forEach(p=>{v=v.split(p[0]).join(p[1])});return v}
function detectLangSmart(text){const s=String(text||'');let gr=0,lat=0;for(const ch of s){if(ch>='α'&&ch<='ω'||ch>='Α'&&ch<='Ω')gr++;else if(/[A-Za-z]/.test(ch))lat++}if(gr===0&&lat===0)return 'en';if(gr/(gr+lat)>=0.20)return 'el';return 'en'}
function oppositeLang(text){return detectLangSmart(text)==='el'?'en':'el'}
function dictLookupWord(w,dst){const raw=String(w||'');const low=raw.toLowerCase();if(ITH_FALLBACK_DICT[low])return ITH_FALLBACK_DICT[low];if(detectLangSmart(raw)==='el'){const key=looseGreekKey(raw);for(const k in ITH_FALLBACK_DICT){if(looseGreekKey(k)===key)return ITH_FALLBACK_DICT[k]}}return raw}
function fallbackTranslate(text,dst=''){const target=dst||oppositeLang(text);let changed=false;const out=String(text||'').split(/(\s+|[.,!?;:()\[\]{}"'«»]+)/).map(tok=>{if(!tok||/^\s+$/.test(tok)||/^[.,!?;:()\[\]{}"'«»]+$/.test(tok))return tok;const tr=dictLookupWord(tok,target);if(tr!==tok)changed=true;return tr}).join('');return changed?out:String(text||'')}
function translationPick(r,text,dst){const vals=[r&&r.translated,r&&r.translated_text,r&&r.translation,r&&r.text_out,r&&r.output,r&&r.result].filter(x=>typeof x==='string'&&x.trim());let best=vals.find(x=>x.trim()!==String(text).trim())||'';if(!best)best=fallbackTranslate(text,dst);if((!best||best===String(text||''))&&r&&(r.provider==='unknown-kept-original-logged'||r.action_required)){return uiText(r.message||'Offline translation model missing on this laptop. Run 02_INSTALL_ARGOS_EN_EL_OFFLINE_MODEL.cmd and restart.')}return best||text}
function translateBlock(id,text){const safe=String(text||'').trim();if(!safe)return;const out=$('tr_'+id);if(out)out.innerHTML='<span class="date">'+uiText('Offline translation...')+'</span>';translateText(safe).then(tt=>{const o=$('tr_'+id);if(o)o.innerHTML=`<div class="translatedText">🌐 ${esc(tt)}</div>`}).catch(()=>{const o=$('tr_'+id);if(o)o.innerHTML=`<div class="translatedText">🌐 ${esc(fallbackTranslate(safe))}</div>`})}
async function translateText(text){const dst=targetLang(text)||oppositeLang(text);try{const r=await fetchJson('/api/bridge/translate',{method:'POST',body:JSON.stringify({text,source_lang:'auto',target_lang:dst,allow_external:false,translation_mode:'offline',mode:'offline'})});return translationPick(r,text,dst)}catch(e){return fallbackTranslate(text,dst)}}
function translateControls(id,text){const clean=esc(String(text||'').slice(0,1200));return `<div class="translateTools"><button class="btn mini" onclick="ITH.translateBlock('${esc(id)}', \`${clean.replace(/`/g,'\\`')}\`)">🌐 ${uiText('Translate')}</button><span id="tr_${esc(id)}" class="translateOut"></span></div>`}
function maybeAutoTranslate(id,text){if(autoTranslateOn())setTimeout(()=>translateBlock(id,text),80)}
function toggleAutoTranslate(){const v=!autoTranslateOn();localStorage.setItem('ith_auto_translate',v?'1':'0');state.autoTranslate=v;toast(v?'Auto-translate ON':'Auto-translate OFF');renderProfile()}
function setTargetLang(lang){try{localStorage.removeItem('ith_target_lang')}catch{}state.contentTarget='auto';toast(uiText('Content translation is automatic: Greek ↔ English'));renderProfile()}
function ithakiVideoSoundUnlocked(){try{return localStorage.getItem('ith_video_sound_enabled_v249220')!=='0'}catch{return true}}
function setIthakiVideoSoundUnlocked(on=true){try{localStorage.setItem('ith_video_sound_enabled_v249220',on?'1':'0')}catch{};document.body.classList.toggle('videoSoundOnV249220',!!on)}
function enableVideoSoundV249220(video){setIthakiVideoSoundUnlocked(true);document.querySelectorAll('video').forEach(v=>{try{v.muted=false;v.volume=1;v.removeAttribute('muted')}catch{}});if(video){try{video.muted=false;video.volume=1;video.removeAttribute('muted');video.play&&video.play().catch(()=>{})}catch{}};toast(uiText('Video sound is on.'))}
function decorateFeedVideoSoundV249220(v){if(!v||v.dataset.soundFixV249220)return;v.dataset.soundFixV249220='1';try{v.controls=true;v.playsInline=true;v.preload='auto';v.volume=1;if(ithakiVideoSoundUnlocked()){v.muted=false;v.removeAttribute('muted')}}catch{};v.addEventListener('click',()=>enableVideoSoundV249220(v),{passive:true});v.addEventListener('volumechange',()=>{try{if(!v.muted&&v.volume>0)setIthakiVideoSoundUnlocked(true)}catch{}},{passive:true});const btn=document.createElement('button');btn.className='videoSoundFloatV249220';btn.type='button';btn.textContent='🔊 Ήχος';btn.onclick=(ev)=>{ev.preventDefault();ev.stopPropagation();enableVideoSoundV249220(v)};try{const wrap=v.closest('.mediaInline')||v.parentElement;if(wrap&&!wrap.querySelector('.videoSoundFloatV249220'))wrap.appendChild(btn)}catch{}}
function stopAllMedia(){document.querySelectorAll('video,audio').forEach(v=>{try{v.pause(); if(!ithakiVideoSoundUnlocked()) v.muted=true}catch{}})}
function activateFeedVideos(){const vids=[...document.querySelectorAll('#feedPage video.feedVideo')];if(!vids.length)return;vids.forEach(decorateFeedVideoSoundV249220);if(!('IntersectionObserver' in window)){vids.forEach(v=>{try{v.muted=!ithakiVideoSoundUnlocked();v.volume=1}catch{}});return}if(state.feedObserver){try{state.feedObserver.disconnect()}catch{}}state.feedObserver=new IntersectionObserver(entries=>{entries.forEach(en=>{const v=en.target;if(en.isIntersecting&&en.intersectionRatio>0.62){vids.forEach(o=>{if(o!==v){try{o.pause(); if(!ithakiVideoSoundUnlocked()) o.muted=true}catch{}}});try{v.muted=!ithakiVideoSoundUnlocked();v.volume=1;if(ithakiVideoSoundUnlocked())v.removeAttribute('muted');const p=v.play();if(p&&p.catch)p.catch(()=>{try{v.muted=false;v.volume=1;v.removeAttribute('muted')}catch{}})}catch{}}else{try{v.pause(); if(!ithakiVideoSoundUnlocked()) v.muted=true}catch{}}})},{threshold:[0,0.35,0.62,0.9]});vids.forEach(v=>state.feedObserver.observe(v))}
function showFeedOnly(){try{window.ITH?.startFeedBackgroundV249545?.('core-show-feed')}catch(e){}stopAllMedia();state.page='feed';if(document.body)document.body.setAttribute('data-page','feed');document.querySelectorAll('.page').forEach(p=>p.classList.remove('active'));const el=$('feedPage');if(el)el.classList.add('active');document.querySelectorAll('.nav button').forEach(b=>b.classList.toggle('active',b.dataset.page==='feed'));$('plusSheet')?.classList.remove('show')}
function page(id){id=String(id||'home');try{window.ITH?.closeTransientScreensR10F26?.('core-page-'+id)}catch(e){}const previous=String(state.page||document.body?.dataset.page||'home');try{if(previous==='feed'&&id!=='feed')window.ITH?.stopFeedBackgroundV249545?.('core-page-'+id)}catch(e){}stopAllMedia();state.page=id;window.__ITHAKI_CORE_STATE__=state;window.state=state;window.ITH=window.ITH||{};window.ITH.state=state;if(document.body)document.body.setAttribute('data-page',id);document.querySelectorAll('.page').forEach(p=>p.classList.remove('active'));const el=$(id+'Page');if(el)el.classList.add('active');document.querySelectorAll('.nav button').forEach(b=>b.classList.toggle('active',b.dataset.page===id));$('plusSheet')?.classList.remove('show');if(id==='feed'&&typeof window.__ITHAKI_ENTER_FEED_V249357__==='function')return window.__ITHAKI_ENTER_FEED_V249357__();if(id==='home')renderHome();else if(id==='feed'){const f=window.__ITHAKI_CANONICAL_FEED_V249357__;return typeof f==='function'?f():false}else if(id==='create')renderCreate();else if(id==='dm')openDM();else if(id==='spaces'){document.documentElement.setAttribute('data-ithaki-community-r7-pending','1');const f=window.ITH&&ITH.activateSpacesPageV249516;if(typeof f==='function')return f();if(window.__ITHAKI_V249517_COMMUNITY_SINGLE_OWNER__){const e=$('spacesPage');if(e)e.innerHTML='<div class="card">Φόρτωση κοινοτήτων…</div>';return false}renderSpaces();}else if(id==='profile')renderProfile();try{window.dispatchEvent(new CustomEvent('ithaki:page-changed',{detail:{page:id,version:'V249411'}}))}catch(e){}return false}
/* BEGIN V249412_DIRECT_CREATE_PLUS_STABLE */
window.__ITHAKI_V249412_DIRECT_CREATE_PLUS_STABLE__=true;
/* END V249412_DIRECT_CREATE_PLUS_STABLE */

function renderNav(){const n=$('nav');if(!n)return;const msgCount=getMessageNoticeCount();n.innerHTML=[['home','🏠',uiText('Home'),0],['feed','🎬',uiText('Feed'),0],['plus','＋','',0],['dm','💬',uiText('Messages'),msgCount],['spaces','🏘️',uiText('Spaces'),0],['profile','👤',uiText('Profile'),0]].map(x=>`<button class="${x[0]==='plus'?'plus':''}" data-page="${x[0]}"><span>${x[1]}</span>${x[2]?`<small>${x[2]}</small>`:''}${x[3]?`<i class="navBadge">${x[3]>9?'9+':x[3]}</i>`:''}</button>`).join('');n.onclick=e=>{const b=e.target.closest('button');if(!b)return;if(b.dataset.page==='plus'){if(window.ITH&&typeof ITH.openPlusMenuV249415==='function')return ITH.openPlusMenuV249415('nav');return togglePlus()}return page(b.dataset.page)}}
function refreshNavBadges(){renderNav();renderTopLang()}
function getMessageNoticeCount(){try{return localNotices().filter(n=>!n.read&&(n.type==='message'||n.type==='contact_invite')).length}catch{return 0}}
function currentMediaDestination(){if(state.page==='dm')return state.activeChannel?{ctx:'dm',target:state.activeChannel}:null;if(state.page==='spaces')return state.currentSpaceChannel?{ctx:'space',target:state.currentSpaceChannel}:null;return {ctx:'feed',target:''}}
function requireMediaDestination(){const d=currentMediaDestination();if(!d)toast(uiText('Choose destination first.'));return d}
function togglePlus(){const s=$('plusSheet');if(!s)return;const d=currentMediaDestination();const where=d?(d.ctx==='dm'?uiText('to Messages'):d.ctx==='space'?uiText('to Community / Room'):uiText('to Feed')):'';s.innerHTML=`<div class="date" style="grid-column:1/-1;text-align:center">${esc(where)}</div><button class="tile" data-act="camera_photo"><b>📷</b>${uiText('Take photo')}</button><button class="tile" data-act="camera_video"><b>🎥</b>${uiText('Record video')}</button><button class="tile" data-act="audio"><b>🎙️</b>${uiText('Record audio')}</button><button class="tile" data-act="file"><b>📎</b>${uiText('File')}</button><button class="tile" data-act="gallery_photo"><b>🖼️</b>${uiText('Photo')}</button><button class="tile" data-act="gallery_video"><b>📼</b>${uiText('Video')}</button><button class="tile" data-act="text"><b>📝</b>${uiText('Text')}</button><button class="tile" data-act="poll"><b>📊</b>${uiText('Poll')}</button><button class="tile" data-act="room"><b>🏘️</b>${uiText('Spaces')}</button><button class="tile" data-act="notify"><b>🔔</b>${uiText('Notifications')}</button><button class="tile" data-act="qr"><b>▦</b>QR</button><button class="tile" data-act="host"><b>🌊</b>${uiText('ITHAKI Host')}</button>`;s.classList.toggle('show')}
function bindPlus(){const s=$('plusSheet');if(!s)return;s.onclick=e=>{const b=e.target.closest('[data-act]');if(!b)return;s.classList.remove('show');const a=b.dataset.act;if(a==='poll')return openPoll();if(a==='room')return page('spaces');if(a==='notify')return notifyCenter();if(a==='qr')return showQR();if(a==='host')return openHostContact();if(a==='text')return page('create');const d=requireMediaDestination();if(!d)return;if(a==='camera_photo')return captureMedia(d.ctx,'photo',d.target);if(a==='camera_video')return captureMedia(d.ctx,'video',d.target);if(a==='audio')return startAudioRecording(d.ctx,d.target);if(a==='gallery_photo')return chooseFile(d.ctx,'photo',d.target);if(a==='gallery_video')return chooseFile(d.ctx,'video',d.target);chooseFile(d.ctx,'file',d.target)}}

function injectV249169LaunchCss(){
  try{
    if(document.getElementById('ithV249169LaunchCss'))return;
    const st=document.createElement('style');
    st.id='ithV249169LaunchCss';
    st.textContent=`
      #homePage{padding-top:0!important}
      .topStoryBarV249169,.topStoryBarV249169{
        position:sticky;top:0;z-index:35;margin:-8px -10px 10px!important;
        padding:7px 8px 6px!important;border-radius:0 0 18px 18px!important;
        background:linear-gradient(180deg,rgba(3,12,23,.62),rgba(3,12,23,.22))!important;
        border:1px solid rgba(255,255,255,.10)!important;border-top:0!important;
        backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
        box-shadow:0 14px 28px rgba(0,0,0,.18)
      }
      .topStoryBarV249169 .storyScroll,.topStoryBarV249169 .storyScroll{display:flex;gap:10px;overflow-x:auto;padding:0 3px 2px;scrollbar-width:none}
      .topStoryBarV249169 .storyScroll::-webkit-scrollbar,.topStoryBarV249169 .storyScroll::-webkit-scrollbar{display:none}
      .topStoryBarV249169 .storyItem,.topStoryBarV249169 .storyItem{background:transparent!important;border:0!important;min-width:58px;color:inherit}
      .topStoryBarV249169 .storyItem .avatar,.topStoryBarV249169 .storyItem .avatar{width:46px;height:46px;border:1px solid rgba(255,255,255,.25);box-shadow:0 0 0 2px rgba(108,240,255,.20)}
      .topStoryBarV249169 .storyHint,.topStoryBarV249169 .storyHint{text-align:center;font-size:12px;opacity:.72;padding:5px 8px}
      .homeWelcomePro.stableHomeV249169{
        margin-top:8px!important;padding:18px 14px 20px!important;
        background:linear-gradient(180deg,rgba(8,25,45,.78),rgba(6,14,28,.58))!important;
        border:1px solid rgba(255,255,255,.11)!important;overflow:hidden
      }
      .homeWelcomePro.stableHomeV249169 .homeTitleTap{
        width:100%;display:grid!important;place-items:center!important;text-align:center!important;
        gap:10px;background:transparent;border:0;color:inherit;padding:0;margin:0
      }
      .homeWelcomePro.stableHomeV249169 .welcomeShip{display:flex;justify-content:center;width:100%}
      .homeWelcomePro.stableHomeV249169 .welcomeShip img{width:min(154px,39vw)!important;height:auto!important;object-fit:contain}
      .homeWelcomePro.stableHomeV249169 .welcomeText{width:100%!important;max-width:620px!important;margin:0 auto!important;text-align:center!important}
      .homeWelcomePro.stableHomeV249169 .welcomeText h1{
        margin:0 auto 8px!important;font-size:clamp(30px,8vw,48px)!important;line-height:1.05!important;
        letter-spacing:.3px;color:#fff!important;text-shadow:0 8px 24px rgba(0,0,0,.45)
      }
      .homeWelcomePro.stableHomeV249169 .welcomeText h3{
        margin:0 auto!important;max-width:560px!important;font-size:clamp(16px,4.2vw,21px)!important;
        line-height:1.35!important;color:rgba(235,250,255,.96)!important;font-weight:700!important
      }
      .homeWelcomePro .okLogo{background:none!important;-webkit-text-fill-color:inherit!important;color:inherit!important}
      .videoSizedFeedCard{
        min-height:calc(100dvh - 88px)!important;display:flex!important;flex-direction:column!important;
        justify-content:center!important;align-items:center!important;text-align:center!important;
        padding:clamp(18px,5vw,34px)!important;margin:12px 0!important;overflow:hidden!important;
        background:
          radial-gradient(circle at 20% 15%,rgba(108,240,255,.20),transparent 35%),
          radial-gradient(circle at 80% 80%,rgba(255,215,112,.18),transparent 38%),
          linear-gradient(160deg,rgba(7,23,45,.98),rgba(5,12,26,.96))!important;
        border:1px solid rgba(255,255,255,.16)!important;border-radius:28px!important;
        box-shadow:0 20px 60px rgba(0,0,0,.30)!important
      }
      .videoSizedFeedCard .feedCardClose{position:absolute;right:14px;top:14px;background:rgba(255,255,255,.12)!important}
      .videoSizedFeedCard .proPanelIcon{
        width:74px;height:74px;display:grid;place-items:center;border-radius:24px;
        font-size:38px;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.15);
        box-shadow:0 12px 32px rgba(0,0,0,.25);margin:0 auto 14px
      }
      .videoSizedFeedCard .proPanelText{max-width:620px;margin:0 auto}
      .videoSizedFeedCard .proPanelText>b{display:inline-block;letter-spacing:.8px;text-transform:uppercase;font-size:12px;color:#aeeeff;margin-bottom:8px}
      .videoSizedFeedCard .proPanelText h3{
        font-size:clamp(25px,7vw,42px)!important;line-height:1.13!important;margin:4px auto 12px!important;
        color:#fff!important;text-wrap:balance;text-shadow:0 10px 34px rgba(0,0,0,.42)
      }
      .videoSizedFeedCard .proPanelText p{font-size:clamp(14px,3.6vw,18px)!important;line-height:1.45;color:rgba(235,250,255,.88)}
      .videoSizedFeedCard .professionalChoiceList{display:grid;grid-template-columns:1fr;gap:10px;margin:16px auto 12px;max-width:520px}
      .videoSizedFeedCard .professionalVideoChoice{
        position:relative;overflow:hidden;border-radius:18px!important;padding:13px 14px!important;
        background:rgba(255,255,255,.08)!important;border:1px solid rgba(255,255,255,.14)!important;color:#fff!important
      }
      .videoSizedFeedCard .professionalVideoChoice span,.videoSizedFeedCard .professionalVideoChoice b{position:relative;z-index:2}
      .videoSizedFeedCard .professionalVideoChoice em{position:absolute;left:0;top:0;bottom:0;background:rgba(108,240,255,.16);z-index:1}
      .professionalStatsStrip{display:flex;justify-content:center;gap:10px;align-items:center;flex-wrap:wrap;margin:12px auto;color:rgba(235,250,255,.75)}
      .professionalStatsStrip b{font-size:22px;color:#fff}
      .videoCardActions{justify-content:center!important;margin-top:12px!important;gap:10px!important;flex-wrap:wrap!important}
    `;
    document.head.appendChild(st);
  }catch{}
}

function homeStories(){
  const serverPeople=peopleArray().filter(x=>x.id!==state.device && (x.avatar||x.animal||x.nickname)).slice(0,80);
  const ithakiStory=`<button class="storyItem on ithakiOfficialStory" onclick="return ITH.openIthakiPostsPreview?ITH.openIthakiPostsPreview():ITH.page('feed')" title="${uiText('Δημοσιεύσεις ΙΘΑΚΗΣ')}"><span class="avatarDotWrap"><span class="avatar"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display='none'"></span><i class="on"></i></span><small>ΙΘΑΚΗ</small></button>`;
  const empty=!serverPeople.length?`<div class="storyHint">${uiText('Τα avatar θα εμφανίζονται εδώ μόλις έρθουν φρέσκα προφίλ από τον server.')}</div>`:'';
  return `<section class="homeStories storyGlassBar topStoryBarV249169" aria-label="${uiText('Avatar μελών')}"><div class="storyScroll">${ithakiStory}${serverPeople.map(p=>{const id=String(p.id||p.device_id||'');const click=unreadFrom(id)?`ITH.startDM('${esc(id)}')`:`ITH.member('${esc(id)}')`;return `<button class="storyItem ${p.online?'on':''}" onclick="${click}"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${avatarDotClass(p)}"></i></span><small>${esc(p.nickname||uiText('Μέλος'))}</small></button>`}).join('')}</div>${empty}</section>`
}
function renderHome(){
  const h=$('homePage');if(!h)return;
  injectV249169LaunchCss();
  h.innerHTML=`
  ${homeStories()}
  <section class="welcomeHero card homeWelcomePro stableHomeV249169">
    <button class="homeTitleTap" onclick="ITH.page('profile')" title="${uiText('Προφίλ')}">
      <div class="welcomeShip"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display='none'"></div>
      <div class="welcomeText"><h1>${uiText('Welcome to ITHAKI')}</h1><h3>${uiText('Human communication, clean flow, respect and anonymity.')}</h3></div>
    </button>
  </section>
  ${homeWisdomPanel()}
  <section class="grid homeMenu professionalHomeGrid stableMainMenu">
    <button class="tile homeModernTileR10F17" style="--home17:#4da3ff" onclick="ITH.page('feed')"><span class="homeModernIconR10F17">🎬</span><b>${uiText('Ροή')}</b><span>${uiText('Βίντεο, φωτογραφίες και λόγια')}</span></button>
    <button class="tile homeModernTileR10F17" style="--home17:#f6c453" onclick="ITH.page('create')"><span class="homeModernIconR10F17">＋</span><b>${uiText('Δημοσίευση')}</b><span>${uiText('Κείμενο, φωτογραφία, βίντεο ή αρχείο')}</span></button>
    <button class="tile homeModernTileR10F17" style="--home17:#35d38a" onclick="ITH.page('dm')"><span class="homeModernIconR10F17">💬</span><b>${uiText('Μηνύματα')}</b><span>${uiText('Συνομιλίες και αρχεία')}</span></button>
    <button class="tile homeModernTileR10F17" style="--home17:#2ed6d0" onclick="ITH.page('spaces')"><span class="homeModernIconR10F17">🏘️</span><b>${uiText('Δωμάτια / Κοινότητες')}</b><span>${uiText('Ομάδες και χώροι συζήτησης')}</span></button>
    <button class="tile homeModernTileR10F17" style="--home17:#a879ff" onclick="ITH.openPoll()"><span class="homeModernIconR10F17">📊</span><b>${uiText('Ψηφοφορία')}</b><span>${uiText('Ρώτα γνώμη με καθαρή κάρτα')}</span></button>
    <button class="tile homeModernTileR10F17" style="--home17:#ff6b6b" onclick="ITH.page('profile')"><span class="homeModernIconR10F17">👤</span><b>${uiText('Προφίλ')}</b><span>${uiText('Όνομα, avatar, προστασία και ειδοποιήσεις')}</span></button>
  </section>
  ${homeProtectionPanel()}`;
  setTimeout(applyUiLanguagePatch,30);
}
function renderCreate(){const e=$('createPage');if(!e)return;e.innerHTML=`<div class="card"><div class="row" style="justify-content:space-between"><button class="icon" onclick="ITH.page('home')">‹</button><h2 style="margin:0">${uiText('Post')}</h2><span></span></div><textarea id="postText" style="width:100%;min-height:150px;resize:vertical;text-align:center" placeholder="${uiText('Write text...')}"></textarea><label class="card row anonymousRow"><input id="postAnonymous" type="checkbox"><span class="anonBadge">🕶️ ${uiText('Anonymous post')}</span></label><div class="row" style="margin-top:10px;justify-content:center;flex-wrap:wrap"><button class="btn" onclick="ITH.captureMedia('feed','photo')">📷</button><button class="btn" onclick="ITH.captureMedia('feed','video')">🎥</button><button class="btn" onclick="ITH.startAudioRecording('feed','')">🎙️</button><button class="btn" onclick="ITH.chooseFile('feed','file')">📎</button><button class="btn gold" onclick="ITH.sendTextPost()">${uiText('Post')}</button></div></div>`}
async function sendTextPost(){const text=($('postText')?.value||'').trim();if(!text)return toast(uiText('Write text'));await sendFeedPayload(text,'text',{anonymous:!!$('postAnonymous')?.checked})}
function chooseFile(ctx,kind,target=''){const inp=$('globalFile');if(!inp)return;inp.value='';inp.accept=kind==='video'?'video/*':kind==='photo'?'image/*':'*/*';inp.onchange=()=>{const f=inp.files?.[0];if(f)openPreview(ctx,f,kind,target)};inp.click()}
function captureMedia(ctx,kind,target=''){const inp=$('globalFile');if(!inp)return false;try{if(kind==='video')bridgeCall('requestMediaPermissions',true);else bridgeCall('requestCameraPermission')}catch{}inp.value='';inp.accept=kind==='video'?'video/*':'image/*';inp.setAttribute('capture','environment');inp.onchange=()=>{inp.removeAttribute('capture');const f=inp.files&&inp.files[0];if(f)openPreview(ctx,f,kind,target)};inp.click();return false}
async function dataUrlToFile(dataUrl,name,mime){const blob=await (await fetch(dataUrl)).blob();return new File([blob],name||('ithaki_audio_'+Date.now()+'.m4a'),{type:mime||blob.type||'audio/mp4',lastModified:Date.now()})}
function showAudioRecorder(ctx,target){state.audioContext={ctx,target};$('previewModal').innerHTML=`<div class="previewBox"><div class="row"><b>🎙️ ${uiText('Record audio')}</b></div><div class="previewStage"><div style="font-size:72px">🎙️</div></div><div class="callStatus">${uiText('Recording audio...')}</div><div class="callActions"><button class="btn green" onclick="ITH.stopAudioRecording()">${uiText('Stop recording')}</button><button class="btn danger" onclick="ITH.cancelAudioRecording()">${uiText('Cancel recording')}</button></div></div>`;$('previewModal').classList.add('show')}
async function startAudioRecording(ctx,target=''){target=target||(ctx==='dm'?state.activeChannel:ctx==='space'?state.currentSpaceChannel:'');if((ctx==='dm'||ctx==='space')&&!target){toast(uiText('Choose destination first.'));return false}if(state.audioRecorder||state.audioStream)return false;try{bridgeCall('requestMicrophonePermission')}catch{}showAudioRecorder(ctx,target);const native=parseBridgeJson(bridgeCall('startNativeAudioRecord')||'{}');if(native.ok){state.audioRecorder={native:true};return false}try{if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)throw new Error('microphone unavailable');state.audioStream=await navigator.mediaDevices.getUserMedia({audio:true});state.audioChunks=[];const rec=new MediaRecorder(state.audioStream);state.audioRecorder=rec;rec.ondataavailable=e=>{if(e.data&&e.data.size)state.audioChunks.push(e.data)};rec.start()}catch(e){cancelAudioRecording();toast('Audio: '+(e.message||e))}return false}
async function stopAudioRecording(){const dest=state.audioContext||{};if(!state.audioRecorder)return false;if(state.audioRecorder.native){const r=parseBridgeJson(bridgeCall('stopNativeAudioRecord')||'{}');state.audioRecorder=null;state.audioContext=null;if(!r.ok||!r.dataUrl){clearAudioRecorder();toast(r.error||'audio recording failed');return false}const f=await dataUrlToFile(r.dataUrl,r.name,r.mime);clearAudioRecorder(false);openPreview(dest.ctx,f,'audio',dest.target||'');return false}const rec=state.audioRecorder;const chunks=state.audioChunks;const stream=state.audioStream;await new Promise(resolve=>{rec.onstop=resolve;rec.stop()});const mime=rec.mimeType||'audio/webm';const blob=new Blob(chunks,{type:mime});const ext=mime.includes('mp4')?'m4a':mime.includes('ogg')?'ogg':'webm';const f=new File([blob],`ithaki_audio_${Date.now()}.${ext}`,{type:mime,lastModified:Date.now()});try{stream&&stream.getTracks().forEach(t=>t.stop())}catch{}state.audioRecorder=null;state.audioStream=null;state.audioChunks=[];state.audioContext=null;$('previewModal').classList.remove('show');openPreview(dest.ctx,f,'audio',dest.target||'');return false}
function clearAudioRecorder(close=true){try{if(state.audioRecorder&&state.audioRecorder.native)bridgeCall('cancelNativeAudioRecord');else if(state.audioRecorder&&state.audioRecorder.state!=='inactive')state.audioRecorder.stop()}catch{}try{state.audioStream&&state.audioStream.getTracks().forEach(t=>t.stop())}catch{}state.audioRecorder=null;state.audioStream=null;state.audioChunks=[];state.audioContext=null;if(close){$('previewModal').classList.remove('show');$('previewModal').innerHTML=''}}
function cancelAudioRecording(){clearAudioRecorder(true);return false}

function studioDefaults(){return{text:'',textX:50,textY:50,textSize:54,textColor:'#ffffff',textOpacity:92,brightness:100,contrast:100,saturate:100,filter:'normal',frame:'none',sticker:'none',collage:'none',audioMode:'keep'}}
function previewStudioKind(){const p=state.preview||{},f=p.file||p.originalFile;if(!f)return'file';if(String(f.type||'').startsWith('image/'))return'photo';if(isVideoFile(f,p.kind))return'video';if(String(f.type||'').startsWith('audio/'))return'audio';return'file'}
function studioNum(id,fallback,min,max){const el=$(id);let n=el?Number(el.value):Number(fallback);if(!Number.isFinite(n))n=Number(fallback)||0;if(min!==undefined)n=Math.max(min,n);if(max!==undefined)n=Math.min(max,n);return n}
function studioRead(){const s=Object.assign(studioDefaults(),state.preview.studio||{});const val=(id,fb)=>{const el=$(id);return el?el.value:fb};s.text=val('studioText',s.text);s.textX=studioNum('studioTextX',s.textX,0,100);s.textY=studioNum('studioTextY',s.textY,0,100);s.textSize=studioNum('studioSize',s.textSize,12,160);s.textColor=val('studioColor',s.textColor);s.textOpacity=studioNum('studioOpacity',s.textOpacity,0,100);s.brightness=studioNum('studioBrightness',s.brightness,40,180);s.contrast=studioNum('studioContrast',s.contrast,40,180);s.saturate=studioNum('studioSaturate',s.saturate,0,220);s.filter=val('studioFilter',s.filter);s.frame=val('studioFrame',s.frame);s.sticker=val('studioSticker',s.sticker);s.collage=val('studioCollage',s.collage);s.audioMode=val('studioAudioMode',s.audioMode);state.preview.studio=s;return s}
function studioFilterCss(s){let extra='';if(s.filter==='mono')extra=' grayscale(1)';else if(s.filter==='warm')extra=' sepia(.26) hue-rotate(-8deg)';else if(s.filter==='cool')extra=' hue-rotate(12deg) saturate(1.08)';else if(s.filter==='vivid')extra=' saturate(1.22) contrast(1.08)';else if(s.filter==='soft')extra=' saturate(.92) contrast(.94)';return`brightness(${s.brightness||100}%) contrast(${s.contrast||100}%) saturate(${s.saturate||100}%)${extra}`}
function studioOption(sel,val){return sel===val?'selected':''}
function openPreviewStudio(){const p=state.preview||{};if(!p.file)return false;const mount=$('previewStudioMount');if(!mount)return false;if(mount.innerHTML.trim()){try{mount.scrollIntoView({behavior:'smooth',block:'start'});const f=mount.querySelector('textarea,input,select,button');if(f)f.focus({preventScroll:true})}catch(e){}return false}p.originalFile=p.originalFile||p.file;p.studio=Object.assign(studioDefaults(),p.studio||{});const s=p.studio,k=previewStudioKind();const canCanvas=k==='photo'||k==='video';mount.innerHTML=`<div class="previewStudioPanel"><div class="row studioHead"><b>✦ ${uiText('ITHAKI Studio')}</b><span class="date">${uiText('External editor module connected to this preview.')}</span><button type="button" class="btn mini" onclick="var m=document.getElementById('previewStudioMount');if(m)m.innerHTML=''">×</button></div>${canCanvas?`<div class="studioCanvasWrap"><canvas id="studioCanvas"></canvas><small>${uiText('Tap on the image to move the text.')}</small></div>`:''}<div class="studioGrid"><label>${uiText('Text')}<textarea id="studioText" placeholder="${uiText('Write text on media...')}">${esc(s.text)}</textarea></label><label>${uiText('Text size')}<input id="studioSize" type="range" min="12" max="160" value="${s.textSize}"></label><label>${uiText('Text color')}<input id="studioColor" type="color" value="${esc(s.textColor)}"></label><label>${uiText('Transparency')}<input id="studioOpacity" type="range" min="0" max="100" value="${s.textOpacity}"></label><label>X<input id="studioTextX" type="range" min="0" max="100" value="${s.textX}"></label><label>Y<input id="studioTextY" type="range" min="0" max="100" value="${s.textY}"></label><label>${uiText('Look')}<select id="studioFilter"><option value="normal" ${studioOption(s.filter,'normal')}>${uiText('Normal')}</option><option value="vivid" ${studioOption(s.filter,'vivid')}>${uiText('Vivid')}</option><option value="soft" ${studioOption(s.filter,'soft')}>${uiText('Soft')}</option><option value="warm" ${studioOption(s.filter,'warm')}>${uiText('Warm')}</option><option value="cool" ${studioOption(s.filter,'cool')}>${uiText('Cool')}</option><option value="mono" ${studioOption(s.filter,'mono')}>${uiText('Black and white')}</option></select></label><label>${uiText('Brightness')}<input id="studioBrightness" type="range" min="40" max="180" value="${s.brightness}"></label><label>${uiText('Contrast')}<input id="studioContrast" type="range" min="40" max="180" value="${s.contrast}"></label><label>${uiText('Color strength')}<input id="studioSaturate" type="range" min="0" max="220" value="${s.saturate}"></label><label>${uiText('Frame')}<select id="studioFrame"><option value="none" ${studioOption(s.frame,'none')}>${uiText('None')}</option><option value="clean" ${studioOption(s.frame,'clean')}>${uiText('Clean white')}</option><option value="gold" ${studioOption(s.frame,'gold')}>${uiText('Gold')}</option><option value="film" ${studioOption(s.frame,'film')}>${uiText('Film')}</option><option value="glass" ${studioOption(s.frame,'glass')}>${uiText('Glass')}</option><option value="story" ${studioOption(s.frame,'story')}>${uiText('Story')}</option></select></label><label>${uiText('Design')}<select id="studioSticker"><option value="none" ${studioOption(s.sticker,'none')}>${uiText('None')}</option><option value="spark" ${studioOption(s.sticker,'spark')}>Spark</option><option value="heart" ${studioOption(s.sticker,'heart')}>Heart</option><option value="ok" ${studioOption(s.sticker,'ok')}>OK</option><option value="ithaki" ${studioOption(s.sticker,'ithaki')}>ITHAKI</option></select></label><label>${uiText('Collage')}<select id="studioCollage"><option value="none" ${studioOption(s.collage,'none')}>${uiText('None')}</option><option value="split" ${studioOption(s.collage,'split')}>${uiText('Two side by side')}</option><option value="stack" ${studioOption(s.collage,'stack')}>${uiText('Two vertical')}</option><option value="inset" ${studioOption(s.collage,'inset')}>${uiText('Small picture inside')}</option></select></label>${k==='video'?`<label>${uiText('Audio')}<select id="studioAudioMode"><option value="keep" ${studioOption(s.audioMode,'keep')}>${uiText('Keep original')}</option><option value="mute" ${studioOption(s.audioMode,'mute')}>${uiText('Mute')}</option><option value="replace" ${studioOption(s.audioMode,'replace')}>${uiText('Replace with selected audio')}</option></select></label>`:''}</div><div class="row studioActions">${k==='photo'?`<button class="btn" onclick="ITH.studioPickExtra('collage')">＋ ${uiText('Collage photo')}</button>`:''}${k==='video'?`<button class="btn" onclick="ITH.studioPickExtra('audio')">＋ ${uiText('Audio file')}</button>`:''}<button class="btn" onclick="ITH.studioSetPreset('bright')">${uiText('Bright')}</button><button class="btn" onclick="ITH.studioSetPreset('cinema')">${uiText('Cinema')}</button><button id="studioApplyBtn" class="btn green" onclick="ITH.applyPreviewStudio()">${k==='video'?uiText('Render video'):uiText('Apply design')}</button></div><div id="studioStatus" class="date">${k==='video'?uiText('Video render may take as long as the video duration.'):uiText('Ready to create a new edited file.')}</div></div>`;bindStudioControls();studioRefresh();applyUiLanguagePatch();return false}
function bindStudioControls(){const box=$('previewStudioMount');if(!box)return;box.querySelectorAll('input,select,textarea').forEach(el=>{el.oninput=studioRefresh;el.onchange=studioRefresh});const c=$('studioCanvas');if(c)c.onclick=e=>{const r=c.getBoundingClientRect();if(!r.width||!r.height)return;const x=Math.round(((e.clientX-r.left)/r.width)*100),y=Math.round(((e.clientY-r.top)/r.height)*100);if($('studioTextX'))$('studioTextX').value=x;if($('studioTextY'))$('studioTextY').value=y;studioRefresh()}}
function studioSetPreset(name){const s=Object.assign(studioDefaults(),state.preview.studio||{});if(name==='bright')Object.assign(s,{brightness:118,contrast:108,saturate:118,filter:'vivid',frame:'clean'});else if(name==='cinema')Object.assign(s,{brightness:92,contrast:122,saturate:88,filter:'warm',frame:'film'});state.preview.studio=s;const mount=$('previewStudioMount');if(mount)mount.innerHTML='';openPreviewStudio();return false}
function studioPickExtra(type){const inp=$('globalFile');if(!inp)return false;inp.value='';inp.accept=type==='audio'?'audio/*':'image/*';inp.onchange=()=>{const f=inp.files&&inp.files[0];if(!f)return;if(type==='audio')state.preview.studioAudioFile=f;else state.preview.studioCollageFile=f;const st=$('studioStatus');if(st)st.textContent=f.name+' · '+mb(f.size);studioRefresh()};inp.click();return false}
function studioRefresh(){if(!state.preview||!state.preview.file)return false;studioRead();const k=previewStudioKind();if(k==='photo')renderStudioPhotoCanvas($('studioCanvas'),false).catch(()=>{});else if(k==='video')renderStudioVideoPoster($('studioCanvas')).catch(()=>{});return false}
function loadStudioImage(file){return new Promise((resolve,reject)=>{const url=URL.createObjectURL(file);const img=new Image();img.onload=()=>resolve({img,url});img.onerror=()=>{URL.revokeObjectURL(url);reject(new Error('image load failed'))};img.src=url})}
function mediaDims(m){return{w:m.videoWidth||m.naturalWidth||m.width||1,h:m.videoHeight||m.naturalHeight||m.height||1}}
function drawCover(ctx,img,x,y,w,h){const d=mediaDims(img),r=Math.max(w/d.w,h/d.h),sw=w/r,sh=h/r,sx=(d.w-sw)/2,sy=(d.h-sh)/2;ctx.drawImage(img,Math.max(0,sx),Math.max(0,sy),Math.min(d.w,sw),Math.min(d.h,sh),x,y,w,h)}
function drawContain(ctx,img,x,y,w,h){const d=mediaDims(img),r=Math.min(w/d.w,h/d.h),dw=d.w*r,dh=d.h*r;ctx.drawImage(img,x+(w-dw)/2,y+(h-dh)/2,dw,dh)}
function drawStudioFrame(ctx,w,h,s){ctx.save();ctx.filter='none';ctx.globalAlpha=1;if(s.frame==='clean'){ctx.strokeStyle='rgba(255,255,255,.92)';ctx.lineWidth=Math.max(18,Math.round(Math.min(w,h)*.035));ctx.strokeRect(ctx.lineWidth/2,ctx.lineWidth/2,w-ctx.lineWidth,h-ctx.lineWidth)}else if(s.frame==='gold'){const g=ctx.createLinearGradient(0,0,w,h);g.addColorStop(0,'#fff2a8');g.addColorStop(.45,'#d99a18');g.addColorStop(1,'#fff2a8');ctx.strokeStyle=g;ctx.lineWidth=Math.max(20,Math.round(Math.min(w,h)*.04));ctx.strokeRect(ctx.lineWidth/2,ctx.lineWidth/2,w-ctx.lineWidth,h-ctx.lineWidth)}else if(s.frame==='film'){ctx.fillStyle='rgba(0,0,0,.72)';const bar=Math.max(18,Math.round(h*.075));ctx.fillRect(0,0,w,bar);ctx.fillRect(0,h-bar,w,bar);ctx.fillStyle='rgba(255,255,255,.82)';for(let x=16;x<w;x+=42){ctx.fillRect(x,bar*.28,16,bar*.28);ctx.fillRect(x,h-bar*.56,16,bar*.28)}}else if(s.frame==='glass'){ctx.strokeStyle='rgba(255,255,255,.36)';ctx.lineWidth=Math.max(10,Math.round(Math.min(w,h)*.02));ctx.strokeRect(ctx.lineWidth/2,ctx.lineWidth/2,w-ctx.lineWidth,h-ctx.lineWidth);ctx.fillStyle='rgba(255,255,255,.10)';ctx.fillRect(0,0,w,h*.16)}else if(s.frame==='story'){const g=ctx.createLinearGradient(0,0,w,0);g.addColorStop(0,'#22d3ee');g.addColorStop(.5,'#facc15');g.addColorStop(1,'#fb7185');ctx.strokeStyle=g;ctx.lineWidth=Math.max(14,Math.round(Math.min(w,h)*.026));ctx.strokeRect(ctx.lineWidth/2,ctx.lineWidth/2,w-ctx.lineWidth,h-ctx.lineWidth)}ctx.restore()}
function drawStudioOverlay(ctx,w,h,s){ctx.save();ctx.filter='none';const mark=s.sticker==='spark'?'✦':s.sticker==='heart'?'♥':s.sticker==='ok'?'OK':s.sticker==='ithaki'?'ITHAKI':'';if(mark){ctx.globalAlpha=.86;ctx.fillStyle='rgba(255,255,255,.92)';ctx.font=`900 ${Math.round(Math.min(w,h)*.09)}px Segoe UI,Arial`;ctx.textAlign='right';ctx.textBaseline='top';ctx.shadowColor='rgba(0,0,0,.45)';ctx.shadowBlur=12;ctx.fillText(mark,w-24,20)}if(String(s.text||'').trim()){ctx.globalAlpha=(+s.textOpacity||100)/100;ctx.fillStyle=s.textColor||'#fff';ctx.font=`900 ${Math.round((+s.textSize||54)*(Math.min(w,h)/900))}px Segoe UI,Arial`;ctx.textAlign='center';ctx.textBaseline='middle';ctx.shadowColor='rgba(0,0,0,.72)';ctx.shadowBlur=18;ctx.lineWidth=Math.max(3,Math.round(Math.min(w,h)*.006));const lines=String(s.text).split(/\n/).slice(0,5),lh=Math.round((+s.textSize||54)*(Math.min(w,h)/900)*1.16),x=w*((+s.textX||50)/100),y=h*((+s.textY||50)/100)-((lines.length-1)*lh/2);lines.forEach((line,i)=>{ctx.strokeStyle='rgba(0,0,0,.46)';ctx.strokeText(line,x,y+i*lh);ctx.fillText(line,x,y+i*lh)})}ctx.restore()}
async function renderStudioPhotoCanvas(canvas,full=false){if(!canvas)return;const s=studioRead(),file=state.preview.originalFile||state.preview.file;if(!file||!String(file.type||'').startsWith('image/'))return;const a=await loadStudioImage(file);let b=null;if(state.preview.studioCollageFile&&String(state.preview.studioCollageFile.type||'').startsWith('image/')){try{b=await loadStudioImage(state.preview.studioCollageFile)}catch{}}const d=mediaDims(a.img),max=full?1800:780;let w,h;if(b&&s.collage!=='none'){w=max;h=s.collage==='split'?Math.round(max*.72):max}else{const r=Math.min(1,max/Math.max(d.w,d.h));w=Math.max(1,Math.round(d.w*r));h=Math.max(1,Math.round(d.h*r))}canvas.width=w;canvas.height=h;const ctx=canvas.getContext('2d');ctx.save();ctx.fillStyle='#02070d';ctx.fillRect(0,0,w,h);ctx.filter=studioFilterCss(s);if(b&&s.collage==='split'){drawCover(ctx,a.img,0,0,w/2,h);drawCover(ctx,b.img,w/2,0,w/2,h)}else if(b&&s.collage==='stack'){drawCover(ctx,a.img,0,0,w,h/2);drawCover(ctx,b.img,0,h/2,w,h/2)}else{drawContain(ctx,a.img,0,0,w,h);if(b&&s.collage==='inset'){ctx.filter=studioFilterCss(s);const iw=w*.34,ih=h*.34;ctx.save();ctx.shadowColor='rgba(0,0,0,.55)';ctx.shadowBlur=24;ctx.fillStyle='rgba(255,255,255,.95)';ctx.fillRect(w-iw-28,h-ih-28,iw+12,ih+12);ctx.restore();drawCover(ctx,b.img,w-iw-22,h-ih-22,iw,ih)}}ctx.restore();drawStudioFrame(ctx,w,h,s);drawStudioOverlay(ctx,w,h,s);try{URL.revokeObjectURL(a.url);b&&URL.revokeObjectURL(b.url)}catch{}}
async function renderStudioVideoPoster(canvas){if(!canvas)return;const file=state.preview.originalFile||state.preview.file;if(!isVideoFile(file,state.preview.kind))return;const s=studioRead();const url=URL.createObjectURL(file);const v=document.createElement('video');v.src=url;v.muted=true;v.playsInline=true;v.preload='metadata';await new Promise((res,rej)=>{v.onloadedmetadata=res;v.onerror=()=>rej(new Error('video load failed'))});try{v.currentTime=Math.min(.1,(v.duration||1)/10);await new Promise(res=>{v.onseeked=res;setTimeout(res,500)})}catch{}const d=mediaDims(v),max=760,r=Math.min(1,max/Math.max(d.w,d.h));canvas.width=Math.max(1,Math.round(d.w*r));canvas.height=Math.max(1,Math.round(d.h*r));const ctx=canvas.getContext('2d');ctx.fillStyle='#02070d';ctx.fillRect(0,0,canvas.width,canvas.height);ctx.filter=studioFilterCss(s);drawContain(ctx,v,0,0,canvas.width,canvas.height);ctx.filter='none';drawStudioFrame(ctx,canvas.width,canvas.height,s);drawStudioOverlay(ctx,canvas.width,canvas.height,s);try{URL.revokeObjectURL(url)}catch{}}
function updatePreviewEditedFile(file,kind){state.preview.file=file;state.preview.kind=kind||state.preview.kind;state.preview.preparedFile=null;state.preview.uploadedRaw=null;state.preview.uploadedReady=null;const url=URL.createObjectURL(file);const stage=$('previewStage');if(stage)stage.innerHTML=previewStageHtml(file,state.preview.kind,url);if($('previewFileName'))$('previewFileName').textContent=file.name;if($('previewFileMeta'))$('previewFileMeta').textContent=(file.type||'file')+' · '+mb(file.size);if($('progressText'))$('progressText').textContent=uiText('Ready')+' · '+mb(file.size)}
async function applyPreviewStudio(){const k=previewStudioKind();if(k==='photo')return applyStudioPhoto();if(k==='video')return renderPreviewStudioVideo();toast(uiText('Studio works for photos and videos.'));return false}
async function applyStudioPhoto(){const btn=$('studioApplyBtn'),st=$('studioStatus');try{if(btn)btn.disabled=true;if(st)st.textContent=uiText('Creating edited photo...');const c=document.createElement('canvas');await renderStudioPhotoCanvas(c,true);const blob=await new Promise((res,rej)=>c.toBlob(b=>b?res(b):rej(new Error('photo render failed')),'image/jpeg',.92));const base=String((state.preview.originalFile||state.preview.file).name||'photo').replace(/\.[^.]+$/,'')||'photo';const out=new File([blob],base+'_ithaki_studio.jpg',{type:'image/jpeg',lastModified:Date.now()});updatePreviewEditedFile(out,'photo');if(st)st.textContent=uiText('Edited photo is ready.');toast(uiText('Edited photo is ready.'))}catch(e){if(st)st.textContent=e.message||String(e);toast('Studio: '+(e.message||e),6000)}finally{if(btn)btn.disabled=false}return false}
async function renderPreviewStudioVideo(){const btn=$('studioApplyBtn'),st=$('studioStatus'),file=state.preview.originalFile||state.preview.file,s=studioRead();try{if(!window.MediaRecorder)throw new Error('MediaRecorder unavailable');if(!document.createElement('canvas').captureStream)throw new Error('canvas capture unavailable');if(btn)btn.disabled=true;if(st)st.textContent=uiText('Rendering video...');const url=URL.createObjectURL(file);const v=document.createElement('video');v.src=url;v.playsInline=true;v.preload='auto';v.muted=s.audioMode!=='keep';v.volume=s.audioMode==='keep'?0:1;await new Promise((res,rej)=>{v.onloadedmetadata=res;v.onerror=()=>rej(new Error('video load failed'))});const d=mediaDims(v),max=960,r=Math.min(1,max/Math.max(d.w,d.h));const c=document.createElement('canvas');c.width=Math.max(2,Math.round(d.w*r));c.height=Math.max(2,Math.round(d.h*r));const ctx=c.getContext('2d');const stream=c.captureStream(24);let audioEl=null;try{if(s.audioMode==='keep'&&v.captureStream){v.captureStream().getAudioTracks().forEach(t=>stream.addTrack(t))}else if(s.audioMode==='replace'&&state.preview.studioAudioFile){const au=URL.createObjectURL(state.preview.studioAudioFile);audioEl=new Audio(au);audioEl.loop=true;audioEl.volume=0;if(audioEl.captureStream)audioEl.captureStream().getAudioTracks().forEach(t=>stream.addTrack(t))}}catch(e){console.warn('studio audio mix skipped',e)}const types=['video/webm;codecs=vp9,opus','video/webm;codecs=vp8,opus','video/webm'];const mime=types.find(t=>MediaRecorder.isTypeSupported(t))||'';const rec=new MediaRecorder(stream,mime?{mimeType:mime}:undefined),chunks=[];rec.ondataavailable=e=>{if(e.data&&e.data.size)chunks.push(e.data)};const done=new Promise((res,rej)=>{rec.onerror=e=>rej(e.error||new Error('video render failed'));rec.onstop=res});let last=0;function draw(){if(v.ended||v.paused)return;ctx.fillStyle='#02070d';ctx.fillRect(0,0,c.width,c.height);ctx.filter=studioFilterCss(s);drawContain(ctx,v,0,0,c.width,c.height);ctx.filter='none';drawStudioFrame(ctx,c.width,c.height,s);drawStudioOverlay(ctx,c.width,c.height,s);if(st&&Date.now()-last>450){last=Date.now();const pct=v.duration?Math.min(99,Math.round(100*v.currentTime/v.duration)):0;st.textContent=uiText('Rendering video...')+' '+pct+'%'}requestAnimationFrame(draw)}rec.start(1000);v.currentTime=0;await v.play();if(audioEl)audioEl.play().catch(()=>{});draw();await new Promise(res=>{v.onended=res});try{audioEl&&audioEl.pause()}catch{}try{rec.stop()}catch{}await done;const blob=new Blob(chunks,{type:mime||'video/webm'});if(!blob.size)throw new Error('video render empty');const base=String(file.name||'video').replace(/\.[^.]+$/,'')||'video';const out=new File([blob],base+'_ithaki_studio.webm',{type:blob.type,lastModified:Date.now()});updatePreviewEditedFile(out,'video');if(st)st.textContent=uiText('Edited video is ready.');toast(uiText('Edited video is ready.'));try{URL.revokeObjectURL(url)}catch{}}catch(e){if(st)st.textContent=e.message||String(e);toast('Studio video: '+(e.message||e),7000)}finally{if(btn)btn.disabled=false}return false}

async function checkServerTools(){try{const a=await fetchJson('/api/argos/status');const f=await fetchJson('/api/media/ffmpeg_health');let msg=(a.ready?uiText('Translation system OK'):uiText('Offline translation model missing on this laptop. Run 02_INSTALL_ARGOS_EN_EL_OFFLINE_MODEL.cmd and restart.'))+' · '+(f.ffmpeg_found?'FFmpeg OK':uiText('FFmpeg missing on this laptop/server. Install FFmpeg and restart.'));toast(msg,7000);return {argos:a,ffmpeg:f}}catch(e){toast('Server tools check failed: '+e.message,6000);return null}}

function previewStageHtml(file,kind,url){if(file.type.startsWith('image/'))return `<img src="${url}">`;if(isVideoFile(file,kind))return `<video src="${url}" controls playsinline></video>`;if(file.type.startsWith('audio/'))return `<audio src="${url}" controls></audio>`;return `<div class="officePreviewStage"><div class="officeIcon">${officeIcon({filename:file.name,mime_type:file.type})}</div><b>${esc(file.name)}</b><small>${esc(file.type||'file')} · ${mb(file.size)}</small><span>${uiText('It will appear as a card and open externally.')}</span></div>`}
function openPreview(ctx,file,kind,target=''){state.preview={ctx,file,kind,target,originalFile:file,studio:studioDefaults()};const url=URL.createObjectURL(file);const stage=previewStageHtml(file,kind,url);const dest=ctx==='feed'?uiText('to Feed'):ctx==='dm'?uiText('to Messages'):ctx==='space'?uiText('to Community / Room'):(ctx==='comment'||ctx==='comment_frame')?'στα σχόλια':uiText('here');$('previewModal').classList.remove('callCompactV249218','voiceCallV249218','videoCallV249218');$('previewModal').innerHTML=`<div class="previewBox previewScrollable"><div class="row"><button class="icon" onclick="ITH.closePreview()">‹</button><b>${uiText('Preview')} ${dest}</b><button class="btn gold" style="margin-left:auto" onclick="ITH.openPreviewStudio()">✦ ${uiText('Studio')}</button><button class="btn" onclick="ITH.closePreview()">${uiText('Cancel')}</button></div><div id="previewStage" class="previewStage">${stage}</div><div class="card previewFileCard"><b id="previewFileName">${esc(file.name)}</b><div id="previewFileMeta" class="date">${esc(file.type||'file')} · ${mb(file.size)}</div></div><div id="previewStudioMount"></div><textarea id="previewCaption" style="width:100%;min-height:96px;resize:vertical" placeholder="${uiText('Add any caption you want...')}"></textarea>${ctx==='feed'?`<label class="card row anonymousRow"><input id="previewAnonymous" type="checkbox"><span class="anonBadge">🕶️ ${uiText('Anonymous post')}</span></label>`:''}<div class="progress"><span id="progressBar"></span></div><div id="progressText" class="date">${uiText('Ready')} · ${mb(file.size)}</div><div class="row"><button id="previewSend" class="btn green" onclick="ITH.sendPreview()">${uiText('Upload / Send')}</button><button class="btn" onclick="ITH.closePreview()">${uiText('Cancel')}</button></div></div>`;$('previewModal').classList.add('show')}
function closePreview(){if(state.sending)return;$('previewModal').classList.remove('show');$('previewModal').innerHTML='';state.preview={};try{window.dispatchEvent(new CustomEvent('ithaki:preview-closed',{detail:{reason:'core-close'}}))}catch(e){}}
function setSending(sent,total){const b=$('previewSend'),p=$('progressBar'),t=$('progressText');if(!b)return;b.classList.add('green');b.disabled=true;b.textContent=uiText('Sending...');if(total){p.style.width=Math.min(100,(sent/total)*100)+'%';t.textContent=`${uiText('Uploading')} ${mb(sent)} / ${mb(total)}`}}
function setProcessing(msg,pct=100){const b=$('previewSend'),p=$('progressBar'),t=$('progressText');if(b){b.disabled=true;b.textContent=msg||uiText('Compressing video...')}if(p)p.style.width=Math.max(0,Math.min(100,pct))+'%';if(t)t.textContent=msg||uiText('Compressing video...')}
function isVideoFile(file,kind=''){const name=String((file&&file.name)||'').toLowerCase();const type=String((file&&file.type)||'').toLowerCase();const ext=(name.match(/\.([a-z0-9]+)$/)||[])[1]||'';return kind==='video'||type.startsWith('video/')||['mp4','mov','m4v','webm','3gp','3gpp','avi','mkv'].includes(ext)}
function uploadErrorMessage(xhr){try{const j=JSON.parse(xhr.responseText||'{}');const d=j.detail||j;if(xhr.status===429)return (d.message||d.reason||'BotGuard/rate limit')+' · '+uiText('Wait a little and try again.');return d.message||d.reason||j.message||('upload '+xhr.status)}catch(e){return 'upload '+xhr.status}}
async function ensureFfmpegReadyForVideo(file,kind){const isVideo=isVideoFile(file,kind);if(!isVideo)return true;const fallbackBytes=100*1024*1024;if(file&&file.size<=fallbackBytes)return true;try{const h=await fetchJson('/api/media/ffmpeg_health');if(!h.ffmpeg_found)throw new Error(uiText('FFmpeg missing on this laptop/server. Install FFmpeg and restart.'));if(h.h264_encoder===null||h.h264_encoder===undefined||h.h264_encoder==='')throw new Error('FFmpeg H.264 encoder missing. Use a different FFmpeg build or upload videos up to 100MB fallback.');return true}catch(e){throw new Error(e.message||uiText('FFmpeg missing on this laptop/server. Install FFmpeg and restart.'))}}
async function preparePhotoForUpload(file,kind){if(kind!=='photo'||!file||!String(file.type||'').startsWith('image/')||file.size<=8*1024*1024)return file;let bmp=null;try{bmp=await createImageBitmap(file);const scale=Math.min(1,2560/Math.max(bmp.width,bmp.height));const canvas=document.createElement('canvas');canvas.width=Math.max(1,Math.round(bmp.width*scale));canvas.height=Math.max(1,Math.round(bmp.height*scale));canvas.getContext('2d',{alpha:false}).drawImage(bmp,0,0,canvas.width,canvas.height);const blob=await new Promise((resolve,reject)=>canvas.toBlob(b=>b?resolve(b):reject(new Error('photo compression failed')),'image/jpeg',.86));if(blob.size>=file.size)return file;const name=(String(file.name||'photo').replace(/\.[^.]+$/,'')||'photo')+'_ithaki.jpg';return new File([blob],name,{type:'image/jpeg',lastModified:Date.now()})}catch(e){console.warn('photo resize skipped',e);return file}finally{try{bmp&&bmp.close&&bmp.close()}catch{}}}
async function waitMediaIfProcessing(up){if(!up||!up.processing)return up;const id=up.meta_id;setProcessing(uiText('Compressing video...'));for(let i=0;i<900;i++){await new Promise(r=>setTimeout(r,2000));let st;try{st=await fetchJson('/api/media/status/'+encodeURIComponent(id))}catch(e){continue}if(st.ready)return Object.assign({},up,st,{processing:false});if(st.failed||st.ok===false)throw new Error(st.message||'ffmpeg_processing_failed');setProcessing(uiText('Video processing...')+' '+Math.min(99,Math.floor(100*(i+1)/900))+'%',Math.min(99,Math.floor(100*(i+1)/900)))}throw new Error('Video compression timeout')}
async function refreshPublicTokenV249505(){
  let token='';
  const urls=[api('/app_connection_config.json'),api('/api/app/bootstrap')];
  for(const url of urls){
    try{
      const r=await fetch(url,{cache:'no-store',credentials:'same-origin'});
      if(!r.ok)continue;
      const j=await r.json();
      const t=String(j.public_app_token||'').trim();
      if(t){token=t;state.token=t}
      const room=String(j.default_room_id||j.room_id||'').trim();if(room)state.room=room;
    }catch(e){}
  }
  return token||String(state.token||'');
}
function uploadWithProgress(file,kind,retry403=true){return new Promise((resolve,reject)=>{const fd=new FormData();fd.append('room_id',state.room);fd.append('device_id',state.device);fd.append('media_kind',kind||'file');fd.append('file',file,file.name);const x=new XMLHttpRequest();x.open('POST',api('/api/media/upload'));x.timeout=20*60*1000;x.setRequestHeader('X-ITHAKI-TOKEN',String(state.token||''));x.upload.onprogress=e=>{if(e.lengthComputable){setSending(e.loaded,e.total);if(e.loaded>=e.total&&isVideoFile(file,kind))setProcessing(uiText('Server received video. Preparing post...'))}};x.onload=async()=>{if((x.status===401||x.status===403)&&retry403){try{await refreshPublicTokenV249505();return resolve(await uploadWithProgress(file,kind,false))}catch(e){return reject(e)}}try{if(x.status<200||x.status>=300)throw new Error(uploadErrorMessage(x));const out=JSON.parse(x.responseText||'{}');if(!out||out.ok===false)throw new Error(out&&((out.message||out.reason))||'upload_not_confirmed');resolve(out)}catch(e){reject(e)}};x.onerror=()=>reject(new Error('network upload'));x.ontimeout=()=>reject(new Error('upload timeout'));x.send(fd)})}
async function sendPreview(){if(state.sending)return false;const {ctx,file,kind,target}=state.preview;if(!file)return false;state.sending=true;try{await refreshPublicTokenV249505();let uploadFile=state.preview.preparedFile;if(!uploadFile){uploadFile=await preparePhotoForUpload(file,kind);uploadFile=await prepareVideoForFastUploadV249503(uploadFile,kind);state.preview.preparedFile=uploadFile}await ensureFfmpegReadyForVideo(uploadFile,kind);let raw=state.preview.uploadedRaw;if(!raw){setSending(0,uploadFile.size);raw=await uploadWithProgress(uploadFile,kind,true);state.preview.uploadedRaw=raw}const caption=($('previewCaption')?.value||'').trim();const keywords=typeof feedKeywordsV249287==='function'?feedKeywordsV249287($('previewKeywords')?.value||''):[];const isVideo=isVideoFile(uploadFile,kind);if(raw&&raw.processing&&isVideo){setProcessing(uiText('Compressing video...'));toast(uiText('Video uploaded. Waiting for final video URL before publishing.'),7000)}let up=state.preview.uploadedReady;if(!up){up=await waitMediaIfProcessing(raw);state.preview.uploadedReady=up}if(isVideo&&(!up.url&&!up.file_url))throw new Error('video_final_url_missing');const mediaReady=normalizeMessageMediaV249464({url:up.url||up.file_url,filename:up.filename||uploadFile.name,mime_type:up.mime_type||uploadFile.type,kind:(up.kind||up.media_kind)||(isVideoFile(uploadFile,kind)?'video':uploadFile.type.startsWith('image/')?'photo':uploadFile.type.startsWith('audio/')?'audio':'file'),size:up.size_bytes||uploadFile.size,meta_id:up.meta_id||raw.meta_id||'',serverStored:true,fallback:!!(up.compression&&up.compression.fallback)});const k=mediaReady.kind;const payload=JSON.stringify({body:caption,description:caption,keywords,media:mediaReady});let confirmed=true;if(ctx==='feed')confirmed=await sendFeedPayload(payload,k,{anonymous:!!$('previewAnonymous')?.checked});else if(ctx==='comment')await sendComment(String(target||state.commentPostId||''),payload);else if(ctx==='comment_frame')await sendMessagePayload('comment:'+String(target||''),payload);else await sendMessagePayload(ctx==='space'?(target||state.currentSpaceChannel):(target||state.activeChannel),payload);if(ctx==='feed'&&confirmed!==true)throw new Error('publication_not_confirmed_by_server');state.sending=false;closePreview();toast(ctx==='feed'?'Η δημοσίευση καταχωρίστηκε στη Ροή.':uiText('Sent'));if(ctx==='feed')page('feed');else if(ctx==='dm'){if(state.page!=='dm')page('dm');await loadMessages(true)}else if(ctx==='space'){if(state.page!=='spaces')await renderSpaces();await loadSpaceMessages(true)}else if(ctx==='comment'){await loadPanelComments(String(target||state.commentPostId||''))}else if(ctx==='comment_frame'){document.querySelectorAll('iframe').forEach(f=>{try{f.contentWindow.postMessage({type:'ithaki-v249395-comment-sent',postId:String(target||'')},'*')}catch(e){}})}return true}catch(e){state.sending=false;const b=$('previewSend');if(b){b.disabled=false;b.textContent=uiText('Send again')}const pt=$('progressText');if(pt)pt.textContent=(e.message||String(e));toast(uiText('Not sent')+': '+(e.message||String(e)),7000);return false}}
window.__ITHAKI_V249464_DM_MEDIA_FIX__={encrypted_media_cards:true,internal_file_forward:true,external_binary_share:true,generic_mime_inference:true};window.__ITHAKI_CORE_OPEN_PREVIEW__=openPreview;window.__ITHAKI_CORE_CLOSE_PREVIEW__=closePreview;window.__ITHAKI_CORE_SEND_PREVIEW__=sendPreview;
function flowServerMessageV249506(data,status,text){
  const d=data&&typeof data==='object'?(data.detail||data):null;
  const m=String((d&&((d.message||d.reason||d.error||d.detail)))||(data&&data.message)||text||'').trim();
  if(status===401)return m||'Η σύνδεση δημοσίευσης έληξε. Έγινε ανανέωση και χρειάζεται νέα προσπάθεια.';
  if(status===403)return m||'Ο server απέρριψε τη δημοσίευση (403).';
  if(status===429)return m||'Πολλές προσπάθειες. Περίμενε λίγο και δοκίμασε ξανά.';
  return m||('flow_send_'+String(status||'error'));
}
async function confirmFeedPayloadV249506(body){
  try{
    const r=await fetch(api('/api/flow/confirm_v249506'),{method:'POST',headers:headers(true),body:JSON.stringify(body),cache:'no-store'});
    const txt=await r.text();let data={};try{data=txt?JSON.parse(txt):{}}catch(e){data={}}
    if(r.ok&&data&&data.confirmed===true&&data.post_id)return Object.assign({},data,{ok:true,confirmed:true,verified_after_response_loss:true});
  }catch(e){}
  return {ok:false,confirmed:false};
}
async function postFeedPayloadV249506(body,retryAuth=true){
  await refreshPublicTokenV249505();
  let r=null,txt='',data={};
  try{
    r=await fetch(api('/api/flow/send'),{method:'POST',headers:headers(true),body:JSON.stringify(body),cache:'no-store'});
    txt=await r.text();
    try{data=txt?JSON.parse(txt):{}}catch(e){data={}}
  }catch(e){
    const verified=await confirmFeedPayloadV249506(body);
    if(verified.confirmed)return verified;
    throw new Error('Η σύνδεση χάθηκε πριν επιβεβαιωθεί η δημοσίευση: '+String(e&&e.message||e));
  }
  if((r.status===401||r.status===403)&&retryAuth){
    await refreshPublicTokenV249505();
    return postFeedPayloadV249506(body,false);
  }
  if(r.ok&&data&&data.ok!==false&&(data.post_id||data.duplicate_prevented===true)){
    return Object.assign({},data,{ok:true,confirmed:true});
  }
  if(r.ok&&data&&data.ok===true){
    const verified=await confirmFeedPayloadV249506(body);
    if(verified.confirmed)return Object.assign({},data,verified,{ok:true,confirmed:true});
  }
  if(r.status>=500||r.status===408){
    const verified=await confirmFeedPayloadV249506(body);
    if(verified.confirmed)return verified;
  }
  throw new Error(flowServerMessageV249506(data,r.status,txt));
}
async function sendFeedPayload(payload,kind='text',opts={}){
  const anon=!!(opts&&opts.anonymous);
  const attemptId='pub_'+Date.now().toString(36)+'_'+Math.random().toString(36).slice(2,8);
  const body={room_id:state.room,sender_id:state.device,nickname:anon?uiText('Anonymous'):state.name,language:uiLang(),avatar:anon?'':avatarValue(),text:payload,post_kind:kind,anonymous:anon,visibility:'public'};
  window.__ITHAKI_LAST_PUBLICATION_V249506__={attempt_id:attemptId,at:Date.now(),confirmed:false,kind:String(kind||'text')};
  try{
    const result=await postFeedPayloadV249506(body,true);
    if(!result||result.confirmed!==true||!result.post_id)throw new Error('Η δημοσίευση δεν βρέθηκε στον server μετά την αποστολή.');
    const sig=String(kind)+'|'+String(payload||'').replace(/\s+/g,' ').trim().toLowerCase().slice(0,420);
    try{localStorage.setItem('ith_last_post_sig_v249164',sig);localStorage.setItem('ith_last_post_at_v249164',String(Date.now()));localStorage.setItem('ith_feed_category_v249429','all');localStorage.removeItem('ith_feed_selected_keyword_v249429')}catch(e){}
    window.__ITHAKI_LAST_PUBLICATION_V249506__={attempt_id:attemptId,at:Date.now(),confirmed:true,post_id:String(result.post_id),duplicate_prevented:!!result.duplicate_prevented,kind:String(kind||'text')};
    try{window.dispatchEvent(new CustomEvent('ithaki:publication-sent',{detail:{kind:kind,device_id:state.device,confirmed:true,post_id:String(result.post_id)}}))}catch(e){}
    setTimeout(()=>{try{if(window.ITH&&typeof ITH.ensurePublishedVisibleV249474==='function')ITH.ensurePublishedVisibleV249474()}catch(e){}},80);
    return true;
  }catch(e){
    window.__ITHAKI_LAST_PUBLICATION_V249506__={attempt_id:attemptId,at:Date.now(),confirmed:false,error:String(e&&e.message||e),kind:String(kind||'text')};
    throw e;
  }
}
function todayKey(){try{return new Date().toISOString().slice(0,10)}catch(e){return String(Math.floor(Date.now()/86400000))}}
function ithakiWisdomText(){
  const arr=[
    'Η καθαρή κουβέντα ανοίγει δρόμο εκεί που η σιωπή έβαλε απόσταση.',
    'Ο σεβασμός δεν μικραίνει την ελευθερία· της δίνει χώρο να σταθεί.',
    'Ο άνθρωπος φαίνεται στον τρόπο που ακούει πριν απαντήσει.',
    'Κάθε μήνυμα μπορεί να γίνει γέφυρα, όταν γράφεται με μέτρο και καρδιά.',
    'Η γνώμη έχει αξία όταν αφήνει χώρο και στη γνώμη του άλλου.',
    'Η αλήθεια χρειάζεται καθαρότητα, όχι φωνές.',
    'Η ΙΘΑΚΗ είναι δρόμος επικοινωνίας: λίγα δεδομένα, καθαρή πρόθεση, ανθρώπινη φωνή.',
    'Ο σοφός λόγος δεν πιέζει· φωτίζει.',
    'Το καλό περιβάλλον χτίζεται με μικρές πράξεις αξιοπρέπειας κάθε μέρα.',
    'Πρώτα γινόμαστε άνθρωποι μεταξύ μας, μετά γινόμαστε κοινότητα.'
  ];
  try{
    const last=+(localStorage.getItem('ith_wisdom_last_v249166')||0);
    let ix=+(localStorage.getItem('ith_wisdom_ix_v249166')||-1);
    if(!last || Date.now()-last>2500){ix=(ix+1+Math.floor(Math.random()*3))%arr.length;localStorage.setItem('ith_wisdom_ix_v249166',String(ix));localStorage.setItem('ith_wisdom_last_v249166',String(Date.now()))}
    return arr[Math.max(0,ix)%arr.length];
  }catch(e){return arr[Math.floor(Date.now()/60000)%arr.length]}
}
function updateNetDotVisual(ok,label){
  try{
    const dot=$('netDot');
    if(dot){
      dot.classList.toggle('on',!!ok);
      dot.classList.toggle('serverOk',!!ok);
      dot.classList.toggle('warn',false);
      dot.classList.toggle('offline',!ok);
      dot.style.background=ok?'#36f0a0':'#777';
      dot.style.boxShadow=ok?'0 0 16px #36f0a0, 0 0 30px rgba(54,240,160,.55)':'none';
      dot.title=label||(ok?'Σύνδεση server ενεργή':'Δεν υπάρχει σύνδεση με server');
      dot.setAttribute('aria-label',dot.title);
    }
    if(document.body)document.body.setAttribute('data-server',ok?'online':'offline');
  }catch(e){}
}
function setConnectionGreen(label){
  updateNetDotVisual(true,label||'Σύνδεση server ενεργή');
  try{setDoveStatus('connected')}catch(e){}
  try{if($('subStatus'))$('subStatus').textContent=label||'Σύνδεση server ενεργή'}catch(e){}
}
function setConnectionOffline(label){
  if(state.wsReady){setConnectionGreen('Realtime WebSocket ενεργό');return}
  updateNetDotVisual(false,label||'Δεν υπάρχει σύνδεση με server');
  try{setDoveStatus('offline')}catch(e){}
  try{if($('subStatus'))$('subStatus').textContent=label||'Δεν υπάρχει σύνδεση με server'}catch(e){}
}
async function connectionPulse(){
  try{
    const ctrl=('AbortController' in window)?new AbortController():null;
    const timer=ctrl?setTimeout(()=>ctrl.abort(),3500):null;
    try{
      const r=await fetch(api('/health'),{cache:'no-store',signal:ctrl?ctrl.signal:undefined});
      if(r&&r.ok){setConnectionGreen('Σύνδεση server ενεργή · '+connectionLabel());return true}
    }finally{if(timer)clearTimeout(timer)}
  }catch(e){}
  if(state.wsReady){setConnectionGreen('Realtime WebSocket ενεργό · '+connectionLabel());return true}
  return false;
}
function startConnectionPulse(){
  try{
    if(window.__ithConnectionPulseV249176)return;
    window.__ithConnectionPulseV249176=1;
    setTimeout(connectionPulse,250);
    setTimeout(connectionPulse,1600);
    setInterval(connectionPulse,6000);
  }catch(e){}
}
async function syncProfileNow(silent=false){
  const payload={room_id:state.room,device_id:state.device,nickname:state.name,language:(typeof uiLang==='function'?uiLang():'el'),adult_confirmed:!!state.age16,policy_accepted:!!state.policyOk,ai_host_enabled:false};
  try{
    if(!state.api)await checkConnections();
    const r=await fetchJson('/api/profile/register',{method:'POST',body:JSON.stringify(payload)});
    try{localStorage.removeItem('ith_profile_name_pending_sync');localStorage.setItem('ith_registered_member_v249154','1');localStorage.setItem('ith_profile_server_active_v249166','1')}catch(e){}
    await heartbeat();
    await loadPeople();
    setConnectionGreen('Προφίλ ενεργό · σύνδεση server ενεργή');
    if(!silent)toast('Το προφίλ ενεργοποιήθηκε στον server.',4500);
    return r;
  }catch(e){
    try{localStorage.setItem('ith_profile_server_active_v249166','0');localStorage.setItem('ith_profile_name_pending_sync','1')}catch(_){}
    if(!silent){
      const msg=String(e&&e.message||e||'');
      if(msg.includes('409'))toast('Το όνομα χρησιμοποιείται ήδη. Το κρατήσαμε στη συσκευή, αλλά διάλεξε άλλο για ενεργοποίηση στον server.',8500);
      else toast('Το προφίλ έμεινε αποθηκευμένο στη συσκευή. Θα γίνει ξανά συγχρονισμός όταν σταθεροποιηθεί η σύνδεση.',7500);
    }
    throw e;
  }
}
function parseText(t){const raw=String(t||'');try{const o=JSON.parse(raw);if(o&&typeof o==='object'){let media=o.media||null;if(!media&&o.kind)media=o;const isPoll=media&&String(media.kind||'').toLowerCase()==='poll';return{body:isPoll?'':(o.body||o.text||''),media:media||null}}}catch{}return{body:raw,media:null}}

function fileExt(name){const n=String(name||'');const m=n.match(/\.([a-zA-Z0-9]{1,8})$/);return m?m[1].toLowerCase():''}
function inferredMessageMediaKindV249464(m){
  m=m||{};const raw=String(m.kind||m.media_kind||'').toLowerCase();const mime=String(m.mime_type||m.type||'').toLowerCase();const ext=fileExt(m.filename||m.name||m.url||m.file_url||m.media_url||'');
  if(raw==='friend_request'||raw==='call_event'||raw==='poll'||raw==='video_processing')return raw;
  if(mime.startsWith('video/')||['mp4','m4v','mov','webm','3gp','3gpp','avi','mkv','mpeg','mpg'].includes(ext))return'video';
  if(mime.startsWith('image/')||['jpg','jpeg','png','gif','webp','bmp','heic','heif','svg'].includes(ext))return'photo';
  if(mime.startsWith('audio/')||['mp3','m4a','aac','wav','ogg','opus','flac','amr'].includes(ext))return'audio';
  if(raw==='video'||raw==='photo'||raw==='image'||raw==='audio'||raw==='file'||raw==='document')return raw==='image'?'photo':raw==='document'?'file':raw;
  return'file';
}
function inferredMessageMimeV249464(m,kind){
  m=m||{};let mime=String(m.mime_type||m.type||'').toLowerCase();if(mime&&mime!=='application/octet-stream'&&mime!=='binary/octet-stream')return mime;
  const ext=fileExt(m.filename||m.name||m.url||m.file_url||m.media_url||'');const map={mp4:'video/mp4',m4v:'video/mp4',mov:'video/quicktime',webm:'video/webm','3gp':'video/3gpp','3gpp':'video/3gpp',avi:'video/x-msvideo',mkv:'video/x-matroska',mpeg:'video/mpeg',mpg:'video/mpeg',jpg:'image/jpeg',jpeg:'image/jpeg',png:'image/png',gif:'image/gif',webp:'image/webp',bmp:'image/bmp',heic:'image/heic',heif:'image/heif',svg:'image/svg+xml',mp3:'audio/mpeg',m4a:'audio/mp4',aac:'audio/aac',wav:'audio/wav',ogg:'audio/ogg',opus:'audio/ogg',flac:'audio/flac',amr:'audio/amr',pdf:'application/pdf',doc:'application/msword',docx:'application/vnd.openxmlformats-officedocument.wordprocessingml.document',xls:'application/vnd.ms-excel',xlsx:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',ppt:'application/vnd.ms-powerpoint',pptx:'application/vnd.openxmlformats-officedocument.presentationml.presentation',txt:'text/plain',csv:'text/csv',zip:'application/zip'};
  return map[ext]||(kind==='video'?'video/mp4':kind==='photo'?'image/jpeg':kind==='audio'?'audio/mpeg':'application/octet-stream');
}
function normalizeMessageMediaV249464(m){if(!m||typeof m!=='object')return m;const out=Object.assign({},m);out.kind=inferredMessageMediaKindV249464(out);out.mime_type=inferredMessageMimeV249464(out,out.kind);return out}
function officeIcon(m){const ext=fileExt(m.filename||m.name||m.url||'');const mime=String(m.mime_type||m.type||'').toLowerCase();if(['doc','docx','odt','rtf'].includes(ext)||mime.includes('word'))return '📄';if(['xls','xlsx','ods','csv'].includes(ext)||mime.includes('excel')||mime.includes('spreadsheet'))return '📊';if(['ppt','pptx','odp'].includes(ext)||mime.includes('presentation'))return '📽️';if(ext==='pdf'||mime.includes('pdf'))return '📕';if(['zip','rar','7z'].includes(ext))return '🗜️';return '📎'}
function isOfficeLike(m){const ext=fileExt(m.filename||m.name||m.url||'');const mime=String(m.mime_type||m.type||'').toLowerCase();return ['doc','docx','odt','rtf','xls','xlsx','ods','csv','ppt','pptx','odp','pdf','txt','zip','rar','7z'].includes(ext)||mime.includes('pdf')||mime.includes('officedocument')||mime.includes('msword')||mime.includes('spreadsheet')||mime.includes('presentation')||mime.includes('text/')}
function externalUrl(url){const v=String(url||'');if(v.startsWith('/api/'))return (isAndroidAssetOriginV249470(state.api)?ITH_DOMAIN_BASE:state.api.replace(/\/$/,''))+v;try{const u=new URL(v,location.href);if(isAndroidAssetOriginV249470(u.origin)&&u.pathname.startsWith('/api/'))return ITH_DOMAIN_BASE+u.pathname+u.search+u.hash}catch(e){}return v}
function renderOfficeCard(m,src,tools=true){const name=esc(m.filename||m.name||'Office file');const raw=externalUrl(src);const rawJs=escJs(raw);const filename=mediaFileNameFrom(raw,m.filename||m.name||'');const fnJs=escJs(filename);const mime=String(m.mime_type||m.type||'application/octet-stream');const mimeJs=escJs(mime);const size=m.size?mb(m.size):'';const icon=officeIcon(m);const actions=tools?`<div class="fileTools"><button class="btn" onclick="ITH.openActualMediaFile('${rawJs}','${fnJs}','${mimeJs}','file')">👁️ ${uiText('Open')}</button><button class="btn" onclick="ITH.downloadMediaFile('${rawJs}','${fnJs}','${mimeJs}','file')">⬇️ ${uiText('Download')}</button><button class="btn" onclick="ITH.shareMediaFile('${rawJs}','${fnJs}','${mimeJs}','file')">📤 ${uiText('Share')}</button></div>`:'';return `<div class="officeFileCard"><div class="officeIcon">${icon}</div><div class="officeInfo"><b>${name}</b><div class="date">${esc(mime||'file')} ${size?'· '+size:''}</div>${actions}</div></div>`}
function mediaHtml(m,tools=true){if(!m)return'';const kind=String(m.kind||'').toLowerCase();if(kind==='poll')return renderPollCard(m);const url=m.url||m.file_url||m.media_url||'';const mime0=String(m.mime_type||m.type||'').toLowerCase();if(kind==='video_processing'||mime0==='video/processing'||(m.meta_id&&!url))return processingMediaHtml(m,tools);if(!url)return'';const raw=externalUrl(url);const src=esc(raw);const rawJs=escJs(raw);const mime=String(m.mime_type||m.type||'').toLowerCase();let inner;if(mime.startsWith('image/')||kind==='photo'||kind==='image')inner=`<div class="mediaInline"><img src="${src}" loading="lazy"><button class="mediaOpenBtn" onclick="event.stopPropagation();ITH.openMediaViewer('${rawJs}','image')">⛶</button></div>`;else if(mime.startsWith('video/')||kind==='video')inner=`<div class="mediaInline"><video class="feedVideo" src="${src}" controls playsinline preload="auto" onclick="ITH.enableVideoSoundV249220&&ITH.enableVideoSoundV249220(this)"></video><button class="mediaOpenBtn" onclick="event.stopPropagation();ITH.openMediaViewer('${rawJs}','video')">⛶</button></div>`;else if(mime.startsWith('audio/')||kind==='audio')inner=`<audio src="${src}" controls></audio>`;else inner=renderOfficeCard(m,src,tools);const fileTools=(tools && !(inner.includes('officeFileCard')))?`<div class="fileTools"><button class="btn" onclick="ITH.openMediaViewer('${rawJs}','${escJs(mime||kind||'file')}')">👁️ ${uiText('Open')}</button><a class="btn" href="${src}" download>⬇️ ${uiText('Download')}</a><button class="btn" onclick="ITH.share('${rawJs}')">📤 ${uiText('Share')}</button></div>`:'';return tools?`<div class="postMediaWrap">${inner}${fileTools}</div>`:(inner+fileTools)}
function messageFileFolder(mime,kind){const k=String(kind||'').toLowerCase(),mm=String(mime||'').toLowerCase();if(mm.startsWith('image/')||k==='photo'||k==='image')return 'photos';if(mm.startsWith('video/')||k==='video')return 'videos';if(mm.startsWith('audio/')||k==='audio')return 'audio';return 'files'}
function mediaFileNameFrom(url,filename=''){let n=String(filename||'').trim();if(!n){try{n=decodeURIComponent(String(url||'').split('/').pop().split('?')[0]||'')}catch{}}if(!n)n='ok_ithaki_file';return n.replace(/[\\/:*?"<>|]+/g,'_')}
function blobToDataUrl(blob){return new Promise((resolve,reject)=>{const r=new FileReader();r.onload=()=>resolve(String(r.result||''));r.onerror=()=>reject(r.error||new Error('file read failed'));r.readAsDataURL(blob)})}
async function fetchMediaBlob(url){const final=externalUrl(url);const headers={};try{if(state&&state.token)headers['X-ITHAKI-TOKEN']=state.token}catch{}const r=await fetch(final,{cache:'no-store',headers});if(!r.ok)throw new Error('download '+r.status);return await r.blob()}
async function downloadMediaFile(url,filename='',mime='',kind='file'){try{const final=externalUrl(url);const name=mediaFileNameFrom(final,filename);const blob=await fetchMediaBlob(final);const type=mime||blob.type||'application/octet-stream';if(bridgeHas('saveBase64ToProfile')){const data=await blobToDataUrl(blob);const path=bridgeCall('saveBase64ToProfile',messageFileFolder(type,kind),name,type,data);toast(String(path||'').startsWith('error')?path:uiText('Download')+' OK');return false}const a=document.createElement('a');const objectUrl=URL.createObjectURL(blob);a.href=objectUrl;a.download=name;document.body.appendChild(a);a.click();setTimeout(()=>{try{URL.revokeObjectURL(objectUrl);a.remove()}catch{}},1200);toast(uiText('Download')+' OK');return false}catch(e){toast('Download failed: '+(e.message||e),6500);return false}}
async function shareMediaFile(url,filename='',mime='',kind='file'){if(window.__ITHAKI_V249523_SHARE_READY__&&window.ITH&&typeof ITH.shareActualFileV249523==='function')return ITH.shareActualFileV249523(url,filename,mime,kind);try{const final=externalUrl(url);const name=mediaFileNameFrom(final,filename);const type=mime||'application/octet-stream';const br=window.AndroidBridge||window.OKITHAKI_ANDROID;if(br&&typeof br.shareRemoteFileV249521==='function'&&/^https?:/i.test(final)){toast('Προετοιμασία πραγματικού αρχείου…');const rr=String(br.shareRemoteFileV249521(final,name,type)||'');if(/^(ok|queued)/i.test(rr))return false;throw new Error(rr||'native remote file share failed')}const blob=await fetchMediaBlob(final);const finalType=mime||blob.type||'application/octet-stream';if(bridgeHas('shareBase64File')&&blob.size<=18*1024*1024){const data=await blobToDataUrl(blob);const r=bridgeCall('shareBase64File',name,finalType,data);toast(String(r||'').toLowerCase().startsWith('ok')?uiText('Share'):String(r||'Share'));return false}let file=null;try{file=new File([blob],name,{type:finalType})}catch{}if(file&&navigator.canShare&&navigator.canShare({files:[file]})&&navigator.share){await navigator.share({files:[file],title:'OK ITHAKI'});return false}return downloadMediaFile(final,name,finalType,kind)}catch(e){toast('Share file failed: '+(e.message||e),6500);return false}}
function injectV249208ProfessionalCss(){
  try{
    if(document.getElementById('ithV249208ProfessionalCss'))return;
    const st=document.createElement('style');
    st.id='ithV249208ProfessionalCss';
    st.textContent=`
      #typing.typingActive{color:#36f0a0!important;font-weight:900!important;text-shadow:0 0 12px rgba(54,240,160,.25)!important}
      .readReceipt{display:inline-flex;align-items:center;gap:3px;margin-left:6px;color:rgba(255,255,255,.58);font-size:11px;font-weight:800}.readReceipt.seen{color:#36f0a0;text-shadow:0 0 10px rgba(54,240,160,.25)}
      .msgCallCard{display:flex;align-items:center;gap:10px;margin:4px 0;padding:9px 11px;border-radius:16px;background:linear-gradient(135deg,rgba(255,217,110,.15),rgba(80,220,255,.08));border:1px solid rgba(255,217,110,.25);box-shadow:0 10px 24px rgba(0,0,0,.18)}
      .msgCallCard b{display:block}.msgCallCard small{display:block;opacity:.78;font-size:12px}.msgCallIcon{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.16);font-size:20px}.msgCallCard.missed{border-color:rgba(255,92,92,.42);background:linear-gradient(135deg,rgba(255,92,92,.14),rgba(255,217,110,.08))}.msgCallCard.answered{border-color:rgba(54,240,160,.34)}
      #feedPage .feedGoldPrompt,#feedPage .photoLikePrompt{display:none!important}
      #feedPage .feedGoldLogo{width:88px!important;height:88px!important;border-radius:25px!important;margin-bottom:7px!important;background:radial-gradient(circle at 30% 20%,rgba(255,255,255,.22),rgba(255,217,110,.12))!important}
      #feedPage .feedGoldLogo img{width:70px!important;height:70px!important;object-fit:contain!important}
      #feedPage .feedGoldBrandText{margin:2px auto 7px!important;text-align:center!important;font-weight:1000!important;letter-spacing:.09em!important;font-size:12px!important;color:#ffe6a2!important;text-transform:uppercase!important}.homeOkRainbow,.feedGoldBrandText .okRainbow{background:linear-gradient(90deg,#ff4d4d,#ffd36e,#36f0a0,#50dcff,#b58cff)!important;-webkit-background-clip:text!important;background-clip:text!important;color:transparent!important;-webkit-text-fill-color:transparent!important;text-shadow:none!important}.feedGoldBrandText small{font-size:10px!important;letter-spacing:.18em!important;color:#fff1c4!important;text-transform:lowercase!important}
      #feedPage .feedGoldWisdomCard .feedGoldQuote,.greekWisdomCard .proPanelText p{color:#ffd36e!important;font-size:clamp(21px,5.4vw,34px)!important;line-height:1.16!important;font-weight:1000!important;text-shadow:0 4px 20px rgba(255,211,110,.22),0 8px 34px rgba(0,0,0,.62)!important}
      #feedPage .feedGoldCardActions,#feedPage .post.pollPost .pollPostActions{right:7px!important;left:auto!important;max-width:46px!important;overflow:visible!important}.feedGoldCardActions .btn,#feedPage .post.pollPost .pollPostActions .actionIcon{font-size:18px!important;color:#fff!important;line-height:1!important}.feedGoldCardActions .btn::before,#feedPage .post.pollPost .pollPostActions .actionIcon::before{content:none!important;display:none!important}.feedGoldCardActions .btn{width:40px!important;height:40px!important;min-width:40px!important;min-height:40px!important;border-radius:50%!important;padding:0!important;display:grid!important;place-items:center!important}.feedGoldCardActions .btn span{display:block!important;font-size:18px!important;line-height:1!important}
      #feedPage .feedGoldPollOptions,#feedPage .pollVoteOptions,#feedPage .photoLikeChoices{max-width:100%!important;box-sizing:border-box!important}.feedGoldPollChoice,.pollChoice,.photoLikeChoice{box-sizing:border-box!important;max-width:100%!important;overflow:hidden!important}.feedGoldPollChoice span,.pollChoice span,.photoLikeChoice span{min-width:0!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}
      @media(max-width:760px){#feedPage .feedGoldLogo{width:78px!important;height:78px!important}#feedPage .feedGoldLogo img{width:62px!important;height:62px!important}#feedPage .feedGoldBrandText{font-size:11px!important;margin-bottom:5px!important}#feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(20px,5.8vw,30px)!important}}
    `;
    document.head.appendChild(st);
  }catch(e){console.warn('v249208 css',e)}
}
function readStateKey(channel){return 'ith_read_state_'+String(channel||'')}
function saveReadState(channel,data){try{localStorage.setItem(readStateKey(channel),JSON.stringify(data||{}))}catch{}}
function getReadState(channel){try{return JSON.parse(localStorage.getItem(readStateKey(channel))||'{}')||{}}catch{return {}}}
async function markActiveChannelRead(){
  try{
    if(!state.activeChannel)return false;
    const box=$('messages'); if(!box)return false;
    const last=[...box.querySelectorAll('.bubble')].map(x=>+(x.dataset.ts||0)).reduce((a,b)=>Math.max(a,b),0);
    if(!last)return false;
    await fetchJson('/api/messages/mark_read',{method:'POST',body:JSON.stringify({room_id:state.room,channel:state.activeChannel,reader_id:state.device,read_until:last})});
    return true;
  }catch(e){return false}
}
async function loadReadState(channel){
  try{
    channel=channel||state.activeChannel; if(!channel)return {};
    const r=await fetchJson(`/api/messages/read_state?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent(channel)}`);
    saveReadState(channel,r.reads||{}); updateReadReceipts(channel,r.reads||{}); return r.reads||{};
  }catch(e){const s=getReadState(channel||state.activeChannel); updateReadReceipts(channel||state.activeChannel,s); return s}
}
function updateReadReceipts(channel,reads){
  try{
    reads=reads||getReadState(channel||state.activeChannel);
    const peer=state.activePeer;
    const until=+(reads&&reads[peer]||0);
    const peerInfo=state.people&&peer?state.people.get(peer):null;
    const peerOnline=!!(peerInfo&&peerInfo.online);
    const peerInChat=($('typing')&&String($('typing').textContent||'').trim().length>0);
    document.querySelectorAll('.bubble.mine .readReceipt').forEach(el=>{
      const ts=+(el.dataset.ts||0);
      const seen=until&&ts&&until>=ts;
      el.classList.toggle('seen',!!seen);
      el.classList.toggle('delivered',!seen&&(peerOnline||peerInChat));
      el.textContent=seen?'✓✓ διαβάστηκε':((peerOnline||peerInChat)?'✓✓ παραδόθηκε':'✓ στάλθηκε');
      el.title=seen?'Το διάβασε':((peerOnline||peerInChat)?'Το πήρε / είναι μέσα':'Στάλθηκε στον server');
    });
  }catch(e){}
}
async function sendTypingNow(active){
  try{
    if(!state.activeChannel)return false;
    await fetchJson('/api/messages/typing',{method:'POST',body:JSON.stringify({room_id:state.room,channel:state.activeChannel,device_id:state.device,nickname:state.name,is_typing:!!active})});
    return true;
  }catch(e){return false}
}
function handleTypingInput(){
  try{sendTypingNow(true); clearTimeout(state.typingStopTimer); state.typingStopTimer=setTimeout(()=>sendTypingNow(false),1700)}catch(e){}
  return true;
}
async function pollTypingState(){
  try{
    if(state.page!=='dm'||!state.activeChannel)return false;
    const r=await fetchJson(`/api/messages/typing?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent(state.activeChannel)}&viewer_id=${encodeURIComponent(state.device)}`);
    const box=$('typing'); if(!box)return false;
    const arr=(r.typing||[]).filter(x=>String(x.device_id)!==String(state.device));
    const typing=arr.find(x=>x.is_typing);
    if(typing){box.textContent=(typing.nickname||'Μέλος')+' γράφει τώρα...';box.classList.add('typingActive','presenceOn')}
    else if(arr.length){box.textContent=(arr[0].nickname||'Μέλος')+' είναι μέσα στη συνομιλία';box.classList.add('presenceOn');box.classList.remove('typingActive')}
    else {
      const p=state.activePeer&&state.people?state.people.get(state.activePeer):null;
      box.textContent=(p&&p.online)?'είναι online':'εκτός συνομιλίας';
      box.classList.toggle('presenceOn',!!(p&&p.online));box.classList.remove('typingActive');
    }
    updateReadReceipts(state.activeChannel);
  }catch(e){}
  return false;
}
function callEventHtml(m){
  const k=String((m&&m.call_kind)||'video'); const st=String((m&&m.status)||'call');
  const icon=k==='voice'?'📞':'📹';
  const title=st==='missed'?'Αναπάντητη κλήση':st==='rejected'?'Απορρίφθηκε κλήση':st==='answered'?'Απαντήθηκε κλήση':st==='ended'?'Τερματίστηκε κλήση':'Κλήση';
  return `<div class="msgCallCard ${esc(st)}"><span class="msgCallIcon">${icon}</span><span><b>${title}</b><small>${k==='voice'?'Τηλεφωνική κλήση':'Βιντεοκλήση'}</small></span></div>`;
}
async function sendCallTimeline(status,kind,channel){
  // V249260: no client-side call cards. The server alone writes one missed-call card only on timeout.
  return false
}
const messageMediaShareRegistryV249464=new Map();
function registerMessageMediaShareV249464(m){const media=normalizeMessageMediaV249464(m);const key='media_'+Date.now().toString(36)+'_'+Math.random().toString(36).slice(2,9);messageMediaShareRegistryV249464.set(key,media);if(messageMediaShareRegistryV249464.size>180){const first=messageMediaShareRegistryV249464.keys().next().value;messageMediaShareRegistryV249464.delete(first)}return key}
function messageMediaFriendsV249464(){try{if(typeof v249235FriendListForMessages==='function')return (v249235FriendListForMessages()||[]).filter(p=>String(p.id||p.device_id||'')&&String(p.id||p.device_id||'')!==String(state.device))}catch(e){}return[]}
function openMessageMediaShareV249464(key){const m=messageMediaShareRegistryV249464.get(String(key||''));if(!m)return toast(uiText('File is no longer available.'));const friends=messageMediaFriendsV249464();const filename=mediaFileNameFrom(m.url||m.file_url||m.media_url||'',m.filename||m.name||'OK_ITHAKI_file');const list=friends.map(p=>{const id=String(p.id||p.device_id||'');return `<button class="dmFriendRowV249235" onclick="ITH.sendMessageMediaToFriendV249464('${escJs(key)}','${escJs(id)}')">${avatarHtml(p)}<span class="who"><b>${esc(p.nickname||'Friend')}</b><small>${p.online?uiText('Active'):uiText('Offline')}</small></span><span class="go">📤</span></button>`}).join('');$('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>📤 ${uiText('Share file')}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><b>${esc(filename)}</b><div class="date">${esc(m.mime_type||'file')}</div><button class="btn green" style="width:100%;margin-top:10px" onclick="ITH.shareMessageMediaExternalV249464('${escJs(key)}')">📱 ${uiLang()==='en'?'Share externally':'Κοινοποίηση εξωτερικά'}</button></div><div class="card"><b>👥 ${uiLang()==='en'?'Send to an ITHAKI friend':'Αποστολή σε φίλο ΙΘΑΚΗΣ'}</b><div class="date">${uiLang()==='en'?'The actual file card is forwarded, not a text link.':'Προωθείται η πραγματική κάρτα αρχείου, όχι σύνδεσμος κειμένου.'}</div></div><div class="dmFriendListV249235">${list||`<div class="card">${uiLang()==='en'?'No accepted friends are available.':'Δεν υπάρχουν διαθέσιμοι αποδεκτοί φίλοι.'}</div>`}</div>`;$('memberMenu').classList.add('show');return false}
async function sendMessageMediaToFriendV249464(key,peerId){const m=messageMediaShareRegistryV249464.get(String(key||''));if(!m||!peerId)return false;try{const channel=channelFor(state.device,String(peerId));await sendMessagePayload(channel,JSON.stringify({body:'',media:normalizeMessageMediaV249464(m)}));toast(uiLang()==='en'?'File sent inside ITHAKI. Opening the conversation.':'Το αρχείο στάλθηκε μέσα στην ΙΘΑΚΗ. Ανοίγω τη συνομιλία.');closeMember();await startDM(String(peerId));setTimeout(()=>{try{showDMChatScreenV249235&&showDMChatScreenV249235()}catch(e){}},80);return true}catch(e){toast((uiLang()==='en'?'File was not sent: ':'Δεν στάλθηκε το αρχείο: ')+(e.message||e),7000);return false}}
function shareMessageMediaExternalV249464(key){const m=messageMediaShareRegistryV249464.get(String(key||''));if(!m)return false;const raw=m.url||m.file_url||m.media_url||'';const f=window.ITH&&ITH.externalActualFileV249525;return typeof f==='function'?f(raw,m.filename||m.name||'',m.mime_type||m.type||''):shareMediaFile(raw,m.filename||m.name||'',m.mime_type||m.type||'',m.kind||'file')}
function messageMediaHtml(m){
  if(!m)return'';m=normalizeMessageMediaV249464(m);const kind=String(m.kind||'').toLowerCase();
  if(kind==='friend_request')return friendRequestHtmlV249223(m);
  if(kind==='call_event')return callEventHtml(m);
  if(kind==='poll')return `<div class="msgMediaWrap msgPollWrap">${renderPollCard(m)}</div>`;
  const url=m.url||m.file_url||m.media_url||'';const mime=String(m.mime_type||m.type||'').toLowerCase();
  if(kind==='video_processing'||mime==='video/processing'||(m.meta_id&&!url))return `<div class="msgMediaWrap">${processingMediaHtml(m,false)}</div>`;
  if(!url)return'';
  const raw=externalUrl(url),src=esc(raw),rawJs=escJs(raw),filename=mediaFileNameFrom(raw,m.filename||m.name||''),fnJs=escJs(filename),mimeJs=escJs(mime||kind||'application/octet-stream'),kindJs=escJs(kind||'file'),shareKey=registerMessageMediaShareV249464(m);
  const open=`<button class="btn mini" title="${uiText('Open')}" onclick="ITH.openMediaViewer('${rawJs}','${mimeJs}','${fnJs}')">⛶ ${uiText('Open full screen')}</button>`;
  const save=`<button class="btn mini" title="${uiText('Download')}" onclick="ITH.downloadMediaFile('${rawJs}','${fnJs}','${mimeJs}','${kindJs}')">⬇️ ${uiText('Save')}</button>`;
  const share=`<button class="btn mini" title="${uiText('Share')}" onclick="ITH.openMessageMediaShareV249464('${escJs(shareKey)}')">📤 ${uiText('Share')}</button>`;
  const tools=`<div class="msgMediaTools">${open}${save}${share}</div>`;
  let inner='';
  if(kind==='photo')inner=`<div class="msgInlineFile"><img class="msgImage" src="${src}" loading="lazy" onclick="ITH.openMediaViewer('${rawJs}','image','${fnJs}')"></div>`;
  else if(kind==='video')inner=`<div class="msgVideoShell"><video class="msgVideo" src="${src}" controls playsinline preload="metadata" onloadedmetadata="this.classList.add('ready')" onerror="this.parentElement.classList.add('videoError')" onclick="ITH.enableVideoSoundV249220&&ITH.enableVideoSoundV249220(this)"></video><span class="msgVideoBadge">${uiText('Video')}</span></div>`;
  else if(kind==='audio')inner=`<audio class="msgAudio" src="${src}" controls preload="metadata"></audio>`;
  else {const size=m.size?mb(m.size):'';return `<div class="msgMediaWrap"><div class="officeFileCard msgOfficeFileCard"><div class="officeIcon">${officeIcon(m)}</div><div class="officeInfo"><b>${esc(filename)}</b><div class="date">${esc(m.mime_type||mime||'file')} ${size?'· '+size:''}</div><div class="fileTools"><button class="btn mini" onclick="ITH.openActualMediaFile('${rawJs}','${fnJs}','${mimeJs}','file')">👁️ ${uiText('Open file')}</button>${save}${share}</div></div></div></div>`}
  return `<div class="msgMediaWrap ${kind==='video'?'msgVideoFrame':''}">${inner}${tools}</div>`;
}

async function openActualMediaFile(url,filename='',mime='',kind='file'){
  try{const final=externalUrl(url),name=mediaFileNameFrom(final,filename),blob=await fetchMediaBlob(final),type=mime||blob.type||'application/octet-stream';
    if(bridgeHas('openBase64File')){const data=await blobToDataUrl(blob),r=bridgeCall('openBase64File',name,type,data);if(String(r||'').toLowerCase().startsWith('error'))throw new Error(r);return false}
    const objectUrl=URL.createObjectURL(blob),a=document.createElement('a');a.href=objectUrl;a.target='_blank';a.rel='noopener';document.body.appendChild(a);a.click();setTimeout(()=>{try{URL.revokeObjectURL(objectUrl);a.remove()}catch{}},60000);return false
  }catch(e){toast(uiText('Open file')+': '+(e.message||e),6500);return false}
}
function openMediaViewer(url,kind='',filename=''){
  const safe=externalUrl(String(url||'')),k=String(kind||'').toLowerCase(),name=mediaFileNameFrom(safe,filename),rawJs=escJs(safe),fnJs=escJs(name),mimeJs=escJs(k||'application/octet-stream');let body='';
  if(k.includes('image'))body=`<img class="fullMediaObj" src="${esc(safe)}">`;
  else if(k.includes('video'))body=`<video class="fullMediaObj" src="${esc(safe)}" controls autoplay playsinline preload="auto" style="background:#000" onclick="ITH.enableVideoSoundV249220&&ITH.enableVideoSoundV249220(this)"></video>`;
  else if(k.includes('audio'))body=`<audio class="fullMediaAudio" src="${esc(safe)}" controls autoplay></audio>`;
  else body=`<div class="card fullFileCard"><div class="officeIcon">${officeIcon({filename:name,mime_type:k})}</div><b>${esc(name)}</b><div class="date">${esc(k||'file')}</div><div class="row" style="margin-top:12px"><button class="btn green" onclick="ITH.openActualMediaFile('${rawJs}','${fnJs}','${mimeJs}','file')">👁️ ${uiText('Open file')}</button><button class="btn" onclick="ITH.downloadMediaFile('${rawJs}','${fnJs}','${mimeJs}','file')">⬇️ ${uiText('Save')}</button><button class="btn" onclick="ITH.shareMediaFile('${rawJs}','${fnJs}','${mimeJs}','file')">📤 ${uiText('Share file')}</button></div></div>`;
  const topTools=(k.includes('image')||k.includes('video')||k.includes('audio'))?`<button class="btn mini" onclick="ITH.downloadMediaFile('${rawJs}','${fnJs}','${mimeJs}','${escJs(k)}')">⬇️ ${uiText('Save')}</button><button class="btn mini" onclick="ITH.shareMediaFile('${rawJs}','${fnJs}','${mimeJs}','${escJs(k)}')">📤 ${uiText('Share')}</button>`:'';
  $('previewModal').classList.remove('callCompactV249218','voiceCallV249218','videoCallV249218');$('previewModal').innerHTML=`<div class="mediaViewer fullScreenViewer"><div class="mediaViewerTop"><button class="feedBackOnly mediaBack" onclick="ITH.closeMediaViewer()">‹</button><b>${esc(name)}</b><span style="margin-left:auto"></span>${topTools}<button class="icon mediaClose" onclick="ITH.closeMediaViewer()">×</button></div><div class="mediaViewerStage">${body}</div></div>`;$('previewModal').classList.add('show','fullscreen');return false
}
function closeMediaViewer(){try{document.querySelectorAll('#previewModal video,#previewModal audio').forEach(v=>v.pause())}catch{}$('previewModal').classList.remove('show','fullscreen');$('previewModal').innerHTML=''}
function safeDomId(id){return String(id).replace(/[^a-zA-Z0-9_-]/g,'_')}
function pollLocalStats(id,options){try{const saved=JSON.parse(localStorage.getItem('ith_poll_stats_'+id)||'null');if(saved&&saved.options)return saved}catch{}return {total_votes:0,options:(options||[]).map((o,i)=>({index:i,text:o,count:0,percent:0}))}}

function pollOptionLabels(m){
  const raw=Array.isArray(m&&m.options)?m.options:[];
  const labels=raw.length?raw.map(o=>{if(o&&typeof o==='object')return String(o.text||o.label||o.option||'').trim();return String(o||'').trim();}).filter(Boolean):[];
  if(labels.length)return labels;
  return uiLang&&uiLang()==='en'?['I agree','Needs discussion','I suggest something else','Open a conversation']:['Συμφωνώ','Θέλει συζήτηση','Προτείνω κάτι άλλο','Άνοιγμα συζήτησης'];
}
function normalizePollStatsPayload(raw,options){
  let s=raw&&raw.stats?raw.stats:raw;
  if(Array.isArray(s))s={options:s};
  const opts=(options||[]).map(String);
  let arr=[];
  if(s&&Array.isArray(s.options))arr=s.options.map((o,i)=>({index:+(o.index??i),text:String(o.text||opts[i]||''),count:+(o.count||0),percent:+(o.percent||0)}));
  else arr=opts.map((o,i)=>({index:i,text:o,count:0,percent:0}));
  let total=+(s&&s.total_votes||0); if(!total)total=arr.reduce((a,o)=>a+(+o.count||0),0);
  arr=arr.map(o=>Object.assign({},o,{percent:total?Math.round((+o.count||0)*100/total):(+o.percent||0)}));
  return {total_votes:total,options:arr};
}
function pollStatsFromMedia(m,id,options){
  try{
    if(m&&m.stats){const st=normalizePollStatsPayload(m.stats,options); if(st.options&&st.options.length)return st;}
    if(m&&Array.isArray(m.options)&&m.options.some(o=>o&&typeof o==='object'&&('count' in o||'percent' in o))){return normalizePollStatsPayload({total_votes:m.total_votes||0,options:m.options},options)}
  }catch(e){}
  return pollLocalStats(id,options);
}
function renderPollCard(m){
  const idRaw=String((m&&(m.poll_id||m.pollId||m.pollID||m.id))||('poll_'+Math.random().toString(36).slice(2)));
  const id=safeDomId(idRaw), idJs=escJs(idRaw);
  const opts=pollOptionLabels(m||{}).slice(0,9);
  const st=pollStatsFromMedia(m||{},idRaw,opts);
  const mode=localStorage.getItem('ith_poll_mode_'+idRaw)||(((m||{}).anonymous_default!==false)?'anonymous':'profile');
  const rawTopic=String((m&&m.topic)||'').trim();
  const topic=(rawTopic&&rawTopic!==uiText('Professional opinion card')&&rawTopic!=='Επαγγελματική κάρτα γνώμης')?rawTopic:'';
  const question=(m&&m.question)||uiText('What is your opinion?');
  const manyCls=opts.length>=7?' pollManyOptions':(opts.length>=5?' pollMediumOptions':'');
  const logo='<div class="pollLogoClean"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display=\'none\'"><div><b><span class="okRainbow">OK</span></b><small>ithaki</small></div></div>';
  const options=opts.map((o,i)=>{const row=(st.options||[]).find(x=>+x.index===i)||{count:0,percent:0};return `<button class="pollChoice" onclick="ITH.votePoll('${idJs}',${i},'${escJs(o)}')"><span>${esc(o)}</span><em style="width:${+row.percent||0}%"></em><b>${+row.count||0} · ${+row.percent||0}%</b></button>`}).join('');
  const modeHtml=`<div class="pollMode row"><span>${uiText('Vote')}:</span><button class="btn ${mode==='anonymous'?'green':''}" data-mode="anonymous" onclick="ITH.setPollVoteMode('${idJs}','anonymous')">${uiText('Anonymous')}</button><button class="btn ${mode==='profile'?'green':''}" data-mode="profile" onclick="ITH.setPollVoteMode('${idJs}','profile')">${uiText('With profile')}</button></div>`;
  const titleHtml=topic?`<div class="pollTitle">${esc(topic)}</div>`:'';
  return `<div class="pollFeedCard professionalPollCard${manyCls}" id="poll_${id}">${logo}<div class="pollQuestion">${esc(question)}</div>${modeHtml}<div class="pollVoteOptions">${options}</div><div class="pollTotal">${uiText('Voted')} ${st.total_votes||0} ${uiText('members')}</div></div>`;
}
function setPollVoteMode(id,mode){localStorage.setItem('ith_poll_mode_'+id,mode);const box=$('poll_'+safeDomId(id));if(box){box.querySelectorAll('.pollMode .btn').forEach(b=>b.classList.remove('green'));const btn=box.querySelector(`.pollMode .btn[data-mode="${mode}"]`);if(btn)btn.classList.add('green')}toast(mode==='anonymous'?uiText('Anonymous'):uiText('With profile'))}
function applyLocalPollVote(id,opts,index){let data=pollLocalStats(id,opts);const key='ith_poll_vote_'+id;let prev=null;try{prev=localStorage.getItem(key)}catch{}data.options=data.options||opts.map((o,i)=>({index:i,text:o,count:0,percent:0}));if(prev!==String(index)){data.options=data.options.map(o=>{let c=+o.count||0;if(String(o.index)===String(prev))c=Math.max(0,c-1);if(+o.index===+index)c+=1;return Object.assign({},o,{count:c})});try{localStorage.setItem(key,String(index))}catch{}}data.total_votes=data.options.reduce((a,o)=>a+(+o.count||0),0);data.options=data.options.map(o=>Object.assign({},o,{percent:data.total_votes?Math.round((+o.count||0)*100/data.total_votes):0}));savePollStats(id,data);return data}
async function votePoll(id,index,text){const mode=localStorage.getItem('ith_poll_mode_'+id)||'anonymous';const opts=[...document.querySelectorAll('#poll_'+safeDomId(id)+' .pollChoice span')].map(x=>x.textContent||'').filter(Boolean);try{const r=await fetchJson('/api/polls/vote',{method:'POST',body:JSON.stringify({room_id:state.room,poll_id:id,device_id:state.device,option_index:index,anonymous:mode==='anonymous',nickname:mode==='profile'?state.name:''})});const st=normalizePollStatsPayload(r,opts);savePollStats(id,st);updatePollCard(id,st);markPollChoice(id,index);toast('Η ψήφος καταμετρήθηκε πραγματικά στον server');return false}catch(e){const data=applyLocalPollVote(id,opts.length?opts:[text],index);updatePollCard(id,data);markPollChoice(id,index);toast('Η ψήφος μετρήθηκε τοπικά μέχρι να συνδεθεί ο server');return false}}
function markPollChoice(id,index){const box=$('poll_'+safeDomId(id));if(!box)return;box.querySelectorAll('.pollChoice').forEach((b,i)=>b.classList.toggle('voted',i===index))}
function savePollStats(id,stats){try{localStorage.setItem('ith_poll_stats_'+id,JSON.stringify(stats))}catch{}}
function updatePollCard(id,stats){const box=$('poll_'+safeDomId(id));if(!box)return;const st=normalizePollStatsPayload(stats,[...box.querySelectorAll('.pollChoice span')].map(x=>x.textContent));(st.options||[]).forEach(o=>{const btn=box.querySelectorAll('.pollChoice')[+o.index];if(btn){const em=btn.querySelector('em'),b=btn.querySelector('b');if(em)em.style.width=(+o.percent||0)+'%';if(b)b.textContent=(+o.count||0)+' · '+(+o.percent||0)+'%'}});const total=box.querySelector('.pollTotal');if(total)total.textContent=uiText('Voted')+' '+(st.total_votes||0)+' '+uiText('members')}
function cardLocalStats(key,options,fallback){try{const saved=JSON.parse(localStorage.getItem('ith_card_stats_'+key)||'null');if(saved&&saved.options)return saved}catch{}const opts=(options||[]).map(String);let arr=(fallback&&fallback.length?fallback:opts.map((o,i)=>({index:i,text:o,count:0,percent:0}))).map((o,i)=>({index:+(o.index??i),text:String(o.text||opts[i]||''),count:+(o.count||0),percent:+(o.percent||0)}));let total=arr.reduce((a,o)=>a+(+o.count||0),0);return {total_votes:total,options:arr}}
function saveCardStats(key,stats){try{localStorage.setItem('ith_card_stats_'+key,JSON.stringify(stats))}catch{}}
function applyLocalCardVote(key,opts,index){let data=cardLocalStats(key,opts);const vkey='ith_card_vote_'+key;let prev=null;try{prev=localStorage.getItem(vkey)}catch{}if(prev!==String(index)){data.options=data.options.map(o=>{let c=+o.count||0;if(String(o.index)===String(prev))c=Math.max(0,c-1);if(+o.index===+index)c+=1;return Object.assign({},o,{count:c})});try{localStorage.setItem(vkey,String(index))}catch{}}data.total_votes=data.options.reduce((a,o)=>a+(+o.count||0),0);data.options=data.options.map(o=>Object.assign({},o,{percent:data.total_votes?Math.round((+o.count||0)*100/data.total_votes):(+o.percent||0)}));saveCardStats(key,data);return data}
function updateCardChoiceSet(box,stats){if(!box)return;const btns=[...box.querySelectorAll('.photoLikeChoice,.feedGoldPollChoice')];(stats.options||[]).forEach(o=>{const btn=btns[+o.index];if(btn){const em=btn.querySelector('em'),b=btn.querySelector('b');if(em)em.style.width=(+o.percent||0)+'%';if(b)b.textContent=(+o.count||0)+' · '+(+o.percent||0)+'%'}});const bars=[...box.querySelectorAll('.feedGoldResults i')];if(bars.length)(stats.options||[]).forEach(o=>{if(bars[+o.index])bars[+o.index].style.height=Math.max(22,+o.percent||0)+'px'});const total=box.querySelector('.cardVoteTotal');if(total)total.textContent=String(stats.total_votes||0)}
async function voteCardChoice(btn,key,index){const box=btn&&btn.closest?btn.closest('article,.photoLikeInfoCard,.feedGoldPollCard,.feedProCard'):null;const opts=[...(box?box.querySelectorAll('.photoLikeChoice span,.feedGoldPollChoice span'):[])].map(x=>x.textContent||'').filter(Boolean);const q=(box?.querySelector('.photoLikeQuote,.feedGoldQuote,.pollQuestion')?.textContent||key||'OK ITHAKI poll').trim();btn&&btn.classList&&btn.classList.add('voted');try{let pollId=localStorage.getItem('ith_real_card_poll_'+key)||'';if(!pollId){const cr=await fetchJson('/api/polls/create',{method:'POST',body:JSON.stringify({room_id:state.room,creator_id:state.device,nickname:state.name,question:q,options:opts,anonymous:true,allow_stats:true,publish_feed:false,community_id:state.currentSpace||''})});pollId=cr.poll_id||'';if(pollId)localStorage.setItem('ith_real_card_poll_'+key,pollId)}if(pollId){const vr=await fetchJson('/api/polls/vote',{method:'POST',body:JSON.stringify({room_id:state.room,poll_id:pollId,device_id:state.device,option_index:index,anonymous:true,nickname:''})});const st=normalizePollStatsPayload(vr,opts);saveCardStats(key,st);updateCardChoiceSet(box,st);toast('Η ψήφος καταμετρήθηκε πραγματικά');return false}}catch(e){}const st=applyLocalCardVote(key,opts,index);updateCardChoiceSet(box,st);toast('Η ψήφος μετρήθηκε τοπικά μέχρι να συνδεθεί ο server');return false}

function injectV249189StableFeedCss(){
  try{
    if(document.getElementById('ithV249189StableFeedCss'))return;
    const st=document.createElement('style');
    st.id='ithV249189StableFeedCss';
    st.textContent=`
      #feedPage{padding:0!important;overflow:hidden!important;background:#02070d!important}
      #feedPage .feedBackOnly{position:fixed!important;top:calc(env(safe-area-inset-top) + 8px)!important;left:10px!important;z-index:80!important;background:rgba(2,7,13,.18)!important;border:1px solid rgba(255,255,255,.10)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important;color:#fff!important}
      .feedSearchGlassV249189{position:fixed;top:calc(env(safe-area-inset-top) + 9px);left:58px;right:12px;z-index:79;display:flex;align-items:center;gap:8px;border:1px solid rgba(255,255,255,.12);border-radius:999px;background:rgba(5,18,31,.20);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);padding:7px 10px;box-shadow:0 10px 30px rgba(0,0,0,.18)}
      .feedSearchGlassV249189 input{flex:1;min-width:0;border:0!important;background:transparent!important;padding:4px 6px!important;color:#fff!important;font-weight:700;outline:0!important}
      .feedSearchGlassV249189 span{opacity:.82}.feedSearchGlassV249189 button{font-size:16px;padding:2px 6px;color:#fff;opacity:.80}
      #feedPage .feedList{height:100dvh!important;overflow-y:auto!important;overflow-x:hidden!important;scroll-snap-type:y mandatory!important;scroll-padding-top:0!important;gap:0!important;padding:0!important;margin:0!important;overscroll-behavior-y:contain;-webkit-overflow-scrolling:touch;background:#000}
      #feedPage .feedList>.post,#feedPage .feedList>.feedProCard,#feedPage .feedList>.feedGoldWisdomCard,#feedPage .feedList>.feedGoldPollCard{height:95dvh!important;min-height:95dvh!important;width:100%!important;margin:2.5dvh 0!important;border-radius:0!important;scroll-snap-align:center!important;scroll-snap-stop:always!important;border:0!important;padding:0!important;background:#000!important;box-shadow:none!important;overflow:hidden!important;display:flex!important;align-items:stretch!important;justify-content:center!important}
      #feedPage .mediaPost .postMediaWrap.tiktokScreen,#feedPage .mediaPost .postMediaWrap,#feedPage .postMediaWrap.tiktokScreen{height:95dvh!important;min-height:95dvh!important;width:100%!important;margin:0!important;border:0!important;border-radius:0!important;background:#000!important;display:block!important;position:relative!important;overflow:hidden!important}
      #feedPage .mediaPost .postMediaWrap .mediaInline,#feedPage .postMediaWrap.tiktokScreen .mediaInline{height:95dvh!important;width:100%!important;margin:0!important;background:#000!important;display:block!important}
      #feedPage video.feedVideo,#feedPage .postMediaWrap.tiktokScreen video,#feedPage .mediaInline video{height:95dvh!important;width:100%!important;max-height:none!important;object-fit:cover!important;background:#000!important;display:block!important}
      #feedPage .mediaInline img{height:95dvh!important;width:100%!important;max-height:none!important;object-fit:cover!important;background:#000!important;display:block!important}
      #feedPage .leftActions{position:absolute!important;left:8px!important;top:50%!important;transform:translateY(-50%)!important;z-index:72!important;display:flex!important;flex-direction:column!important;gap:10px!important;padding:8px 5px!important;border-radius:999px!important;background:rgba(5,18,31,.14)!important;border:1px solid rgba(255,255,255,.08)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important}
      #feedPage .actionIcon,#feedPage .leftActions button{background:rgba(255,255,255,.08)!important;border:1px solid rgba(255,255,255,.10)!important;border-radius:16px!important;min-width:42px!important;min-height:42px!important;display:grid!important;place-items:center!important;text-shadow:0 3px 12px rgba(0,0,0,.7)!important;color:#fff!important;box-shadow:0 10px 24px rgba(0,0,0,.22)!important}
      #feedPage .leftActions .count{font-size:10px!important;color:#fff!important;text-shadow:0 2px 8px #000!important;font-weight:900!important}
      #feedPage .feedAvatarOverlay{background:rgba(0,0,0,.16)!important;border:1px solid rgba(255,255,255,.10)!important;border-radius:18px!important;color:#fff!important;backdrop-filter:blur(7px)!important}
      #feedPage .mediaOpenBtn{right:14px!important;top:58px!important;border-radius:16px!important;background:rgba(5,18,31,.18)!important;border:1px solid rgba(255,255,255,.10)!important;color:#fff!important;backdrop-filter:blur(8px)!important}
      #feedPage .feedGoldWisdomCard,#feedPage .feedGoldPollCard{position:relative!important;color:#fff7dc!important;text-align:center!important;background:radial-gradient(circle at 20% 12%,rgba(255,224,120,.24),transparent 30%),radial-gradient(circle at 80% 82%,rgba(255,142,62,.18),transparent 34%),linear-gradient(145deg,#080604 0%,#201204 45%,#050403 100%)!important;border:0!important;padding:0!important;display:grid!important;place-items:center!important}
      .feedGoldCardInner{width:min(92vw,720px);padding:clamp(18px,5vw,34px) 18px;position:relative;z-index:2;margin:auto}
      .feedGoldLogo{width:82px;height:82px;margin:0 auto 12px;border-radius:22px;display:grid;place-items:center;background:rgba(255,217,110,.11);border:1px solid rgba(255,217,110,.34);box-shadow:0 18px 45px rgba(0,0,0,.32)}
      .feedGoldLogo img{width:62px;height:62px;object-fit:contain;filter:drop-shadow(0 12px 20px rgba(0,0,0,.45))}.feedGoldLogo span{font-size:42px}
      .feedGoldLabel{color:#ffd971;font-size:13px;font-weight:1000;letter-spacing:1.8px;text-transform:uppercase;margin:8px 0}.feedGoldQuote{font-size:clamp(24px,6.2vw,38px)!important;line-height:1.16!important;margin:10px auto 14px!important;color:#ffd86e!important;text-shadow:0 8px 32px rgba(0,0,0,.72),0 0 28px rgba(255,202,83,.20)}
      .feedGoldPrompt{font-size:clamp(14px,3.4vw,18px);color:#fff0c1;margin:8px auto 16px}.feedGoldPollOptions{display:grid;gap:11px;margin:18px auto;max-width:560px}.feedGoldPollOptions div{position:relative;overflow:hidden;border-radius:18px;padding:13px 15px;border:1px solid rgba(255,217,110,.34);background:rgba(255,255,255,.07);color:#fff6da;text-align:left;font-weight:900}.feedGoldPollOptions div em{position:absolute;left:0;top:0;bottom:0;background:rgba(255,210,80,.20);z-index:0}.feedGoldPollOptions div span,.feedGoldPollOptions div b{position:relative;z-index:1}.feedGoldPollOptions div b{float:right;color:#ffd971}.feedGoldVoteMode{justify-content:center!important;margin:14px auto!important;color:#fff0c1}.feedGoldVoteMode label{display:inline-flex;align-items:center;gap:6px;border:1px solid rgba(255,217,110,.28);border-radius:999px;padding:8px 12px;background:rgba(255,255,255,.06)}.feedGoldResults{height:112px;display:flex;align-items:end;justify-content:center;gap:12px;margin:14px auto 4px}.feedGoldResults i{width:34px;border-radius:14px 14px 4px 4px;background:linear-gradient(180deg,#ffe58a,#b77816);box-shadow:0 10px 26px rgba(0,0,0,.3)}.feedGoldCardActions{position:absolute!important;left:8px!important;top:50%!important;transform:translateY(-50%)!important;z-index:74!important;display:flex!important;flex-direction:column!important;gap:10px!important;padding:8px 5px!important;border-radius:999px!important;background:rgba(5,18,31,.14)!important;border:1px solid rgba(255,255,255,.08)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important}.feedGoldCardActions .btn{border-radius:16px!important;padding:0!important;min-width:42px!important;min-height:42px!important;display:grid!important;place-items:center!important;font-size:0!important;font-weight:1000!important;background:rgba(255,255,255,.08)!important;border:1px solid rgba(255,255,255,.10)!important;color:#fff!important;box-shadow:0 10px 24px rgba(0,0,0,.22)!important}.feedGoldCardActions .btn:before{content:"💬";font-size:22px!important;line-height:1!important}.feedGoldCardActions .btn.green{background:rgba(255,255,255,.08)!important;border-color:rgba(255,255,255,.10)!important;color:#fff!important}
      #feedPage .feedProCard{display:none!important}

      /* V249192 compact gold cards and real visible vote buttons */
      .feedGoldCardInner{width:min(86vw,612px)!important;padding:clamp(15px,4.25vw,29px) 15px!important}
      .feedGoldLogo{width:70px!important;height:70px!important;margin-bottom:10px!important}.feedGoldLogo img{width:54px!important;height:54px!important;object-fit:contain!important}.feedGoldLogo span{display:none!important}
      .feedGoldLabel{font-size:11px!important;margin:6px 0!important}.feedGoldQuote{font-size:clamp(20px,5.25vw,32px)!important;line-height:1.13!important;margin:8px auto 10px!important}.feedGoldPrompt{font-size:clamp(12px,2.9vw,15px)!important;margin:6px auto 10px!important}
      .feedGoldVoteMode{margin:8px auto!important;gap:6px!important}.feedGoldVoteMode label{padding:6px 9px!important;font-size:12px!important}.feedGoldPollOptions{gap:8px!important;margin:10px auto!important;max-width:500px!important}
      .feedGoldPollOptions button.feedGoldPollChoice{position:relative!important;overflow:hidden!important;width:100%!important;border-radius:15px!important;padding:9px 11px!important;border:1px solid rgba(255,217,110,.34)!important;background:rgba(255,255,255,.07)!important;color:#fff6da!important;text-align:left!important;font-weight:900!important;font:inherit!important;appearance:none!important}
      .feedGoldPollOptions button.feedGoldPollChoice em{position:absolute!important;left:0!important;top:0!important;bottom:0!important;background:rgba(255,210,80,.20)!important;z-index:0!important}.feedGoldPollOptions button.feedGoldPollChoice span,.feedGoldPollOptions button.feedGoldPollChoice b{position:relative!important;z-index:1!important}.feedGoldPollOptions button.feedGoldPollChoice b{float:right!important;color:#ffd971!important}
      .feedGoldResults{height:90px!important;gap:9px!important;margin:8px auto 2px!important}.feedGoldResults i{width:29px!important}.feedGoldPollChoice.voted{border-color:#36f0a0!important;box-shadow:0 0 0 1px rgba(54,240,160,.42),0 0 18px rgba(54,240,160,.16)!important}

      /* V249193: remove top bars from gold ITHAKI/poll cards and keep content inside card with inner scroll */
      #feedPage .feedGoldWisdomCard .feedGoldLabel,#feedPage .feedGoldPollCard .feedGoldLabel,#feedPage .professionalPollCard .photoLikeTop,#feedPage .professionalPollCard .pollRibbon,#feedPage .professionalPollCard .cardIconBar,#feedPage .ithakiQuestionCard .photoLikeTop,#feedPage .ithakiQuestionCard .cardIconBar,#feedPage .photoLikeInfoCard .photoLikeTop,#feedPage .photoLikeInfoCard .cardIconBar{display:none!important}
      #feedPage .feedGoldCardInner{width:min(88vw,612px)!important;max-height:min(78dvh,620px)!important;overflow-y:auto!important;overflow-x:hidden!important;overscroll-behavior:contain!important;-webkit-overflow-scrolling:touch!important;padding:clamp(12px,3.4vw,23px) 13px!important;scrollbar-width:thin!important}
      #feedPage .feedGoldLogo{width:62px!important;height:62px!important;margin-bottom:6px!important;border-radius:18px!important}#feedPage .feedGoldLogo img{width:48px!important;height:48px!important}
      #feedPage .feedGoldQuote{font-size:clamp(18px,4.75vw,30px)!important;line-height:1.12!important;margin:6px auto 8px!important}#feedPage .feedGoldPrompt{font-size:clamp(11px,2.7vw,14px)!important;margin:4px auto 6px!important}
      #feedPage .feedGoldVoteMode{display:none!important}#feedPage .feedGoldPollOptions{max-height:min(31dvh,235px)!important;overflow-y:auto!important;overflow-x:hidden!important;overscroll-behavior:contain!important;-webkit-overflow-scrolling:touch!important;gap:6px!important;margin:6px auto!important;padding-right:4px!important}
      #feedPage .feedGoldPollOptions div,#feedPage .feedGoldPollOptions button.feedGoldPollChoice{padding:8px 10px!important;border-radius:14px!important;font-size:12.5px!important}
      #feedPage .feedGoldResults{height:62px!important;gap:7px!important;margin:5px auto 0!important}#feedPage .feedGoldResults i{width:24px!important}
      #feedPage .photoLikeInfoCard,#feedPage .professionalPollCard,#feedPage .ithakiQuestionCard{min-height:0!important;max-height:min(78dvh,620px)!important;overflow-y:auto!important;overflow-x:hidden!important;overscroll-behavior:contain!important;-webkit-overflow-scrolling:touch!important;justify-content:flex-start!important;padding:10px!important}
      #feedPage .photoLikeCenter{gap:5px!important;padding:4px 3px!important}#feedPage .photoLikeIcon{font-size:40px!important}#feedPage .photoLikeQuote{font-size:clamp(17px,4.7vw,28px)!important;line-height:1.13!important}
      #feedPage .pollVoteOptions,#feedPage .photoLikeChoices{max-height:min(32dvh,245px)!important;overflow-y:auto!important;overflow-x:hidden!important;overscroll-behavior:contain!important;-webkit-overflow-scrolling:touch!important;padding-right:4px!important}
      #feedPage .pollChoice,#feedPage .photoLikeChoice{min-height:36px!important;padding:7px 9px!important;border-radius:14px!important;font-size:12.5px!important}
      
      /* V249194: gold cards do not trap the main feed; vote choices keep their own visible side scroll. */
      body[data-page="feed"] #feedPage{overflow-y:auto!important;-webkit-overflow-scrolling:touch!important;padding-bottom:calc(var(--bar) + 72px)!important;overscroll-behavior-y:auto!important}
      #feedPage .feedGoldWisdomCard,#feedPage .feedGoldPollCard{position:relative!important;width:min(100%,680px)!important;max-width:680px!important;min-height:calc(100dvh - var(--bar) - 34px)!important;margin:0 auto calc(var(--bar) + 18px)!important;padding:8px 58px 8px 8px!important;display:grid!important;place-items:center!important;overflow:visible!important;scroll-snap-align:start!important;touch-action:pan-y!important}
      #feedPage .feedGoldCardInner{width:min(86vw,594px)!important;max-height:calc(100dvh - var(--bar) - 74px)!important;overflow:visible!important;overscroll-behavior-y:auto!important;padding:12px 12px!important;touch-action:pan-y!important}
      #feedPage .feedGoldPollOptions{max-height:calc(100dvh - var(--bar) - 365px)!important;min-height:108px!important;overflow-y:auto!important;overflow-x:hidden!important;overscroll-behavior-y:auto!important;-webkit-overflow-scrolling:touch!important;touch-action:pan-y!important;padding-right:8px!important;scrollbar-width:auto!important;scrollbar-color:rgba(255,217,110,.95) rgba(255,217,110,.16)!important}
      #feedPage .feedGoldPollOptions::-webkit-scrollbar,#feedPage .pollVoteOptions::-webkit-scrollbar,#feedPage .photoLikeChoices::-webkit-scrollbar{width:8px!important;display:block!important}
      #feedPage .feedGoldPollOptions::-webkit-scrollbar-track,#feedPage .pollVoteOptions::-webkit-scrollbar-track,#feedPage .photoLikeChoices::-webkit-scrollbar-track{background:rgba(255,217,110,.14)!important;border-radius:999px!important}
      #feedPage .feedGoldPollOptions::-webkit-scrollbar-thumb,#feedPage .pollVoteOptions::-webkit-scrollbar-thumb,#feedPage .photoLikeChoices::-webkit-scrollbar-thumb{background:rgba(255,217,110,.92)!important;border-radius:999px!important}
      #feedPage .feedGoldCardActions{position:absolute!important;right:7px!important;top:50%!important;transform:translateY(-50%)!important;z-index:15!important;display:flex!important;flex-direction:column!important;gap:8px!important;margin:0!important;padding:7px 5px!important;border-radius:999px!important;background:linear-gradient(180deg,rgba(5,18,31,.72),rgba(5,18,31,.34))!important;border:1px solid rgba(255,217,110,.30)!important;backdrop-filter:blur(12px)!important;box-shadow:0 14px 38px rgba(0,0,0,.32)!important}
      #feedPage .feedGoldCardActions .btn{width:42px!important;min-width:42px!important;height:42px!important;min-height:42px!important;padding:0!important;border-radius:50%!important;font-size:0!important;display:grid!important;place-items:center!important}
      #feedPage .feedGoldCardActions .btn::before{content:"💬";font-size:22px!important;line-height:1!important}
      #feedPage .feedGoldQuote,#feedPage .photoLikeQuote,#feedPage .pollQuestion,.greekWisdomCard .proPanelText p{color:#ffd36e!important;text-shadow:0 3px 18px rgba(255,211,110,.18)!important}
      #feedPage .feedGoldQuote{font-size:clamp(17px,4.35vw,27px)!important;line-height:1.13!important}#feedPage .feedGoldLogo span{display:none!important}#feedPage .feedGoldLogo{width:54px!important;height:54px!important;margin-bottom:4px!important}#feedPage .feedGoldLogo img{width:42px!important;height:42px!important}#feedPage .feedGoldPrompt{font-size:12px!important;line-height:1.28!important;color:rgba(255,246,218,.88)!important}#feedPage .feedGoldResults{height:48px!important;margin:3px auto 0!important}#feedPage .feedGoldResults i{width:20px!important}
      #feedPage .professionalPollCard,#feedPage .photoLikeInfoCard,#feedPage .ithakiQuestionCard{max-height:calc(100dvh - var(--bar) - 70px)!important;margin-bottom:calc(var(--bar) + 16px)!important;overflow:visible!important;touch-action:pan-y!important}
      #feedPage .pollVoteOptions,#feedPage .photoLikeChoices{max-height:calc(100dvh - var(--bar) - 330px)!important;min-height:96px!important;overflow-y:auto!important;overflow-x:hidden!important;overscroll-behavior-y:auto!important;-webkit-overflow-scrolling:touch!important;touch-action:pan-y!important;padding-right:8px!important;scrollbar-width:auto!important;scrollbar-color:rgba(255,217,110,.95) rgba(255,217,110,.16)!important}
      .topStoryBarV249169 .ithakiOfficialStory .avatar,.storyGlassBar .ithakiOfficialStory .avatar{background:rgba(255,217,110,.10)!important;border-color:rgba(255,217,110,.60)!important;box-shadow:0 0 0 2px rgba(255,217,110,.20),0 0 18px rgba(255,217,110,.18)!important}.ithakiOfficialStory .avatar img{width:100%!important;height:100%!important;object-fit:contain!important;border-radius:50%!important}
      @media(max-width:760px){#feedPage .feedGoldWisdomCard,#feedPage .feedGoldPollCard{padding-right:52px!important;min-height:calc(100dvh - var(--bar) - 22px)!important;margin-bottom:calc(var(--bar) + 10px)!important}#feedPage .feedGoldCardInner{width:min(84vw,560px)!important;max-height:calc(100dvh - var(--bar) - 58px)!important;padding:10px 10px!important}#feedPage .feedGoldPollOptions{max-height:calc(100dvh - var(--bar) - 342px)!important;min-height:102px!important}#feedPage .feedGoldQuote{font-size:clamp(17px,5.05vw,25px)!important}#feedPage .feedGoldCardActions{right:5px!important}#feedPage .feedGoldCardActions .btn{width:39px!important;min-width:39px!important;height:39px!important;min-height:39px!important}}
      @media(max-width:760px){.feedSearchGlassV249189{top:calc(env(safe-area-inset-top) + 8px);left:56px;right:10px;padding:6px 9px}#feedPage .leftActions,.feedGoldCardActions{left:6px!important;gap:8px!important}#feedPage .actionIcon,#feedPage .leftActions button,.feedGoldCardActions .btn{min-width:39px!important;min-height:39px!important}.feedGoldLogo{width:74px!important;height:74px!important}.feedGoldLogo img{width:56px!important;height:56px!important}.feedGoldQuote{font-size:clamp(23px,6.7vw,34px)!important}}
      /* V249199: real viewport fit for poll/wisdom cards; keep bottom buttons visible */
      #feedPage .feedOutdoorBtn{font-size:17px!important;font-weight:1000!important;color:#111!important;background:linear-gradient(180deg,#fff8a8,#ffd36e)!important;border:1px solid rgba(255,211,110,.9)!important;border-radius:999px!important;box-shadow:0 8px 22px rgba(0,0,0,.22)!important;padding:4px 8px!important;min-width:36px!important}
      #feedPage .feedList>.feedGoldWisdomCard,#feedPage .feedList>.feedGoldPollCard{height:calc(100dvh - var(--bar) - 18px)!important;min-height:calc(100dvh - var(--bar) - 18px)!important;margin:0 0 calc(var(--bar) + 10px) 0!important;box-sizing:border-box!important;align-items:flex-start!important;justify-content:center!important;padding-top:calc(env(safe-area-inset-top) + 8px)!important;padding-bottom:calc(var(--bar) + 18px)!important;overflow:hidden!important;scroll-snap-align:start!important;touch-action:pan-y!important}
      #feedPage .feedGoldWisdomCard .feedGoldCardInner,#feedPage .feedGoldPollCard .feedGoldCardInner{overflow:visible!important;max-height:none!important;overscroll-behavior:auto!important;-webkit-overflow-scrolling:auto!important;box-sizing:border-box!important}
      #feedPage .feedGoldPollCard .feedGoldCardInner{transform:translateY(-clamp(16px,4.8dvh,48px))!important;width:min(82vw,560px)!important;padding:4px 8px calc(var(--bar) + 44px) 8px!important}
      #feedPage .feedGoldWisdomCard .feedGoldCardInner{transform:translateY(-clamp(8px,2.5dvh,26px))!important;width:min(84vw,590px)!important;padding:8px 10px calc(var(--bar) + 32px) 10px!important}
      #feedPage .feedGoldPollCard .feedGoldLogo{width:42px!important;height:42px!important;margin:0 auto 2px!important;border-radius:14px!important}
      #feedPage .feedGoldPollCard .feedGoldLogo img{width:32px!important;height:32px!important}
      #feedPage .feedGoldPollCard .feedGoldQuote{font-size:clamp(15px,4.25vw,22px)!important;line-height:1.08!important;margin:2px auto 5px!important;max-width:96%!important}
      #feedPage .feedGoldPollCard .feedGoldPrompt{font-size:11px!important;line-height:1.15!important;margin:1px auto 4px!important;max-width:94%!important}
      #feedPage .feedGoldPollCard .feedGoldPollOptions{overflow:visible!important;max-height:none!important;min-height:0!important;display:grid!important;gap:5px!important;margin:3px auto 5px!important;padding-right:0!important;width:min(100%,500px)!important}
      #feedPage .feedGoldPollCard .feedGoldPollOptions button.feedGoldPollChoice{min-height:33px!important;padding:6px 9px!important;border-radius:13px!important;font-size:12px!important;line-height:1.12!important;display:grid!important;grid-template-columns:1fr auto!important;align-items:center!important;gap:6px!important}
      #feedPage .feedGoldPollCard .feedGoldPollOptions button.feedGoldPollChoice b{font-size:11px!important;white-space:nowrap!important;float:none!important}
      #feedPage .feedGoldPollCard .feedGoldResults{height:28px!important;margin:1px auto 0!important;gap:7px!important}
      #feedPage .feedGoldPollCard .feedGoldResults i{width:17px!important;min-height:10px!important;border-radius:8px 8px 3px 3px!important}
      #feedPage .feedGoldPollCard .feedGoldCardActions{right:5px!important;left:auto!important;top:42%!important;transform:translateY(-50%)!important}
      #feedPage .feedGoldPollCard .feedGoldCardActions .btn{width:38px!important;min-width:38px!important;height:38px!important;min-height:38px!important}
      #feedPage .professionalPollCard{transform:translateY(-clamp(10px,3dvh,28px))!important;max-height:calc(100dvh - var(--bar) - 34px)!important;margin-bottom:calc(var(--bar) + 18px)!important;padding-bottom:calc(var(--bar) + 18px)!important;box-sizing:border-box!important}
      #feedPage .professionalPollCard .pollVoteOptions{overflow:visible!important;max-height:none!important;gap:5px!important;margin-top:4px!important;padding-right:0!important}
      #feedPage .professionalPollCard .pollChoice{min-height:34px!important;padding:7px 9px!important;border-radius:13px!important;font-size:12px!important;line-height:1.12!important}
      body[data-screen-theme="outdoor"] #feedPage .feedSearchGlassV249189,body[data-screen-theme="outdoor"] #feedPage .leftActions,body[data-screen-theme="outdoor"] #feedPage .feedGoldCardActions{background:rgba(255,248,170,.94)!important;border-color:rgba(0,0,0,.55)!important;color:#06131f!important;box-shadow:0 0 0 2px rgba(255,255,255,.95),0 8px 24px rgba(0,0,0,.28)!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
      body[data-screen-theme="outdoor"] #feedPage .actionIcon,body[data-screen-theme="outdoor"] #feedPage .leftActions button,body[data-screen-theme="outdoor"] #feedPage .feedGoldCardActions .btn{background:#fffdf0!important;color:#06131f!important;border-color:rgba(0,0,0,.55)!important;text-shadow:none!important;box-shadow:0 0 0 1px rgba(0,0,0,.22)!important}
      body[data-screen-theme="outdoor"] #feedPage .feedGoldQuote,body[data-screen-theme="outdoor"] #feedPage .photoLikeQuote,body[data-screen-theme="outdoor"] #feedPage .pollQuestion{color:#ffdd55!important;text-shadow:0 3px 2px #000,0 0 16px rgba(255,210,80,.40)!important}
      @media(max-height:720px){#feedPage .feedGoldPollCard .feedGoldCardInner{transform:translateY(-clamp(22px,6dvh,54px))!important}#feedPage .feedGoldPollCard .feedGoldPrompt{display:none!important}#feedPage .feedGoldPollCard .feedGoldResults{display:none!important}#feedPage .feedGoldPollCard .feedGoldPollOptions button.feedGoldPollChoice{min-height:31px!important;padding:5px 8px!important}}
      @media(max-width:760px){#feedPage .feedList>.feedGoldWisdomCard,#feedPage .feedList>.feedGoldPollCard{height:calc(100dvh - var(--bar) - 12px)!important;min-height:calc(100dvh - var(--bar) - 12px)!important;margin:0 0 calc(var(--bar) + 8px) 0!important;padding-right:48px!important}#feedPage .feedGoldPollCard .feedGoldCardInner{width:min(80vw,520px)!important;transform:translateY(-clamp(20px,5.8dvh,55px))!important}#feedPage .feedGoldWisdomCard .feedGoldCardInner{width:min(82vw,540px)!important}#feedPage .feedGoldPollCard .feedGoldPollOptions button.feedGoldPollChoice{font-size:11.6px!important}}
    `;
    document.head.appendChild(st);
  }catch(e){console.warn('feed css v249189',e)}
}

function injectV249204CompactMobileCardsCss(){
  try{
    if(document.getElementById('ithV249204CompactMobileCardsCss'))return;
    const st=document.createElement('style');
    st.id='ithV249204CompactMobileCardsCss';
    st.textContent=`
      /* V249204: rebuild mobile gold/poll cards compact, no inner scroll, no feed lock */
      #feedPage .feedList{scroll-snap-type:y proximity!important;overscroll-behavior-y:auto!important;padding-bottom:calc(var(--bar) + 34px)!important}
      #feedPage .feedList>.feedGoldWisdomCard,
      #feedPage .feedList>.feedGoldPollCard,
      #feedPage .feedList>.professionalPollCard,
      #feedPage .feedList>.photoLikeInfoCard,
      #feedPage .feedList>.ithakiQuestionCard,
      #feedPage .professionalPollCard,
      #feedPage .photoLikeInfoCard,
      #feedPage .ithakiQuestionCard{
        height:auto!important;min-height:0!important;max-height:none!important;width:min(94vw,620px)!important;
        margin:12px auto calc(var(--bar) + 18px)!important;padding:12px 52px 12px 12px!important;
        border-radius:22px!important;box-sizing:border-box!important;overflow:visible!important;display:block!important;
        scroll-snap-align:start!important;scroll-snap-stop:normal!important;touch-action:pan-y!important;
        background:radial-gradient(circle at 18% 8%,rgba(255,225,120,.18),transparent 32%),linear-gradient(145deg,#120b03,#281606 55%,#070504)!important;
        border:1px solid rgba(255,217,110,.26)!important;box-shadow:0 16px 42px rgba(0,0,0,.34)!important;color:#fff7dc!important;
      }
      #feedPage .feedGoldCardInner,
      #feedPage .feedGoldWisdomCard .feedGoldCardInner,
      #feedPage .feedGoldPollCard .feedGoldCardInner,
      #feedPage .photoLikeCenter,
      #feedPage .pollFeedCard .photoLikeCenter{
        width:100%!important;max-width:100%!important;max-height:none!important;overflow:visible!important;transform:none!important;
        padding:6px 4px!important;box-sizing:border-box!important;touch-action:pan-y!important;overscroll-behavior:auto!important;
      }
      #feedPage .feedGoldPollCard .feedGoldLogo{display:none!important}
      #feedPage .feedGoldLabel,#feedPage .photoLikeTop,#feedPage .pollRibbon,#feedPage .cardIconBar{display:none!important}
      #feedPage .feedGoldQuote,#feedPage .pollQuestion,#feedPage .photoLikeQuote{
        font-size:clamp(15px,4.2vw,22px)!important;line-height:1.12!important;margin:2px auto 7px!important;
        color:#ffd36e!important;text-shadow:0 3px 14px rgba(0,0,0,.55)!important;text-align:center!important;
      }
      #feedPage .pollTitle{font-size:13px!important;margin:2px 0 4px!important;color:#ffe6a2!important;text-align:center!important}
      #feedPage .feedGoldPrompt,#feedPage .photoLikePrompt{font-size:11px!important;line-height:1.18!important;margin:2px auto 6px!important;color:rgba(255,246,218,.82)!important;text-align:center!important}
      #feedPage .feedGoldVoteMode,#feedPage .pollMode{display:none!important}
      #feedPage .feedGoldPollOptions,#feedPage .pollVoteOptions,#feedPage .photoLikeChoices{
        display:grid!important;gap:5px!important;margin:5px auto 6px!important;padding:0!important;max-height:none!important;min-height:0!important;
        overflow:visible!important;overscroll-behavior:auto!important;touch-action:pan-y!important;width:100%!important;max-width:500px!important;
      }
      #feedPage .feedGoldPollOptions button.feedGoldPollChoice,#feedPage .pollChoice,#feedPage .photoLikeChoice{
        min-height:31px!important;padding:6px 8px!important;border-radius:13px!important;font-size:11.7px!important;line-height:1.12!important;
        display:grid!important;grid-template-columns:1fr auto!important;align-items:center!important;gap:6px!important;position:relative!important;
        border:1px solid rgba(255,217,110,.32)!important;background:rgba(255,255,255,.07)!important;color:#fff6da!important;text-align:left!important;font-weight:900!important;
      }
      #feedPage .feedGoldPollOptions button.feedGoldPollChoice span,#feedPage .pollChoice span,#feedPage .photoLikeChoice span{min-width:0!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;position:relative!important;z-index:1!important}
      #feedPage .feedGoldPollOptions button.feedGoldPollChoice b,#feedPage .pollChoice b,#feedPage .photoLikeChoice b{font-size:10.5px!important;white-space:nowrap!important;float:none!important;position:relative!important;z-index:1!important;color:#ffd971!important}
      #feedPage .feedGoldResults{display:none!important}
      #feedPage .pollTotal{font-size:11px!important;text-align:center!important;margin-top:4px!important;color:#ffe6a2!important}
      #feedPage .feedGoldCardActions{position:absolute!important;right:7px!important;left:auto!important;top:50%!important;transform:translateY(-50%)!important;z-index:75!important;display:flex!important;flex-direction:column!important;gap:7px!important;background:rgba(5,18,31,.18)!important;border:1px solid rgba(255,255,255,.10)!important;border-radius:999px!important;padding:6px 4px!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important;touch-action:manipulation!important}
      #feedPage .feedGoldCardActions .btn{width:37px!important;min-width:37px!important;height:37px!important;min-height:37px!important;border-radius:50%!important;padding:0!important;font-size:0!important;display:grid!important;place-items:center!important}
      #feedPage .feedGoldCardActions .btn:before{content:'💬❤️';font-size:17px!important;line-height:1!important}
      body[data-screen-theme="outdoor"] #feedPage .feedList>.feedGoldWisdomCard,
      body[data-screen-theme="outdoor"] #feedPage .feedList>.feedGoldPollCard,
      body[data-screen-theme="outdoor"] #feedPage .professionalPollCard,
      body[data-screen-theme="outdoor"] #feedPage .photoLikeInfoCard,
      body[data-screen-theme="outdoor"] #feedPage .ithakiQuestionCard{background:#fff8b8!important;color:#04121f!important;border-color:#111!important;box-shadow:0 0 0 2px #fff,0 14px 34px rgba(0,0,0,.35)!important}
      body[data-screen-theme="outdoor"] #feedPage .feedGoldQuote,
      body[data-screen-theme="outdoor"] #feedPage .pollQuestion,
      body[data-screen-theme="outdoor"] #feedPage .photoLikeQuote{color:#4a2d00!important;text-shadow:none!important}
      body[data-screen-theme="outdoor"] #feedPage .feedGoldPrompt,
      body[data-screen-theme="outdoor"] #feedPage .photoLikePrompt,
      body[data-screen-theme="outdoor"] #feedPage .pollTotal{color:#111!important;text-shadow:none!important}
      @media(max-height:720px){
        #feedPage .feedGoldPrompt,#feedPage .photoLikePrompt{display:none!important}
        #feedPage .feedGoldPollOptions button.feedGoldPollChoice,#feedPage .pollChoice,#feedPage .photoLikeChoice{min-height:29px!important;padding:5px 7px!important;font-size:11.2px!important}
        #feedPage .feedGoldQuote,#feedPage .pollQuestion,#feedPage .photoLikeQuote{font-size:clamp(14px,3.9vw,19px)!important;margin-bottom:5px!important}
      }
      @media(max-width:760px){
        #feedPage .feedList>.feedGoldWisdomCard,#feedPage .feedList>.feedGoldPollCard,#feedPage .professionalPollCard,#feedPage .photoLikeInfoCard,#feedPage .ithakiQuestionCard{width:min(92vw,520px)!important;padding-right:48px!important;margin-top:10px!important;margin-bottom:calc(var(--bar) + 16px)!important}
      }
    `;
    document.head.appendChild(st);
  }catch(e){console.warn('v249204 compact mobile cards css',e)}
}


function injectV249206FeedVersionAndCardFitCss(){
  try{
    if(document.getElementById('ithV249206FeedVersionAndCardFitCss'))return;
    const st=document.createElement('style');
    st.id='ithV249206FeedVersionAndCardFitCss';
    st.textContent=`
      /* V249206 final override: same Feed/cards on laptop + APK, no sticky card lock */
      #feedPage{overflow:hidden!important;background:#000!important}
      #feedPage .feedList{height:100dvh!important;overflow-y:auto!important;overflow-x:hidden!important;scroll-snap-type:y proximity!important;scroll-padding-bottom:calc(var(--bar) + 18px)!important;padding-bottom:calc(var(--bar) + 24px)!important;overscroll-behavior-y:auto!important;-webkit-overflow-scrolling:touch!important;touch-action:pan-y!important;background:#000!important}
      #feedPage .feedList>.post.pollPost{height:auto!important;min-height:0!important;max-height:none!important;width:min(94vw,660px)!important;margin:10px auto calc(var(--bar) + 22px)!important;padding:0!important;border:0!important;border-radius:0!important;background:transparent!important;box-shadow:none!important;display:block!important;overflow:visible!important;scroll-snap-align:start!important;scroll-snap-stop:normal!important;touch-action:pan-y!important;overscroll-behavior-y:auto!important}
      #feedPage .post.pollPost .postHead{display:none!important}
      #feedPage .post.pollPost .pollAsText{display:block!important;width:100%!important;height:auto!important;max-height:none!important;overflow:visible!important;touch-action:pan-y!important;overscroll-behavior-y:auto!important}
      #feedPage .pollFeedCard,#feedPage .professionalPollCard,#feedPage .photoLikeInfoCard{width:100%!important;max-width:660px!important;min-height:0!important;height:auto!important;max-height:calc(100dvh - var(--bar) - 56px)!important;margin:0 auto!important;padding:10px 50px 10px 10px!important;border-radius:20px!important;box-sizing:border-box!important;overflow:visible!important;display:flex!important;flex-direction:column!important;justify-content:center!important;background:radial-gradient(circle at 18% 8%,rgba(255,225,120,.16),transparent 30%),linear-gradient(145deg,#130d05,#2a1706 55%,#070504)!important;border:1px solid rgba(255,217,110,.30)!important;box-shadow:0 12px 34px rgba(0,0,0,.34)!important;color:#fff7dc!important;touch-action:pan-y!important;overscroll-behavior-y:auto!important}
      #feedPage .pollFeedCard .photoLikeTop,#feedPage .pollFeedCard .photoLikeIcon,#feedPage .pollFeedCard .photoLikeBadge,#feedPage .pollFeedCard .cardIconBar,#feedPage .pollFeedCard .pollRibbon,#feedPage .pollFeedCard .photoLikePrompt,#feedPage .pollFeedCard .pollMode{display:none!important}
      #feedPage .pollFeedCard .photoLikeCenter{width:100%!important;max-width:100%!important;padding:0!important;margin:0!important;overflow:visible!important;display:block!important;transform:none!important;touch-action:pan-y!important}
      #feedPage .pollFeedCard .pollTitle{font-size:12px!important;line-height:1.08!important;margin:0 auto 3px!important;text-align:center!important;color:#ffe6a2!important;font-weight:1000!important;letter-spacing:.02em!important;max-width:100%!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}
      #feedPage .pollFeedCard .pollQuestion{font-size:clamp(14px,3.6vw,20px)!important;line-height:1.08!important;margin:0 auto 6px!important;text-align:center!important;color:#ffd36e!important;font-weight:1000!important;text-shadow:0 3px 12px rgba(0,0,0,.55)!important;max-width:100%!important;text-wrap:balance!important}
      #feedPage .pollFeedCard .pollVoteOptions{display:grid!important;grid-template-columns:1fr!important;gap:4px!important;margin:4px auto 4px!important;padding:0!important;width:100%!important;max-width:560px!important;min-height:0!important;max-height:none!important;overflow:visible!important;touch-action:pan-y!important;overscroll-behavior-y:auto!important}
      #feedPage .pollFeedCard .pollChoice{min-height:27px!important;padding:4px 7px!important;border-radius:12px!important;font-size:11.1px!important;line-height:1.08!important;display:grid!important;grid-template-columns:minmax(0,1fr) auto!important;align-items:center!important;gap:5px!important;background:rgba(255,255,255,.07)!important;border:1px solid rgba(255,217,110,.32)!important;color:#fff6da!important;font-weight:900!important;text-align:left!important;position:relative!important;overflow:hidden!important;touch-action:manipulation!important}
      #feedPage .pollFeedCard .pollChoice span{position:relative!important;z-index:1!important;min-width:0!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}
      #feedPage .pollFeedCard .pollChoice b{position:relative!important;z-index:1!important;font-size:10px!important;white-space:nowrap!important;color:#ffd971!important}
      #feedPage .pollFeedCard .pollChoice em{position:absolute!important;left:0!important;top:0!important;bottom:0!important;background:rgba(255,211,110,.16)!important;border-radius:12px!important;pointer-events:none!important}
      #feedPage .pollFeedCard .pollTotal{font-size:10.5px!important;line-height:1!important;text-align:center!important;margin:4px 0 0!important;color:#ffe6a2!important}
      #feedPage .post.pollPost .pollPostActions{position:absolute!important;right:7px!important;top:50%!important;transform:translateY(-50%)!important;z-index:75!important;display:flex!important;flex-direction:column!important;gap:6px!important;padding:5px 4px!important;border-radius:999px!important;background:rgba(5,18,31,.18)!important;border:1px solid rgba(255,255,255,.10)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important}
      #feedPage .post.pollPost .pollPostActions .actionIcon{min-width:36px!important;width:36px!important;height:36px!important;min-height:36px!important;border-radius:50%!important;font-size:15px!important;padding:0!important;background:rgba(255,255,255,.09)!important;color:#fff!important;display:grid!important;place-items:center!important}
      @media(min-width:761px){#feedPage .feedList>.post.pollPost{width:min(78vw,720px)!important;margin-top:18px!important;margin-bottom:calc(var(--bar) + 18px)!important}#feedPage .pollFeedCard{max-width:720px!important;padding:12px 56px 12px 12px!important;max-height:calc(100dvh - var(--bar) - 70px)!important}#feedPage .pollFeedCard .pollVoteOptions{grid-template-columns:1fr 1fr!important;max-width:620px!important;gap:5px!important}#feedPage .pollFeedCard .pollQuestion{font-size:clamp(16px,2.2vw,23px)!important;margin-bottom:8px!important}#feedPage .pollFeedCard .pollChoice{min-height:32px!important;font-size:12px!important;padding:6px 8px!important}}
      @media(max-width:760px){#feedPage .feedList>.post.pollPost{width:min(92vw,520px)!important;margin-top:8px!important;margin-bottom:calc(var(--bar) + 20px)!important}#feedPage .pollFeedCard{max-height:calc(100dvh - var(--bar) - 44px)!important;padding:9px 46px 9px 9px!important;border-radius:18px!important}#feedPage .pollFeedCard .pollQuestion{font-size:clamp(13px,3.8vw,18px)!important;margin-bottom:5px!important}#feedPage .pollFeedCard .pollChoice{min-height:26px!important;font-size:10.8px!important;padding:4px 6px!important}#feedPage .pollFeedCard .pollTotal{font-size:10px!important}}
      @media(max-height:700px){#feedPage .pollFeedCard{padding-top:7px!important;padding-bottom:7px!important;max-height:calc(100dvh - var(--bar) - 36px)!important}#feedPage .pollFeedCard .pollTitle{display:none!important}#feedPage .pollFeedCard .pollQuestion{font-size:clamp(12px,3.3vw,17px)!important;line-height:1.04!important;margin-bottom:4px!important}#feedPage .pollFeedCard .pollVoteOptions{gap:3px!important;margin:3px auto!important}#feedPage .pollFeedCard .pollChoice{min-height:24px!important;padding:3px 6px!important;font-size:10.4px!important;border-radius:10px!important}#feedPage .pollFeedCard .pollTotal{display:none!important}}
      body[data-screen-theme="outdoor"] #feedPage .pollFeedCard{background:#fff8b8!important;color:#04121f!important;border-color:#111!important;box-shadow:0 0 0 2px #fff,0 14px 34px rgba(0,0,0,.35)!important}body[data-screen-theme="outdoor"] #feedPage .pollFeedCard .pollQuestion{color:#4a2d00!important;text-shadow:none!important}body[data-screen-theme="outdoor"] #feedPage .pollFeedCard .pollChoice{background:#fff!important;color:#000!important;border-color:#111!important}body[data-screen-theme="outdoor"] #feedPage .pollFeedCard .pollChoice b,body[data-screen-theme="outdoor"] #feedPage .pollFeedCard .pollTotal{color:#3a2500!important}
    `;
    document.head.appendChild(st);
  }catch(e){console.warn('v249206 feed/card fit css',e)}
}


function injectV249206EqualFeedCardSlotsCss(){
  try{
    if(document.getElementById('ithV249206EqualFeedCardSlotsCss'))return;
    const st=document.createElement('style');
    st.id='ithV249206EqualFeedCardSlotsCss';
    st.textContent=`
      /* V249206: same Feed slot for video, poll, wisdom and text cards; compact inner card; no inner scroll lock */
      #feedPage{overflow:hidden!important;background:#000!important}
      #feedPage .feedList{height:100dvh!important;overflow-y:auto!important;overflow-x:hidden!important;scroll-snap-type:y mandatory!important;scroll-padding-top:0!important;scroll-padding-bottom:0!important;padding:0!important;margin:0!important;overscroll-behavior-y:auto!important;-webkit-overflow-scrolling:touch!important;touch-action:pan-y!important;background:#000!important}
      #feedPage .feedList>.post,
      #feedPage .feedList>.post.pollPost,
      #feedPage .feedList>.feedGoldWisdomCard,
      #feedPage .feedList>.feedGoldPollCard,
      #feedPage .feedList>.professionalPollCard,
      #feedPage .feedList>.photoLikeInfoCard,
      #feedPage .feedList>.ithakiQuestionCard{
        height:95dvh!important;min-height:95dvh!important;max-height:95dvh!important;width:100%!important;max-width:none!important;
        margin:2.5dvh 0!important;padding:0!important;border:0!important;border-radius:0!important;background:#000!important;box-shadow:none!important;
        display:flex!important;align-items:center!important;justify-content:center!important;overflow:hidden!important;
        scroll-snap-align:center!important;scroll-snap-stop:always!important;touch-action:pan-y!important;overscroll-behavior-y:auto!important;
      }
      #feedPage .feedList>.post.pollPost{position:relative!important;background:#000!important}
      #feedPage .post.pollPost .pollAsText{width:min(88vw,760px)!important;max-width:760px!important;display:flex!important;align-items:center!important;justify-content:center!important;overflow:visible!important;touch-action:pan-y!important}
      #feedPage .pollFeedCard,
      #feedPage .feedGoldCardInner,
      #feedPage .professionalPollCard .photoLikeCenter,
      #feedPage .photoLikeInfoCard .photoLikeCenter,
      #feedPage .ithakiQuestionCard .photoLikeCenter{
        width:min(86vw,760px)!important;max-width:760px!important;max-height:calc(95dvh - var(--bar) - 26px)!important;
        margin:0 auto!important;padding:clamp(12px,2.2vw,20px) 56px clamp(12px,2.2vw,20px) clamp(12px,2.2vw,20px)!important;
        border-radius:24px!important;box-sizing:border-box!important;overflow:hidden!important;display:flex!important;flex-direction:column!important;justify-content:center!important;
        background:radial-gradient(circle at 18% 8%,rgba(255,225,120,.18),transparent 32%),linear-gradient(145deg,#120b03,#2a1706 55%,#070504)!important;
        border:1px solid rgba(255,217,110,.34)!important;box-shadow:0 18px 48px rgba(0,0,0,.42)!important;color:#fff7dc!important;
        touch-action:pan-y!important;overscroll-behavior:auto!important;transform:none!important;
      }
      #feedPage .feedGoldWisdomCard .feedGoldCardInner{padding-right:clamp(18px,2.4vw,26px)!important;text-align:center!important}
      #feedPage .feedGoldPollCard .feedGoldCardInner{padding-right:56px!important;text-align:center!important}
      #feedPage .feedGoldLabel,#feedPage .pollRibbon,#feedPage .cardIconBar,#feedPage .photoLikeTop,#feedPage .feedGoldVoteMode,#feedPage .pollMode,#feedPage .feedGoldPollCard .feedGoldLogo{display:none!important}
      #feedPage .feedGoldQuote,#feedPage .pollQuestion,#feedPage .photoLikeQuote{
        color:#ffd36e!important;text-shadow:0 3px 14px rgba(0,0,0,.68),0 0 22px rgba(255,205,70,.16)!important;
        text-align:center!important;font-weight:1000!important;line-height:1.12!important;margin:0 auto clamp(8px,1.4dvh,13px)!important;max-width:100%!important;text-wrap:balance!important;
      }
      #feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(24px,4.4vw,42px)!important;line-height:1.16!important;color:#ffd36e!important;letter-spacing:.01em!important}
      #feedPage .feedGoldPollCard .feedGoldQuote,#feedPage .pollFeedCard .pollQuestion{font-size:clamp(16px,2.8vw,27px)!important}
      #feedPage .pollFeedCard .pollTitle{font-size:clamp(12px,1.4vw,15px)!important;line-height:1.08!important;margin:0 auto 5px!important;text-align:center!important;color:#ffe6a2!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important;max-width:100%!important}
      #feedPage .feedGoldPrompt,#feedPage .photoLikePrompt{font-size:clamp(11px,1.5vw,14px)!important;line-height:1.2!important;margin:0 auto clamp(8px,1.4dvh,12px)!important;color:rgba(255,246,218,.86)!important;text-align:center!important;max-width:92%!important}
      #feedPage .feedGoldPollOptions,#feedPage .pollVoteOptions,#feedPage .photoLikeChoices{
        width:100%!important;max-width:650px!important;margin:0 auto!important;padding:0!important;display:grid!important;grid-template-columns:1fr 1fr!important;gap:clamp(5px,.9dvh,8px)!important;
        overflow:visible!important;max-height:none!important;min-height:0!important;touch-action:pan-y!important;overscroll-behavior:auto!important;
      }
      #feedPage .feedGoldPollOptions button.feedGoldPollChoice,#feedPage .pollChoice,#feedPage .photoLikeChoice{
        min-height:clamp(32px,5dvh,44px)!important;padding:clamp(6px,.9dvh,9px) 10px!important;border-radius:14px!important;
        font-size:clamp(11.4px,1.55vw,13.5px)!important;line-height:1.12!important;display:grid!important;grid-template-columns:minmax(0,1fr) auto!important;align-items:center!important;gap:6px!important;
        background:rgba(255,255,255,.075)!important;border:1px solid rgba(255,217,110,.34)!important;color:#fff6da!important;text-align:left!important;font-weight:900!important;position:relative!important;overflow:hidden!important;touch-action:manipulation!important;
      }
      #feedPage .feedGoldPollOptions button.feedGoldPollChoice span,#feedPage .pollChoice span,#feedPage .photoLikeChoice span{min-width:0!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important;position:relative!important;z-index:1!important}
      #feedPage .feedGoldPollOptions button.feedGoldPollChoice b,#feedPage .pollChoice b,#feedPage .photoLikeChoice b{font-size:clamp(10px,1.2vw,12px)!important;color:#ffd971!important;white-space:nowrap!important;position:relative!important;z-index:1!important;float:none!important}
      #feedPage .feedGoldResults{display:none!important}
      #feedPage .pollTotal{font-size:clamp(10px,1.2vw,12px)!important;line-height:1.05!important;text-align:center!important;margin:clamp(6px,1dvh,9px) 0 0!important;color:#ffe6a2!important}
      #feedPage .post.pollPost .pollPostActions,#feedPage .feedGoldCardActions{position:absolute!important;right:clamp(7px,1.4vw,13px)!important;left:auto!important;top:50%!important;transform:translateY(-50%)!important;z-index:80!important;display:flex!important;flex-direction:column!important;gap:7px!important;padding:6px 4px!important;border-radius:999px!important;background:rgba(5,18,31,.22)!important;border:1px solid rgba(255,255,255,.12)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important;touch-action:manipulation!important}
      #feedPage .post.pollPost .pollPostActions .actionIcon,#feedPage .feedGoldCardActions .btn{min-width:38px!important;width:38px!important;height:38px!important;min-height:38px!important;border-radius:50%!important;padding:0!important;display:grid!important;place-items:center!important;background:rgba(255,255,255,.09)!important;color:#fff!important;font-size:0!important}
      #feedPage .feedGoldCardActions .btn:before{content:'💬❤️';font-size:17px!important;line-height:1!important}
      @media(max-width:760px){
        #feedPage .post.pollPost .pollAsText{width:min(88vw,520px)!important;max-width:520px!important}
        #feedPage .pollFeedCard,#feedPage .feedGoldCardInner,#feedPage .professionalPollCard .photoLikeCenter,#feedPage .photoLikeInfoCard .photoLikeCenter,#feedPage .ithakiQuestionCard .photoLikeCenter{width:min(88vw,520px)!important;max-height:calc(95dvh - var(--bar) - 20px)!important;padding:11px 48px 11px 11px!important;border-radius:20px!important}
        #feedPage .feedGoldWisdomCard .feedGoldCardInner{padding:14px 18px!important;width:min(88vw,520px)!important}
        #feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(22px,7vw,34px)!important}
        #feedPage .feedGoldPollCard .feedGoldQuote,#feedPage .pollFeedCard .pollQuestion{font-size:clamp(15px,4.4vw,20px)!important;margin-bottom:7px!important}
        #feedPage .feedGoldPollOptions,#feedPage .pollVoteOptions,#feedPage .photoLikeChoices{grid-template-columns:1fr!important;gap:5px!important;max-width:100%!important}
        #feedPage .feedGoldPollOptions button.feedGoldPollChoice,#feedPage .pollChoice,#feedPage .photoLikeChoice{min-height:31px!important;font-size:11.2px!important;padding:5px 7px!important;border-radius:12px!important}
        #feedPage .pollTotal{font-size:10.5px!important;margin-top:5px!important}
        #feedPage .post.pollPost .pollPostActions,#feedPage .feedGoldCardActions{right:6px!important;gap:6px!important}
        #feedPage .post.pollPost .pollPostActions .actionIcon,#feedPage .feedGoldCardActions .btn{min-width:36px!important;width:36px!important;height:36px!important;min-height:36px!important}
      }
      @media(max-height:700px){
        #feedPage .feedGoldPrompt,#feedPage .photoLikePrompt{display:none!important}
        #feedPage .pollFeedCard .pollTitle{display:none!important}
        #feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(20px,5.8vw,30px)!important}
        #feedPage .feedGoldPollCard .feedGoldQuote,#feedPage .pollFeedCard .pollQuestion{font-size:clamp(13px,3.6vw,18px)!important;margin-bottom:5px!important}
        #feedPage .feedGoldPollOptions button.feedGoldPollChoice,#feedPage .pollChoice,#feedPage .photoLikeChoice{min-height:27px!important;padding:4px 6px!important;font-size:10.6px!important}
        #feedPage .pollTotal{display:none!important}
      }
      body[data-screen-theme="outdoor"] #feedPage .pollFeedCard,body[data-screen-theme="outdoor"] #feedPage .feedGoldCardInner{background:#fff8b8!important;color:#04121f!important;border-color:#111!important;box-shadow:0 0 0 2px #fff,0 14px 34px rgba(0,0,0,.35)!important}
      body[data-screen-theme="outdoor"] #feedPage .feedGoldQuote,body[data-screen-theme="outdoor"] #feedPage .pollQuestion,body[data-screen-theme="outdoor"] #feedPage .photoLikeQuote{color:#4a2d00!important;text-shadow:none!important}
      body[data-screen-theme="outdoor"] #feedPage .pollChoice,body[data-screen-theme="outdoor"] #feedPage .feedGoldPollChoice{background:#fff!important;color:#000!important;border-color:#111!important}
    `;
    document.head.appendChild(st);
  }catch(e){console.warn('v249206 equal feed card slots css',e)}
}


function injectV249207PollSingleCardAndNoDuplicateCss(){
  try{
    if(document.getElementById('ithV249207PollSingleCardCss'))return;
    const st=document.createElement('style');
    st.id='ithV249207PollSingleCardCss';
    st.textContent=`
      /* V249207: one poll post = one full Feed slot + one inner card, no duplicate text/card */
      #feedPage .post.pollPost>.textClamp,
      #feedPage .post.pollPost>.postTranslateOut,
      #feedPage .post.pollPost>.moreText{display:none!important}
      #feedPage .feedList>.post.pollPost{height:95dvh!important;min-height:95dvh!important;max-height:95dvh!important;width:100%!important;max-width:none!important;margin:2.5dvh 0!important;padding:0!important;background:#000!important;overflow:hidden!important;display:flex!important;align-items:center!important;justify-content:center!important;scroll-snap-align:center!important;touch-action:pan-y!important;overscroll-behavior:auto!important}
      #feedPage .post.pollPost .pollAsText{height:100%!important;width:100%!important;max-width:none!important;display:flex!important;align-items:center!important;justify-content:center!important;overflow:hidden!important;touch-action:pan-y!important;overscroll-behavior:auto!important}
      #feedPage .post.pollPost .pollFeedCard{width:min(88vw,760px)!important;max-width:760px!important;max-height:calc(95dvh - var(--bar) - 24px)!important;min-height:0!important;height:auto!important;margin:0 auto!important;overflow:hidden!important;touch-action:pan-y!important;overscroll-behavior:auto!important}
      #feedPage .post.pollPost .pollVoteOptions{overflow:visible!important;max-height:none!important;touch-action:pan-y!important;overscroll-behavior:auto!important}
      @media(max-width:760px){#feedPage .post.pollPost .pollFeedCard{width:min(89vw,520px)!important;max-height:calc(95dvh - var(--bar) - 18px)!important;padding:10px 48px 10px 10px!important}#feedPage .post.pollPost .pollChoice{min-height:29px!important;font-size:11px!important;padding:5px 7px!important}}
      @media(max-height:700px){#feedPage .post.pollPost .pollFeedCard{max-height:calc(95dvh - var(--bar) - 12px)!important;padding-top:8px!important;padding-bottom:8px!important}#feedPage .post.pollPost .pollChoice{min-height:26px!important;font-size:10.5px!important;padding:4px 6px!important}}
    `;
    document.head.appendChild(st);
  }catch(e){console.warn('v249207 poll single card css',e)}
}


function injectV249213CardsPollCss(){
  try{
    if(document.getElementById('ithV249213CardsPollCss'))return;
    const st=document.createElement('style');
    st.id='ithV249213CardsPollCss';
    st.textContent=`
      /* V249213: clean ITHAKI cards, visible side icons, centered polls up to 9 options */
      #feedPage .pollRibbon,#feedPage .photoLikeBadge,#feedPage .photoLikeTop,#feedPage .pollTitle,#feedPage .photoLikePrompt,#feedPage .pollMode{display:none!important}
      #feedPage .pollFeedCard,#feedPage .feedGoldCardInner,#feedPage .professionalPollCard{position:relative!important;width:min(88vw,760px)!important;max-width:760px!important;margin:0 auto!important;padding:clamp(12px,2.2vw,20px) 58px clamp(12px,2.2vw,20px) clamp(12px,2.2vw,20px)!important;border-radius:24px!important;box-sizing:border-box!important;overflow:hidden!important;display:flex!important;flex-direction:column!important;justify-content:center!important;align-items:center!important;background:radial-gradient(circle at 18% 8%,rgba(255,225,120,.18),transparent 32%),linear-gradient(145deg,#120b03,#2a1706 55%,#070504)!important;border:1px solid rgba(255,217,110,.34)!important;box-shadow:0 18px 48px rgba(0,0,0,.42)!important;color:#fff7dc!important;touch-action:pan-y!important;overscroll-behavior:auto!important}
      #feedPage .pollLogoClean,#feedPage .feedGoldLogo{display:flex!important;align-items:center!important;justify-content:center!important;gap:8px!important;margin:0 auto clamp(8px,1.3dvh,12px)!important;text-align:center!important;color:#fff!important}
      #feedPage .pollLogoClean img,#feedPage .feedGoldLogo img{display:block!important;width:clamp(54px,10vw,92px)!important;height:clamp(54px,10vw,92px)!important;object-fit:contain!important;filter:drop-shadow(0 10px 24px rgba(0,0,0,.45))!important}
      #feedPage .pollLogoClean b,#feedPage .feedGoldBrandText .okRainbow{font-size:clamp(18px,3.8vw,32px)!important;font-weight:1000!important;line-height:1!important}
      #feedPage .pollLogoClean small,#feedPage .feedGoldBrandText small{display:block!important;font-size:clamp(12px,2.2vw,17px)!important;letter-spacing:.14em!important;text-transform:lowercase!important;color:#ffe29b!important;font-weight:900!important}
      #feedPage .feedGoldBrandText{display:block!important;text-align:center!important;margin:-6px auto 8px!important;color:#fff!important}
      #feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(25px,4.7vw,45px)!important;line-height:1.15!important;color:#ffd36e!important;text-align:center!important;font-weight:1000!important;letter-spacing:.01em!important;text-shadow:0 3px 14px rgba(0,0,0,.72),0 0 22px rgba(255,205,70,.18)!important;max-width:100%!important;text-wrap:balance!important}
      #feedPage .pollQuestion,#feedPage .feedGoldPollCard .feedGoldQuote,#feedPage .photoLikeQuote{font-size:clamp(16px,2.6vw,28px)!important;line-height:1.13!important;color:#ffd36e!important;text-align:center!important;font-weight:1000!important;margin:0 auto clamp(8px,1.2dvh,12px)!important;max-width:100%!important;text-wrap:balance!important;text-shadow:0 3px 14px rgba(0,0,0,.72),0 0 22px rgba(255,205,70,.16)!important}
      #feedPage .pollVoteOptions,#feedPage .feedGoldPollOptions,#feedPage .photoLikeChoices{width:100%!important;max-width:650px!important;margin:0 auto!important;padding:0!important;display:grid!important;grid-template-columns:repeat(2,minmax(0,1fr))!important;gap:clamp(5px,.9dvh,8px)!important;overflow:visible!important;max-height:none!important;min-height:0!important;touch-action:pan-y!important;overscroll-behavior:auto!important}
      #feedPage .pollManyOptions .pollVoteOptions{grid-template-columns:repeat(3,minmax(0,1fr))!important;max-width:720px!important}
      #feedPage .pollChoice,#feedPage .feedGoldPollChoice,#feedPage .photoLikeChoice{min-height:clamp(30px,4.7dvh,42px)!important;padding:clamp(5px,.8dvh,8px) 8px!important;border-radius:14px!important;font-size:clamp(10.8px,1.45vw,13.2px)!important;line-height:1.08!important;display:grid!important;grid-template-columns:minmax(0,1fr) auto!important;align-items:center!important;gap:6px!important;background:rgba(255,255,255,.075)!important;border:1px solid rgba(255,217,110,.34)!important;color:#fff6da!important;text-align:left!important;font-weight:900!important;position:relative!important;overflow:hidden!important;touch-action:manipulation!important;box-sizing:border-box!important;max-width:100%!important}
      #feedPage .pollChoice span,#feedPage .feedGoldPollChoice span,#feedPage .photoLikeChoice span{min-width:0!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;position:relative!important;z-index:2!important}
      #feedPage .pollChoice b,#feedPage .feedGoldPollChoice b,#feedPage .photoLikeChoice b{font-size:clamp(9.5px,1.1vw,11.5px)!important;color:#ffd971!important;white-space:nowrap!important;position:relative!important;z-index:2!important;float:none!important}
      #feedPage .pollChoice em,#feedPage .feedGoldPollChoice em,#feedPage .photoLikeChoice em{position:absolute!important;left:0!important;top:0!important;bottom:0!important;background:linear-gradient(90deg,rgba(255,215,90,.24),rgba(255,215,90,.05))!important;z-index:1!important;border-radius:inherit!important;pointer-events:none!important}
      #feedPage .pollTotal{font-size:clamp(10px,1.2vw,12px)!important;line-height:1.05!important;text-align:center!important;margin:clamp(6px,1dvh,9px) 0 0!important;color:#ffe6a2!important}
      #feedPage .post.pollPost .pollPostActions,#feedPage .feedGoldCardActions{position:absolute!important;right:clamp(7px,1.4vw,13px)!important;left:auto!important;top:50%!important;transform:translateY(-50%)!important;z-index:80!important;display:flex!important;flex-direction:column!important;gap:7px!important;padding:6px 4px!important;border-radius:999px!important;background:rgba(5,18,31,.24)!important;border:1px solid rgba(255,255,255,.12)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important;touch-action:manipulation!important}
      #feedPage .post.pollPost .pollPostActions .actionIcon,#feedPage .feedGoldCardActions .btn{min-width:38px!important;width:38px!important;height:38px!important;min-height:38px!important;border-radius:50%!important;padding:0!important;display:grid!important;place-items:center!important;background:rgba(255,255,255,.10)!important;color:#fff!important;font-size:18px!important;line-height:1!important;overflow:visible!important}
      #feedPage .post.pollPost .pollPostActions .actionIcon .count{display:block!important;position:absolute!important;right:-4px!important;bottom:-3px!important;min-width:15px!important;height:15px!important;border-radius:999px!important;padding:0 3px!important;background:#ffd36e!important;color:#241200!important;font-size:9px!important;line-height:15px!important;font-weight:1000!important}
      #feedPage .feedGoldCardActions .btn:before{content:none!important;display:none!important}
      #feedPage .feedGoldCardActions .btn span{display:block!important;font-size:18px!important;line-height:1!important;color:#fff!important}
      .proPollModal .pollHead b{font-size:0!important}.proPollModal .pollHead b:after{content:'📊 Ψηφοφορία ΙΘΑΚΗΣ';font-size:18px!important}.proPollModal #pollFeed{accent-color:#ffd36e}.proPollModal .pollBuilder{max-width:720px!important;margin:0 auto!important}.proPollModal #pollOptions{display:grid!important;grid-template-columns:repeat(2,minmax(0,1fr))!important;gap:7px!important}.proPollModal .pollOpt{width:100%!important;margin-top:0!important;box-sizing:border-box!important}.proPollModal .pollOptionRow{display:flex!important;gap:8px!important;flex-wrap:wrap!important;align-items:center!important;justify-content:center!important}
      @media(max-width:760px){#feedPage .pollFeedCard,#feedPage .feedGoldCardInner,#feedPage .professionalPollCard{width:min(89vw,520px)!important;padding:11px 50px 11px 11px!important;border-radius:20px!important}#feedPage .pollVoteOptions,#feedPage .feedGoldPollOptions,#feedPage .photoLikeChoices,#feedPage .pollManyOptions .pollVoteOptions{grid-template-columns:1fr!important;gap:5px!important;max-width:100%!important}#feedPage .pollChoice,#feedPage .feedGoldPollChoice,#feedPage .photoLikeChoice{min-height:28px!important;font-size:10.7px!important;padding:4px 6px!important;border-radius:12px!important}#feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(24px,7vw,36px)!important}#feedPage .post.pollPost .pollPostActions,#feedPage .feedGoldCardActions{right:6px!important;gap:6px!important}.proPollModal #pollOptions{grid-template-columns:1fr!important}}
      @media(max-height:700px){#feedPage .pollLogoClean img,#feedPage .feedGoldLogo img{width:44px!important;height:44px!important}#feedPage .feedGoldBrandText{display:none!important}#feedPage .pollQuestion,#feedPage .feedGoldPollCard .feedGoldQuote{font-size:clamp(13px,3.6vw,18px)!important;margin-bottom:5px!important}#feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(21px,5.8vw,31px)!important}#feedPage .pollChoice,#feedPage .feedGoldPollChoice,#feedPage .photoLikeChoice{min-height:24px!important;padding:3px 5px!important;font-size:10px!important}#feedPage .pollTotal{display:none!important}}
    `;
    document.head.appendChild(st);
  }catch(e){console.warn('v249213 cards poll css',e)}
}

function filterFeedCardsV249189(){try{const q=(document.getElementById('feedSearchV249189')?.value||'').toLowerCase().trim();document.querySelectorAll('#feedPage .feedList>article').forEach(a=>{if(!q){a.style.display='';return}const tx=(a.textContent||'').toLowerCase();a.style.display=tx.includes(q)?'':'none'})}catch{}}
function isSimpleIthakiPlainPostV249189(p){try{const t=parseText(p.text);const body=String(t.body||'').trim();if(!body||t.media)return false;const who=(String(p.nickname||'')+' '+String(p.sender_id||'')).toLowerCase();return (who.includes('ithaki')||who.includes('ιθακη')||who.includes('ιθάκη')||who.includes('host'))}catch{return false}}


/* BEGIN V249429_NEW_FEED_ONLY_CORE_BRIDGE */
let loadFeed = async function v249429NewFeedOnlyBridge(){
  if(window.__ITHAKI_MEMBER_FEED_MODE_V249483__===true||window.__ITHAKI_MEMBER_FEED_MODE_V249481__===true)return false;
  try{
    if(window.ITH && typeof window.ITH.openProfessionalFeedV249430==='function'){
      return window.ITH.openProfessionalFeedV249430('core-bridge');
    }
    if(window.ITH && typeof window.ITH.openProfessionalFeedV249429==='function'){
      return window.ITH.openProfessionalFeedV249429('core-bridge');
    }
    window.__ITHAKI_PENDING_NEW_FEED_V249429__=true;
  }catch(e){}
  return false;
};
window.__ITHAKI_ACTIVE_LEGACY_FEED_LOADERS_V249429__=0;
/* END V249429_NEW_FEED_ONLY_CORE_BRIDGE */
/* V249429_LEGACY_LOAD_FEED_REMOVED */
function counts(p){return{likes:+(p.likes||p.like_count||0),comments:+(p.comments||p.comment_count||0)}}
function actionButtons(p,c,mine){const rawId=String(p.post_id||''),id=esc(rawId),idJs=escJs(rawId);const body=(parseText(p.text).body||'').trim();const translate=body?`<button class="actionIcon translateAction" title="${uiText('Translate')}" onclick="ITH.translateBlock('post_${idJs}','${escJs(body.slice(0,1200))}')">🌐<small>TR</small></button>`:'';return `<button class="actionIcon" onclick="ITH.like('${idJs}')">❤️<span class="count" id="like_${id}">${c.likes}</span></button><button class="actionIcon" onclick="ITH.openPostCommentsPanel('${idJs}')">💬<span class="count" id="comment_count_${id}">${c.comments}</span></button>${translate}<button class="actionIcon" onclick="ITH.savePost('${idJs}')">💾</button><button class="actionIcon" onclick="ITH.sharePost('${idJs}')">📤</button>${mine?`<button class="actionIcon" onclick="ITH.deletePost('${idJs}')">🗑️</button>`:''}`}
function renderPost(p){const t=parseText(p.text),c=counts(p),mine=String(p.sender_id)===state.device;const pid=esc(p.post_id||''),sender=esc(p.sender_id||'');const rawSender=String(p.sender_id||'');const anon=!!p.anonymous;const isPoll=t.media&&String(t.media.kind||'').toLowerCase()==='poll';const hasMedia=!!t.media;const bodyText=String(t.body||'').trim();const more=(bodyText&&bodyText.length>120)?`<button class="moreText" onclick="this.previousElementSibling.classList.toggle('open')">more</button>`:'';const bodyHtml=bodyText?`<div class="textClamp" onclick="this.classList.toggle('open')">${esc(bodyText)}</div><div id="tr_post_${pid}" class="translateOut postTranslateOut"></div>${more}`:'';const shownName=anon?uiText('Anonymous'):p.nickname||'Member';const pinfo={id:rawSender,nickname:shownName,avatar:anon?'':(p.avatar||''),online:false};const dot=(!anon&&unreadFrom(rawSender))?'red':'';const memberClick=anon?'return false':(mine?`ITH.openMemberFeed('${sender}','${pid}')`:`ITH.member('${sender}')`);const head=`<div class="postHead"><button onclick="${memberClick}" title="${anon?uiText('Anonymous post'):(mine?'Οι δημοσιεύσεις μου':uiText('Member menu'))}">${avatarHtml(pinfo)}</button><div><div class="name">${esc(shownName)}${anon?' <span class="anonBadge">🕶️ '+uiText('Anonymous')+'</span>':''}</div><div class="date">${fmt(p.created_at)}</div></div></div>`;const overlayAvatar=`<button class="feedAvatarOverlay" onclick="event.stopPropagation();${anon?'return false':(mine?`ITH.openMemberFeed(\'${sender}\',\'${pid}\')`:`ITH.member(\'${sender}\')`)}" title="${anon?uiText('Anonymous post'):(mine?'Οι δημοσιεύσεις μου':uiText('Member menu'))}"><span class="avatarDotWrap">${avatarHtml(pinfo)}<i class="${dot}"></i></span><small>${esc(shownName)}</small></button>`;let media='',actions='',topHead=head;if(isPoll){media=`<div class="pollAsText">${mediaHtml(t.media,false)}</div>`;actions=`<div class="pollPostActions">${actionButtons(p,c,mine)}</div>`}else{actions=`<div class="leftActions" ${hasMedia?'':'style="position:static;transform:none;flex-direction:row"'}>${hasMedia?overlayAvatar:''}${actionButtons(p,c,mine)}</div>`;if(hasMedia){topHead='';media=`<div class="postMediaWrap tiktokScreen">${mediaHtml(t.media,false)}${actions}</div>`}else media=actions}return `<article class="card post ${hasMedia?'mediaPost':''} ${isPoll?'pollPost':''} ${anon?'anonymousPost':''}" data-post="${pid}" data-sender="${sender}">${topHead}${bodyHtml}${media}${isPoll?actions:''}</article>`}
async function like(id){try{await fetchJson('/api/reactions/toggle',{method:'POST',body:JSON.stringify({target_id:id,device_id:state.device,emoji:'❤️',nickname:state.name})});const el=$('like_'+id);if(el)el.textContent=String((+el.textContent||0)+1)}catch{toast('Not counted')}}
function comments(id){openPostCommentsPanel(id)}

const BAD_WORDS=['μαλακ','βλακ','ηλιθ','γαμ','σκατ','πουτα','μουν','f@@k','fuck','shit'];
function maskWord(w){if(!w||w.length<3)return w;return w[0]+'$'.repeat(Math.max(1,w.length-2))+w[w.length-1]}
function maskBadWords(text){let changed=false;const out=String(text||'').split(/(\s+)/).map(part=>{const low=part.toLowerCase();if(BAD_WORDS.some(b=>low.includes(b))){changed=true;return maskWord(part)}return part}).join('');return {text:out,changed}}
async function openPostCommentsPanel(id){$('memberMenu').innerHTML=`<div class="commentPanel"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>💬❤️ ${uiText('Post comments')}</b><span id="panelCommentCount" class="date"></span><button class="icon" style="margin-left:auto" onclick="ITH.like('${esc(id)}')" title="Like">❤️<span id="like_${esc(id)}" class="count">0</span></button></div><div id="panelComments" class="panelComments"><div class="date">${uiText('Loading comments...')}</div></div><div id="commentReplyBox" class="card" style="display:none;margin-top:8px;padding:8px"></div><div class="commentComposer"><textarea id="commentInput" placeholder="${uiText('Write a comment or reply...')}"></textarea><button class="icon" onclick="ITH.sendPanelComment('${esc(id)}')">➤</button></div></div>`;$('memberMenu').classList.add('show');state.commentReply=null;state.commentPostId=id;state.commentChannel='comments:'+id;wsSubscribe(state.commentChannel);await loadPanelComments(id)}
async function loadPanelComments(id){const list=$('panelComments');if(!list)return;try{const r=await fetchJson(`/api/messages?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent('comments:'+id)}&since=0&limit=120`);const items=uniqueMessages(r.messages||[]);if($('panelCommentCount'))$('panelCommentCount').textContent=items.length+' comments';list.innerHTML=items.map((m,i)=>{const t=parseText(m.text);const body=t.body||m.text||'';return `<div class="commentBubble"><b>${i+1}. ${esc(m.nickname||'Member')}</b><div>${esc(body)}</div>${messageMediaHtml(t.media,false)}${translateControls('com_'+esc(m.message_id||i),body)}<button class="icon small" onclick="ITH.setCommentReply('${esc(id)}','${esc((body||'').slice(0,60))}')">↩</button></div>`}).join('')||`<div class="date">${uiText('No comments yet. Write the first one.')}</div>`;if(autoTranslateOn())items.forEach((m,i)=>{const t=parseText(m.text);maybeAutoTranslate('com_'+(m.message_id||i),t.body||m.text||'')})}catch(e){list.innerHTML=`<div class="date">${uiText('Comments are not loading.')}</div>`}}
function setCommentReply(id,txt){state.commentReply={id,txt};const b=$('commentReplyBox');if(b){b.style.display='block';b.innerHTML=`<div class="row" style="justify-content:space-between"><span>↩ Reply: ${esc(txt)}</span><button class="icon small" onclick="ITH.clearCommentReply()">×</button></div>`}const i=$('commentInput');if(i)i.focus()}
function clearCommentReply(){state.commentReply=null;const b=$('commentReplyBox');if(b){b.style.display='none';b.innerHTML=''}}
async function sendPanelComment(id){const input=$('commentInput');const txt=(input?.value||'').trim();if(!txt)return;const clean=maskBadWords(txt);if(clean.changed)toast('Civility filter: only the first and last letter were kept in inappropriate words.');const payload=state.commentReply?JSON.stringify({body:clean.text,reply_to:state.commentReply.txt||''}):clean.text;try{input.value='';clearCommentReply();await sendComment(id,payload);await loadPanelComments(id)}catch(e){toast('Comment not sent')}}
async function openInlineComments(id){return openPostCommentsPanel(id)}
function quickComment(id){return openPostCommentsPanel(id)}
function replyComment(id,txt){state.commentReply={id,txt};return openPostCommentsPanel(id)}
async function sendComment(id,txt){await fetchJson('/api/messages/send',{method:'POST',body:JSON.stringify({room_id:state.room,channel:'comments:'+id,sender_id:state.device,nickname:state.name,language:'en',text:txt})});const c=$('comment_count_'+id),ct=$('comment_count_text_'+id);if(c)c.textContent=String((+c.textContent||0)+1);if(ct)ct.textContent=String((+ct.textContent||0)+1)}
function savePost(id){let a=[];try{a=JSON.parse(localStorage.getItem('ith_saved_posts')||'[]')}catch{}if(!a.includes(id))a.push(id);localStorage.setItem('ith_saved_posts',JSON.stringify(a));toast(uiText('Saved'))}
function sharePost(id){let url=shareSiteBase();try{const u=new URL(url);u.searchParams.set('post',id);u.hash='post='+encodeURIComponent(id);url=u.toString()}catch{url=ITH_PUBLIC_SITE+'/?post='+encodeURIComponent(id)+'#post='+encodeURIComponent(id)}share(url,'OK ITHAKI post · '+uiText('If the app is not installed, this active link opens the OK ITHAKI site.'))}
async function deletePost(id){if(!confirm('Delete post?'))return;try{await fetchJson('/api/flow/delete',{method:'POST',body:JSON.stringify({room_id:state.room,post_id:id,device_id:state.device})});toast('Deleted');loadFeed()}catch(e){toast('Cannot delete')}}
function showMemberMenu(id){const p=state.people.get(id)||{id,nickname:'Member'};markPeerRead(id);$('memberMenu').innerHTML=`<div class="postHead"><button class="icon" type="button" onclick="ITH.closeMember()" aria-label="Πίσω">‹</button>${avatarHtml(p)}<div><b>${esc(p.nickname)}</b><div class="date">${p.online?uiText('Online'):uiText('Offline')}</div></div><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="grid"><button class="tile" onclick="ITH.startDM('${esc(id)}')"><b>💬</b>${uiText('Message')}</button><button class="tile" onclick="ITH.startDM('${esc(id)}').then(()=>ITH.startVideoCall())"><b>📹</b>${uiText('Βιντεοκλήση')}</button><button class="tile" onclick="ITH.startDM('${esc(id)}').then(()=>ITH.startVoiceCall())"><b>📞</b>${uiText('Τηλεφωνική κλήση')}</button><button class="tile" onclick="ITH.memberPosts('${esc(id)}')"><b>🎬</b>${uiText('Posts')}</button><button class="tile" onclick="ITH.inviteContact('${esc(id)}')"><b>🤝</b>${uiText('Contact invite')}</button><button class="tile" onclick="ITH.follow('${esc(id)}')"><b>➕</b>${uiText('Follow')}</button><button class="tile" onclick="ITH.block('${esc(id)}')"><b>🚫</b>${uiText('Block')}</button><button class="tile" onclick="ITH.report('${esc(id)}')"><b>🚩</b>${uiText('Report')}</button></div>`;$('memberMenu').classList.add('show');renderPeople();if(state.page==='home')renderHome()}
async function memberPosts(id){$('memberMenu').classList.remove('show');return openMemberPostPicker(id)}

function localFollowingListV249210(){try{return JSON.parse(localStorage.getItem('ith_following')||'[]').map(String)}catch{return[]}}
function memberProfileStatsV249210(id,posts,p){
  const mine=String(id)===String(state.device);
  const followingLocal=localFollowingListV249210();
  const likes=(posts||[]).reduce((a,x)=>a+(+(x.likes||x.like_count||0)||0),0);
  let followers=+(p?.followers||p?.follower_count||p?.followers_count||0)||0;
  let following=+(p?.following||p?.following_count||0)||0;
  if(mine)following=Math.max(following,followingLocal.length);
  if(!mine&&followingLocal.includes(String(id)))followers=Math.max(followers,1);
  return{followers,following,likes,posts:(posts||[]).length};
}
function memberProfileHeaderV249210(p,id,posts){
  p=p||{};const st=memberProfileStatsV249210(id,posts,p);const online=!!p.online;
  const stat=(num,label)=>`<div class="memberStatV249210"><b>${esc(num)}</b><span>${esc(label)}</span></div>`;
  return `<section class="memberProfileHeroV249210 card"><div class="memberHeroTopV249210"><div class="memberHeroAvatarV249210">${avatarHtml(p)}</div><div class="memberHeroNameV249210"><h2>${esc(p.nickname||'Μέλος')}</h2><span class="memberHeroOnlineV249210 ${online?'on':''}">${online?'● Online':'○ Offline'}</span></div></div><div class="memberStatsRowV249210">${stat(st.followers,'Ακόλουθοι')}${stat(st.following,'Ακολουθεί')}${stat(st.likes,'Likes')}</div></section>`;
}

function renderMemberThumb(p,id){
  const t=parseText(p.text);const m=t.media;const pid=esc(p.post_id||'');let media='<span class="memberThumbText">📝</span>';
  if(m){
    const url=m.url||m.file_url||m.media_url||'';
    const raw=externalUrl(url);
    const src=esc(raw);
    const kind=String(m.kind||m.mime_type||m.type||'').toLowerCase();
    if(kind==='poll'||m.poll_id||m.pollId||Array.isArray(m.options)){
      media='<span class="memberThumbText">📊</span>';
    }else if(kind.includes('video')){
      media=`<div class="thumbVideoBox stableVideoThumb"><video src="${src}" muted playsinline preload="metadata" onloadeddata="this.classList.add('ready');try{this.currentTime=.15}catch(e){}" onerror="this.parentElement.classList.add('videoError')"></video><i>▶</i><em>Βίντεο</em></div>`;
    }else if(kind.includes('photo')||kind.includes('image')){
      media=`<img src="${src}" loading="lazy" onerror="this.replaceWith(Object.assign(document.createElement('span'),{className:'memberThumbText',textContent:'🖼️'}))">`;
    }else media='<span class="memberThumbText">📎</span>';
  }
  const label=String((m&&(m.question||m.title))||t.body||'').trim()||(m&&String(m.kind||'').toLowerCase()==='poll'?'Ψηφοφορία':'Δημοσίευση με media');
  return `<button class="thumbCard professionalThumbCard" onclick="ITH.openMemberFeed('${esc(id)}','${pid}')">${media}<span>${esc(label.slice(0,96))}</span></button>`;
}
async function openMemberPostPicker(id){
  window.__ITHAKI_MEMBER_FEED_MODE_V249483__=true;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=true;
  showFeedOnly();const p=state.people.get(id)||{nickname:'Μέλος'};
  $('feedPage').innerHTML=`<button class="feedBackOnly" onclick="window.__ITHAKI_MEMBER_FEED_MODE_V249483__=false;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=false;ITH.loadFeed()" aria-label="Πίσω">‹</button><div class="card">Φόρτωση δημοσιεύσεων μέλους...</div>`;
  try{
    const all=await fetchJson(`/api/flow?room_id=${encodeURIComponent(state.room)}&visibility=public&limit=300&lite=1&viewer_id=${encodeURIComponent(state.device)}`);
    const posts=uniquePosts((all.posts||[]).filter(x=>String(x.sender_id)===String(id)));
    $('feedPage').innerHTML=`<button class="feedBackOnly" onclick="window.__ITHAKI_MEMBER_FEED_MODE_V249483__=false;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=false;ITH.loadFeed()" aria-label="Πίσω">‹</button><section class="memberPostPicker">${memberProfileHeaderV249210(p,id,posts)}<div class="memberThumbGrid">${posts.map(x=>renderMemberThumb(x,id)).join('')||`<div class="card">Δεν βρέθηκαν δημοσιεύσεις.</div>`}</div></section>`;
  }catch(e){
    $('feedPage').innerHTML=`<button class="feedBackOnly" onclick="window.__ITHAKI_MEMBER_FEED_MODE_V249483__=false;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=false;ITH.loadFeed()" aria-label="Πίσω">‹</button><div class="card">Οι δημοσιεύσεις μέλους δεν φορτώνουν: ${esc(e.message||e)}</div>`;
  }
}
let memberFeedReturnV249494=null;
function captureMemberFeedReturnV249494(){const fp=$('feedPage');if(!fp||window.__ITHAKI_MEMBER_FEED_MODE_V249483__===true)return;const list=fp.querySelector('.feedList');memberFeedReturnV249494={html:fp.innerHTML,scrollTop:list?list.scrollTop:fp.scrollTop||0,page:String(state.page||'feed')};}
async function closeMemberFeedV249494(){stopAllMedia();window.__ITHAKI_MEMBER_FEED_MODE_V249483__=false;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=false;document.body.classList.remove('memberFeedV249485','memberFeedTikTokV249494');const fp=$('feedPage');if(fp)delete fp.dataset.memberFeedV249483;showFeedOnly();const snap=memberFeedReturnV249494;memberFeedReturnV249494=null;if(snap&&fp&&snap.html){fp.innerHTML=snap.html;const list=fp.querySelector('.feedList');setTimeout(()=>{if(list)list.scrollTop=Number(snap.scrollTop||0);activateFeedVideos();try{setupFeedCycleV249217&&setupFeedCycleV249217({loop_feed_enabled:false})}catch(e){}},40);return false}try{return await loadFeed()}catch(e){return false}}
async function openMemberFeed(id,startPost=''){
  captureMemberFeedReturnV249494();window.__ITHAKI_MEMBER_FEED_MODE_V249483__=true;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=true;
  document.body.classList.add('memberFeedTikTokV249494');showFeedOnly();const p=state.people.get(id)||{nickname:String(id)===String(state.device)?(state.name||'Εσύ'):'Μέλος'};
  $('feedPage').innerHTML=`<button class="feedBackOnly" onclick="ITH.closeMemberFeedV249494()" aria-label="Πίσω στην προηγούμενη οθόνη">‹</button><div class="card">Φόρτωση δημοσιεύσεων μέλους...</div>`;
  try{
    const all=await fetchJson(`/api/flow?room_id=${encodeURIComponent(state.room)}&visibility=public&limit=300&lite=1&viewer_id=${encodeURIComponent(state.device)}`);
    let posts=uniquePosts((all.posts||[]).filter(x=>String(x.sender_id)===String(id)));
    if(startPost){const i=posts.findIndex(x=>String(x.post_id)===String(startPost));if(i>0)posts=[...posts.slice(i),...posts.slice(0,i)]}
    $('feedPage').innerHTML=`<button class="feedBackOnly" onclick="ITH.closeMemberFeedV249494()" aria-label="Πίσω στην προηγούμενη οθόνη">‹</button><div class="feedMemberLabel">${String(id)===String(state.device)?'Οι δημοσιεύσεις μου':'Δημοσιεύσεις: '+esc(p.nickname||'Μέλος')}</div><div class="feedList memberTikTokFeedV249494">${posts.map(renderPost).join('')||`<div class="card">Δεν βρέθηκαν δημοσιεύσεις.</div>`}</div>`;
    const list=$('feedPage').querySelector('.memberTikTokFeedV249494');if(list)list.scrollTop=0;setTimeout(()=>{activateFeedVideos();if(list)list.focus({preventScroll:true})},80);
  }catch(e){$('feedPage').innerHTML=`<button class="feedBackOnly" onclick="ITH.closeMemberFeedV249494()" aria-label="Πίσω">‹</button><div class="card">Η ροή του μέλους δεν φορτώνει: ${esc(e.message||e)}</div>`}
  return false;
}

function isIthakiOfficialPostV249194(p){
  try{
    const who=(String(p.nickname||'')+' '+String(p.sender_id||'')+' '+String(p.creator_id||'')+' '+String(p.name||'')).toLowerCase();
    return who.includes('ithaki')||who.includes('ok ithaki')||who.includes('ιθακη')||who.includes('ιθάκη')||who.includes('host')||who.includes('οικοδεσπότης');
  }catch{return false}
}
function renderIthakiThumbV249194(p){
  const t=parseText(p.text);const m=t.media;const pid=esc(p.post_id||'');let media='<span class="memberThumbText">📝</span>';
  if(m){
    const url=m.url||m.file_url||m.media_url||'';const raw=externalUrl(url);const src=esc(raw);const kind=String(m.kind||m.mime_type||m.type||'').toLowerCase();
    if(raw && kind.includes('video'))media=`<div class="thumbVideoBox stableVideoThumb"><video src="${src}" muted playsinline preload="metadata"></video><span class="thumbPlay">▶</span></div>`;
    else if(raw && (kind.includes('image')||kind.includes('photo')))media=`<img class="memberThumbImg" src="${src}" loading="lazy">`;
    else if(raw)media='<span class="memberThumbText">📎</span>';
  }
  const body=esc((t.body||p.text||'').slice(0,90));
  return `<button class="professionalThumbCard" onclick="ITH.openIthakiFeed('${escJs(pid)}')">${media}<b>ΙΘΑΚΗ</b><small>${body||'Δημοσίευση'}</small></button>`;
}
async function openIthakiPostsPreview(){
  showFeedOnly();
  const fp=$('feedPage');
  fp.innerHTML=`<button class="feedBackOnly" onclick="window.__ITHAKI_MEMBER_FEED_MODE_V249483__=false;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=false;ITH.loadFeed()" aria-label="Πίσω">‹</button><div class="card">Φόρτωση δημοσιεύσεων ΙΘΑΚΗΣ...</div>`;
  try{
    const all=await fetchJson(`/api/flow?room_id=${encodeURIComponent(state.room)}&visibility=public&limit=300&lite=1&viewer_id=${encodeURIComponent(state.device)}`);
    const posts=uniquePosts((all.posts||[]).filter(isIthakiOfficialPostV249194));
    fp.innerHTML=`<button class="feedBackOnly" onclick="window.__ITHAKI_MEMBER_FEED_MODE_V249483__=false;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=false;ITH.loadFeed()" aria-label="Πίσω">‹</button><section class="memberPostPicker"><div class="card pickerHead"><h2><img src="ok_ithaki_ship_logo.png" style="width:38px;height:38px;object-fit:contain;vertical-align:middle"> ΙΘΑΚΗ</h2><p>Κανονική προεπισκόπηση δημοσιεύσεων ΙΘΑΚΗΣ. Πάτησε μία κάρτα για να ανοίξει σαν ροή.</p></div><div class="memberThumbGrid">${posts.map(renderIthakiThumbV249194).join('')||`<div class="card">Δεν βρέθηκαν ακόμη δημοσιεύσεις ΙΘΑΚΗΣ στον server.</div>`}</div></section>`;
  }catch(e){
    fp.innerHTML=`<button class="feedBackOnly" onclick="window.__ITHAKI_MEMBER_FEED_MODE_V249483__=false;window.__ITHAKI_MEMBER_FEED_MODE_V249481__=false;ITH.loadFeed()" aria-label="Πίσω">‹</button><div class="card">Οι δημοσιεύσεις ΙΘΑΚΗΣ δεν φορτώνουν: ${esc(e.message||e)}</div>`;
  }
  return false;
}
async function openIthakiFeed(startPost=''){
  showFeedOnly();
  const fp=$('feedPage');
  fp.innerHTML=`<button class="feedBackOnly" onclick="ITH.openIthakiPostsPreview()" aria-label="Πίσω">‹</button><div class="card">Φόρτωση ροής ΙΘΑΚΗΣ...</div>`;
  try{
    const all=await fetchJson(`/api/flow?room_id=${encodeURIComponent(state.room)}&visibility=public&limit=300&lite=1&viewer_id=${encodeURIComponent(state.device)}`);
    let posts=uniquePosts((all.posts||[]).filter(isIthakiOfficialPostV249194));
    if(startPost){const i=posts.findIndex(x=>String(x.post_id)===String(startPost));if(i>0)posts=[...posts.slice(i),...posts.slice(0,i)]}
    fp.innerHTML=`<button class="feedBackOnly" onclick="ITH.openIthakiPostsPreview()" aria-label="Πίσω">‹</button><div class="feedMemberLabel">Μόνο ΙΘΑΚΗ · προεπισκόπηση δημοσιεύσεων</div><div class="feedList">${posts.map(renderPost).join('')||`<div class="card">Δεν βρέθηκαν δημοσιεύσεις.</div>`}</div>`;
    setTimeout(activateFeedVideos,80);
  }catch(e){
    fp.innerHTML=`<button class="feedBackOnly" onclick="ITH.openIthakiPostsPreview()" aria-label="Πίσω">‹</button><div class="card">Η ροή ΙΘΑΚΗΣ δεν φορτώνει.</div>`;
  }
  return false;
}

function homeWisdomPanel(){
  return `<section class="card homeProPanel hourlyWisdomCard greekWisdomCard"><div class="proPanelIcon">🕯️</div><div class="proPanelText"><b>Σοφός λόγος</b><p>${esc(ithakiWisdomText())}</p></div></section>`
}
function homeProtectionPanel(){
  const open=localStorage.getItem('ith_home_protection_open_v249166')==='1';
  return `<section class="card homeProPanel homeProtectionPro bottomProtection ${open?'open':'closed'}"><button class="homeProtectionToggle" onclick="ITH.toggleHomeProtection()" type="button"><span>🛡️ Προστασία</span><b>${open?'▲':'▼'}</b></button><div class="protectList" style="display:${open?'grid':'none'}"><div>Η ΙΘΑΚΗ κρατά την επικοινωνία καθαρή, ανθρώπινη και αξιοπρεπή.</div><div>Υπάρχουν όρια κατά spam, bots και κακόβουλης μαζικής συμπεριφοράς.</div><div>Δεν ζητάμε υποχρεωτικά τηλέφωνο, email ή ιδιωτική λίστα επαφών.</div><div>Οι ειδοποιήσεις FCM είναι προαιρετικές και ενεργοποιούνται μόνο αν το επιλέξεις.</div><div>Το προφίλ αποθηκεύεται πρώτα στη συσκευή και μετά συγχρονίζεται με τον server.</div></div></section>`
}
function toggleHomeProtection(){
  const key='ith_home_protection_open_v249166';
  const next=localStorage.getItem(key)!=='1';
  localStorage.setItem(key,next?'1':'0');
  renderHome();
  return false;
}
function isFeedVideoPost(p){try{const t=parseText(p.text);const m=t.media||{};const k=String(m.kind||'').toLowerCase();const mt=String(m.mime_type||m.type||'').toLowerCase();return k==='video'||mt.startsWith('video/')}catch{return false}}
function feedPanelSeen(key){try{return localStorage.getItem('ith_feed_panel_seen_'+key)===todayKey()}catch{return false}}
function markFeedPanelSeen(key){try{localStorage.setItem('ith_feed_panel_seen_'+key,todayKey())}catch{}}
function hideFeedPanel(key){markFeedPanelSeen(key);const el=document.querySelector('[data-feed-panel="'+key+'"]');if(el)el.remove();return false}
function feedProPanel(kind,index=0){
  if(kind==='wisdom')index=(Math.floor(Math.abs(index))*2);
  const wisdoms=[
    'Η καθαρή κουβέντα ανοίγει δρόμο εκεί που ο θόρυβος έκλεισε την πόρτα.',
    'Ο σεβασμός δεν μικραίνει την ελευθερία· της δίνει χώρο να σταθεί.',
    'Η σοφία αρχίζει όταν ακούμε λίγο περισσότερο πριν απαντήσουμε.',
    'Μια καλή κοινότητα φαίνεται από τον τρόπο που προστατεύει τη συζήτηση.'
  ];
  const polls=[
    {q:'Πώς κρατάμε τη Ροή πιο καθαρή και ανθρώπινη;',opts:['Με σεβασμό','Με λιγότερο θόρυβο','Με ανωνυμία','Με καλύτερη προστασία'],bars:[64,48,36,72]},
    {q:'Τι βοηθά περισσότερο μια δημόσια συζήτηση;',opts:['Καθαρό θέμα','Ήρεμες απαντήσεις','Επιλογή ανωνυμίας','Καλύτερα εργαλεία'],bars:[58,70,44,52]},
    {q:'Εσύ τι θα ήθελες να δυναμώσει στην ΙΘΑΚΗ;',opts:['Βίντεο','Συζητήσεις','Ψηφοφορίες','Κοινότητες'],bars:[46,62,38,56]}
  ];
  const logo='<div class="feedGoldLogo"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display=\'none\'"></div><div class="feedGoldBrandText"><span class="okRainbow">OK</span> <small>ithaki</small></div>';
  if((index%2)===0){
    const q=wisdoms[index%wisdoms.length];
    return `<article class="card feedGoldWisdomCard" data-feed-panel="gold_wisdom_${index}"><div class="feedGoldCardInner">${logo}<h3 class="feedGoldQuote">${esc(q)}</h3><div class="row feedGoldCardActions"><button class="btn green" onclick="ITH.openPostCommentsPanel('${escJs('gold_wisdom_'+index)}')"><span>💬</span></button><button class="btn" onclick="ITH.like('${escJs('gold_wisdom_'+index)}')"><span>❤️</span></button></div></div></article>`;
  }
  const p=polls[index%polls.length];
  const key=`gold_poll_${index}`;
  const local=cardLocalStats(key,p.opts,p.opts.map((o,i)=>({index:i,text:o,count:Math.max(1,Math.round(p.bars[i]/12)),percent:p.bars[i]})));
  const opts=p.opts.map((o,i)=>{const row=(local.options||[]).find(x=>+x.index===i)||{count:0,percent:p.bars[i]||0};return `<button class="feedGoldPollChoice" onclick="ITH.voteCardChoice(this,'${escJs(key)}',${i})"><em style="width:${+row.percent||0}%"></em><span>${esc(o)}</span><b>${+row.count||0} · ${+row.percent||0}%</b></button>`}).join('');
  const bars=(local.options||[]).map(x=>`<i style="height:${Math.max(22,+x.percent||0)}px"></i>`).join('');
  return `<article class="card feedGoldPollCard" data-feed-panel="gold_poll_${index}"><div class="feedGoldCardInner">${logo}<h3 class="feedGoldQuote">${esc(p.q)}</h3><div class="feedGoldPollOptions">${opts}</div><div class="feedGoldResults">${bars}</div><div class="row feedGoldCardActions"><button class="btn green" onclick="ITH.openPostCommentsPanel('${escJs('gold_poll_'+index)}')"><span>💬</span></button><button class="btn" onclick="ITH.like('${escJs('gold_poll_'+index)}')"><span>❤️</span></button></div></div></article>`;
}
function renderFeedWithPanels(posts,cfg){
  cfg=cfg||{};
  const minVideos=+(cfg.min_videos_before_cards??5)||5;
  const everyVideos=Math.max(1,+(cfg.card_every_videos??5)||5);
  const minutes=Math.max(1,+(cfg.card_interval_minutes??10)||10);
  const maxCards=Math.max(0,Math.min(10,+(cfg.card_max_per_load??1)||1));
  const publishedVideos=+(cfg.published_video_count??0)||0;
  const totalVideoPosts=(posts||[]).filter(isFeedVideoPost).length;
  const enoughVideos=Math.max(publishedVideos,totalVideoPosts)>=minVideos;
  let html='',videoCount=0,inserted=0;
  const due=(()=>{try{return Date.now()-(+(localStorage.getItem('ith_last_feed_gold_panel_v249217')||0))>=minutes*60000}catch{return true}})();
  for(const p of posts){
    html+=renderPost(p);
    if(isFeedVideoPost(p)){
      videoCount++;
      if(enoughVideos&&due&&inserted<maxCards&&videoCount>=minVideos&&((videoCount-minVideos)%everyVideos===0)){
        html+=feedProPanel('wisdom',(Math.floor(Date.now()/(minutes*60000))%6)*2+inserted);
        inserted++;
      }
    }
  }
  if(inserted>0){try{localStorage.setItem('ith_last_feed_gold_panel_v249217',String(Date.now()))}catch{}}
  return html;
}

function setupFeedCycleV249217(cfg){
  try{
    const list=document.querySelector('#feedPage .feedList');
    if(!list)return;
    cfg=cfg||{};
    list.dataset.loopFeedV249217=String(cfg.loop_feed_enabled!==false);
    if(list.dataset.boundLoopV249217==='1')return;
    list.dataset.boundLoopV249217='1';
    let lock=false;
    list.addEventListener('scroll',()=>{
      if(lock||list.dataset.loopFeedV249217==='false')return;
      const nearEnd=list.scrollTop+list.clientHeight>=list.scrollHeight-18;
      if(nearEnd&&list.scrollHeight>list.clientHeight*1.5){
        lock=true;
        setTimeout(()=>{try{list.scrollTo({top:0,behavior:'smooth'})}catch{list.scrollTop=0}setTimeout(()=>lock=false,800)},180);
      }
    },{passive:true});
  }catch(e){console.warn('feed loop v249217',e)}
}
async function serverFiveMinuteTest(){
  try{
    const r=await fetchJson('/health');
    localStorage.setItem('ith_last_server_test',String(Date.now()));
    if(r&&r.ok){setConnectionGreen('Σύνδεση server ενεργή · '+connectionLabel());return true}
    if($('subStatus'))$('subStatus').textContent='Έλεγχος server σε αναμονή · '+connectionLabel();
    return false;
  }catch(e){
    if(state.wsReady){setConnectionGreen('Realtime WebSocket ενεργό · '+connectionLabel());return true}
    if($('subStatus'))$('subStatus').textContent='Ο server δεν απάντησε: '+(e.message||e);
    return false;
  }
}

function callSessionKey(s){return String((s&&s.session_id)||'')}
function callClosedSet(){try{return new Set(JSON.parse(localStorage.getItem('ith_closed_call_sessions_v249212')||'[]'))}catch{return new Set()}}
function rememberClosedCallSession(session){try{const id=callSessionKey(session);if(!id)return;const a=[...callClosedSet()].filter(Boolean).slice(-40);if(!a.includes(id))a.push(id);localStorage.setItem('ith_closed_call_sessions_v249212',JSON.stringify(a.slice(-60)))}catch{}}
function isClosedCallSession(session){const id=callSessionKey(session);return !!id&&callClosedSet().has(id)}
async function timeoutIncomingCall(){
  const c=state.call;if(!c||!c.incoming||!c.session)return false;try{bridgeCall('cancelCallNotification',String(c.session.session_id||''))}catch{}
  try{rememberClosedCallSession(c.session);stopCallAlert();callStatusText('Δεν απαντήθηκε σε 1 λεπτό');sendCallTimeline('missed',c.kind,c.peerId?channelFor(state.device,c.peerId):state.activeChannel);await fetchJson('/api/video/session/end',{method:'POST',body:JSON.stringify({room_id:state.room,session_id:c.session.session_id,device_id:state.device,reason:'timeout_missed'})})}catch(e){}
  setTimeout(()=>clearCallState(),700);return false
}

function stopCallAlert(){try{bridgeCall('stopCallAlert')}catch{}try{navigator.vibrate&&navigator.vibrate(0)}catch{}try{if(ALERT_AUDIO_CTX&&ALERT_AUDIO_CTX.state==='running'){} }catch{}}
function callStatusText(text){const el=$('callStatus');if(el)el.textContent=text||''}
function callControlsHtmlLegacyV249218(video,incoming){if(incoming)return `<button class="btn green" onclick="ITH.answerIncomingCall(true)">${uiText('Απάντηση')}</button><button class="btn danger" onclick="ITH.answerIncomingCall(false)">${uiText('Απόρριψη')}</button>`;return `${video?`<button id="callCameraBtn" class="btn callControlBtn" onclick="ITH.toggleCallCamera()" title="Camera on/off">📷</button><button class="btn callControlBtn" onclick="ITH.switchCallCamera()" title="Front/back camera">🔄</button>`:''}<button id="callMicBtn" class="btn callControlBtn" onclick="ITH.toggleCallMic()" title="Microphone on/off">🎙️</button><button id="callSpeakerBtn" class="btn callControlBtn" onclick="ITH.toggleCallSpeaker()" title="Speaker/external audio">🔊</button><button class="btn danger" onclick="ITH.endActiveCall()">${uiText('Τερματισμός κλήσης')}</button>`}
function showCallModalLegacyV249218(kind,title,status,incoming=false){const video=kind==='video';const pm=$('previewModal');pm.classList.remove('fullscreen');pm.classList.add('callCompactV249218',video?'videoCallV249218':'voiceCallV249218');pm.innerHTML=`<div class="callBox ${video?'videoCallBox':'voiceCallBox'} ${incoming?'incomingCallBox':''}"><div class="row"><b>${video?'📹':'📞'} ${esc(title||uiText(video?'Βιντεοκλήση':'Κλήση φωνής'))}</b></div><div class="callStage">${video?'<video id="callRemote" autoplay playsinline controls></video><video id="callLocal" class="callLocal" autoplay muted playsinline></video>':'<audio id="callRemote" autoplay controls></audio><div style="font-size:72px">📞</div>'}</div><div id="callStatus" class="callStatus">${esc(status||'')}</div><div class="callActions">${callControlsHtml(video,incoming)}</div></div>`;pm.classList.add('show')}
function stopCallMedia(){const c=state.call;if(!c)return;clearInterval(c.signalTimer);clearInterval(c.statusTimer);clearTimeout(c.ringTimer);clearTimeout(c.incomingTimer);try{if(c.pc){c.pc.getSenders&&c.pc.getSenders().forEach(s=>{try{s.replaceTrack&&s.replaceTrack(null)}catch{}});c.pc.close&&c.pc.close()}}catch{}try{c.localStream&&c.localStream.getTracks().forEach(t=>{try{t.enabled=false}catch{};try{t.stop()}catch{}})}catch{}try{const l=$('callLocal'),r=$('callRemote');if(l)l.srcObject=null;if(r)r.srcObject=null}catch{}try{bridgeCall('setCallAudioMode',false)}catch{}try{bridgeCall('stopCallMedia')}catch{}try{bridgeCall('releaseCameraAndMicrophone')}catch{}stopCallAlert()}
function clearCallState(closeModal=true){try{if(state.call&&state.call.session){if(state.call.ended||state.call.missedLogged)rememberClosedCallSession(state.call.session);bridgeCall('cancelCallNotification',String(state.call.session.session_id||''))}}catch{}stopCallMedia();state.call=null;if(closeModal){const pm=$('previewModal');pm.classList.remove('show','callCompactV249218','voiceCallV249218','videoCallV249218');pm.innerHTML=''}}
async function callSignal(type,payload={}){const c=state.call;if(!c)return;await fetchJson('/api/video/signal/send',{method:'POST',body:JSON.stringify({room_id:state.room,session_id:c.session.session_id,sender_id:state.device,target_id:c.peerId,signal_type:type,payload})})}
async function pollCallSignals(){const c=state.call;if(!c||!c.pc)return;try{const r=await fetchJson(`/api/video/signal/poll?room_id=${encodeURIComponent(state.room)}&session_id=${encodeURIComponent(c.session.session_id)}&device_id=${encodeURIComponent(state.device)}&after=${encodeURIComponent(c.signalAfter||0)}`);for(const s of (r.signals||[])){c.signalAfter=Math.max(c.signalAfter||0,+s.created_at||0);if(s.signal_type==='offer'){await c.pc.setRemoteDescription(new RTCSessionDescription(s.payload));const ans=await c.pc.createAnswer();await c.pc.setLocalDescription(ans);await callSignal('answer',c.pc.localDescription)}else if(s.signal_type==='answer'){await c.pc.setRemoteDescription(new RTCSessionDescription(s.payload))}else if(s.signal_type==='ice'){if(c.pc.remoteDescription)await c.pc.addIceCandidate(new RTCIceCandidate(s.payload));else c.pendingIce.push(s.payload)}else if(s.signal_type==='bye'){if(state.call){state.call.ended=true;rememberClosedCallSession(state.call.session)}stopCallAlert();callStatusText(uiText('Η κλήση τερματίστηκε'));setTimeout(()=>clearCallState(),700)}}if(c.pc.remoteDescription&&c.pendingIce.length){for(const ice of c.pendingIce.splice(0)){try{await c.pc.addIceCandidate(new RTCIceCandidate(ice))}catch{}}}}catch(e){console.warn('call signal poll',e)}}
async function beginWebRtcCall(session,kind,initiator){const c=state.call;if(!c)return;stopCallAlert();try{bridgeCall('setCallAudioMode',true)}catch{}c.speakerOn=true;c.micOn=true;c.cameraOn=(kind==='video');c.videoFacing=c.videoFacing||'user';updateCallControlButtons();const settings=await fetchJson(`/api/video/settings?room_id=${encodeURIComponent(state.room)}`);if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)throw new Error('Η κάμερα/το μικρόφωνο χρειάζονται HTTPS ή την Android εφαρμογή.');const profile=(settings.quality_profiles||{})[session.quality||settings.default_quality||'low']||{};const constraints={audio:{echoCancellation:true,noiseSuppression:true,autoGainControl:true},video:kind==='video'?{width:{ideal:+profile.width||320},height:{ideal:+profile.height||240},frameRate:{ideal:+profile.fps||12},facingMode:{ideal:c.videoFacing||'user'}}:false};try{c.localStream=await navigator.mediaDevices.getUserMedia(constraints)}catch(e){try{bridgeCall('requestMediaPermissions',kind==='video')}catch{}throw new Error((kind==='video'?uiText('Επιτρέψτε κάμερα και μικρόφωνο στις ρυθμίσεις Android.'):uiText('Επιτρέψτε μικρόφωνο στις ρυθμίσεις Android.'))+' '+(e.message||''))}c.pc=new RTCPeerConnection({iceServers:settings.ice_servers||[]});c.pendingIce=[];c.pc.onicecandidate=e=>{if(e.candidate)callSignal('ice',e.candidate.toJSON()).catch(()=>{})};c.pc.ontrack=e=>{const remote=$('callRemote');if(remote){remote.srcObject=e.streams[0];remote.muted=false;remote.autoplay=true;remote.playsInline=true;remote.volume=1;try{callStatusText('Λήψη φωνής/εικόνας...')}catch{};try{const pr=remote.play&&remote.play();if(pr&&pr.catch)pr.catch(()=>{try{const u=$('callAudioUnlock');if(u)u.style.display='inline-flex'}catch{}})}catch{}}};c.pc.onconnectionstatechange=()=>{if(!state.call)return;const s=c.pc.connectionState;callStatusText(s==='connected'?uiText('Συνδέθηκε'):s==='failed'?uiText('Η σύνδεση κλήσης απέτυχε'):s==='disconnected'?uiText('Η κλήση αποσυνδέθηκε'):s)};if(kind==='video'){try{const vt=c.localStream.getVideoTracks()[0];const vs=vt&&vt.getSettings?vt.getSettings():{};c.videoDeviceId=vs.deviceId||c.videoDeviceId||'';c.videoFacing=vs.facingMode||c.videoFacing||'user';navigator.mediaDevices.enumerateDevices().then(ds=>{const ids=(ds||[]).filter(d=>d.kind==='videoinput').map(d=>d.deviceId).filter(Boolean);if(ids.length){c.videoDeviceIds=ids;c.videoDeviceIndex=ids.indexOf(c.videoDeviceId)}}).catch(()=>{})}catch{}}c.localStream.getTracks().forEach(t=>c.pc.addTrack(t,c.localStream));const local=$('callLocal');if(local)local.srcObject=c.localStream;updateCallControlButtons();c.signalTimer=setInterval(pollCallSignals,900);await pollCallSignals();if(initiator){const offer=await c.pc.createOffer();await c.pc.setLocalDescription(offer);await callSignal('offer',c.pc.localDescription)}await fetchJson('/api/video/session/ping',{method:'POST',body:JSON.stringify({room_id:state.room,session_id:session.session_id,device_id:state.device})})}
function updateCallControlButtons(){const c=state.call||{};const mic=$('callMicBtn'),cam=$('callCameraBtn'),sp=$('callSpeakerBtn');if(mic){mic.classList.toggle('off',c.micOn===false);mic.textContent=c.micOn===false?'🎙️✕':'🎙️'}if(cam){cam.classList.toggle('off',c.cameraOn===false);cam.textContent=c.cameraOn===false?'📷✕':'📷'}if(sp){sp.classList.toggle('off',c.speakerOn===false);sp.textContent=c.speakerOn===false?'🔈':'🔊'}}
function toggleCallMic(){const c=state.call;if(!c||!c.localStream)return toast('Η κλήση δεν έχει συνδεθεί ακόμη.');const tracks=c.localStream.getAudioTracks();if(!tracks.length)return toast('Δεν βρέθηκε μικρόφωνο.');const next=!(tracks[0].enabled);tracks.forEach(t=>t.enabled=next);c.micOn=next;updateCallControlButtons();toast(next?'Μικρόφωνο ανοιχτό':'Μικρόφωνο κλειστό');return false}
function toggleCallCamera(){const c=state.call;if(!c||!c.localStream)return toast('Η βιντεοκλήση δεν έχει συνδεθεί ακόμη.');const tracks=c.localStream.getVideoTracks();if(!tracks.length)return toast('Δεν βρέθηκε κάμερα.');const next=!(tracks[0].enabled);tracks.forEach(t=>t.enabled=next);c.cameraOn=next;updateCallControlButtons();toast(next?'Κάμερα ανοιχτή':'Κάμερα κλειστή');return false}
async function switchCallCamera(){
  const c=state.call;
  if(!c||c.kind!=='video'||!c.pc)return toast('Η αλλαγή κάμερας θέλει ενεργή βιντεοκλήση.');
  if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)return toast('Δεν υπάρχει πρόσβαση κάμερας.');
  if(c.switchingCamera)return false;
  c.switchingCamera=true;
  try{bridgeCall('requestVideoCallPermissions')}catch{}
  try{
    const old=(c.localStream&&c.localStream.getVideoTracks()[0])||null;
    const oldSettings=old&&old.getSettings?old.getSettings():{};
    const oldFacing=String(c.videoFacing||oldSettings.facingMode||'user');
    const nextFacing=(oldFacing==='environment'||oldFacing==='back'||oldFacing==='rear')?'user':'environment';
    const oldW=+oldSettings.width||360, oldH=+oldSettings.height||240, oldFps=+oldSettings.frameRate||12;
    let devices=[];
    try{devices=(await navigator.mediaDevices.enumerateDevices()).filter(d=>d.kind==='videoinput')}catch{}
    const currentId=oldSettings.deviceId||c.videoDeviceId||'';
    let nextDevice=null;
    if(devices.length>1){
      const ids=devices.map(d=>d.deviceId).filter(Boolean);
      c.videoDeviceIds=ids;
      const labelMatch=d=>{const l=String(d.label||'').toLowerCase();return nextFacing==='environment'?(/back|rear|environment|πίσω/.test(l)):(/front|user|selfie|μπροστ/.test(l))};
      nextDevice=devices.find(d=>d.deviceId&&d.deviceId!==currentId&&labelMatch(d));
      if(!nextDevice){
        let idx=ids.indexOf(currentId);
        if(idx<0)idx=Number.isFinite(+c.videoDeviceIndex)?(+c.videoDeviceIndex):-1;
        const nextId=ids[(idx+1+ids.length)%ids.length];
        nextDevice=devices.find(d=>d.deviceId===nextId)||devices.find(d=>d.deviceId&&d.deviceId!==currentId)||devices[0];
      }
    }
    const sender=c.pc.getSenders().find(x=>x.track&&x.track.kind==='video')||c.pc.getSenders().find(x=>x.track===old);
    if(old){
      try{if(sender&&sender.replaceTrack)await sender.replaceTrack(null)}catch{}
      try{c.localStream&&c.localStream.removeTrack(old)}catch{}
      try{old.stop()}catch{}
    }
    const tries=[];
    if(nextDevice&&nextDevice.deviceId)tries.push({deviceId:{exact:nextDevice.deviceId},width:{ideal:oldW},height:{ideal:oldH},frameRate:{ideal:oldFps}});
    tries.push({facingMode:{exact:nextFacing},width:{ideal:oldW},height:{ideal:oldH},frameRate:{ideal:oldFps}});
    tries.push({facingMode:{ideal:nextFacing},width:{ideal:oldW},height:{ideal:oldH},frameRate:{ideal:oldFps}});
    tries.push({width:{ideal:oldW},height:{ideal:oldH},frameRate:{ideal:oldFps}});
    let stream=null,err=null;
    for(const video of tries){try{stream=await navigator.mediaDevices.getUserMedia({video,audio:false});break}catch(e){err=e}}
    if(!stream)throw err||new Error('camera not found');
    const nt=stream.getVideoTracks()[0];if(!nt)throw new Error('camera track not found');
    if(sender&&sender.replaceTrack)await sender.replaceTrack(nt);
    else try{c.pc.addTrack(nt,c.localStream||stream)}catch{}
    if(!c.localStream)c.localStream=new MediaStream();
    try{c.localStream.addTrack(nt)}catch{}
    const local=$('callLocal');if(local){local.srcObject=null;local.srcObject=c.localStream;try{local.play&&local.play().catch(()=>{})}catch{}}
    const ns=nt.getSettings?nt.getSettings():{};
    c.videoDeviceId=ns.deviceId||(nextDevice&&nextDevice.deviceId)||'';
    c.videoDeviceIndex=(c.videoDeviceIds||[]).indexOf(c.videoDeviceId);
    if(c.videoDeviceIndex<0)c.videoDeviceIndex=Number.isFinite(+c.videoDeviceIndex)?+c.videoDeviceIndex:0;
    c.videoFacing=ns.facingMode||nextFacing;
    c.cameraOn=true;updateCallControlButtons();
    const realChanged=!currentId||!c.videoDeviceId||String(currentId)!==String(c.videoDeviceId)||String(c.videoFacing).includes(nextFacing);
    toast((c.videoFacing==='environment'||nextFacing==='environment')?'Πίσω κάμερα':'Μπροστινή κάμερα');
    if(!realChanged&&devices.length>1)setTimeout(()=>toast('Αν το κινητό ξαναγυρίζει μπροστά, η WebView κρατάει την ίδια κάμερα. Ξαναπάτα 🔄 μία φορά.',5000),600);
  }catch(e){toast('Δεν άλλαξε κάμερα: '+(e.message||e),6500)}
  finally{if(state.call)state.call.switchingCamera=false}
  return false
}

function toggleCallSpeaker(){const c=state.call;if(!c)return false;c.speakerOn=!(c.speakerOn!==false);try{bridgeCall('setCallAudioMode',!!c.speakerOn)}catch{}const r=$('callRemote');try{if(r){r.muted=false;r.volume=c.speakerOn?1:.72;r.play&&r.play().catch(()=>{})}}catch{}updateCallControlButtons();toast(c.speakerOn?'Εξωτερική ακρόαση / ηχείο ανοιχτό':'Εξωτερική ακρόαση / ηχείο κλειστό');return false}
async function waitOutgoingAccepted(){
  const c=state.call;if(!c)return;
  try{
    const r=await fetchJson(`/api/video/session/status?room_id=${encodeURIComponent(state.room)}&session_id=${encodeURIComponent(c.session.session_id)}&device_id=${encodeURIComponent(state.device)}`);
    const s=r.session||{};
    if(s.status==='accepted'||s.status==='active'){clearTimeout(c.ringTimer);clearInterval(c.statusTimer);callStatusText(uiText('Σύνδεση κλήσης...'));await beginWebRtcCall(s,c.kind,true)}
    else if(['rejected','ended','expired'].includes(s.status)){stopCallAlert();callStatusText(uiText('Η κλήση δεν απαντήθηκε'));c.missedLogged=true;rememberClosedCallSession(c.session);if(!c.callEndLogged){c.callEndLogged=true;sendCallTimeline(s.status==='rejected'?'rejected':'missed',c.kind,state.activeChannel)}setTimeout(()=>clearCallState(),900)}
    else if((Date.now()-(c.ringStartedAt||Date.now()))>60000){
      callStatusText('Δεν απάντησε σε 1 λεπτό');
      if(!c.missedLogged){c.missedLogged=true;rememberClosedCallSession(c.session);sendCallTimeline('missed',c.kind,state.activeChannel)}
      try{await fetchJson('/api/video/session/end',{method:'POST',body:JSON.stringify({room_id:state.room,session_id:c.session.session_id,device_id:state.device,reason:'timeout_missed'})})}catch{}
      setTimeout(()=>clearCallState(),700);
    }
  }catch(e){console.warn('call status',e)}
}
async function sendCallRequest(kind){
  if(state.call)return toast(uiText('Υπάρχει ήδη ενεργή κλήση.'));
  if(!state.activePeer||!state.activeChannel){toast(uiText('Διαλέξτε πρώτα επαφή.'));return false}
  const p=state.people.get(state.activePeer)||{nickname:'Μέλος'};
  try{
    const r=await fetchJson('/api/video/session/create',{method:'POST',body:JSON.stringify({room_id:state.room,caller_id:state.device,caller_name:state.name,callee_id:state.activePeer,callee_name:p.nickname||'Μέλος',quality:'low',call_type:kind,ring_timeout_seconds:60})});
    state.call={session:r.session,kind,peerId:state.activePeer,signalAfter:0,callLogged:false,ringStartedAt:Date.now()};
    showCallModal(kind,p.nickname||'Μέλος',uiText('Κλήση σε εξέλιξη...'));
    sendCallTimeline('outgoing',kind,state.activeChannel);
    state.call.ringTimer=setTimeout(async()=>{
      try{
        if(state.call&&state.call.session&&state.call.session.session_id===r.session.session_id&&!state.call.pc){
          callStatusText('Δεν απάντησε σε 1 λεπτό');
          if(state.call){state.call.missedLogged=true;rememberClosedCallSession(state.call.session)}
          sendCallTimeline('missed',kind,state.activeChannel);
          await fetchJson('/api/video/session/end',{method:'POST',body:JSON.stringify({room_id:state.room,session_id:r.session.session_id,device_id:state.device,reason:'timeout_missed'})});
          setTimeout(()=>clearCallState(),700);
        }
      }catch(e){clearCallState()}
    },60000);
    state.call.statusTimer=setInterval(waitOutgoingAccepted,1200);
    await waitOutgoingAccepted();
    return false
  }catch(e){clearCallState();toast(uiText('Δεν στάλθηκε')+': '+(e.message||e));return false}
}
function startVoiceCall(){try{bridgeCall('requestMediaPermissions',false)}catch{}return sendCallRequest('voice')}
function startVideoCall(){try{bridgeCall('requestMediaPermissions',true)}catch{}return sendCallRequest('video')}
async function checkIncomingCalls(){
  if(state.call)return;
  try{
    const r=await fetchJson(`/api/video/session/incoming?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);
    const nowMs=Date.now();
    const s=(r.sessions||[]).find(x=>x.status==='ringing'&&!isClosedCallSession(x)&&(+x.time_left_seconds||60)>0);
    if(!s)return;
    const kind=s.call_type==='voice'?'voice':'video';
    const ttl=Math.max(5,Math.min(60,+s.time_left_seconds||60));
    state.call={session:s,kind,peerId:s.caller_id,signalAfter:0,incoming:true,ringStartedAt:nowMs};
    try{if(bridgeHas('notifyIncomingCallV249531'))bridgeCall('notifyIncomingCallV249531','OK ITHAKI',uiText('Εισερχόμενη κλήση')+' '+(s.caller_name||'Μέλος'),String(s.session_id||''),kind);else notifyAppEvent('OK ITHAKI',uiText('Εισερχόμενη κλήση')+' '+(s.caller_name||'Μέλος'),'call')}catch(e){notifyAppEvent('OK ITHAKI',uiText('Εισερχόμενη κλήση')+' '+(s.caller_name||'Μέλος'),'call')};
    showCallModal(kind,s.caller_name||'Μέλος',uiText('Εισερχόμενη κλήση')+' · '+ttl+'s',true);
    state.call.incomingTimer=setTimeout(timeoutIncomingCall,ttl*1000);
  }catch(e){}
}
async function answerIncomingCall(accepted){const c=state.call;if(!c)return false;stopCallAlert();try{bridgeCall('cancelCallNotification',String(c.session?.session_id||''))}catch{}clearTimeout(c.incomingTimer);const ch=c.peerId?channelFor(state.device,c.peerId):state.activeChannel;try{await fetchJson('/api/video/session/respond',{method:'POST',body:JSON.stringify({room_id:state.room,session_id:c.session.session_id,device_id:state.device,accepted:!!accepted})});if(!accepted){c.ended=true;rememberClosedCallSession(c.session);sendCallTimeline('rejected',c.kind,ch);clearCallState();return false}try{bridgeCall(c.kind==='video'?'requestVideoCallPermissions':'requestVoiceCallPermissions')}catch{}showCallModal(c.kind,c.session.caller_name||'Μέλος',uiText('Σύνδεση κλήσης...'));sendCallTimeline('answered',c.kind,ch);await beginWebRtcCall(c.session,c.kind,false)}catch(e){toast(uiText('Η σύνδεση κλήσης απέτυχε')+': '+(e.message||e));await endActiveCall()}return false}
async function endActiveCall(){const c=state.call;if(!c){stopCallAlert();clearCallState();return false}try{bridgeCall('cancelCallNotification',String(c.session?.session_id||''))}catch{}try{if(c.pc)await callSignal('bye',{});await fetchJson('/api/video/session/end',{method:'POST',body:JSON.stringify({room_id:state.room,session_id:c.session.session_id,device_id:c.device_id||state.device,reason:'user_end'})});c.ended=true;rememberClosedCallSession(c.session);sendCallTimeline('ended',c.kind,c.peerId?channelFor(state.device,c.peerId):state.activeChannel)}catch{}clearCallState();return false}
function openMessageCamera(kind='photo'){if(!state.activeChannel){toast(uiText('Choose a contact first.'));return false}return captureMedia('dm',kind==='video'?'video':'photo',state.activeChannel)}


/* V249235 MESSAGES CONTACT-FIRST PATCH
   Μηνύματα: πρώτα μία καθαρή λίστα φίλων ενεργών/ανενεργών. Πάτημα στο όνομα ανοίγει απευθείας τη συνομιλία. */
function injectV249235MessageFirstCss(){try{if(document.getElementById('ithV249235MessageFirstCss'))return;const st=document.createElement('style');st.id='ithV249235MessageFirstCss';st.textContent=`
  body[data-page="dm"] #dmPage{height:calc(100dvh - var(--top) - var(--bar));min-height:0;overflow:hidden!important;padding:0!important}
  .dmContactFirstShellV249235{height:100%;min-height:0;display:block;overflow:hidden;padding:8px;box-sizing:border-box}
  .dmFriendScreenV249235{height:100%;min-height:0;display:flex;flex-direction:column;gap:8px;overflow:hidden}
  .dmFriendHeroV249235{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:20px;background:linear-gradient(135deg,rgba(255,217,110,.13),rgba(54,240,160,.08));border:1px solid rgba(255,217,110,.22);box-shadow:0 12px 38px rgba(0,0,0,.22)}
  .dmFriendHeroV249235 .ship{width:42px;height:42px;border-radius:16px;display:grid;place-items:center;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.12);font-size:23px;flex:0 0 auto}.dmFriendHeroV249235 b{display:block;color:#ffd96e;font-size:17px}.dmFriendHeroV249235 small{display:block;color:rgba(238,247,255,.76);line-height:1.32}
  .dmFriendToolsV249235{display:flex;align-items:center;gap:8px}.dmFriendToolsV249235 .search{flex:1;min-height:42px;border-radius:999px;padding:8px 13px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.12);color:#fff}
  .dmFriendListV249235{flex:1 1 auto;min-height:0;overflow-y:auto!important;overflow-x:hidden!important;-webkit-overflow-scrolling:touch;display:block!important;padding:2px 2px 14px!important;touch-action:pan-y!important;overscroll-behavior:contain!important}
  .dmFriendSummaryV249235{display:flex;gap:8px;flex-wrap:wrap;margin:4px 0 10px}.dmPillV249235{border-radius:999px;padding:7px 10px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.10);font-size:12px;font-weight:900;color:#eef7ff}.dmPillV249235.green{color:#0b2417;background:linear-gradient(135deg,#36f0a0,#ffd96e)}
  .dmFriendSectionTitleV249235{margin:12px 4px 7px;color:#ffe39b;font-size:13px;font-weight:1000;letter-spacing:.2px}.dmFriendSectionV249235{display:grid;gap:8px}.dmFriendRowV249235{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:10px;width:100%;text-align:left;border-radius:20px;padding:10px 11px;background:rgba(255,255,255,.065);border:1px solid rgba(255,255,255,.10);color:#eef7ff;box-shadow:0 8px 22px rgba(0,0,0,.14);cursor:pointer;box-sizing:border-box}.dmFriendRowV249235:active,.dmFriendRowV249235.active{background:rgba(54,240,160,.16);border-color:rgba(54,240,160,.35)}
  .dmFriendRowV249235 .avatar,.dmFriendRowV249235 .avatar img{width:48px;height:48px;border-radius:50%;object-fit:cover}.dmFriendRowV249235 .who{min-width:0}.dmFriendRowV249235 .who b{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.dmFriendRowV249235 .who small{display:block;color:rgba(238,247,255,.68);font-size:12px;margin-top:3px}.dmFriendRowV249235 .go{display:flex;align-items:center;gap:7px}.dmFriendRowV249235 .go .msgGo{border-radius:999px;padding:8px 10px;background:linear-gradient(135deg,rgba(54,240,160,.24),rgba(255,217,110,.18));border:1px solid rgba(255,217,110,.28);font-weight:1000;color:#ffe9ac}.dmMemberMenuBtnV249235{width:34px!important;height:34px!important;min-width:34px!important;min-height:34px!important;font-size:18px!important}
  .avatarDotWrap i.off{background:#7b8591!important;box-shadow:none!important}.dmEmptyV249235{margin-top:8px}.dmChatScreenV249235{height:100%;min-height:0;display:none;overflow:hidden}.dmChatScreenV249235 .chatPane{height:100%!important;min-height:0!important;display:flex!important;flex-direction:column!important}.dmChatScreenV249235 .messages{flex:1 1 auto!important;min-height:0!important;overflow-y:auto!important}.dmContactFirstShellV249235.chatOpen .dmFriendScreenV249235{display:none!important}.dmContactFirstShellV249235.chatOpen .dmChatScreenV249235{display:block!important}
  @media(max-width:760px){.dmContactFirstShellV249235{padding:6px}.dmFriendHeroV249235{border-radius:17px;padding:8px 9px}.dmFriendHeroV249235 .ship{width:36px;height:36px;font-size:20px;border-radius:14px}.dmFriendHeroV249235 b{font-size:15px}.dmFriendHeroV249235 small{font-size:11px}.dmFriendToolsV249235 .search{min-height:38px}.dmFriendRowV249235{grid-template-columns:auto 1fr auto;padding:8px 9px;border-radius:17px}.dmFriendRowV249235 .avatar,.dmFriendRowV249235 .avatar img{width:43px;height:43px}.dmFriendRowV249235 .go .msgGo{font-size:12px;padding:7px 8px}.dmFriendRowV249235 .who small{font-size:11px}.dmChatScreenV249235 .chatHead{height:48px!important;min-height:48px!important}.dmChatScreenV249235 .composer{flex-shrink:0!important}}
`;document.head.appendChild(st)}catch(e){console.warn('v249235 css',e)}}
function v249235FriendListForMessages(){const friendIds=v249231FriendIds();const m=new Map();try{v249231MergeFriendsAndPeople().forEach(p=>{const id=String(p.id||p.device_id||'');if(id)m.set(id,Object.assign({id,device_id:id},p,{id,device_id:id}))})}catch{}try{(state.socialFriendsV249225||[]).forEach(p=>{const id=String(p.device_id||p.id||'');if(id)m.set(id,Object.assign({},m.get(id)||{},p,{id,device_id:id}))})}catch{}try{JSON.parse(localStorage.getItem('ith_contacts')||'[]').forEach(id=>{id=String(id||'');if(id&&!m.has(id))m.set(id,{id,device_id:id,nickname:'Φίλος',avatar:'',online:false})})}catch{}let arr=[...m.values()].filter(p=>{const id=String(p.id||p.device_id||'');return id&&id!==String(state.device)&&friendIds.has(id)&&!isBlocked(id)});arr=arr.map(p=>{const id=String(p.id||p.device_id||'');const sp=state.people.get(id)||{};return Object.assign({},p,sp,{id,device_id:id,nickname:p.nickname||sp.nickname||'Φίλος',avatar:p.avatar||sp.avatar||'',online:!!(p.online||sp.online)})});const seen=new Set();arr=arr.filter(p=>{const id=String(p.id||p.device_id||'');if(seen.has(id))return false;seen.add(id);return true});arr.sort((a,b)=>((unreadFrom(b.id)?1:0)-(unreadFrom(a.id)?1:0))||((b.online?1:0)-(a.online?1:0))||String(a.nickname||'').localeCompare(String(b.nickname||''),'el'));return arr}
function v249235FriendRow(p){const id=String(p.id||p.device_id||'');const unread=unreadFrom(id);const status=unread?'Νέο μήνυμα':(p.online?'Ενεργός τώρα':'Ανενεργός');const dot=unread?'red':(p.online?'on':'off');return `<div class="dmFriendRowV249235 ${state.activePeer===id?'active':''}" data-id="${esc(id)}"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${dot}"></i></span><span class="who"><b>${esc(p.nickname||'Φίλος')}</b><small>${esc(status)}</small></span><span class="go"><span class="msgGo">💬 Μήνυμα</span><button class="icon dmMemberMenuBtnV249235" data-menu-id="${esc(id)}" title="Μενού μέλους">⋯</button></span></div>`}
function v249235FriendSection(title,arr,empty){if(!arr.length)return empty?`<div class="dmFriendSectionTitleV249235">${esc(title)}</div><div class="card date">${esc(empty)}</div>`:'';return `<div class="dmFriendSectionTitleV249235">${esc(title)}</div><div class="dmFriendSectionV249235">${arr.map(v249235FriendRow).join('')}</div>`}
function showDMFriendListV249235(){const shell=$('dmShellV249235');if(shell)shell.classList.remove('chatOpen');if($('dmFriendScreen'))$('dmFriendScreen').style.display='';if($('dmChatScreen'))$('dmChatScreen').style.display='none';renderPeople();return false}
function showDMChatScreenV249235(){const shell=$('dmShellV249235');if(shell)shell.classList.add('chatOpen');if($('dmFriendScreen'))$('dmFriendScreen').style.display='none';if($('dmChatScreen'))$('dmChatScreen').style.display='block';return false}
function openDMV249235(){injectV249235MessageFirstCss();const pageEl=$('dmPage');if(!pageEl)return;state.page='dm';if(document.body)document.body.setAttribute('data-page','dm');pageEl.innerHTML=`<div id="dmShellV249235" class="dmContactFirstShellV249235"><section id="dmFriendScreen" class="dmFriendScreenV249235"><div class="dmFriendHeroV249235"><button class="icon" onclick="ITH.page('home')">‹</button><div class="ship">💬</div><div><b>Μηνύματα</b><small>Διάλεξε φίλο, ενεργό ή ανενεργό. Πατάς στο όνομα και μπαίνεις κατευθείαν στη συνομιλία.</small></div></div><div class="dmFriendToolsV249235"><input id="peopleSearch" class="search" placeholder="Αναζήτηση φίλου..."><button class="icon" onclick="ITH.refreshFriendsForMessagesV249246&&ITH.refreshFriendsForMessagesV249246(true)">🔄</button></div><div id="peopleList" class="peopleList dmFriendListV249235"></div></section><section id="dmChatScreen" class="dmChatScreenV249235"><div class="chatPane"><div class="chatHead"><button class="icon" onclick="ITH.clearChat()">‹</button><button id="chatAvatar" class="avatar chatAvatarBtn" onclick="ITH.memberActive()">💬</button><div class="chatTitle"><b id="chatName">${uiText('Choose a contact')}</b><div id="typing" class="typing"></div></div><button class="icon chatActionBtn" title="${uiText('Voice call')}" onclick="ITH.startVoiceCall()">📞</button><button class="icon chatActionBtn" title="${uiText('Video call')}" onclick="ITH.startVideoCall()">📹</button><button class="icon chatActionBtn" title="${uiText('Take photo')}" onclick="ITH.openMessageCamera('photo')">📷</button><button class="icon chatActionBtn" title="${uiText('Record video')}" onclick="ITH.openMessageCamera('video')">🎥</button><button class="icon chatActionBtn" title="${uiText('Record audio')}" onclick="ITH.startAudioRecording('dm')">🎙️</button><button class="icon chatActionBtn" title="${uiText('Private lock')}" onclick="ITH.openE2EPanel()">🔐</button><button class="icon" onclick="ITH.memberActive()">⋯</button></div><div id="messages" class="messages"><div class="card">Διάλεξε φίλο από τη λίστα για μήνυμα.</div></div><div id="replyBox" class="card" style="display:none;margin:0 9px 6px;padding:8px"></div><div class="composer"><button class="icon" onclick="ITH.chooseFile('dm','file')">📎</button><textarea id="dmInput" placeholder="${uiText('Write a message...')}" oninput="ITH.handleTypingInput()" onfocus="ITH.handleTypingInput()"></textarea><button class="icon" onclick="ITH.sendDMText()">➤</button></div></div></section></div>`;const search=$('peopleSearch');if(search)search.oninput=renderPeople;renderPeople();loadPeople();loadSocialFriendsV249225().then(renderPeople);setTimeout(applyUiLanguagePatch,30)}
function channelFor(a,b){return'dm:'+[a,b].sort().join(':')}
async function startDM(id){id=String(id||'');if(!id)return false;state.activePeer=id;state.activeChannel=channelFor(state.device,id);state.lastMsgIds.clear();state.messagesSince=0;markPeerRead(id);try{$('memberMenu').classList.remove('show')}catch{};page('dm');state.activePeer=id;state.activeChannel=channelFor(state.device,id);showDMChatScreenV249235();const p=v249231PersonById(id)||state.people.get(id)||{id,nickname:'Φίλος',avatar:''};if($('chatName'))$('chatName').textContent=p.nickname||'Φίλος';const av=avatarHtml(p);const ca=$('chatAvatar');if(ca)ca.outerHTML=`<button id="chatAvatar" class="chatAvatarBtn" onclick="ITH.memberActive()">${av}</button>`;renderPeople();wsSubscribe(state.activeChannel);await loadMessages(true);await markActiveChannelRead();await loadReadState(state.activeChannel);pollTypingState();markPeerRead(id);return false}
function clearChat(){state.activePeer='';state.activeChannel='';state.lastMsgIds.clear();state.messagesSince=0;if($('messages'))$('messages').innerHTML=`<div class="card">Διάλεξε φίλο από τη λίστα για μήνυμα.</div>`;if($('chatName'))$('chatName').textContent=uiText('Choose a contact');showDMFriendListV249235();renderPeople();return false}

async function loadMessages(reset=false){if(!state.activeChannel)return;const box=$('messages');if(!box)return;try{const path=`/api/messages?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent(state.activeChannel)}&since=${reset?0:state.messagesSince}&limit=300`;const r=await fetchJson(path);const items=uniqueMessages(r.messages||[]);const oldSuppress=state.suppressMessageAlerts;if(reset){box.innerHTML='';state.lastMsgIds.clear();state.suppressMessageAlerts=true}items.forEach(appendMessage);state.suppressMessageAlerts=oldSuppress;if(items.length){state.messagesSince=Math.max(...items.map(x=>+x.created_at||0),state.messagesSince);box.scrollTop=box.scrollHeight;await markActiveChannelRead();await loadReadState(state.activeChannel)}if(!box.children.length)box.innerHTML='<div class="card">Ξεκίνα τη συνομιλία.</div>'}catch(e){state.suppressMessageAlerts=false;if(reset)box.innerHTML=`<div class="card">Τα μηνύματα δεν φόρτωσαν: ${esc(e.message||e)}</div>`}}
function renderDecryptedMessagePayloadV249464(div,plaintext,translationId){const t=parseText(plaintext);const body=div.querySelector('.msgBody');if(body)body.textContent=t.body||'';const mediaHost=div.querySelector('.msgMediaHostV249464');if(mediaHost)mediaHost.innerHTML=messageMediaHtml(t.media);const translateHost=div.querySelector('.msgTranslateHostV249464');if(translateHost)translateHost.innerHTML=translateControls(translationId,t.body||'');if(t.body)maybeAutoTranslate(translationId,t.body);div.classList.toggle('hasMediaV249464',!!t.media);return t}
function appendMessage(m){const box=$('messages');if(!box||state.lastMsgIds.has(m.message_id))return;state.lastMsgIds.add(m.message_id);const mine=String(m.sender_id)===state.device;let t=parseText(m.text);const number=box.querySelectorAll?box.querySelectorAll('.bubble').length+1:state.lastMsgIds.size;const div=document.createElement('div');div.className='bubble '+(mine?'mine':'');div.dataset.ts=String(m.created_at||0);const translationId='msg_'+esc(m.message_id||number);if(m.is_encrypted)t={body:'🔐 '+uiText('Decrypting...'),media:null};const receipt=mine?`<span class="readReceipt" data-ts="${esc(String(m.created_at||0))}">✓ ${uiLang()==='en'?'sent':'στάλθηκε'}</span>`:'';div.innerHTML=`<div class="msgNo">#${number}</div><div class="msgBody">${esc(t.body)}</div><div class="msgTranslateHostV249464">${translateControls(translationId,t.body)}</div><div class="msgMediaHostV249464">${messageMediaHtml(t.media)}</div><div class="meta">${fmt(m.created_at)} ${receipt} <button class="icon small" onclick="ITH.replyMsg('${esc(m.message_id)}','${esc((t.body||'').slice(0,60))}')">↩</button> ${mine?`<button class="icon small" onclick="ITH.deleteMsg('${esc(m.message_id)}')">🗑️</button>`:''}</div>`;box.appendChild(div);if(m.is_encrypted){e2eDecryptText(m.iv,m.cipher_text,m.channel||state.activeChannel).then(txt=>renderDecryptedMessagePayloadV249464(div,txt,translationId)).catch(e=>{const body=div.querySelector('.msgBody');if(body)body.textContent='🔐 '+String(e&&e.message||e)})}try{window.ITHAKI_SECURE_V249389&&window.ITHAKI_SECURE_V249389.onMessageRendered(m,div)}catch(e){}if(!m.is_encrypted)maybeAutoTranslate(translationId,t.body);if(mine)updateReadReceipts(state.activeChannel);if(!mine){markActiveChannelRead();notifyIncomingMessage(m,t.body);if(String(m.sender_id)===String(state.activePeer))markPeerRead(m.sender_id);else{addNotice({type:'message',from_id:m.sender_id,from_name:m.nickname||'Member',text:uiText('New message')+' '+(m.nickname||'Member')});refreshNavBadges()}}}

function replyMsg(id,text){state.replyTo={id,text};const rb=$('replyBox');if(rb){rb.style.display='block';rb.innerHTML=`<div class="row" style="justify-content:space-between"><span>↩ Reply: ${esc(text||id)}</span><button class="icon small" onclick="ITH.clearReply()">×</button></div>`}const i=$('dmInput');if(i)i.focus()}
function clearReply(){state.replyTo=null;const rb=$('replyBox');if(rb){rb.style.display='none';rb.innerHTML=''}}
async function sendDMText(){const input=$('dmInput');const txt=(input?.value||'').trim();if(!state.activeChannel)return toast('Choose a contact');if(!txt)return;try{input.value='';const payload=state.replyTo?JSON.stringify({body:txt,reply_to:state.replyTo}):txt;clearReply();await sendMessagePayload(state.activeChannel,payload);await loadMessages(true);await loadReadState(state.activeChannel);pollTypingState()}catch(e){toast('Not sent')}}


/* V249141 active E2E + Push hooks in live index.js */
function e2eKeyName(channel){return 'ith_e2e_key_'+String(channel||'main')}
function e2eEnabled(channel){return !!localStorage.getItem(e2eKeyName(channel))}
function setE2EKey(channel,key){if(key)localStorage.setItem(e2eKeyName(channel),key);else localStorage.removeItem(e2eKeyName(channel));toast(key?'E2E is active for this channel':'E2E is off for this channel')}
async function e2eImportKey(pass){const enc=new TextEncoder();const base=await crypto.subtle.digest('SHA-256',enc.encode(String(pass||'')));return crypto.subtle.importKey('raw',base,{name:'AES-GCM'},false,['encrypt','decrypt'])}
function b64(buf){return btoa(String.fromCharCode(...new Uint8Array(buf)))}
function fromB64(s){return Uint8Array.from(atob(String(s||'')),c=>c.charCodeAt(0))}
async function e2eEncryptText(text,channel){const pass=localStorage.getItem(e2eKeyName(channel));if(!pass||!crypto?.subtle)return null;const iv=crypto.getRandomValues(new Uint8Array(12));const key=await e2eImportKey(pass);const data=new TextEncoder().encode(String(text||''));const cipher=await crypto.subtle.encrypt({name:'AES-GCM',iv},key,data);return {iv:b64(iv),cipher_text:b64(cipher)}}
async function legacyE2EDecryptTextV249389(iv,cipher,channel){const pass=localStorage.getItem(e2eKeyName(channel));if(!pass||!crypto?.subtle)return '';try{const key=await e2eImportKey(pass);const plain=await crypto.subtle.decrypt({name:'AES-GCM',iv:fromB64(iv)},key,fromB64(cipher));return new TextDecoder().decode(plain)}catch{return '🔐 Encrypted message · wrong or missing key'}}
async function e2eDecryptText(iv,cipher,channel){try{const secure=window.ITHAKI_SECURE_V249389;if(secure&&typeof secure.decryptText==='function')return await secure.decryptText(iv,cipher,channel,legacyE2EDecryptTextV249389)}catch(e){}return legacyE2EDecryptTextV249389(iv,cipher,channel)}
function openE2EPanel(channel){const secureCh=channel||state.activeChannel||state.currentSpaceChannel||'';if(String(secureCh).startsWith('dm:')){if(window.ITHAKI_SECURE_V249389)return window.ITHAKI_SECURE_V249389.openPanel(secureCh);toast('Η ασφαλής κλειδαριά V249389 δεν φορτώθηκε.');return false}const ch=channel||state.activeChannel||state.currentSpaceChannel||'';$('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔐 ${uiText('Private lock')}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><p class="date">${uiText('Use the same shared key on both devices to decrypt private messages.')}</p><input id="e2eKeyInput" style="width:100%" placeholder="${uiText('Shared secret key')}"><div class="row" style="margin-top:10px"><button class="btn green" onclick="ITH.saveE2EKey('${esc(ch)}')">${uiText('Enable E2E')}</button><button class="btn danger" onclick="ITH.clearE2EKey('${esc(ch)}')">${uiText('Turn off E2E')}</button></div><div class="date" style="margin-top:8px">${uiText('Secure key panel opened.')}</div></div>`;$('memberMenu').classList.add('show')}
function saveE2EKey(ch){setE2EKey(ch||state.activeChannel||state.currentSpaceChannel,$('e2eKeyInput')?.value||'');$('memberMenu').classList.remove('show')}
function clearE2EKey(ch){setE2EKey(ch||state.activeChannel||state.currentSpaceChannel,'');$('memberMenu').classList.remove('show')}
async function registerPushToken(token,source='manual'){if(!token)return toast('No FCM token');try{const r=await fetchJson('/api/push/fcm/register',{method:'POST',body:JSON.stringify({room_id:state.room,device_id:state.device,nickname:state.name,token,platform:'android',source})});localStorage.setItem('ith_fcm_token',token);toast(r.fcm_enabled_on_server?'Push is active on the server':'Token saved · server FCM credentials are missing')}catch(e){toast('Push token was not saved')}}
function openPushPanel(){$('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 ${uiText('Notifications and app sleep')}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><p class="date">${uiText('Choose how OK ITHAKI notifies you. FCM is optional and only works after Firebase credentials are configured in the APK and server.')}</p><div class="notificationModeGrid">${notificationChoice('open_only','📱','Notifications only while the app is open. Best battery saving, but no closed-app alerts.')}${notificationChoice('fcm','🔔','The app can sleep. Firebase/FCM wakes notifications when configured.')}${notificationChoice('stay_awake','🟢','Keeps an active foreground connection. Faster, but uses more battery.')}${notificationChoice('hybrid','🔔🟢','Recommended: active when open, FCM fallback when the app sleeps.')}</div></div><div class="card"><b>🔔 Άμεσος έλεγχος ειδοποιήσεων</b><p class="date">Οι ειδοποιήσεις μέσα στην εφαρμογή δουλεύουν άμεσα. Για κλειστή εφαρμογή χρειάζεται Firebase/FCM και νέο APK.</p><div class="row" style="margin-top:10px"><button class="btn green" onclick="ITH.requestWebNotificationPermissionV249220()">Άδεια ειδοποιήσεων</button><button class="btn" onclick="ITH.testLocalNotificationV249220()">Δοκιμή ειδοποίησης</button><button class="btn" onclick="ITH.openPushStatusV249220()">Έλεγχος FCM</button></div></div><div class="card"><b>FCM token</b><p class="date">${uiText('Manual token registration is only for testing.')}</p><input id="pushTokenInput" style="width:100%" placeholder="FCM token from Android/APK"><div class="row" style="margin-top:10px"><button class="btn green" onclick="ITH.registerPushToken((document.getElementById('pushTokenInput')||{}).value,'manual')">Register push token</button></div></div>`;$('memberMenu').classList.add('show')}
function initPushHooks(){try{
  const tryRegister=(source='auto')=>{try{const token=bridgeCall('getFcmToken')||localStorage.getItem('ith_fcm_token')||''; if(token){registerPushToken(token,source); return true}}catch(e){} return false};
  if(bridgeHas('requestFcmToken')){try{bridgeCall('requestFcmToken',state.room,state.device,state.name,state.api)}catch(e){}}
  tryRegister('boot');
  setTimeout(()=>tryRegister('boot-delay-1500'),1500);
  setTimeout(()=>tryRegister('boot-delay-5000'),5000);
  setTimeout(()=>tryRegister('boot-delay-12000'),12000);
}catch{}}
async function requestWebNotificationPermissionV249220(){try{try{bridgeCall('requestNotificationPermission')}catch{};if('Notification' in window&&Notification.permission==='default'){const p=await Notification.requestPermission();toast(p==='granted'?uiText('Notifications are enabled.'):uiText('Notifications are not enabled.'))}else if('Notification' in window&&Notification.permission==='granted'){toast(uiText('Notifications are enabled.'))}else{toast(uiText('Browser notifications are not available.'))}}catch(e){toast(uiText('Notifications are not enabled.'))}}
function testLocalNotificationV249220(){try{requestWebNotificationPermissionV249220().then(()=>{notifyAppEvent('OK ITHAKI','Δοκιμαστική ειδοποίηση','message')})}catch{notifyAppEvent('OK ITHAKI','Δοκιμαστική ειδοποίηση','message')}}
async function openPushStatusV249220(){try{const r=await fetchJson('/api/diagnostics/v249220?room_id='+encodeURIComponent(state.room));toast('FCM server: '+(r.notifications&&r.notifications.fcm_server_enabled?'ON':'OFF')+' · tokens: '+((r.notifications&&r.notifications.active_fcm_tokens)||0),7000)}catch(e){toast('Δεν φορτώνει ο έλεγχος ειδοποιήσεων')}}
function wsUrl(){try{const u=new URL(state.api.replace(/\/$/,'')+'/ws');u.protocol=u.protocol==='https:'?'wss:':'ws:';return u.toString()}catch{return ''}}
function wsWantedChannels(){const a=[];if(state.activeChannel)a.push(state.activeChannel);if(state.currentSpaceChannel)a.push(state.currentSpaceChannel);if(state.commentChannel)a.push(state.commentChannel);return [...new Set(a.filter(Boolean))]}
function wsStatus(s){if($('subStatus'))$('subStatus').textContent=s}
function ensureWs(){if(!('WebSocket' in window))return false;if(state.ws&&(state.ws.readyState===0||state.ws.readyState===1))return true;const url=wsUrl();if(!url)return false;try{const ws=new WebSocket(url);state.ws=ws;state.wsReady=false;ws.onopen=()=>{state.wsReady=true;state.wsChannels=new Set(wsWantedChannels());ws.send(JSON.stringify({type:'hello',room_id:state.room,device_id:state.device,channels:[...state.wsChannels]}));wsStatus('realtime WebSocket active')};ws.onmessage=ev=>{let d=null;try{d=JSON.parse(ev.data)}catch{return}if(d.type==='ready'){state.wsReady=true;return}if(d.type==='messages'&&Array.isArray(d.items))handleWsMessages(d.items);if(d.type==='pong')return};ws.onclose=()=>{state.wsReady=false;wsStatus('realtime fallback polling');clearTimeout(state.wsReconnect);state.wsReconnect=setTimeout(()=>ensureWs(),1800)};ws.onerror=()=>{state.wsReady=false;try{ws.close()}catch{}};return true}catch(e){state.wsReady=false;return false}}
function wsSubscribe(channels){const arr=[...new Set((Array.isArray(channels)?channels:[channels]).filter(Boolean))];if(!arr.length)return;ensureWs();if(state.ws&&state.ws.readyState===1){for(const c of arr)state.wsChannels.add(c);try{state.ws.send(JSON.stringify({type:'sub',channels:arr}))}catch{}}}
function wsPing(){try{if(state.ws&&state.ws.readyState===1)state.ws.send(JSON.stringify({type:'ping',ts:Date.now()}))}catch{}}
function handleWsMessages(items){for(const m of items){const ch=String(m.channel||'');if(ch&&ch===state.activeChannel){appendMessage(m);state.messagesSince=Math.max(state.messagesSince,+m.created_at||0);const box=$('messages');if(box)box.scrollTop=box.scrollHeight;markActiveChannelRead();loadReadState(ch)}else if(ch&&ch===state.currentSpaceChannel){appendSpaceMessage(m);const box=$('spaceMsgs');if(box)box.scrollTop=box.scrollHeight}else if(ch&&ch===state.commentChannel&&state.commentPostId){loadPanelComments(state.commentPostId)}else if(ch&&ch.startsWith('dm:')){notifyIncomingMessage(m,'New message from '+(m.nickname||'Member'));addNotice({type:'message',from_id:m.sender_id,from_name:m.nickname||'Member',text:'New message from '+(m.nickname||'Member')});refreshNavBadges()}}}
function appendSpaceMessage(m){const box=$('spaceMsgs');const mid=String(m.message_id||'');if(!box)return;if(mid&&(','+(box.dataset.lastIds||'')+',').includes(','+mid+','))return;if(!box.dataset.lastIds)box.dataset.lastIds='';if(mid)box.dataset.lastIds+=','+mid;let t=parseText(m.text);const div=document.createElement('div');div.className='bubble '+(String(m.sender_id)===state.device?'mine':'');if(mid)div.dataset.spaceMessageId=mid;const translationId='space_'+esc(m.message_id||Date.now());if(m.is_encrypted)t={body:'🔐 '+uiText('Decrypting...'),media:null};div.innerHTML=`<b>${esc(m.nickname||'Member')}</b><div class="msgBody">${esc(t.body)}</div><div class="msgTranslateHostV249464">${translateControls(translationId,t.body)}</div><div class="msgMediaHostV249464">${messageMediaHtml(t.media)}</div><div class="meta">${fmt(m.created_at)}</div>`;box.appendChild(div);if(m.is_encrypted)e2eDecryptText(m.iv,m.cipher_text,m.channel||state.currentSpaceChannel).then(txt=>renderDecryptedMessagePayloadV249464(div,txt,translationId));else maybeAutoTranslate(translationId,t.body)}

async function sendMessagePayload(channel,payload){if(!channel)throw new Error('no channel');const enc=e2eEnabled(channel)?await e2eEncryptText(payload,channel):null;const body=enc?{room_id:state.room,channel,sender_id:state.device,nickname:state.name,language:(typeof uiLang==='function'?uiLang():'el'),text:'',is_encrypted:true,iv:enc.iv,cipher_text:enc.cipher_text}:{room_id:state.room,channel,sender_id:state.device,nickname:state.name,language:(typeof uiLang==='function'?uiLang():'el'),text:payload};const result=await fetchJson('/api/messages/send',{method:'POST',body:JSON.stringify(body)});wsSubscribe(channel);return result}
async function deleteMsg(id){if(!confirm('Delete message?'))return;try{await fetchJson('/api/messages/delete',{method:'POST',body:JSON.stringify({room_id:state.room,channel:state.activeChannel,message_id:id,device_id:state.device})});loadMessages(true)}catch{toast('Cannot delete')}}

/* R10F15 source lock: legacy community renderers may never paint. */
function __ithakiCanonicalSpacesR10F15(){
  const o=window.ITH||{},f=o.openCanonicalCommunitiesR10F15||window.openCanonicalCommunitiesR10F15||o.activateSpacesPageV249516||window.activateSpacesPageV249516||o.renderSpacesV249516||window.renderSpacesV249516;
  if(typeof f==='function'&&f!==__ithakiCanonicalSpacesR10F15)return f.call(o);
  const s=window.state||o.state;if(s)s.page='spaces';
  if(document.body)document.body.dataset.page='spaces';
  document.querySelectorAll('.page').forEach(p=>p.classList.remove('active'));
  const p=document.getElementById('spacesPage');if(p){p.classList.add('active');if(!p.querySelector('[data-community-owner="r10f15"]'))p.innerHTML='<div class="card"><b>Φόρτωση κοινοτήτων…</b><small>Ενεργοποίηση της μοναδικής οθόνης.</small></div>'}
  return false;
}
async function renderSpaces(){if(window.__ITHAKI_R10F15_SINGLE_COMMUNITY_RUNTIME__)return __ithakiCanonicalSpacesR10F15();state.spaceTab=state.spaceTab||'rooms';$('spacesPage').innerHTML=`<div class="row" style="margin-bottom:10px"><button class="icon" onclick="ITH.page('home')">‹</button><button class="btn ${state.spaceTab==='rooms'?'green':''}" onclick="ITH.spaceTab('rooms')">🏠 ${uiText('Rooms')}</button><button class="btn ${state.spaceTab==='communities'?'green':''}" onclick="ITH.spaceTab('communities')">🌐 ${uiText('Communities')}</button><button class="btn gold" onclick="ITH.createSpaceCard()">＋ ${uiText('Create')}</button><button class="btn" onclick="ITH.openPoll()">📊 Poll</button><button class="btn" onclick="ITH.loadRooms()">🔄</button></div><div id="spaceSamples" class="spaceSamples"></div><div class="roomLayout"><div><div id="roomList" class="roomList"></div></div><div class="chatPane"><div class="chatHead"><b id="spaceTitle">${uiText('Choose a space')}</b><button class="icon chatActionBtn" title="${uiText('Take photo')}" onclick="ITH.openSpaceMedia('photo',true)">📷</button><button class="icon chatActionBtn" title="${uiText('Record video')}" onclick="ITH.openSpaceMedia('video',true)">🎥</button><button class="icon chatActionBtn" title="${uiText('Record audio')}" onclick="ITH.startAudioRecording('space')">🎙️</button><button class="icon" onclick="ITH.openSpaceMedia('file',false)">📎</button><button class="icon" onclick="ITH.openE2EPanel()">🔐</button><button class="icon" onclick="ITH.openSpaceAdmin()">⚙️</button></div><div id="spaceMsgs" class="messages"><div class="card">${uiText('Choose a space.')}</div></div><div class="composer"><textarea id="spaceInput" placeholder="${uiText('Message this space...')}"></textarea><button class="icon" onclick="ITH.sendSpaceText()">➤</button></div></div></div>`;renderSpaceSamples();await loadRooms();if(state.currentSpaceChannel){const s=state.spaces.find(x=>x.subroom_id===state.currentSpace)||{};if($('spaceTitle'))$('spaceTitle').textContent=s.title||'Space';await loadSpaceMessages(true)}}
function openSpaceMedia(kind,camera=false){if(!state.currentSpaceChannel){toast(uiText('Choose destination first.'));return false}return camera?captureMedia('space',kind,state.currentSpaceChannel):(chooseFile('space',kind,state.currentSpaceChannel),false)}
function spaceTab(tab){state.spaceTab=tab;if(window.__ITHAKI_R10F15_SINGLE_COMMUNITY_RUNTIME__)return __ithakiCanonicalSpacesR10F15();return renderSpaces()}
function renderSpaceSamples(){const box=$('spaceSamples');if(!box)return;const arr=state.spaceTab==='communities'?['Engineers','ITHAKI Friends','Art','Travel','Help','Polls']:['General discussion','Private room','Project team','Friends','Family','Meeting'];box.innerHTML=`<div class="card"><b>${state.spaceTab==='communities'?'Suggested communities':'Suggested rooms'}</b><div class="row" style="margin-top:8px">${arr.map(x=>`<button class="btn" onclick="ITH.prefillSpace('${esc(x)}')">${esc(x)}</button>`).join('')}</div></div>`}
function prefillSpace(title){createSpaceCard(title)}
function createSpaceCard(prefill=''){$('memberMenu').innerHTML=`<div class="row"><b>＋ New ${state.spaceTab==='communities'?'community':'room'}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><label>Title</label><input id="newSpaceTitle" style="width:100%" value="${esc(prefill)}" placeholder="Title"><label>Description / rules</label><textarea id="newSpaceDesc" style="width:100%;min-height:80px" placeholder="What is this space?"></textarea><label>Access</label><select id="newSpaceAccess" style="width:100%"><option value="public">Open</option><option value="invite">By invitation/approval</option><option value="private_code">With member code</option></select><label>Member code</label><input id="newSpaceCode" style="width:100%" placeholder="e.g. ITHAKI-2026"><label>Admin code</label><input id="newAdminCode" style="width:100%" placeholder="creator code"><div class="row" style="margin-top:10px"><button class="btn green" onclick="ITH.createRoomUIFromCard()">Create</button><button class="btn" onclick="ITH.showQR()">▦ Code/QR</button></div></div>`;$('memberMenu').classList.add('show')}
async function createRoomUIFromCard(){const title=($('newSpaceTitle')?.value||'').trim();if(!title)return toast('Enter a title');const access=$('newSpaceAccess')?.value||'public';const join_code=($('newSpaceCode')?.value||'').trim();const owner_secret=($('newAdminCode')?.value||'').trim()||('admin-'+state.device);try{await fetchJson('/api/rooms/create',{method:'POST',body:JSON.stringify({room_id:state.room,owner_id:state.device,title,description:($('newSpaceDesc')?.value||''),category:state.spaceTab==='communities'?'community':'room',access_type:access,join_code,owner_secret})});toast('Created');$('memberMenu').classList.remove('show');loadRooms()}catch(e){toast('Not created')}}
async function loadRooms(){try{const r=await fetchJson(`/api/rooms?room_id=${encodeURIComponent(state.room)}`);state.spaces=r.rooms||[];renderRoomList()}catch{$('roomList').innerHTML='<div class="card">Spaces are not loading.</div>'}}
function renderRoomList(){const list=$('roomList');if(!list)return;const want=state.spaceTab==='communities'?'community':'room';let arr=(state.spaces||[]).filter(s=>(s.category||'room')===want);if(!arr.length)arr=state.spaces||[];list.innerHTML=arr.map(s=>`<button class="tile spaceTile" onclick="ITH.openSpace('${esc(s.subroom_id)}')"><b>${(s.category||want)==='community'?'🌐':'🏠'} ${esc(s.title||'Space')}</b><span class="date">${esc(s.access_type||'public')} ${s.join_code?'· code':''}</span><div class="row" style="margin-top:8px"><button class="btn" onclick="event.stopPropagation();ITH.inviteToSpace('${esc(s.subroom_id)}')">Invite</button><button class="btn" onclick="event.stopPropagation();ITH.showSpaceCode('${esc(s.subroom_id)}')">▦ Code</button></div></button>`).join('')||'<div class="card">Nothing here yet.</div>'}
function createRoomUI(){createSpaceCard()}
async function openSpace(id){const s=state.spaces.find(x=>x.subroom_id===id)||{};const nextChannel='space:'+id;try{await fetchJson('/api/rooms/join',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:id,device_id:state.device,nickname:state.name,join_code:s.access_type==='private_code'?(prompt('Member code:')||''):''})})}catch{return toast('Correct code or approval required')}state.currentSpace=id;state.currentSpaceChannel=nextChannel;$('spaceTitle').textContent=s.title||'Space';wsSubscribe(state.currentSpaceChannel);await loadSpaceMessages(true)}
async function loadSpaceMessages(){if(!state.currentSpaceChannel)return;const box=$('spaceMsgs');box.innerHTML='';box.dataset.lastIds='';try{const r=await fetchJson(`/api/messages?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent(state.currentSpaceChannel)}&since=0&limit=300`);uniqueMessages(r.messages||[]).forEach(appendSpaceMessage);if(!box.children.length)box.innerHTML='<div class="card">Start the space.</div>';box.scrollTop=box.scrollHeight}catch{box.innerHTML='<div class="card">Space messages are not loading.</div>'}}
async function sendSpaceText(){const i=$('spaceInput');const txt=(i?.value||'').trim();if(!state.currentSpaceChannel)return toast('Choose a space');if(!txt)return;i.value='';await sendMessagePayload(state.currentSpaceChannel,txt);if(!state.wsReady)loadSpaceMessages()}
function openPoll(){const opts=['',''];$('memberMenu').innerHTML=`<div class="pollFull proPollModal"><div class="row pollHead"><button class="icon" onclick="ITH.closeMember()">‹</button><b>📊 ${uiText('Poll')}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="pollScroll"><div class="card pollBuilder proPollBuilder"><div class="proPanelIcon">📊</div><label>${uiText('Poll type')}</label><select id="pollPreset" onchange="ITH.applyPollPreset()" style="width:100%"><option value="custom">${uiText('My choices')}</option><option value="yesno">${uiText('Yes / No')}</option><option value="questions">${uiText('Ready question list')}</option></select><label>${uiText('Poll topic')}</label><input id="pollTopic" placeholder="${uiText('Quick community question')}"><label>${uiText('Question')}</label><textarea id="pollQuestion" placeholder="${uiText('Write the question clearly...')}"></textarea><div class="row" style="justify-content:space-between"><b>${uiText('Poll options')}</b><button class="btn" onclick="ITH.addPollOption()">＋ ${uiText('option')}</button><button class="btn" onclick="ITH.setYesNoPoll()">${uiText('Yes / No')}</button></div><div id="pollOptions">${opts.map((o,i)=>`<input class="pollOpt" value="${o}" placeholder="${uiText('Write option')} ${i+1}">`).join('')}</div><div class="pollOptionRow"><label><input id="pollAnonymous" type="checkbox" checked> ${uiText('Anonymous')}</label><label><input id="pollAvatar" type="checkbox"> ${uiText('With profile')}</label><label><input id="pollFeed" type="checkbox"> ${uiText('Post to Feed')}</label></div><button class="btn green" style="width:100%;margin-top:12px" onclick="ITH.createPollFromCard()">${uiText('Post poll')}</button><div id="pollStatsPreview" class="pollStats"><div class="card"><b>${uiText('Statistics')}</b><div class="date">0 ${uiText('members voted')} · 0%</div><div class="date">${uiText('Percentages will appear after posting and voting.')}</div></div></div></div></div></div>`;$('memberMenu').classList.add('show')}
function applyPollPreset(){const v=$('pollPreset')?.value;if(v==='yesno')return setYesNoPoll();if(v==='questions')return setQuestionPoll();if($('pollOptions'))$('pollOptions').innerHTML=`<input class="pollOpt" placeholder="Write option 1"><input class="pollOpt" placeholder="Write option 2">`}
function setQuestionPoll(){if($('pollTopic'))$('pollTopic').value='Ideas for ITHAKI';if($('pollQuestion'))$('pollQuestion').value='Which option should move forward first?';const box=$('pollOptions');if(box)box.innerHTML=['Better Feed','More communities','Better messages','More anonymity'].map((x,i)=>`<input class="pollOpt" value="${x}" placeholder="Option ${i+1}">`).join('')}
function setYesNoPoll(){const box=$('pollOptions');if(box)box.innerHTML=`<input class="pollOpt" value="Yes" placeholder="Option 1"><input class="pollOpt" value="No" placeholder="Option 2">`}
function addPollOption(){const box=$('pollOptions');if(!box)return;const n=box.querySelectorAll('.pollOpt').length+1;if(n>9){toast('Μέχρι 9 επιλογές για να χωράνε σωστά.');return false}box.insertAdjacentHTML('beforeend',`<input class="pollOpt" style="width:100%;margin-top:7px" placeholder="Option ${n}">`)}
async function createPollFromCard(){
  const topic=($('pollTopic')?.value||'').trim();
  const q=($('pollQuestion')?.value||'').trim();
  const opts=[...document.querySelectorAll('.pollOpt')].map(x=>x.value.trim()).filter(Boolean).slice(0,9);
  if(!q||opts.length<2)return toast(uiText('A question and at least 2 options are required'));
  const anon=!!$('pollAnonymous')?.checked&&!$('pollAvatar')?.checked;
  try{
    const res=await fetchJson('/api/polls/create',{method:'POST',body:JSON.stringify({room_id:state.room,creator_id:state.device,nickname:state.name,question:(topic?topic+' — ':'')+q,options:opts,anonymous:anon,allow_stats:true,publish_feed:true,community_id:state.currentSpace||''})});
    const poll_id=res.poll_id||('poll_'+Date.now());
    const statsHtml=`<div class="card"><b>${uiText('Statistics')}</b><div class="date">${uiText('Voted')} 0 ${uiText('members')} · ${opts.length} ${uiText('options')} · ${anon?uiText('anonymous'):uiText('with profile')}</div>${opts.map(o=>`<div class="pollLine"><span>${esc(o)}</span><em style="width:0%"></em><b>0%</b></div>`).join('')}</div>`;
    if($('pollStatsPreview'))$('pollStatsPreview').innerHTML=statsHtml;
    $('memberMenu')?.classList.remove('show');
    try{window.dispatchEvent(new CustomEvent('ithaki:publication-sent',{detail:{kind:'poll',poll_id:poll_id,server_published:true}}))}catch(e){}
    page('feed');
    setTimeout(()=>{try{const f=(window.ITH&&ITH.openProfessionalFeedV249429)||(window.ITH&&ITH.loadFeed)||window.loadFeed;if(typeof f==='function')f('poll-published-v249476')}catch(e){}},100);
    toast(uiText('Poll created'));
    return false;
  }catch(e){toast((uiText('Poll not created'))+': '+(e.message||e),7000);return false}
}
function markPeerRead(id){try{const sid=String(id||'');if(!sid)return;const a=localNotices().map(n=>String(n.from_id||n.to_id||'')===sid?Object.assign({},n,{read:true,status:n.status||'seen'}):n);saveNotices(a);refreshNavBadges();renderPeople();if(state.page==='home')renderHome()}catch{}}
function localNotices(){try{return JSON.parse(localStorage.getItem('ith_notifications')||'[]')}catch{return[]}}
function saveNotices(a){localStorage.setItem('ith_notifications',JSON.stringify(a.slice(-100)))}
function addNotice(n){const a=localNotices();const nn=Object.assign({id:'n_'+Date.now(),created_at:new Date().toISOString(),read:false},n);const key=(nn.type||'')+'|'+(nn.from_id||'')+'|'+(nn.to_id||'')+'|'+(nn.text||'');const exists=a.some(x=>!x.read&&((x.type||'')+'|'+(x.from_id||'')+'|'+(x.to_id||'')+'|'+(x.text||''))===key);if(!exists)a.push(nn);saveNotices(uniqueNotices(a));try{refreshNavBadges();renderPeople();if(state.page==='home')renderHome()}catch{}}
function inviteContact(id){const p=state.people.get(id)||{nickname:'Member'};addNotice({type:'contact_invite',from_id:state.device,from_name:state.name,to_id:id,to_name:p.nickname,text:`${state.name} requested contact approval.`});toast('Contact invite sent');try{if('Notification' in window&&Notification.permission==='granted')new Notification('OK ITHAKI',{body:'Contact invite to '+p.nickname})}catch{}}
function acceptContact(id){let a=[];try{a=JSON.parse(localStorage.getItem('ith_contacts')||'[]')}catch{}if(!a.includes(id))a.push(id);localStorage.setItem('ith_contacts',JSON.stringify(a));saveNotices(localNotices().map(n=>String(n.from_id||n.to_id)!==String(id)?n:Object.assign({},n,{read:true,status:'accepted'})));toast(uiText('Contact accepted'));refreshNavBadges();renderPeople();if(state.page==='home')renderHome();notifyCenter()}
function rejectContact(id){saveNotices(localNotices().map(n=>String(n.from_id||n.to_id)!==String(id)?n:Object.assign({},n,{read:true,status:'rejected'})));toast('Contact rejected');notifyCenter()}
function legacyNotifyCenterV249526_1(){const ns=uniqueNotices(localNotices()).reverse();const avatars=ns.slice(0,12).map(n=>{const p=state.people.get(n.from_id)||state.people.get(n.to_id)||{nickname:n.from_name||n.to_name||'Member',avatar:''};return `<button class="storyItem ${n.read?'':'on'}" onclick="${n.from_id?`ITH.member('${esc(n.from_id)}')`:'void 0'}"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${n.read?'on':'red'}"></i></span><small>${esc(p.nickname||'Member')}</small></button>`}).join('')||`<span class="date">${uiText('No new notifications.')}</span>`;$('memberMenu').innerHTML=`<div class="row"><b>🔔 ${uiText('Notification center')}</b><button class="icon" style="margin-left:auto" onclick="ITH.markNoticesRead()">✓</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="noticeAvatarStrip">${avatars}</div><div class="noticeList">${ns.map((n,i)=>`<div class="card noticeCard"><b>${i+1}. ${esc(labelNotice(n.type))}</b><div>${esc(n.text||'')}</div><div class="date">${esc(n.created_at||'')}</div>${n.type==='contact_invite'?`<div class="row"><button class="btn green" onclick="ITH.acceptContact('${esc(n.from_id||n.to_id||'')}')">${uiText('Contact accepted')}</button><button class="btn danger" onclick="ITH.rejectContact('${esc(n.from_id||n.to_id||'')}')">${uiText('Reject')}</button></div>`:''}${n.type==='message'&&n.from_id?`<button class="btn" onclick="ITH.startDM('${esc(n.from_id)}')">${uiText('Open message')}</button>`:''}</div>`).join('')||`<div class="card">${uiText('No notifications.')}</div>`}</div><div class="card"><b>${uiText('Outside the app')}</b><div class="date">${uiText('If the app is not installed, the link opens on the OK ITHAKI site.')}</div><button class="btn green" onclick="ITH.openPushPanel()">${uiText('Connect Push / FCM')}</button></div>`;$('memberMenu').classList.add('show')}
function labelNotice(t){return t==='contact_invite'?'Contact invite':t==='message'?'Message':'Notification'}
function markNoticesRead(){const a=localNotices().map(n=>Object.assign({},n,{read:true}));saveNotices(a);refreshNavBadges();renderPeople();if(state.page==='home')renderHome();notifyCenter()}
function showQR(){const site=(location&&location.origin)||'OK-ITHAKI';const code=`ITHAKI_SITE:${site}`;$('memberMenu').innerHTML=`<div class="row"><b>▦ ITHAKI site QR</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="qrBox" id="qrBox"></div><div class="card"><b>Only for the ITHAKI site</b><div style="overflow-wrap:anywhere">${esc(site)}</div><textarea id="qrShareText" style="width:100%;min-height:70px;margin-top:8px" placeholder="Optional sharing text...">Join OK ITHAKI · anonymous, free and respectful communication.</textarea><div class="row" style="margin-top:8px"><button class="btn green" onclick="ITH.shareQRSite()">📤 Share</button><button class="btn" onclick="navigator.clipboard&&navigator.clipboard.writeText('${esc(site)}')">Copy site</button></div></div>`;$('memberMenu').classList.add('show');drawFakeQR(code)}
function shareQRSite(){const site=shareSiteBase();const text=($('qrShareText')?.value||'OK ITHAKI').trim();return share(site,text)}
function drawFakeQR(text){const box=$('qrBox');if(!box)return;let h=0;for(let i=0;i<text.length;i++)h=(h*31+text.charCodeAt(i))>>>0;let cells='';for(let y=0;y<17;y++){for(let x=0;x<17;x++){const on=(x<3&&y<3)||(x>13&&y<3)||(x<3&&y>13)||(((h+(x*17+y)*2654435761)>>>((x+y)%16))&1);cells+=`<span class="${on?'on':''}"></span>`}}box.innerHTML=cells}

function inviteToSpace(subroom_id){const to=prompt('Member code/name to invite:');if(!to)return;addNotice({type:'space_invite',from_id:state.device,from_name:state.name,to_id:to,text:'Invite to space '+subroom_id});toast('Space invite sent')}
function showSpaceCode(subroom_id){const code=`SPACE:${state.room}:${subroom_id}`;$('memberMenu').innerHTML=`<div class="row"><b>▦ Space code</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="qrBox" id="qrBox"></div><div class="card" style="overflow-wrap:anywhere">${esc(code)}<br><button class="btn" onclick="navigator.clipboard&&navigator.clipboard.writeText('${esc(code)}')">Copy</button></div>`;$('memberMenu').classList.add('show');drawFakeQR(code)}
function openSpaceAdmin(){if(!state.currentSpace)return toast('Choose a space');const code=prompt('Admin code:');if(!code)return;$('memberMenu').innerHTML=`<div class="row"><b>🔐 Space management</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="grid"><button class="tile" onclick="ITH.adminMessageMember()"><b>💬</b>Message member</button><button class="tile" onclick="ITH.adminMessageSpace()"><b>📣</b>Message space</button><button class="tile" onclick="ITH.adminBlockMember()"><b>🚫</b>Block member</button><button class="tile" onclick="ITH.adminUnblockMember()"><b>↩</b>Unblock</button><button class="tile" onclick="ITH.showSpaceCode('${esc(state.currentSpace)}')"><b>▦</b>Code/QR</button></div>`;$('memberMenu').classList.add('show')}
function openAdminAccess(){page('spaces');setTimeout(()=>openSpaceAdmin(),150)}
function adminMessageMember(){const id=prompt('Member code:');const msg=prompt('Message:');if(id&&msg)sendMessagePayload('dm:'+[state.device,id].sort().join(':'),'[admin] '+msg).then(()=>toast('Sent'))}
function adminMessageSpace(){const msg=prompt('Message to space:');if(msg&&state.currentSpaceChannel)sendMessagePayload(state.currentSpaceChannel,'[admin] '+msg).then(()=>loadSpaceMessages())}
function adminBlockMember(){const id=prompt('Member to block:');if(!id)return;const a=blocked();if(!a.includes(id))a.push(id);saveBlocked(a);toast('Blocked locally')}
function adminUnblockMember(){const id=prompt('Member to unblock:');if(!id)return;saveBlocked(blocked().filter(x=>x!==id));toast('Unblocked')}

function openHostContact(){$('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🌊 ${uiText('Contact ITHAKI Host')}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><p>${uiText('Write thoughts, observations or advice. The message stays internally in ITHAKI.')}</p><textarea id="hostMsg" style="width:100%;min-height:150px" placeholder="${uiText('My message to ITHAKI Host...')}"></textarea><label class="card row" style="margin-top:10px"><input id="hostAnonymous" type="checkbox" checked><span>${uiText('Anonymous contact')}</span></label><button class="btn green" style="width:100%;margin-top:10px" onclick="ITH.sendHostMessage()">${uiText('Send to Host')}</button></div>`;$('memberMenu').classList.add('show')}
async function sendHostMessage(){const txt=($('hostMsg')?.value||'').trim();if(!txt)return toast('Write a message');const anon=!!$('hostAnonymous')?.checked;try{await sendMessagePayload('host:inbox',JSON.stringify({body:txt,kind:'host_contact',anonymous:anon,from:anon?'Anonymous':state.name,device_id:state.device}));addNotice({type:'host_contact',from_id:state.device,from_name:anon?'Anonymous':state.name,text:'Message sent to ITHAKI Host'});toast('Sent to ITHAKI Host');$('memberMenu').classList.remove('show')}catch(e){toast('Not sent to Host')}}
function profilePanelOpen(key){try{return localStorage.getItem('ith_profile_panel_'+key+'_v249164')==='1'}catch{return false}}
function toggleProfilePanel(key){try{localStorage.setItem('ith_profile_panel_'+key+'_v249164',profilePanelOpen(key)?'0':'1')}catch{}renderProfile();return false}
function stayConnectedOn(){try{return localStorage.getItem('ith_stay_connected')==='1'}catch{return false}}
function toggleStayConnected(){const next=!stayConnectedOn();try{localStorage.setItem('ith_stay_connected',next?'1':'0')}catch{}try{const b=bridgeObj&&bridgeObj();if(b){if(next&&typeof b.startStayConnected==='function')b.startStayConnected();if(!next&&typeof b.stopStayConnected==='function')b.stopStayConnected()}}catch{}toast(next?uiText('Stay connected: ON'):uiText('Stay connected: OFF'));renderProfile();return false}
function profileNameLockValue(){try{return localStorage.getItem('ith_profile_name_locked_v249164')||''}catch{return''}}
function unlockProfileNameChange(){try{localStorage.removeItem('ith_profile_name_locked_v249164')}catch{}toast(uiText('Name change unlocked. Save again to lock the new name.'),6500);renderProfile();return false}
function notificationMode(){try{return localStorage.getItem('ith_notifications_mode_v249164')||'hybrid'}catch{return'hybrid'}}
function notificationModeText(mode){
  const m=mode||notificationMode();
  if(m==='open_only')return 'Μόνο όταν έχω ανοιχτή την εφαρμογή';
  if(m==='fcm')return 'FCM — η εφαρμογή κοιμάται και ειδοποιεί';
  if(m==='stay_awake')return 'Ενεργό πρόγραμμα — δεν κοιμάται';
  return 'Έξυπνο — FCM + ενεργή σύνδεση';
}
function setNotificationMode(mode){const allowed=['open_only','fcm','stay_awake','hybrid'];if(!allowed.includes(mode))mode='hybrid';try{localStorage.setItem('ith_notifications_mode_v249164',mode)}catch{}try{if(mode==='stay_awake'||mode==='hybrid'){localStorage.setItem('ith_stay_connected','1');const b=bridgeObj&&bridgeObj();if(b&&typeof b.startStayConnected==='function')b.startStayConnected()}else{localStorage.setItem('ith_stay_connected','0');const b=bridgeObj&&bridgeObj();if(b&&typeof b.stopStayConnected==='function')b.stopStayConnected()}}catch{}try{if(mode==='fcm'||mode==='hybrid'){if(bridgeHas('requestNotificationPermission'))bridgeCall('requestNotificationPermission');initPushHooks()}}catch{}toast(notificationModeText(mode));renderProfile();return false}
function notificationChoice(mode,icon,note){const active=notificationMode()===mode;return `<button class="notifModeCard ${active?'active':''}" onclick="return ITH.setNotificationMode('${mode}')"><span class="notifRadio">${active?'●':'○'}</span><b>${icon} ${notificationModeText(mode)}</b><small>${uiText(note)}</small></button>`}
function renderProfile(){if(window.__ITHAKI_PROFILE_EXCLUSIVE_R10F37F1F3__&&typeof window.renderProfessionalProfileR10F37F1F3==='function')return window.renderProfessionalProfileR10F37F1F3();const b=blocked().map(id=>state.people.get(id)||{id,nickname:id});const langOpen=profilePanelOpen('language');const safeOpen=profilePanelOpen('safety');const notifOpen=profilePanelOpen('notifications');const toolsOpen=profilePanelOpen('tools');const lockedValue=profileNameLockValue();const locked=!!lockedValue;const shownName=locked?lockedValue:state.name;$('profilePage').innerHTML=`<div class="profileCleanWrap profileV249164"><div class="card profileHeroClean"><div class="row profileHeadClean"><button class="icon cleanBackBtn" onclick="ITH.page('home')">‹</button><div class="row profileIdentityClean">${avatarHtml({nickname:shownName,avatar:avatarValue()})}<div><h2 style="margin:0">${uiText('Profile')}</h2><div class="date">${uiText('Professional profile: saved locally first, checked with server after save.')}</div></div></div></div><label>${uiText('Name')}</label><div class="profileNameLockBox"><input id="profName" class="profileNameInput" value="${esc(shownName)}" autocomplete="nickname" ${locked?'readonly':''} oninput="ITH.checkProfileNameLiveV249246&&ITH.checkProfileNameLiveV249246(false)" onblur="ITH.checkProfileNameLiveV249246&&ITH.checkProfileNameLiveV249246(true)"><span class="nameLockBadge">${locked?'🔒 '+uiText('Name locked'):'🔓 '+uiText('Name ready to lock')}</span></div><div class="profileNameNote">${locked?uiText('This name is locked on this device. Unlock only if you really want to change it.'):uiText('Write your name and press Save. The app checks immediately if the name already exists and suggests another.')}</div><div id="profileNameLiveStatus" class="profileNameLiveStatusV249246" style="display:none"></div><div class="row avatarToolsClean"><button class="btn" onclick="ITH.avatarPick('camera')">📷 ${uiText('Camera')}</button><button class="btn" onclick="ITH.avatarPick('file')">🖼️ ${uiText('Photo')}</button><button class="btn" onclick="ITH.showAnimals()">🐾 ${uiText('Avatar')}</button>${locked?`<button class="btn danger" onclick="return ITH.unlockProfileNameChange()">🔓 ${uiText('Unlock name')}</button>`:''}</div><div id="animalBox" class="row animalClean" style="display:none">${animals.map(a=>`<button class="btn" onclick="ITH.setAnimal('${a}')">${a}</button>`).join('')}</div><label class="card row cleanCheck"><input id="age16" type="checkbox" ${state.age16?'checked':''}><span>${uiText('I am over 16 years old.')}</span></label><div class="card row legalAcceptRow cleanCheck"><label class="row legalAcceptCheck"><input id="policyOk" type="checkbox" ${state.policyOk?'checked':''}><span>${uiText('I agree to the policy and terms of use.')}</span></label><button class="btn" type="button" onclick="return ITH.openLegalPolicy()">${uiText('Read policy')}</button></div><div class="row saveProfileRow"><button class="btn gold" onclick="return ITH.saveProfile()">💾 ${uiText('Save and lock name')}</button><span class="date">${uiText('Profile is kept on this device even if server is offline.')}</span></div><div id="profileSaveNotice" class="profileSaveNotice" style="display:none"></div></div><section class="card profilePanelClean"><button class="profilePanelToggle" onclick="return ITH.toggleProfilePanel('language')"><span>🌐 ${uiText('Menu language')} / ${uiText('Content translation')}</span><b>${langOpen?'▲':'▼'}</b></button><div class="profilePanelBody" style="display:${langOpen?'grid':'none'}"><div class="row"><button class="btn ${uiLang()==='en'?'green':''}" onclick="ITH.setUiLang('en')">English</button><button class="btn ${uiLang()==='el'?'green':''}" onclick="ITH.setUiLang('el')">Ελληνικά</button></div><div class="row"><button class="btn" onclick="ITH.toggleAutoTranslate()">Auto: ${autoTranslateOn()?'ON':'OFF'}</button><button class="btn" onclick="ITH.setTargetLang('auto')">${uiText('Auto Greek ↔ English')}</button></div><div class="date">${uiText('Menu language is separate from message translation.')}</div></div></section><section class="card profilePanelClean notificationPanelPro"><button class="profilePanelToggle" onclick="return ITH.toggleProfilePanel('notifications')"><span>🔔 ${uiText('Notifications and app sleep')}</span><b>${notifOpen?'▲':'▼'}</b></button><div class="profilePanelBody notificationModeGrid" style="display:${notifOpen?'grid':'none'}">${notificationChoice('open_only','📱','Notifications only while the app is open. Best battery saving, but no closed-app alerts.')}${notificationChoice('fcm','🔔','The app can sleep. Firebase/FCM wakes notifications when configured.')}${notificationChoice('stay_awake','🟢','Keeps an active foreground connection. Faster, but uses more battery.')}${notificationChoice('hybrid','🔔🟢','Recommended: active when open, FCM fallback when the app sleeps.')}</div></section><section class="card profilePanelClean"><button class="profilePanelToggle" onclick="return ITH.toggleProfilePanel('safety')"><span>🛡️ ${uiText('Permissions')} / ${uiText('Protection')}</span><b>${safeOpen?'▲':'▼'}</b></button><div class="profilePanelBody" style="display:${safeOpen?'grid':'none'}"><div class="grid"><button class="tile" onclick="ITH.openPermissionsPanel()"><b>🔔</b>${uiText('Permissions')}</button><button class="tile" onclick="ITH.openServerDataPanel()"><b>🗄️</b>${uiText('What the server keeps')}</button><button class="tile ${stayConnectedOn()?'green':''}" onclick="ITH.toggleStayConnected()"><b>🔌</b>${stayConnectedOn()?uiText('Stay connected: ON'):uiText('Stay connected: OFF')}</button></div></div></section><section class="card profilePanelClean"><button class="profilePanelToggle" onclick="return ITH.toggleProfilePanel('tools')"><span>⚙️ ${uiText('Profile tools')}</span><b>${toolsOpen?'▲':'▼'}</b></button><div class="profilePanelBody" style="display:${toolsOpen?'grid':'none'}"><div class="grid"><button class="tile" data-r10f26-account="1"><b>💾</b>${uiText('Save account')}</button><button class="tile" onclick="ITH.openSavedPostsPanel()"><b>💾</b>${uiText('My saved items')}</button><button class="tile danger" onclick="ITH.deleteAccountData()"><b>🗑️</b>${uiText('Delete account')}</button></div><div class="card blockedClean"><b>${uiText('Blocked')}</b><div class="row">${b.map(p=>`<span class="btn">${esc(p.nickname)} <button class="icon small" onclick="ITH.unblock('${esc(p.id)}')">↩</button></span>`).join('')||`<span class="date">${uiText('No blocked members.')}</span>`}</div></div></div></section></div>`}
function toggleGear(){state.gearOpen=!state.gearOpen;renderProfile()}
function showAnimals(){const a=$('animalBox');if(a)a.style.display=a.style.display==='none'?'flex':'none'}
function setAnimal(a){state.avatar='';state.animal=a;persistProfile();renderProfile();renderHome()}
function avatarPick(mode){let inp=$('profileAvatarFileV249512');if(!inp){inp=document.createElement('input');inp.id='profileAvatarFileV249512';inp.type='file';inp.setAttribute('data-profile-avatar-only-v249512','1');inp.className='hiddenInput';inp.style.cssText='position:fixed;left:-10000px;top:-10000px;width:1px;height:1px;opacity:0;pointer-events:none';document.body.appendChild(inp)}inp.value='';inp.accept='image/*';if(mode==='camera')inp.setAttribute('capture','environment');else inp.removeAttribute('capture');inp.onchange=(ev)=>{try{ev&&ev.stopPropagation&&ev.stopPropagation();ev&&ev.stopImmediatePropagation&&ev.stopImmediatePropagation()}catch(e){}inp.removeAttribute('capture');const f=inp.files?.[0];if(!f)return false;const r=new FileReader();r.onload=()=>{state.avatar=String(r.result||'');persistProfile();heartbeat();renderProfile();renderHome();try{document.documentElement.setAttribute('data-profile-avatar-v249512','saved-only-profile')}catch(e){};toast(uiLang()==='en'?'Profile photo updated. Press Save to confirm.':'Η φωτογραφία προφίλ ενημερώθηκε. Πάτησε Αποθήκευση για επιβεβαίωση.')};r.onerror=()=>toast(uiLang()==='en'?'The profile photo could not be read.':'Δεν διαβάστηκε η φωτογραφία προφίλ.');r.readAsDataURL(f);return false};inp.click();return false}
function persistProfile(){localStorage.setItem('ith_name',state.name);localStorage.setItem('ith_avatar',state.avatar);localStorage.setItem('ith_animal',state.animal);localStorage.setItem('ith_age16',state.age16?'1':'0');localStorage.setItem('ith_policy_ok',state.policyOk?'1':'0')}
function saveProfile(){
  const inputName=($('profName')?.value||'').trim()||'Μέλος';
  const lockedName=profileNameLockValue();
  if(lockedName&&inputName!==lockedName){toast('Ξεκλείδωσε το όνομα πριν το αλλάξεις.',6500);return false}
  state.name=inputName;
  state.age16=!!$('age16')?.checked;
  state.policyOk=!!$('policyOk')?.checked;
  if(!state.age16||!state.policyOk){toast('Χρειάζεται επιβεβαίωση ηλικίας και αποδοχή πολιτικής.',6500);return false}
  persistProfile();
  try{
    localStorage.setItem('ith_registered_member_v249154','1');
    localStorage.setItem('ith_profile_name_locked_v249164',state.name);
    localStorage.setItem('ith_profile_name_pending_sync','1');
    localStorage.setItem('ith_profile_name_pending_at',String(Date.now()));
    localStorage.setItem('ith_ui_lang_v249141',(typeof uiLang==='function'?uiLang():'el'));
    localStorage.setItem('ith_ui_lang',(typeof uiLang==='function'?uiLang():'el'));
  }catch(e){}
  renderProfile();
  const msg='Το όνομα αποθηκεύτηκε στη συσκευή. Θα γίνει έλεγχος διαθεσιμότητας και συγχρονισμός με τον server. Αν δεν χρησιμοποιείται ήδη, θα ενεργοποιηθεί στο προφίλ σας σε λίγο.';
  try{const n=$('profileSaveNotice');if(n){n.style.display='block';n.innerHTML=`<b>✅ Το προφίλ αποθηκεύτηκε</b><br>${esc(msg)}<br><small>Κατάσταση: γίνεται συγχρονισμός...</small>`}}catch(e){}
  toast(msg,9500);
  syncProfileNow(true).then(()=>{
    try{const n=$('profileSaveNotice');if(n){n.style.display='block';n.innerHTML='<b>✅ Το προφίλ είναι ενεργό</b><br>Το όνομα αποθηκεύτηκε και συγχρονίστηκε με τον server.'}}catch(e){}
    toast('Το προφίλ ενεργοποιήθηκε στον server.',4500);
    renderProfile();
  }).catch((e)=>{
    try{const n=$('profileSaveNotice');if(n){n.style.display='block';n.innerHTML='<b>ℹ️ Το προφίλ έμεινε στη συσκευή</b><br>Ο συγχρονισμός θα ξαναδοκιμάσει όταν η σύνδεση σταθεροποιηθεί.'}}catch(_){}
  });
  return false;
}
function backup(){const data={version:VERSION,device:state.device,room:state.room,name:state.name,avatar:state.avatar,animal:state.animal,age16:state.age16,policyOk:state.policyOk};const a=document.createElement('a');a.href=URL.createObjectURL(new Blob([JSON.stringify(data,null,2)],{type:'application/json'}));a.download='ithaki_account.json';a.click();toast('Save the file outside the phone')}
function restore(){const inp=$('globalFile');inp.value='';inp.accept='.json,application/json';inp.onchange=async()=>{try{const o=JSON.parse(await inp.files[0].text());state.name=o.name||state.name;state.avatar=o.avatar||'';state.animal=o.animal||state.animal;state.age16=!!o.age16;state.policyOk=!!o.policyOk;persistProfile();renderProfile();heartbeat();toast('Recovery complete')}catch{toast('Could not read')}};inp.click()}
function follow(id){let a=[];try{a=JSON.parse(localStorage.getItem('ith_following')||'[]')}catch{}if(!a.includes(id))a.push(id);localStorage.setItem('ith_following',JSON.stringify(a));toast('Following')}
function block(id){const a=blocked();if(!a.includes(String(id)))a.push(String(id));saveBlocked(a);state.people.delete(id);$('memberMenu').classList.remove('show');renderHome();renderPeople();toast('Block')}
function unblock(id){saveBlocked(blocked().filter(x=>x!==String(id)));renderProfile();loadPeople();toast('Unblock')}
function report(id){toast('Anonymous report sent')}
function copyShareFallback(finalUrl,text=''){const out=((text||'')+' '+finalUrl).trim();try{if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(out).then(()=>toast(uiText('Active link copied'))).catch(()=>toast(finalUrl,7000));return true}}catch{}try{const ta=document.createElement('textarea');ta.value=out;ta.style.position='fixed';ta.style.left='-9999px';document.body.appendChild(ta);ta.focus();ta.select();const ok=document.execCommand&&document.execCommand('copy');ta.remove();toast(ok?uiText('Active link copied'):finalUrl,ok?2800:7000);return ok}catch{toast(finalUrl,7000);return false}}
function androidShareUrl(finalUrl,text=''){try{const r=bridgeCall('shareUrl',finalUrl,text||'OK ITHAKI');return String(r||'').toLowerCase().startsWith('ok')}catch{return false}}
function share(url,text=''){if(window.__ITHAKI_V249523_SHARE_READY__&&window.ITH&&typeof ITH.share==='function'&&ITH.share!==share)return ITH.share(url,text);let finalUrl=String(url||shareSiteBase());try{if(finalUrl.startsWith('/'))finalUrl=new URL(finalUrl,shareSiteBase()).toString()}catch{}const payload={title:'OK ITHAKI',text:text||uiText('If the app is not installed, this active link opens the OK ITHAKI site.'),url:finalUrl};if(androidShareUrl(finalUrl,payload.text))return false;try{if(navigator.share){Promise.resolve(navigator.share(payload)).catch(()=>copyShareFallback(finalUrl,payload.text));return false}}catch{}copyShareFallback(finalUrl,payload.text);return false}

Object.assign(ITH_UI_EN,{
'Anonymous post':'Anonymous post','Anonymous':'Anonymous','Member media center':'Member media center','Photos, videos, files':'Photos, videos, files','My media and files':'My media and files','Upload, open saved items and manage your local member media from one active center.':'Upload, open saved items and manage your local member media from one active center.','Saved':'Saved','Photos on screen':'Photos on screen','Videos on screen':'Videos on screen','Upload photo':'Upload photo','Upload video':'Upload video','Upload file':'Upload file','Voted':'Voted','members':'members','options':'options','anonymous':'anonymous','with profile':'with profile','Professional protection for clean communication':'Professional protection for clean communication'});
Object.assign(ITH_UI_EL,{
'Anonymous post':'Ανώνυμη δημοσίευση','Anonymous':'Ανώνυμα','Member media center':'Κέντρο μίντια μέλους','Photos, videos, files':'Φωτογραφίες, βίντεο, αρχεία','My media and files':'Τα μίντια και τα αρχεία μου','Upload, open saved items and manage your local member media from one active center.':'Ανέβασε, άνοιξε αποθηκευμένα και διαχειρίσου τα μίντια του μέλους από ένα ενεργό κέντρο.','Saved':'Αποθηκευμένα','Photos on screen':'Φωτογραφίες στην οθόνη','Videos on screen':'Βίντεο στην οθόνη','Upload photo':'Ανέβασμα φωτογραφίας','Upload video':'Ανέβασμα βίντεο','Upload file':'Ανέβασμα αρχείου','Voted':'Ψήφισαν','members':'μέλη','options':'επιλογές','anonymous':'ανώνυμα','with profile':'με προφίλ','Professional protection for clean communication':'Επαγγελματική προστασία και καθαρή επικοινωνία','Contact server':'Κέντρο μίντια μέλους','Contact the server':'Κέντρο μίντια μέλους'});
Object.assign(ITH_UI_EN,{'Screen appearance':'Screen appearance','Automatic':'Automatic','Automatic screen theme':'Automatic screen theme','Morning · Mountain':'Morning · Mountain','Midday · Sea':'Midday · Sea','Afternoon · Sunset':'Afternoon · Sunset','Night':'Night','Automatic changes the screen by local time without changing any app function.':'Automatic changes the screen by local time without changing any app function.','Changes automatically by time':'Changes automatically by time'});
Object.assign(ITH_UI_EL,{'Screen appearance':'Εμφάνιση οθόνης','Automatic':'Αυτόματο','Automatic screen theme':'Αυτόματο θέμα οθόνης','Morning · Mountain':'Πρωί · Βουνό','Midday · Sea':'Μεσημέρι · Θάλασσα','Afternoon · Sunset':'Απόγευμα · Ηλιοβασίλεμα','Night':'Βράδυ','Automatic changes the screen by local time without changing any app function.':'Η οθόνη αλλάζει αυτόματα με την τοπική ώρα, χωρίς να αλλάζει καμία λειτουργία.','Changes automatically by time':'Αλλάζει αυτόματα ανάλογα με την ώρα'});
Object.assign(ITH_UI_EN,{'Outdoor · Sun':'Outdoor · Sun','High contrast for sun/outside':'High contrast for sun/outside','Sun/outside screen':'Sun/outside screen'});
Object.assign(ITH_UI_EL,{'Outdoor · Sun':'Ήλιος · Έξω','High contrast for sun/outside':'Υψηλή αντίθεση για ήλιο/έξω','Sun/outside screen':'Οθόνη για ήλιο/έξω'});
Object.assign(ITH_UI_EN,{'Policy & terms':'Policy & terms','Read policy':'Read policy','Accept policy':'Accept policy','Policy accepted':'Policy accepted','I agree to the policy and terms of use.':'I agree to the policy and terms of use.','Travel together with us, humanly, freely, anonymously.':'Travel with us, humanly, freely, anonymously.'});
Object.assign(ITH_UI_EL,{'Policy & terms':'Πολιτική & όροι','Read policy':'Πολιτική','Accept policy':'Αποδοχή πολιτικής','Policy accepted':'Η πολιτική έγινε αποδεκτή','I agree to the policy and terms of use.':'Συμφωνώ με την πολιτική και τους όρους χρήσης.','Travel together with us, humanly, freely, anonymously.':'Ταξιδέψτε μαζί μας ανθρώπινα, ελεύθερα, ανώνυμα.'});
Object.assign(ITH_UI_EN,{'ITHAKI Studio':'ITHAKI Studio','External editor module connected to this preview.':'External editor module connected to this preview.','Tap on the image to move the text.':'Tap on the image to move the text.','Studio':'Studio','Text':'Text','Write text on media...':'Write text on media...','Text size':'Text size','Text color':'Text color','Transparency':'Transparency','Look':'Look','Normal':'Normal','Vivid':'Vivid','Soft':'Soft','Warm':'Warm','Cool':'Cool','Black and white':'Black and white','Brightness':'Brightness','Contrast':'Contrast','Color strength':'Color strength','Frame':'Frame','None':'None','Clean white':'Clean white','Gold':'Gold','Film':'Film','Glass':'Glass','Story':'Story','Design':'Design','Collage':'Collage','Two side by side':'Two side by side','Two vertical':'Two vertical','Small picture inside':'Small picture inside','Audio':'Audio','Keep original':'Keep original','Mute':'Mute','Replace with selected audio':'Replace with selected audio','Collage photo':'Collage photo','Audio file':'Audio file','Bright':'Bright','Cinema':'Cinema','Render video':'Render video','Apply design':'Apply design','Video render may take as long as the video duration.':'Video render may take as long as the video duration.','Ready to create a new edited file.':'Ready to create a new edited file.','Creating edited photo...':'Creating edited photo...','Edited photo is ready.':'Edited photo is ready.','Rendering video...':'Rendering video...','Edited video is ready.':'Edited video is ready.','Studio works for photos and videos.':'Studio works for photos and videos.'});
Object.assign(ITH_UI_EL,{'ITHAKI Studio':'ITHAKI Studio','External editor module connected to this preview.':'Εξωτερικό εργαλείο επεξεργασίας συνδεδεμένο με αυτή την προεπισκόπηση.','Tap on the image to move the text.':'Πάτα πάνω στην εικόνα για να μετακινήσεις τα γράμματα.','Studio':'Studio','Text':'Κείμενο','Write text on media...':'Γράψε πάνω στη φωτογραφία ή στο βίντεο...','Text size':'Μέγεθος γραμμάτων','Text color':'Χρώμα γραμμάτων','Transparency':'Διαφάνεια','Look':'Ύφος','Normal':'Κανονικό','Vivid':'Ζωντανό','Soft':'Απαλό','Warm':'Ζεστό','Cool':'Δροσερό','Black and white':'Ασπρόμαυρο','Brightness':'Φωτεινότητα','Contrast':'Αντίθεση','Color strength':'Δύναμη χρώματος','Frame':'Κορνίζα','None':'Καμία','Clean white':'Καθαρή λευκή','Gold':'Χρυσή','Film':'Φιλμ','Glass':'Γυάλινη','Story':'Story','Design':'Σχέδιο','Collage':'Κολάζ','Two side by side':'Δύο δίπλα δίπλα','Two vertical':'Δύο κάθετα','Small picture inside':'Μικρή εικόνα μέσα','Audio':'Ήχος','Keep original':'Κράτα τον αρχικό','Mute':'Χωρίς ήχο','Replace with selected audio':'Αλλαγή με επιλεγμένο ήχο','Collage photo':'Φωτογραφία κολάζ','Audio file':'Αρχείο ήχου','Bright':'Φωτεινό','Cinema':'Σινεμά','Render video':'Φτιάξε βίντεο','Apply design':'Εφαρμογή σχεδίου','Video render may take as long as the video duration.':'Το φτιάξιμο βίντεο μπορεί να κρατήσει όσο κρατάει το βίντεο.','Ready to create a new edited file.':'Έτοιμο να δημιουργήσει νέο επεξεργασμένο αρχείο.','Creating edited photo...':'Δημιουργία επεξεργασμένης φωτογραφίας...','Edited photo is ready.':'Η επεξεργασμένη φωτογραφία είναι έτοιμη.','Rendering video...':'Δημιουργία βίντεο...','Edited video is ready.':'Το επεξεργασμένο βίντεο είναι έτοιμο.','Studio works for photos and videos.':'Το Studio δουλεύει για φωτογραφίες και βίντεο.'});

Object.assign(ITH_UI_EN,{
'Profile name saved locally. Availability check and server sync will run now. If the name is not already used, it will become active shortly.':'Profile name saved locally. Availability check and server sync will run now. If the name is not already used, it will become active shortly.',
'Profile sync check completed.':'Profile sync check completed.',
'Profile remains saved on this device. Server sync will retry when connection is stable.':'Profile remains saved on this device. Server sync will retry when connection is stable.',
'Opinion card':'Opinion card','We would be happy to hear your opinion.':'We would be happy to hear your opinion.',
'What do you suggest for ITHAKI? Choose an idea, add your thought, or open a professional poll for the community.':'What do you suggest for ITHAKI? Choose an idea, add your thought, or open a professional poll for the community.',
'Create professional poll':'Create professional poll','Wisdom card':'Wisdom card',
'Ancient and modern voices appear inside the feed as clean professional cards, without hiding the posts.':'Ancient and modern voices appear inside the feed as clean professional cards, without hiding the posts.'
});
Object.assign(ITH_UI_EL,{
'Profile name saved locally. Availability check and server sync will run now. If the name is not already used, it will become active shortly.':'Το όνομα αποθηκεύτηκε στη συσκευή. Θα γίνει έλεγχος διαθεσιμότητας και συγχρονισμός με τον server. Αν δεν χρησιμοποιείται ήδη, θα ενεργοποιηθεί στο προφίλ σας σε λίγο.',
'Profile sync check completed.':'Ο έλεγχος συγχρονισμού προφίλ ολοκληρώθηκε.',
'Profile remains saved on this device. Server sync will retry when connection is stable.':'Το προφίλ παραμένει αποθηκευμένο στη συσκευή. Ο συγχρονισμός με τον server θα ξαναδοκιμάσει όταν η σύνδεση είναι σταθερή.',
'Opinion card':'Κάρτα γνώμης','We would be happy to hear your opinion.':'Θα χαρούμε να ακούσουμε τη γνώμη σας.',
'What do you suggest for ITHAKI? Choose an idea, add your thought, or open a professional poll for the community.':'Τι προτείνετε για την ΙΘΑΚΗ; Διαλέξτε ιδέα, γράψτε σκέψη ή ανοίξτε επαγγελματική ψηφοφορία για την κοινότητα.',
'Create professional poll':'Δημιουργία επαγγελματικής ψηφοφορίας','Wisdom card':'Κάρτα σοφού λόγου',
'Ancient and modern voices appear inside the feed as clean professional cards, without hiding the posts.':'Αρχαίοι και νεότεροι στοχαστές εμφανίζονται στη ροή σε καθαρές επαγγελματικές κάρτες, χωρίς να κρύβουν τις δημοσιεύσεις.'
});


Object.assign(ITH_UI_EN,{
'Professional profile: saved locally first, checked with server after save.':'Professional profile: saved locally first, checked with server after save.','Name locked':'Name locked','Name ready to lock':'Name ready to lock','Unlock name':'Unlock name','Save and lock name':'Save and lock name','This name is locked on this device. Unlock only if you really want to change it.':'This name is locked on this device. Unlock only if you really want to change it.','Write your name and press Save. The app saves it locally and then checks availability with the server.':'Write your name and press Save. The app saves it locally and then checks availability with the server.','Name change unlocked. Save again to lock the new name.':'Name change unlocked. Save again to lock the new name.','Unlock the name before changing it.':'Unlock the name before changing it.','The name was saved on this device. Availability check and server sync will run shortly. If the name is not already used, it will be activated in your profile soon.':'The name was saved on this device. Availability check and server sync will run shortly. If the name is not already used, it will be activated in your profile soon.','Profile saved':'Profile saved','Notifications and app sleep':'Notifications and app sleep','Only when the app is open':'Only when the app is open','FCM — sleeps and notifies':'FCM — sleeps and notifies','Active program — does not sleep':'Active program — does not sleep','Smart — FCM + active connection':'Smart — FCM + active connection','Notifications only while the app is open. Best battery saving, but no closed-app alerts.':'Notifications only while the app is open. Best battery saving, but no closed-app alerts.','The app can sleep. Firebase/FCM wakes notifications when configured.':'The app can sleep. Firebase/FCM wakes notifications when configured.','Keeps an active foreground connection. Faster, but uses more battery.':'Keeps an active foreground connection. Faster, but uses more battery.','Recommended: active when open, FCM fallback when the app sleeps.':'Recommended: active when open, FCM fallback when the app sleeps.','Choose how OK ITHAKI notifies you. FCM is optional and only works after Firebase credentials are configured in the APK and server.':'Choose how OK ITHAKI notifies you. FCM is optional and only works after Firebase credentials are configured in the APK and server.','Manual token registration is only for testing.':'Manual token registration is only for testing.','Professional opinion card':'Professional opinion card','Better full-screen video feed':'Better full-screen video feed','Cleaner messages and media':'Cleaner messages and media','More local server tools':'More local server tools','Stronger privacy controls':'Stronger privacy controls','Opinion':'Opinion','What is your opinion?':'What is your opinion?','Vote':'Vote','Voted':'Voted','members':'members','This publication was already sent. Duplicate blocked.':'This publication was already sent. Duplicate blocked.','Media post':'Media post','Loading member publications...':'Loading member publications...','Choose a small video, text, card or file. After selection, the feed shows only this member until you press the back arrow.':'Choose a small video, text, card or file. After selection, the feed shows only this member until you press the back arrow.','Member publications are not loading.':'Member publications are not loading.'});
Object.assign(ITH_UI_EL,{
'Professional profile: saved locally first, checked with server after save.':'Επαγγελματικό προφίλ: αποθηκεύεται πρώτα στη συσκευή και μετά ελέγχεται στον server.','Name locked':'Το όνομα κλειδώθηκε','Name ready to lock':'Το όνομα είναι έτοιμο για κλείδωμα','Unlock name':'Ξεκλείδωμα ονόματος','Save and lock name':'Αποθήκευση και κλείδωμα ονόματος','This name is locked on this device. Unlock only if you really want to change it.':'Αυτό το όνομα είναι κλειδωμένο σε αυτή τη συσκευή. Ξεκλειδώστε το μόνο αν θέλετε πραγματικά να το αλλάξετε.','Write your name and press Save. The app saves it locally and then checks availability with the server.':'Γράψτε το όνομα και πατήστε Αποθήκευση. Η εφαρμογή το αποθηκεύει τοπικά και μετά ελέγχει διαθεσιμότητα με τον server.','Name change unlocked. Save again to lock the new name.':'Η αλλαγή ονόματος ξεκλειδώθηκε. Αποθηκεύστε ξανά για να κλειδώσει το νέο όνομα.','Unlock the name before changing it.':'Ξεκλειδώστε πρώτα το όνομα για να το αλλάξετε.','The name was saved on this device. Availability check and server sync will run shortly. If the name is not already used, it will be activated in your profile soon.':'Το όνομα αποθηκεύτηκε στη συσκευή. Θα γίνει έλεγχος διαθεσιμότητας και συγχρονισμός με τον server. Αν δεν χρησιμοποιείται ήδη, θα ενεργοποιηθεί στο προφίλ σας σε λίγο.','Profile saved':'Το προφίλ αποθηκεύτηκε','Notifications and app sleep':'Ειδοποιήσεις και ύπνος εφαρμογής','Only when the app is open':'Μόνο όταν έχω ανοιχτή την εφαρμογή','FCM — sleeps and notifies':'FCM — κοιμάται και ειδοποιεί','Active program — does not sleep':'Ενεργό πρόγραμμα — δεν κοιμάται','Smart — FCM + active connection':'Έξυπνο — FCM + ενεργή σύνδεση','Notifications only while the app is open. Best battery saving, but no closed-app alerts.':'Ειδοποιήσεις μόνο όταν η εφαρμογή είναι ανοιχτή. Καλύτερη οικονομία μπαταρίας, αλλά όχι ειδοποίηση με κλειστή εφαρμογή.','The app can sleep. Firebase/FCM wakes notifications when configured.':'Η εφαρμογή μπορεί να κοιμάται. Το Firebase/FCM φέρνει ειδοποιήσεις όταν ρυθμιστεί.','Keeps an active foreground connection. Faster, but uses more battery.':'Κρατά ενεργή σύνδεση στο προσκήνιο. Πιο γρήγορο, αλλά καταναλώνει περισσότερη μπαταρία.','Recommended: active when open, FCM fallback when the app sleeps.':'Προτεινόμενο: ενεργό όταν είναι ανοιχτό, FCM όταν η εφαρμογή κοιμηθεί.','Choose how OK ITHAKI notifies you. FCM is optional and only works after Firebase credentials are configured in the APK and server.':'Διαλέξτε πώς θα σας ειδοποιεί η OK ITHAKI. Το FCM είναι προαιρετικό και δουλεύει μόνο αφού ρυθμιστούν Firebase στοιχεία στο APK και στον server.','Manual token registration is only for testing.':'Η χειροκίνητη καταχώρηση token είναι μόνο για δοκιμή.','Professional opinion card':'Επαγγελματική κάρτα γνώμης','Better full-screen video feed':'Καλύτερη ροή βίντεο πλήρους οθόνης','Cleaner messages and media':'Πιο καθαρά μηνύματα και media','More local server tools':'Περισσότερα εργαλεία τοπικού server','Stronger privacy controls':'Ισχυρότεροι έλεγχοι ιδιωτικότητας','Opinion':'Γνώμη','What is your opinion?':'Ποια είναι η γνώμη σας;','Vote':'Ψήφος','Voted':'Ψήφισαν','members':'μέλη','This publication was already sent. Duplicate blocked.':'Αυτή η δημοσίευση έχει ήδη σταλεί. Η διπλοεγγραφή μπλοκαρίστηκε.','Media post':'Δημοσίευση media','Loading member publications...':'Φόρτωση δημοσιεύσεων μέλους...','Choose a small video, text, card or file. After selection, the feed shows only this member until you press the back arrow.':'Διαλέξτε μικρό βίντεο, λόγια, κάρτα ή αρχείο. Μετά την επιλογή, η ροή δείχνει μόνο αυτό το μέλος μέχρι να πατήσετε το βελάκι πίσω.','Member publications are not loading.':'Οι δημοσιεύσεις του μέλους δεν φορτώνουν.'});


Object.assign(ITH_UI_EN,{
'Choose where to go from the clean start screen.':'Choose where to go from the clean start screen.',
'Full-screen videos, photos and words':'Full-screen videos, photos and words',
'Server connection active':'Server connection active',
'No server connection':'No server connection',
'Only this member':'Only this member',
'Loading member feed...':'Loading member feed...',
'No posts found.':'No posts found.',
'Member feed is not loading.':'Member feed is not loading.',
'Back':'Back'
});
Object.assign(ITH_UI_EL,{
'Choose where to go from the clean start screen.':'Διάλεξε καθαρά από πού θέλεις να ξεκινήσεις.',
'Full-screen videos, photos and words':'Βίντεο πλήρους οθόνης, φωτογραφίες και λόγια',
'Server connection active':'Σύνδεση server ενεργή',
'No server connection':'Δεν υπάρχει σύνδεση με server',
'Only this member':'Μόνο αυτό το μέλος',
'Loading member feed...':'Φόρτωση ροής μέλους...',
'No posts found.':'Δεν βρέθηκαν δημοσιεύσεις.',
'Member feed is not loading.':'Η ροή του μέλους δεν φορτώνει.',
'Back':'Πίσω',
'Welcome to':'Καλώς ήρθατε στην',
'Travel together with us, humanly, freely, anonymously.':'Ταξιδεύουμε μαζί ανθρώπινα, ελεύθερα και ανώνυμα.',
'Rooms / communities':'Δωμάτια / κοινότητες',
'Notification center':'Κέντρο ειδοποιήσεων',
'Open contact':'Άνοιγμα επικοινωνίας',
'ITHAKI Host':'Οικοδεσπότης ΙΘΑΚΗΣ',
'Post':'Δημοσίευση',
'Poll':'Ψηφοφορία'
});

/* V249169 Greek completion translations */

Object.assign(ITH_UI_EL,{
'Server test OK':'Έλεγχος server ΟΚ',
'server test failed':'Ο έλεγχος server απέτυχε',
'Start the conversation.':'Ξεκίνησε τη συζήτηση.',
'Messages are not loading:':'Τα μηνύματα δεν φορτώνουν:',
'Start the space.':'Ξεκίνησε το δωμάτιο.',
'Space messages are not loading.':'Τα μηνύματα του χώρου δεν φορτώνουν.',
'Choose a space':'Διάλεξε χώρο',
'Delete post?':'Να διαγραφεί η δημοσίευση;',
'Deleted':'Διαγράφηκε',
'Cannot delete':'Δεν μπορεί να γίνει διαγραφή',
'Member':'Μέλος',
'Profile':'Προφίλ',
'Feed':'Ροή',
'Post':'Δημοσίευση',
'Messages':'Μηνύματα',
'Spaces':'Δωμάτια',
'Poll':'Ψηφοφορία',
'Open':'Άνοιγμα',
'Download':'Λήψη',
'Share':'Κοινοποίηση',
'Posted':'Δημοσιεύτηκε',
'Write text':'Γράψε κείμενο',
'This publication was already sent. Duplicate blocked.':'Αυτή η δημοσίευση έχει ήδη σταλεί. Η διπλή εγγραφή μπλοκαρίστηκε.',
'Save and lock name':'Αποθήκευση και κλείδωμα ονόματος',
'Profile saved':'Το προφίλ αποθηκεύτηκε',
'Name locked':'Το όνομα κλειδώθηκε',
'Unlock name':'Ξεκλείδωμα ονόματος',
'Name ready to lock':'Το όνομα είναι έτοιμο για κλείδωμα',
'Professional profile: saved locally first, checked with server after save.':'Επαγγελματικό προφίλ: αποθήκευση πρώτα στη συσκευή και μετά έλεγχος server.',
'Profile is kept on this device even if server is offline.':'Το προφίλ μένει στη συσκευή ακόμη κι αν ο server είναι εκτός.',
'The name was saved on this device. Availability check and server sync will run shortly. If the name is not already used, it will be activated in your profile soon.':'Το όνομα αποθηκεύτηκε στη συσκευή. Θα γίνει έλεγχος διαθεσιμότητας και συγχρονισμός με τον server. Αν δεν χρησιμοποιείται ήδη, θα ενεργοποιηθεί στο προφίλ σας σε λίγο.'
});


/* V249169 final Greek/English home and call translations */
Object.assign(ITH_UI_EN,{
'Τα avatar θα εμφανίζονται εδώ μόλις έρθουν φρέσκα προφίλ από τον server.':'Avatars will appear here when fresh profiles arrive from the server.',
'Avatar μελών':'Member avatars',
'Μέλος':'Member',
'Καλώς ήρθες στην':'Welcome to',
'ΙΘΑΚΗ':'ITHAKI',
'Ανθρώπινη επικοινωνία, καθαρή ροή, σεβασμός και ανωνυμία.':'Human communication, a clean feed, respect and anonymity.',
'Διάλεξε πού θέλεις να πας.':'Choose where you want to go.',
'Ροή':'Feed',
'Βίντεο, φωτογραφίες και λόγια':'Videos, photos and words',
'Δημοσίευση':'Post',
'Κείμενο, φωτογραφία, βίντεο ή αρχείο':'Text, photo, video or file',
'Μηνύματα':'Messages',
'Συνομιλίες και αρχεία':'Conversations and files',
'Δωμάτια / Κοινότητες':'Rooms / Communities',
'Ομάδες και χώροι συζήτησης':'Groups and discussion spaces',
'Ψηφοφορία':'Poll',
'Ρώτα γνώμη με καθαρή κάρτα':'Ask for opinions with a clean card',
'Προφίλ':'Profile',
'Όνομα, avatar, προστασία και ειδοποιήσεις':'Name, avatar, protection and notifications',
'Ερώτηση ΙΘΑΚΗΣ':'ITHAKI question',
'Σοφός λόγος':'Wise thought',
'Στατιστική καρτέλα':'Statistics card',
'Εσείς τι λέτε; Επιλέξτε μία απάντηση ή ανοίξτε συζήτηση.':'What do you think? Choose an answer or open a discussion.',
'Άνοιγμα ψηφοφορίας':'Open poll',
'Συζήτηση':'Discussion',
'Απάντηση':'Answer',
'Απόρριψη':'Reject',
'Τερματισμός κλήσης':'End call',
'Βιντεοκλήση':'Video call',
'Κλήση φωνής':'Voice call',
'Η κλήση τερματίστηκε':'Call ended',
'Συνδέθηκε':'Connected',
'Η σύνδεση κλήσης απέτυχε':'Call connection failed',
'Η κλήση αποσυνδέθηκε':'Call disconnected',
'Σύνδεση κλήσης...':'Connecting call...',
'Η κλήση δεν απαντήθηκε':'Call was not answered',
'Υπάρχει ήδη ενεργή κλήση.':'A call is already active.',
'Διαλέξτε πρώτα επαφή.':'Choose a contact first.',
'Κλήση σε εξέλιξη...':'Calling...',
'Εισερχόμενη κλήση':'Incoming call',
'Δεν στάλθηκε':'Not sent',
'Επιτρέψτε κάμερα και μικρόφωνο στις ρυθμίσεις Android.':'Allow camera and microphone in Android settings.',
'Επιτρέψτε μικρόφωνο στις ρυθμίσεις Android.':'Allow microphone in Android settings.'
});
Object.assign(ITH_UI_EL,{
'Τα avatar θα εμφανίζονται εδώ μόλις έρθουν φρέσκα προφίλ από τον server.':'Τα avatar θα εμφανίζονται εδώ μόλις έρθουν φρέσκα προφίλ από τον server.',
'Avatar μελών':'Avatar μελών',
'Μέλος':'Μέλος',
'Καλώς ήρθες στην':'Καλώς ήρθες στην',
'ΙΘΑΚΗ':'ΙΘΑΚΗ',
'Ανθρώπινη επικοινωνία, καθαρή ροή, σεβασμός και ανωνυμία.':'Ανθρώπινη επικοινωνία, καθαρή ροή, σεβασμός και ανωνυμία.',
'Διάλεξε πού θέλεις να πας.':'Διάλεξε πού θέλεις να πας.',
'Ροή':'Ροή',
'Βίντεο, φωτογραφίες και λόγια':'Βίντεο, φωτογραφίες και λόγια',
'Δημοσίευση':'Δημοσίευση',
'Κείμενο, φωτογραφία, βίντεο ή αρχείο':'Κείμενο, φωτογραφία, βίντεο ή αρχείο',
'Μηνύματα':'Μηνύματα',
'Συνομιλίες και αρχεία':'Συνομιλίες και αρχεία',
'Δωμάτια / Κοινότητες':'Δωμάτια / Κοινότητες',
'Ομάδες και χώροι συζήτησης':'Ομάδες και χώροι συζήτησης',
'Ψηφοφορία':'Ψηφοφορία',
'Ρώτα γνώμη με καθαρή κάρτα':'Ρώτα γνώμη με καθαρή κάρτα',
'Προφίλ':'Προφίλ',
'Όνομα, avatar, προστασία και ειδοποιήσεις':'Όνομα, avatar, προστασία και ειδοποιήσεις',
'Ερώτηση ΙΘΑΚΗΣ':'Ερώτηση ΙΘΑΚΗΣ',
'Σοφός λόγος':'Σοφός λόγος',
'Στατιστική καρτέλα':'Στατιστική καρτέλα',
'Εσείς τι λέτε; Επιλέξτε μία απάντηση ή ανοίξτε συζήτηση.':'Εσείς τι λέτε; Επιλέξτε μία απάντηση ή ανοίξτε συζήτηση.',
'Άνοιγμα ψηφοφορίας':'Άνοιγμα ψηφοφορίας',
'Συζήτηση':'Συζήτηση',
'Απάντηση':'Απάντηση',
'Απόρριψη':'Απόρριψη',
'Τερματισμός κλήσης':'Τερματισμός κλήσης',
'Βιντεοκλήση':'Βιντεοκλήση',
'Κλήση φωνής':'Κλήση φωνής',
'Η κλήση τερματίστηκε':'Η κλήση τερματίστηκε',
'Συνδέθηκε':'Συνδέθηκε',
'Η σύνδεση κλήσης απέτυχε':'Η σύνδεση κλήσης απέτυχε',
'Η κλήση αποσυνδέθηκε':'Η κλήση αποσυνδέθηκε',
'Σύνδεση κλήσης...':'Σύνδεση κλήσης...',
'Η κλήση δεν απαντήθηκε':'Η κλήση δεν απαντήθηκε',
'Υπάρχει ήδη ενεργή κλήση.':'Υπάρχει ήδη ενεργή κλήση.',
'Διαλέξτε πρώτα επαφή.':'Διαλέξτε πρώτα επαφή.',
'Κλήση σε εξέλιξη...':'Κλήση σε εξέλιξη...',
'Εισερχόμενη κλήση':'Εισερχόμενη κλήση',
'Δεν στάλθηκε':'Δεν στάλθηκε',
'Επιτρέψτε κάμερα και μικρόφωνο στις ρυθμίσεις Android.':'Επιτρέψτε κάμερα και μικρόφωνο στις ρυθμίσεις Android.',
'Επιτρέψτε μικρόφωνο στις ρυθμίσεις Android.':'Επιτρέψτε μικρόφωνο στις ρυθμίσεις Android.'
});


Object.assign(ITH_UI_EN,{
  'Welcome to ITHAKI':'Welcome to ITHAKI',
  'Human communication, clean flow, respect and anonymity.':'Human communication, clean flow, respect and anonymity.'
});
Object.assign(ITH_UI_EL,{
  'Welcome to ITHAKI':'Καλώς ήρθες στην ΙΘΑΚΗ',
  'Human communication, clean flow, respect and anonymity.':'Ανθρώπινη επικοινωνία, καθαρή ροή, σεβασμός και ανωνυμία.'
});


/* ITHAKI V249176 verified EL/EN home text additions */
try{
Object.assign(ITH_UI_EN,{
'Τα avatar θα εμφανίζονται εδώ μόλις έρθουν φρέσκα προφίλ από τον server.':'Fresh member avatars will appear here when the server sends new profiles.',
'Ανθρώπινη επικοινωνία, καθαρή ροή, σεβασμός και ανωνυμία.':'Human communication, a clean feed, respect and anonymity.',
'Ρώτα γνώμη με καθαρή κάρτα':'Ask for opinions with a clean card',
'Εσείς τι λέτε; Επιλέξτε μία απάντηση ή ανοίξτε συζήτηση.':'What do you think? Choose an answer or open a discussion.',
'Συμμετοχή':'Participation','Συζήτηση':'Discussion','Άνοιγμα ψηφοφορίας':'Open poll',
'Βίντεο, φωτογραφίες και λόγια':'Videos, photos and words',
'Κείμενο, φωτογραφία, βίντεο ή αρχείο':'Text, photo, video or file',
'Συνομιλίες και αρχεία':'Chats and files',
'Ομάδες και χώροι συζήτησης':'Groups and discussion spaces',
'Όνομα, avatar, προστασία και ειδοποιήσεις':'Name, avatar, protection and notifications'
});
Object.assign(ITH_UI_EL,{
'Human communication, a clean feed, respect and anonymity.':'Ανθρώπινη επικοινωνία, καθαρή ροή, σεβασμός και ανωνυμία.',
'Fresh member avatars will appear here when the server sends new profiles.':'Τα avatar θα εμφανίζονται εδώ μόλις έρθουν φρέσκα προφίλ από τον server.'
});
}catch(e){}


/* V249196 permission/comment labels */
Object.assign(ITH_UI_EN,{'Accept and save':'Accept and save','Check video call permissions':'Check video call permissions','Video call permissions':'Video call permissions','Camera and microphone before video call.':'Camera and microphone before video call.','Media permissions':'Media permissions','Photos, videos, audio and files.':'Photos, videos, audio and files.','Permissions saved':'Permissions saved','Video call permissions checked':'Video call permissions checked'});
Object.assign(ITH_UI_EL,{'Accept and save':'Αποδοχή και αποθήκευση','Check video call permissions':'Έλεγχος αδειών βιντεοκλήσης','Video call permissions':'Άδειες βιντεοκλήσης','Camera and microphone before video call.':'Κάμερα και μικρόφωνο πριν τη βιντεοκλήση.','Media permissions':'Άδειες αρχείων/media','Photos, videos, audio and files.':'Φωτογραφίες, βίντεο, ήχος και αρχεία.','Permissions saved':'Οι άδειες αποθηκεύτηκαν','Video call permissions checked':'Οι άδειες βιντεοκλήσης ελέγχθηκαν'});



/* V249210 professional member profile stats above member posts */
try{if(!document.getElementById('ithV249210MemberStatsCss')){const st=document.createElement('style');st.id='ithV249210MemberStatsCss';st.textContent=`
.memberProfileHeroV249210{margin:10px 10px 12px!important;padding:14px 13px 13px!important;border-radius:22px!important;background:linear-gradient(145deg,rgba(8,25,45,.96),rgba(7,15,28,.92))!important;border:1px solid rgba(255,215,110,.22)!important;box-shadow:0 16px 42px rgba(0,0,0,.24)!important;position:relative!important;overflow:hidden!important}
.memberProfileHeroV249210:before{content:"";position:absolute;inset:-40% -20% auto auto;width:160px;height:160px;background:radial-gradient(circle,rgba(255,215,110,.22),transparent 62%);pointer-events:none}
.memberHeroTopV249210{display:flex!important;align-items:center!important;gap:12px!important;position:relative!important;z-index:1!important}
.memberHeroAvatarV249210 .avatar,.memberHeroAvatarV249210 img.avatar{width:58px!important;height:58px!important;border-radius:50%!important;border:2px solid rgba(255,215,110,.62)!important;box-shadow:0 0 0 4px rgba(255,215,110,.10),0 10px 26px rgba(0,0,0,.30)!important;background:rgba(255,255,255,.08)!important;display:grid!important;place-items:center!important;font-size:26px!important;object-fit:cover!important}
.memberHeroNameV249210{min-width:0!important;text-align:left!important;flex:1!important}.memberHeroNameV249210 h2{margin:0!important;font-size:clamp(18px,5vw,24px)!important;line-height:1.05!important;color:#fff!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}.memberHeroOnlineV249210{display:inline-flex!important;align-items:center!important;gap:4px!important;margin-top:6px!important;font-size:12px!important;font-weight:800!important;color:rgba(255,255,255,.62)!important}.memberHeroOnlineV249210.on{color:#84ffbd!important}
.memberStatsRowV249210{display:grid!important;grid-template-columns:repeat(3,1fr)!important;gap:8px!important;margin-top:12px!important;position:relative!important;z-index:1!important}.memberStatV249210{padding:9px 6px!important;border-radius:16px!important;background:rgba(255,255,255,.075)!important;border:1px solid rgba(255,255,255,.11)!important;text-align:center!important;min-width:0!important}.memberStatV249210 b{display:block!important;font-size:clamp(17px,5vw,23px)!important;line-height:1!important;color:#ffd96e!important;font-weight:950!important}.memberStatV249210 span{display:block!important;margin-top:4px!important;font-size:11px!important;line-height:1.05!important;color:rgba(238,246,255,.82)!important;font-weight:850!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}.memberPostPicker{padding-bottom:84px!important}.memberThumbGrid{padding:0 10px 12px!important}.feedMemberLabel{margin:0 10px 8px!important}
@media(min-width:760px){.memberProfileHeroV249210{max-width:820px!important;margin:14px auto 14px!important;padding:18px 18px!important}.memberHeroAvatarV249210 .avatar,.memberHeroAvatarV249210 img.avatar{width:70px!important;height:70px!important}.memberStatsRowV249210{gap:12px!important}.memberStatV249210{padding:12px 8px!important}.memberStatV249210 span{font-size:12px!important}}
`;document.head.appendChild(st)}}catch(e){}

/* V249209 message presence, receipts and visible call status */
try{if(!document.getElementById('ithV249209Css')){const st=document.createElement('style');st.id='ithV249209Css';st.textContent='.readReceipt{display:inline-flex!important;align-items:center!important;gap:3px!important;margin-left:6px!important;padding:2px 6px!important;border-radius:999px!important;background:rgba(255,255,255,.08)!important;color:#dfe8ff!important;font-size:10.5px!important;font-weight:800!important}.readReceipt.delivered{color:#d8f8ff!important;background:rgba(80,190,255,.12)!important}.readReceipt.seen{color:#90ffbd!important;background:rgba(40,230,120,.13)!important}.typing.presenceOn{color:#8fffd1!important;font-weight:800!important}.typing.typingActive:before{content:"✍️ ";}.msgCallCard{border:1px solid rgba(255,215,0,.28)!important;background:linear-gradient(135deg,rgba(12,22,34,.95),rgba(52,34,10,.92))!important;border-radius:16px!important;padding:10px 12px!important}.callBox{box-shadow:0 24px 80px rgba(0,0,0,.58)!important}.callStatus{font-weight:900!important;color:#ffd36e!important}.memberMenu .tile b{font-size:26px!important;line-height:1!important}';document.head.appendChild(st)}}catch(e){}

/* V249209 message/call labels */
Object.assign(ITH_UI_EN,{'διαβάστηκε':'read','στάλθηκε':'sent','γράφει τώρα...':'is typing...','είναι μέσα στη συνομιλία':'is in the chat','Αναπάντητη κλήση':'Missed call','Απορρίφθηκε κλήση':'Call rejected','Απαντήθηκε κλήση':'Call answered','Τερματίστηκε κλήση':'Call ended','Τηλεφωνική κλήση':'Voice call','Βιντεοκλήση':'Video call'});


function friendRequestHtmlV249223(m){
  const from=esc(m.from_id||''), to=esc(m.to_id||''), eid=esc(m.event_id||'');
  const fromName=esc((state.people.get(m.from_id||'')||{}).nickname||m.from_name||'Μέλος');
  const body=esc(m.body||`${fromName} ζητά φιλία`);
  const mineTarget=String(m.to_id||'')===String(state.device);
  return `<div class="msgCallCard friendRequestCardV249223"><span class="msgCallIcon">🤝</span><span><b>Αίτημα φιλίας</b><small>${body}</small></span>${mineTarget?`<div class="row" style="margin-left:auto"><button class="btn green" onclick="ITH.respondFriendProposalV249223('${eid}',true,'${from}')">Αποδοχή</button><button class="btn danger" onclick="ITH.respondFriendProposalV249223('${eid}',false,'${from}')">Απόρριψη</button></div>`:`<button class="btn" style="margin-left:auto" onclick="ITH.member('${from}')">Προφίλ</button>`}</div>`;
}
async function respondFriendProposalV249223(eventId,accepted,peerId){try{await fetchJson('/api/social/friend/respond',{method:'POST',body:JSON.stringify({room_id:state.room,id:eventId,device_id:state.device,accepted:!!accepted})});if(accepted){let a=[];try{a=JSON.parse(localStorage.getItem('ith_contacts')||'[]')}catch{}if(peerId&&!a.includes(String(peerId)))a.push(String(peerId));localStorage.setItem('ith_contacts',JSON.stringify(a))}toast(accepted?'Η φιλία έγινε αποδεκτή':'Το αίτημα απορρίφθηκε');if(state.activeChannel)loadMessages(true)}catch(e){toast('Δεν ολοκληρώθηκε: '+(e.message||e))}return false}

/* V249223 SAFE PRO SOCIAL + CALL AUDIO PATCH
   Additive only: it stays on the working V249220 frontend and replaces only safe UI functions. */
function injectV249223ProSocialCss(){try{if(document.getElementById('ithV249223ProSocialCss'))return;const st=document.createElement('style');st.id='ithV249223ProSocialCss';st.textContent=`
.v249223SocialMini{display:flex!important;gap:6px!important;align-items:center!important;justify-content:center!important;margin-top:5px!important;flex-wrap:wrap!important}.v249223HeartCount{font-size:11px!important;font-weight:950!important;color:#ffd96e!important;background:rgba(0,0,0,.34)!important;border:1px solid rgba(255,217,110,.33)!important;border-radius:999px!important;padding:3px 7px!important;max-width:120px!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.v249223ListCard{display:flex!important;align-items:center!important;gap:10px!important;padding:10px!important;border-radius:16px!important;background:rgba(255,255,255,.07)!important;border:1px solid rgba(255,255,255,.10)!important;margin:7px 0!important}.v249223ListCard .memberLine{min-width:0!important;flex:1!important}.v249223ListCard .memberLine b{display:block!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.v249223QuickActions{display:flex!important;gap:5px!important;flex-wrap:wrap!important;justify-content:flex-end!important}.v249223QuickActions button{min-width:38px!important}.memberStatsRowV249210.proV249223{grid-template-columns:repeat(4,1fr)!important}.memberStatV249210.clickable{cursor:pointer!important;transition:.15s transform,.15s background!important}.memberStatV249210.clickable:active{transform:scale(.96)!important;background:rgba(255,215,110,.16)!important}.memberHeroActionsV249223{display:flex!important;gap:8px!important;flex-wrap:wrap!important;margin-top:12px!important;position:relative!important;z-index:2!important}.memberHeroActionsV249223 .btn{flex:1!important;min-width:96px!important}.callFullV249223.show{position:fixed!important;inset:0!important;z-index:99999!important;background:radial-gradient(circle at top,rgba(32,54,82,.98),rgba(3,6,12,.99))!important;display:grid!important;place-items:center!important;padding:max(10px,env(safe-area-inset-top)) 10px max(14px,env(safe-area-inset-bottom))!important}.callFullV249223 .callBox{width:min(96vw,860px)!important;height:min(94dvh,880px)!important;border-radius:28px!important;background:linear-gradient(145deg,rgba(7,18,33,.96),rgba(2,8,18,.98))!important;border:1px solid rgba(255,215,110,.30)!important;box-shadow:0 26px 100px rgba(0,0,0,.72)!important;padding:12px!important;display:flex!important;flex-direction:column!important;gap:10px!important}.callFullV249223 .callStage{flex:1!important;min-height:0!important;border-radius:24px!important;background:#05070d!important;overflow:hidden!important;position:relative!important;display:grid!important;place-items:center!important}.callFullV249223 video#callRemote{width:100%!important;height:100%!important;object-fit:cover!important;background:#05070d!important}.callFullV249223 audio#callRemote{width:92%!important;max-width:520px!important}.callFullV249223 .callLocal{position:absolute!important;right:12px!important;bottom:12px!important;width:min(34vw,190px)!important;height:min(28vh,150px)!important;border-radius:18px!important;border:2px solid rgba(255,215,110,.72)!important;object-fit:cover!important;background:#111!important}.callFullV249223 .voiceAvatarV249223{font-size:82px!important;filter:drop-shadow(0 8px 18px rgba(0,0,0,.45))}.callFullV249223 .callActions{display:flex!important;gap:8px!important;justify-content:center!important;flex-wrap:wrap!important}.callFullV249223 .callStatus{font-size:14px!important;text-align:center!important;color:#ffd96e!important;font-weight:950!important}.callFullV249223 .btn{border-radius:999px!important}.callAudioHintV249223{display:none!important}.callAudioHintV249223.show{display:inline-flex!important}.callDiagLineV249223{font-size:11px!important;text-align:center!important;color:rgba(238,246,255,.72)!important}.feedList [data-post].v249223Target{outline:3px solid rgba(255,217,110,.82)!important;box-shadow:0 0 0 8px rgba(255,217,110,.12)!important}
@media(max-width:640px){.memberStatsRowV249210.proV249223{gap:5px!important}.memberStatV249210 b{font-size:17px!important}.memberStatV249210 span{font-size:9.8px!important}.callFullV249223 .callBox{width:100vw!important;height:100dvh!important;border-radius:0!important;border-left:0!important;border-right:0!important}.callFullV249223 .callLocal{width:34vw!important;height:23vh!important}.callFullV249223 .callActions .btn{padding:10px 12px!important;min-width:54px!important}}
`;document.head.appendChild(st)}catch(e){console.warn('V249223 css',e)}}

function v249223MemberName(id){try{return (state.people.get(id)||{}).nickname||'Μέλος'}catch{return'Μέλος'}}
function v249223PersonRow(p,context=''){p=p||{};const id=esc(String(p.device_id||p.id||''));const name=esc(p.nickname||'Μέλος');return `<div class="v249223ListCard"><span class="avatarDotWrap">${avatarHtml({id:p.device_id||p.id,nickname:p.nickname||'Μέλος',avatar:p.avatar||'',online:!!p.online})}<i class="${p.online?'on':''}"></i></span><div class="memberLine"><b>${name}</b><small class="date">${esc(context||'μέλος')}</small></div><div class="v249223QuickActions"><button class="icon" title="Μήνυμα" onclick="ITH.startDM('${id}')">💬</button><button class="icon" title="Βιντεοκλήση" onclick="ITH.startDM('${id}').then(()=>ITH.startVideoCall())">📹</button><button class="icon" title="Φωνή" onclick="ITH.startDM('${id}').then(()=>ITH.startVoiceCall())">📞</button><button class="icon" title="Πρόταση φιλίας" onclick="ITH.sendFriendProposal('${id}')">🤝</button></div></div>`}

function actionButtons(p,c,mine){const rawId=String(p.post_id||''),id=esc(rawId),idJs=escJs(rawId);const body=(parseText(p.text).body||'').trim();const sender=String(p.sender_id||'');const senderJs=escJs(sender);const bodyPart=body?`<button class="actionIcon translateAction" title="${uiText('Translate')}" onclick="ITH.translateBlock('post_${idJs}','${escJs(body.slice(0,1200))}')">🌐<small>TR</small></button>`:'';return `<button class="actionIcon" title="Καρδιά" onclick="ITH.like('${idJs}')">❤️<span class="count" id="like_${id}">${c.likes}</span></button><button class="actionIcon" title="Ποιος έκανε like" onclick="ITH.openPostLikers('${idJs}')">👥<small>Like</small></button>${sender&&sender!==state.device?`<button class="actionIcon" title="Πρόταση φιλίας" onclick="ITH.sendFriendProposal('${senderJs}')">🤝<small>Φίλος</small></button>`:''}<button class="actionIcon" onclick="ITH.openPostCommentsPanel('${idJs}')">💬<span class="count" id="comment_count_${id}">${c.comments}</span></button>${bodyPart}<button class="actionIcon" onclick="ITH.savePost('${idJs}')">💾</button><button class="actionIcon" onclick="ITH.sharePost('${idJs}')">📤</button>${mine?`<button class="actionIcon" onclick="ITH.deletePost('${idJs}')">🗑️</button>`:''}`}

async function like(id){try{const r=await fetchJson('/api/reactions/toggle',{method:'POST',body:JSON.stringify({target_id:id,device_id:state.device,emoji:'❤️',nickname:state.name})});const el=$('like_'+id);if(el)el.textContent=String((r&&Number.isFinite(+r.count))?+r.count:((+el.textContent||0)+(r&&r.active?1:-1)));toast(r&&r.active?'❤️':'♡')}catch(e){toast('Not counted')}}

async function openPostLikers(id){injectV249223ProSocialCss();$('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>❤️ Ποιοι έκαναν like</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card">Φόρτωση...</div>`;$('memberMenu').classList.add('show');try{const r=await fetchJson(`/api/social/likers?room_id=${encodeURIComponent(state.room)}&post_id=${encodeURIComponent(id)}`);const list=(r.likers||[]);$('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>❤️ ${list.length} καρδιές</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="noticeList">${list.map(p=>v249223PersonRow(p,'έκανε like')).join('')||'<div class="card">Δεν έχει καρδιές ακόμη.</div>'}</div>`}catch(e){$('memberMenu').innerHTML=`<div class="card">Δεν φορτώνει η λίστα likes: ${esc(e.message||e)}</div>`}}

async function sendFriendProposal(id){if(!id||String(id)===String(state.device))return toast('Δεν γίνεται πρόταση στον εαυτό σου.');const p=state.people.get(id)||{nickname:'Μέλος'};try{const r=await fetchJson('/api/social/friend/request',{method:'POST',body:JSON.stringify({room_id:state.room,from_id:state.device,from_name:state.name||'Μέλος',to_id:id,to_name:p.nickname||'Μέλος'})});try{inviteContact(id)}catch{}toast(r&&r.duplicate?'Υπάρχει ήδη αίτημα φιλίας':'Στάλθηκε αίτημα φιλίας με μήνυμα');return false}catch(e){try{inviteContact(id)}catch{}toast('Τοπικό αίτημα φιλίας στάλθηκε. Server: '+(e.message||e));return false}}

async function toggleFollowMember(id){if(!id||String(id)===String(state.device))return toast('Δεν μπορείς να ακολουθείς τον εαυτό σου.');const p=state.people.get(id)||{nickname:'Μέλος'};try{const r=await fetchJson('/api/social/follow/toggle',{method:'POST',body:JSON.stringify({room_id:state.room,follower_id:state.device,follower_name:state.name||'Μέλος',target_id:id,target_name:p.nickname||'Μέλος'})});let a=[];try{a=JSON.parse(localStorage.getItem('ith_following')||'[]').map(String)}catch{}if(r.following){if(!a.includes(String(id)))a.push(String(id));toast('Ακολουθείς το μέλος')}else{a=a.filter(x=>x!==String(id));toast('Σταμάτησες να το ακολουθείς')}localStorage.setItem('ith_following',JSON.stringify(a));return false}catch(e){return follow(id)}}

async function openSocialList(id,type='friends'){injectV249223ProSocialCss();const title=type==='followers'?'Ακόλουθοι':type==='following'?'Ακολουθεί':'Φίλοι';$('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.member('${esc(id)}')">‹</button><b>${title}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card">Φόρτωση...</div>`;$('memberMenu').classList.add('show');try{const r=await fetchJson(`/api/social/member_lists?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(id)}`);const list=(r[type]||[]);$('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.member('${esc(id)}')">‹</button><b>${title} · ${list.length}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="noticeList">${list.map(p=>v249223PersonRow(p,title)).join('')||'<div class="card">Δεν υπάρχει λίστα ακόμη.</div>'}</div>`}catch(e){$('memberMenu').innerHTML=`<div class="card">Δεν φορτώνει η λίστα: ${esc(e.message||e)}</div>`}}

function memberProfileHeaderV249210(p,id,posts){p=p||{};const online=!!p.online;const localFollowing=localFollowingListV249210();const likes=(posts||[]).reduce((a,x)=>a+(+(x.likes||x.like_count||0)||0),0);let followers=+(p.followers||p.follower_count||p.followers_count||0)||0;let following=+(p.following||p.following_count||0)||0;let friends=+(p.friends||p.friend_count||0)||0;if(String(id)===String(state.device))following=Math.max(following,localFollowing.length);if(String(id)!==String(state.device)&&localFollowing.includes(String(id)))followers=Math.max(followers,1);const stat=(num,label,type)=>`<button class="memberStatV249210 clickable" onclick="ITH.openSocialList('${esc(id)}','${type}')"><b>${esc(num)}</b><span>${esc(label)}</span></button>`;return `<section class="memberProfileHeroV249210 card"><div class="memberHeroTopV249210"><div class="memberHeroAvatarV249210">${avatarHtml(p)}</div><div class="memberHeroNameV249210"><h2>${esc(p.nickname||'Μέλος')}</h2><span class="memberHeroOnlineV249210 ${online?'on':''}">${online?'● Online':'○ Offline'}</span></div></div><div class="memberStatsRowV249210 proV249223">${stat(followers,'Ακόλουθοι','followers')}${stat(following,'Ακολουθεί','following')}${stat(friends,'Φίλοι','friends')}<div class="memberStatV249210"><b>${esc(likes)}</b><span>Likes</span></div></div><div class="memberHeroActionsV249223">${String(id)!==String(state.device)?`<button class="btn green" onclick="ITH.toggleFollowMember('${esc(id)}')">➕ Follow</button><button class="btn" onclick="ITH.sendFriendProposal('${esc(id)}')">🤝 Φίλος</button>`:''}<button class="btn" onclick="ITH.memberPosts('${esc(id)}')">🎬 Δημοσιεύσεις</button></div></section>`}

function showMemberMenu(id){injectV249223ProSocialCss();const p=state.people.get(id)||{id,nickname:'Member'};markPeerRead(id);$('memberMenu').innerHTML=`<div class="postHead"><button class="icon" type="button" onclick="ITH.closeMember()" aria-label="Πίσω">‹</button>${avatarHtml(p)}<div><b>${esc(p.nickname)}</b><div class="date">${p.online?uiText('Online'):uiText('Offline')}</div></div><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="grid"><button class="tile" onclick="ITH.startDM('${esc(id)}')"><b>💬</b>${uiText('Message')}</button><button class="tile" onclick="ITH.startDM('${esc(id)}').then(()=>ITH.startVideoCall())"><b>📹</b>${uiText('Βιντεοκλήση')}</button><button class="tile" onclick="ITH.startDM('${esc(id)}').then(()=>ITH.startVoiceCall())"><b>📞</b>${uiText('Τηλεφωνική κλήση')}</button><button class="tile" onclick="ITH.memberPosts('${esc(id)}')"><b>🎬</b>${uiText('Posts')}</button><button class="tile" onclick="ITH.sendFriendProposal('${esc(id)}')"><b>🤝</b>Πρόταση φιλίας</button><button class="tile" onclick="ITH.toggleFollowMember('${esc(id)}')"><b>➕</b>Follow</button><button class="tile" onclick="ITH.openSocialList('${esc(id)}','friends')"><b>👥</b>Φίλοι</button><button class="tile" onclick="ITH.openSocialList('${esc(id)}','followers')"><b>👣</b>Ακόλουθοι</button><button class="tile" onclick="ITH.block('${esc(id)}')"><b>🚫</b>${uiText('Block')}</button><button class="tile" onclick="ITH.report('${esc(id)}')"><b>🚩</b>${uiText('Report')}</button></div>`;$('memberMenu').classList.add('show');renderPeople();if(state.page==='home')renderHome()}

function callControlsHtml(video,incoming){if(incoming)return `<button class="btn green" onclick="ITH.answerIncomingCall(true)">${uiText('Απάντηση')}</button><button class="btn danger" onclick="ITH.answerIncomingCall(false)">${uiText('Απόρριψη')}</button>`;return `${video?`<button id="callCameraBtn" class="btn callControlBtn" onclick="ITH.toggleCallCamera()" title="Camera on/off">📷</button><button class="btn callControlBtn" onclick="ITH.switchCallCamera()" title="Front/back camera">🔄</button>`:''}<button id="callMicBtn" class="btn callControlBtn" onclick="ITH.toggleCallMic()" title="Microphone on/off">🎙️</button><button id="callSpeakerBtn" class="btn callControlBtn" onclick="ITH.toggleCallSpeaker()" title="Speaker/external audio">🔊</button><button id="callAudioUnlock" class="btn callAudioHintV249223" onclick="ITH.unlockCallAudioV249223()">🔊 Άνοιγμα φωνής</button><button class="btn" onclick="ITH.openCallDiagnosticsV249223()">🧪 Έλεγχος φωνής</button><button class="btn danger" onclick="ITH.endActiveCall()">${uiText('Τερματισμός κλήσης')}</button>`}
function callBackArrowV249531(){const c=state.call;if(c&&c.incoming&&!c.pc)return answerIncomingCall(false);return endActiveCall()}
function showCallModal(kind,title,status,incoming=false){injectV249223ProSocialCss();const video=kind==='video';const pm=$('previewModal');pm.classList.remove('fullscreen','callCompactV249218','voiceCallV249218','videoCallV249218');pm.classList.add('callFullV249223',video?'videoCallV249223':'voiceCallV249223');pm.innerHTML=`<div class="callBox ${video?'videoCallBox':'voiceCallBox'} ${incoming?'incomingCallBox':''}"><div class="row"><button type="button" class="icon ithR10CallBack" aria-label="Επιστροφή" onclick="return ITH.callBackArrowV249531()">←</button><b>${video?'📹':'📞'} ${esc(title||uiText(video?'Βιντεοκλήση':'Κλήση φωνής'))}</b><button class="icon" style="margin-left:auto" aria-label="Κλείσιμο κλήσης" onclick="return ITH.callBackArrowV249531()">×</button></div><div class="callStage">${video?'<video id="callRemote" autoplay playsinline></video><video id="callLocal" class="callLocal" autoplay muted playsinline></video>':'<audio id="callRemote" autoplay controls playsinline></audio><div class="voiceAvatarV249223">📞</div>'}</div><div id="callStatus" class="callStatus">${esc(status||'')}</div><div class="callDiagLineV249223" id="callDiagLineV249223">Μικρόφωνο + ηχείο ενεργά όταν συνδεθεί η κλήση.</div><div class="callActions">${callControlsHtml(video,incoming)}</div></div>`;pm.classList.add('show')}
function unlockCallAudioV249223(){try{bridgeCall('setCallAudioMode',true)}catch{}const r=$('callRemote');try{if(r){r.muted=false;r.volume=1;r.autoplay=true;r.playsInline=true;const pr=r.play&&r.play();if(pr&&pr.then)pr.then(()=>toast('Η φωνή άνοιξε')).catch(e=>toast('Πάτα πάλι στο 🔊 ή δες άδειες ήχου: '+(e.message||e)))}}catch(e){toast('Δεν άνοιξε η φωνή: '+(e.message||e))}const u=$('callAudioUnlock');if(u)u.classList.add('show');return false}
async function openCallDiagnosticsV249223(){try{const r=await fetchJson(`/api/video/diagnostics/v249223?room_id=${encodeURIComponent(state.room)}`);const s=(r.recent_sessions||[])[0]||{};const line=$('callDiagLineV249223');if(line)line.textContent=`ICE/STUN: ${(r.settings&&r.settings.ice_servers||[]).length} · τελευταία κλήση: ${s.call_type||'-'} ${s.status||'-'}`;toast('Έλεγχος φωνής: δες τη γραμμή κάτω από την κλήση')}catch(e){toast('Δεν φορτώνει ο έλεγχος φωνής: '+(e.message||e))}return false}
async function openLinkedPostFromUrlV249223(){try{const u=new URL(location.href);let pid=u.searchParams.get('post')||'';if(!pid&&location.hash&&location.hash.includes('post='))pid=decodeURIComponent(location.hash.split('post=')[1].split('&')[0]||'');if(!pid)return;page('feed');await loadFeed();setTimeout(()=>{const el=document.querySelector(`[data-post="${CSS.escape(pid)}"]`);if(el){el.classList.add('v249223Target');el.scrollIntoView({behavior:'smooth',block:'center'});setTimeout(()=>el.classList.remove('v249223Target'),4200)}else toast('Η δημοσίευση δεν βρέθηκε στη Ροή ακόμη.')},300)}catch(e){}}



/* V249224 SAFE SOCIAL PLACEMENT PATCH
   Request: remove Friend/Like-list from the main video side bar; show like counts on member thumbnails;
   liker screens only offer friend request; keep wisdom/poll action bars visible. */
function injectV249224ThumbLikesCardsCss(){try{if(document.getElementById('ithV249224ThumbLikesCardsCss'))return;const st=document.createElement('style');st.id='ithV249224ThumbLikesCardsCss';st.textContent=`
  /* Remove labels/extra social clutter from Feed video side bar. */
  #feedPage .leftActions .actionIcon small{display:none!important}
  #feedPage .leftActions .feedLikeListBtnV249223,
  #feedPage .leftActions .feedFriendBtnV249223{display:none!important}
  /* Member-post thumbnails: visible heart counter on every small video/photo card. */
  .professionalThumbCard{position:relative!important;overflow:hidden!important;border-radius:19px!important}
  .professionalThumbCard .thumbVideoBox,.professionalThumbCard .thumbImageBox{position:relative!important;overflow:hidden!important;border-radius:16px!important}
  .v249224ThumbLikes{position:absolute!important;top:7px!important;right:7px!important;z-index:8!important;display:inline-flex!important;align-items:center!important;gap:4px!important;min-width:42px!important;justify-content:center!important;border-radius:999px!important;padding:5px 8px!important;background:rgba(0,0,0,.62)!important;border:1px solid rgba(255,217,110,.65)!important;color:#ffd96e!important;font-size:12px!important;font-weight:1000!important;box-shadow:0 8px 20px rgba(0,0,0,.35)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important}
  .v249224ThumbLikes:active{transform:scale(.94)!important;background:rgba(255,217,110,.25)!important}
  .v249224FriendOnlyRow{display:grid!important;grid-template-columns:auto 1fr auto!important;gap:10px!important;align-items:center!important;padding:10px!important;border-radius:17px!important;background:rgba(255,255,255,.07)!important;border:1px solid rgba(255,255,255,.12)!important;margin:7px 0!important}
  .v249224FriendOnlyRow .avatar{width:44px!important;height:44px!important}.v249224FriendOnlyRow b{display:block!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}.v249224FriendOnlyRow .btn{white-space:nowrap!important;border-radius:999px!important}
  /* Wisdom and polls: keep right action bar visible and keep cards above bottom nav. */
  #feedPage .feedList>.feedGoldWisdomCard,#feedPage .feedList>.feedGoldPollCard,#feedPage .feedList>.post.pollPost{position:relative!important;overflow:visible!important;padding-bottom:calc(var(--bar) + 12px)!important;box-sizing:border-box!important}
  #feedPage .feedGoldCardInner,#feedPage .pollFeedCard,#feedPage .professionalPollCard .photoLikeCenter,#feedPage .photoLikeInfoCard .photoLikeCenter,#feedPage .ithakiQuestionCard .photoLikeCenter{padding-right:clamp(58px,9vw,72px)!important;max-height:calc(100dvh - var(--bar) - 34px)!important;overflow:hidden!important}
  #feedPage .feedGoldCardActions,#feedPage .post.pollPost .pollPostActions{display:flex!important;visibility:visible!important;opacity:1!important;pointer-events:auto!important;position:absolute!important;right:7px!important;left:auto!important;top:50%!important;transform:translateY(-50%)!important;z-index:240!important;background:rgba(5,18,31,.42)!important;border:1px solid rgba(255,217,110,.34)!important;box-shadow:0 12px 32px rgba(0,0,0,.36)!important}
  #feedPage .feedGoldCardActions .btn,#feedPage .post.pollPost .pollPostActions .actionIcon{display:grid!important;place-items:center!important;width:39px!important;height:39px!important;min-width:39px!important;min-height:39px!important;border-radius:50%!important;color:#fff!important;background:rgba(255,255,255,.10)!important;font-size:18px!important}
  #feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(22px,6vw,38px)!important;line-height:1.18!important;color:#ffd36e!important;text-align:center!important;text-wrap:balance!important}
  #feedPage .pollQuestion,#feedPage .feedGoldPollCard .feedGoldQuote{font-size:clamp(15px,4.6vw,26px)!important;line-height:1.15!important;text-align:center!important;text-wrap:balance!important}
  #feedPage .pollVoteOptions,#feedPage .feedGoldPollOptions,#feedPage .photoLikeChoices{max-height:calc(100dvh - var(--bar) - 310px)!important;overflow:auto!important;padding-right:3px!important;scrollbar-width:thin!important}
  @media(max-width:760px){
    #feedPage .feedGoldCardInner,#feedPage .pollFeedCard,#feedPage .professionalPollCard .photoLikeCenter,#feedPage .photoLikeInfoCard .photoLikeCenter,#feedPage .ithakiQuestionCard .photoLikeCenter{width:min(89vw,520px)!important;padding:10px 52px 10px 10px!important;max-height:calc(100dvh - var(--bar) - 28px)!important;border-radius:20px!important}
    #feedPage .feedGoldCardActions,#feedPage .post.pollPost .pollPostActions{right:5px!important;gap:5px!important;padding:5px 4px!important}
    #feedPage .feedGoldCardActions .btn,#feedPage .post.pollPost .pollPostActions .actionIcon{width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;font-size:17px!important}
    #feedPage .feedGoldWisdomCard .feedGoldQuote{font-size:clamp(21px,6.4vw,33px)!important}
    #feedPage .pollQuestion,#feedPage .feedGoldPollCard .feedGoldQuote{font-size:clamp(13px,4vw,19px)!important}
    #feedPage .pollVoteOptions,#feedPage .feedGoldPollOptions,#feedPage .photoLikeChoices{grid-template-columns:1fr!important;max-height:calc(100dvh - var(--bar) - 280px)!important;gap:5px!important}
  }
  @media(max-height:700px){#feedPage .pollVoteOptions,#feedPage .feedGoldPollOptions,#feedPage .photoLikeChoices{max-height:calc(100dvh - var(--bar) - 245px)!important}#feedPage .feedGoldLogo,#feedPage .pollLogoClean{display:none!important}}
`;document.head.appendChild(st)}catch(e){console.warn('V249224 css',e)}}

function actionButtons(p,c,mine){
  const rawId=String(p.post_id||''),id=esc(rawId),idJs=escJs(rawId);
  const body=(parseText(p.text).body||'').trim();
  const translate=body?`<button class="actionIcon translateAction" title="${uiText('Translate')}" onclick="ITH.translateBlock('post_${idJs}','${escJs(body.slice(0,1200))}')">🌐<small>TR</small></button>`:'';
  return `<button class="actionIcon" title="Καρδιά" onclick="ITH.like('${idJs}')">❤️<span class="count" id="like_${id}">${c.likes}</span></button><button class="actionIcon" onclick="ITH.openPostCommentsPanel('${idJs}')">💬<span class="count" id="comment_count_${id}">${c.comments}</span></button>${translate}<button class="actionIcon" onclick="ITH.savePost('${idJs}')">💾</button><button class="actionIcon" onclick="ITH.sharePost('${idJs}')">📤</button>${mine?`<button class="actionIcon" onclick="ITH.deletePost('${idJs}')">🗑️</button>`:''}`;
}

function v249224FriendOnlyLikerRow(p){
  p=p||{};const raw=String(p.device_id||p.id||'');const id=esc(raw);const name=esc(p.nickname||'Μέλος');
  return `<div class="v249224FriendOnlyRow"><button class="icon" onclick="ITH.sendFriendProposal('${id}')">${avatarHtml({id:raw,nickname:p.nickname||'Μέλος',avatar:p.avatar||'',online:!!p.online})}</button><div><b>${name}</b><small class="date">έκανε like στη δημοσίευση</small></div><button class="btn green" onclick="ITH.sendFriendProposal('${id}')">🤝 Αίτημα φιλίας</button></div>`;
}
async function openPostLikersFriendOnly(id){
  injectV249224ThumbLikesCardsCss();
  $('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>❤️ Ποιοι έκαναν like</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card">Φόρτωση...</div>`;
  $('memberMenu').classList.add('show');
  try{
    const r=await fetchJson(`/api/social/likers?room_id=${encodeURIComponent(state.room)}&post_id=${encodeURIComponent(id)}`);
    const list=(r.likers||[]);
    $('memberMenu').innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>❤️ ${list.length} καρδιές</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="noticeList">${list.map(v249224FriendOnlyLikerRow).join('')||'<div class="card">Δεν έχει καρδιές ακόμη.</div>'}</div>`;
  }catch(e){$('memberMenu').innerHTML=`<div class="card">Δεν φορτώνει η λίστα likes: ${esc(e.message||e)}</div>`}
  return false;
}
async function openPostLikers(id){return openPostLikersFriendOnly(id)}

function renderMemberThumb(p,id){
  const t=parseText(p.text);const m=t.media;const pid=esc(p.post_id||'');const pidJs=escJs(String(p.post_id||''));const c=counts(p);let media='<span class="memberThumbText">📝</span>';
  const likeBadge=`<button class="v249224ThumbLikes" title="Ποιοι έκαναν like" onclick="event.stopPropagation();ITH.openPostLikersFriendOnly('${pidJs}')">❤️ ${c.likes}</button>`;
  if(m){
    const url=m.url||m.file_url||m.media_url||'';const raw=externalUrl(url);const src=esc(raw);const kind=String(m.kind||m.mime_type||m.type||'').toLowerCase();
    if(kind.includes('video')) media=`<div class="thumbVideoBox stableVideoThumb"><video src="${src}" muted playsinline preload="metadata" onloadeddata="this.classList.add('ready');try{this.currentTime=.15}catch(e){}" onerror="this.parentElement.classList.add('videoError')"></video><i>▶</i><em>Βίντεο</em>${likeBadge}</div>`;
    else if(kind.includes('photo')||kind.includes('image')) media=`<div class="thumbImageBox"><img src="${src}" loading="lazy" onerror="this.replaceWith(Object.assign(document.createElement('span'),{className:'memberThumbText',textContent:'🖼️'}))">${likeBadge}</div>`;
    else media=`<span class="memberThumbText">📎</span>${likeBadge}`;
  }else media=`<span class="memberThumbText">📝</span>${likeBadge}`;
  const label=(t.body||'').trim()||'Δημοσίευση με media';
  return `<button class="thumbCard professionalThumbCard" onclick="ITH.openMemberFeed('${esc(id)}','${pid}')">${media}<span>${esc(label.slice(0,96))}</span></button>`;
}

function openReactionMemberFriendOnly(id){return sendFriendProposal(id)}



/* V249225 SAFE FEED/MESSAGES/SOCIAL FIX
   - thumbnail like badge is always visible on member/avatar post grids
   - liker/follower/following/friend lists show only Friend Request
   - DM starts with All / Online / Friends list
   - feed no longer jumps back to top at the end; optional unlock-all button asks first
*/
function injectV249225SafeSocialCss(){try{if(document.getElementById('ithV249225SafeSocialCss'))return;const st=document.createElement('style');st.id='ithV249225SafeSocialCss';st.textContent=`
  .professionalThumbCard,.thumbCard.professionalThumbCard,.v249225ThumbCard{position:relative!important;overflow:visible!important;min-height:142px!important;border:1px solid rgba(255,217,110,.22)!important}
  .v249225ThumbLikes{position:absolute!important;top:6px!important;right:6px!important;z-index:9999!important;display:inline-flex!important;align-items:center!important;justify-content:center!important;gap:4px!important;min-width:46px!important;min-height:28px!important;padding:5px 9px!important;border-radius:999px!important;background:rgba(0,0,0,.78)!important;border:2px solid rgba(255,217,110,.85)!important;color:#ffd96e!important;font-size:13px!important;line-height:1!important;font-weight:1000!important;box-shadow:0 8px 22px rgba(0,0,0,.55)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important;pointer-events:auto!important}
  .v249225ThumbLikes:active{transform:scale(.94)!important;background:rgba(255,217,110,.22)!important}
  .v249225FriendOnlyRow{display:grid!important;grid-template-columns:auto 1fr auto!important;gap:10px!important;align-items:center!important;padding:10px!important;border-radius:18px!important;background:rgba(255,255,255,.075)!important;border:1px solid rgba(255,255,255,.14)!important;margin:8px 0!important}
  .v249225FriendOnlyRow .avatar{width:46px!important;height:46px!important}.v249225FriendOnlyRow b{display:block!important;color:#fff!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}.v249225FriendOnlyRow .btn{white-space:nowrap!important;border-radius:999px!important;font-weight:900!important}
  .dmFilterTabsV249225{display:grid!important;grid-template-columns:repeat(3,1fr)!important;gap:5px!important;padding:6px 7px 7px!important;background:rgba(255,255,255,.04)!important;border-bottom:1px solid rgba(255,255,255,.08)!important}.dmFilterTabsV249225 .btn{min-height:33px!important;border-radius:999px!important;padding:5px 7px!important;font-size:12px!important}.dmFilterTabsV249225 .btn.green{box-shadow:0 0 0 2px rgba(255,217,110,.18) inset!important}
  .person .dmBadgesV249225{display:inline-flex!important;gap:3px!important;margin-left:auto!important;align-items:center!important}.person .dmBadgeV249225{min-width:16px!important;height:16px!important;line-height:16px!important;text-align:center!important;border-radius:999px!important;background:#ffd96e!important;color:#2a1700!important;font-size:10px!important;font-weight:1000!important}.person .dmBadgeV249225.online{background:#5cff9e!important;color:#03140a!important}.person .dmBadgeV249225.friend{background:#7ab8ff!important;color:#021124!important}
  .feedEndUnlockV249225{margin:12px auto calc(var(--bar) + 22px)!important;max-width:560px!important;text-align:center!important;border:1px solid rgba(255,217,110,.32)!important;background:linear-gradient(135deg,rgba(10,25,40,.96),rgba(45,32,7,.92))!important}.feedEndUnlockV249225 h3{margin:0 0 6px!important;color:#ffd96e!important}.feedEndUnlockV249225 p{margin:0 0 10px!important;color:rgba(255,255,255,.78)!important}.feedEndUnlockV249225 .row{justify-content:center!important}
  #feedPage .feedList{scroll-behavior:auto!important}
  #feedPage .feedGoldCardActions,#feedPage .post.pollPost .pollPostActions{display:flex!important;visibility:visible!important;opacity:1!important;z-index:300!important}
  @media(max-width:760px){.v249225ThumbLikes{top:5px!important;right:5px!important;min-width:44px!important;min-height:27px!important;font-size:12.5px!important}.v249225FriendOnlyRow{grid-template-columns:auto 1fr!important}.v249225FriendOnlyRow .btn{grid-column:1/3!important;width:100%!important}.feedEndUnlockV249225{margin-left:8px!important;margin-right:8px!important}}
`;document.head.appendChild(st)}catch(e){console.warn('V249225 css',e)}}
function v249225StoredFriendIds(){const s=new Set();try{JSON.parse(localStorage.getItem('ith_contacts')||'[]').forEach(x=>x&&s.add(String(x)))}catch{}try{(state.socialFriendsV249225||[]).forEach(p=>{const id=p&&String(p.device_id||p.id||'');if(id)s.add(id)})}catch{}return s}
async function loadSocialFriendsV249225(){try{const r=await fetchJson(`/api/social/member_lists?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);state.socialFriendsV249225=(r.friends||[]);try{const ids=(r.friends||[]).map(p=>String(p.device_id||p.id||'')).filter(Boolean);localStorage.setItem('ith_contacts',JSON.stringify([...new Set([...(JSON.parse(localStorage.getItem('ith_contacts')||'[]')), ...ids])]))}catch{};return state.socialFriendsV249225}catch(e){return state.socialFriendsV249225||[]}}
function v249225SetDmFilter(mode){state.dmFilterV249225=mode||'all';try{localStorage.setItem('ith_dm_filter_v249225',state.dmFilterV249225)}catch{};renderPeople();return false}
function v249225DmFilter(){try{return state.dmFilterV249225||localStorage.getItem('ith_dm_filter_v249225')||'all'}catch{return state.dmFilterV249225||'all'}}
function v249225FriendOnlyRow(p,context){p=p||{};const raw=String(p.device_id||p.id||'');const id=esc(raw);const idJs=escJs(raw);const name=esc(p.nickname||'Μέλος');const mine=String(raw)===String(state.device||'');const already=v249225StoredFriendIds().has(raw);const action=mine?'<button class="btn" disabled>Εσύ</button>':already?'<button class="btn" disabled>✓ Φίλος</button>':`<button class="btn green" data-request-friend="${id}" onclick="ITH.sendFriendProposal('${idJs}')">🤝 Αίτημα φιλίας</button>`;return `<div class="v249225FriendOnlyRow" data-social-peer="${id}"><button class="icon" title="Άνοιγμα προφίλ" onclick="ITH.member('${idJs}')">${avatarHtml({id:raw,nickname:p.nickname||'Μέλος',avatar:p.avatar||'',online:!!p.online})}</button><div><b>${name}</b><small class="date">${esc(context||'μέλος')}</small></div>${action}</div>`}
function v249223PersonRow(p,context=''){return v249225FriendOnlyRow(p,context)}
function v249224FriendOnlyLikerRow(p){return v249225FriendOnlyRow(p,'έκανε like στη δημοσίευση')}
function openReactionMemberFriendOnly(id){return sendFriendProposal(id)}
function renderMemberThumb(p,id){injectV249225SafeSocialCss();const t=parseText(p.text);const m=t.media;const pid=esc(p.post_id||'');const pidJs=escJs(String(p.post_id||''));const c=counts(p);let media='<span class="memberThumbText">📝</span>';const likeBadge=`<span class="v249225ThumbLikes" role="button" title="Ποιοι έκαναν like" onclick="event.stopPropagation();ITH.openPostLikersFriendOnly('${pidJs}')">❤️ ${c.likes}</span>`;if(m){const url=m.url||m.file_url||m.media_url||'';const raw=externalUrl(url);const src=esc(raw);const kind=String(m.kind||m.mime_type||m.type||'').toLowerCase();if(kind.includes('video'))media=`<div class="thumbVideoBox stableVideoThumb"><video src="${src}" muted playsinline preload="metadata" onloadeddata="this.classList.add('ready');try{this.currentTime=.15}catch(e){}" onerror="this.parentElement.classList.add('videoError')"></video><i>▶</i><em>Βίντεο</em></div>`;else if(kind.includes('photo')||kind.includes('image'))media=`<div class="thumbImageBox"><img src="${src}" loading="lazy" onerror="this.replaceWith(Object.assign(document.createElement('span'),{className:'memberThumbText',textContent:'🖼️'}))"></div>`;else media='<span class="memberThumbText">📎</span>'}const label=(t.body||'').trim()||'Δημοσίευση με media';return `<button class="thumbCard professionalThumbCard v249225ThumbCard" onclick="ITH.openMemberFeed('${esc(id)}','${pid}')">${likeBadge}${media}<span>${esc(label.slice(0,96))}</span></button>`}
function setupFeedCycleV249217(cfg){try{const list=document.querySelector('#feedPage .feedList');if(!list)return;list.dataset.loopFeedV249217='false';if(list.dataset.noJumpV249225==='1')return;list.dataset.noJumpV249225='1';list.addEventListener('scroll',()=>{try{sessionStorage.setItem('ith_feed_scroll_v249225',String(list.scrollTop||0))}catch{}},{passive:true})}catch(e){console.warn('feed no-jump v249225',e)}}
function feedUnlockedAllV249225(){try{return localStorage.getItem('ith_unlock_all_feed_v249225')==='1'}catch{return false}}
function feedEndUnlockHtmlV249225(count){const unlocked=feedUnlockedAllV249225();return `<div class="card feedEndUnlockV249225"><h3>${unlocked?'✅ Ελεύθερη Ροή':'Τέλος τελευταίων δημοσιεύσεων'}</h3><p>${unlocked?'Εμφανίζονται περισσότερες δημοσιεύσεις χωρίς αυτόματο γύρισμα στην αρχή.':'Η Ροή δεν θα σε πετάξει πια στην αρχή. Θέλεις να ελευθερώσεις περισσότερα/όλα τα διαθέσιμα βίντεο;'}</p><div class="row"><button class="btn green" onclick="window.unlockAllFeedVideosV249225()">🎬 Ελευθέρωσε όλα τα βίντεο</button><button class="btn" onclick="window.keepLatestFeedV249225()">Μείνε στις τελευταίες</button></div><div class="date">Φορτώθηκαν ${esc(String(count||0))} δημοσιεύσεις.</div></div>`}
window.unlockAllFeedVideosV249225=function(){if(confirm('Να ελευθερωθούν περισσότερα/όλα τα βίντεο στη Ροή; Μπορεί να φορτώνει πιο βαριά στο κινητό.')){try{localStorage.setItem('ith_unlock_all_feed_v249225','1')}catch{};ITH.loadFeed()}};
window.keepLatestFeedV249225=function(){try{localStorage.removeItem('ith_unlock_all_feed_v249225')}catch{};toast('Η Ροή μένει στις τελευταίες δημοσιεύσεις.');ITH.loadFeed()};
/* V249429_LEGACY_LOAD_FEED_REMOVED */
function openDM(){return openDMV249235()}
function renderPeople(){const list=$('peopleList');if(!list)return;injectV249231AvatarDmNotifyCss();injectV249235MessageFirstCss();const q=($('peopleSearch')?.value||'').toLowerCase().trim();let arr=v249235FriendListForMessages();arr=arr.filter(p=>String(p.nickname||'').toLowerCase().includes(q)||String(p.id||p.device_id||'').toLowerCase().includes(q));const active=arr.filter(p=>p.online||unreadFrom(p.id));const offline=arr.filter(p=>!p.online&&!unreadFrom(p.id));const allCount=arr.length, activeCount=active.length;const summary=`<div class="dmFriendSummaryV249235"><span class="dmPillV249235 green">${allCount} φίλοι</span><span class="dmPillV249235">${activeCount} ενεργοί / με νέο μήνυμα</span><span class="dmPillV249235">${Math.max(0,allCount-activeCount)} ανενεργοί</span></div>`;let html=summary+v249235FriendSection('Ενεργοί φίλοι / νέα μηνύματα',active,'Δεν υπάρχει ενεργός φίλος αυτή τη στιγμή.')+v249235FriendSection('Ανενεργοί φίλοι',offline,'');if(!arr.length){html=`<div class="card friendGateCardV249227 dmEmptyV249235"><b>Δεν εμφανίζεται φίλος ακόμη.</b><div class="date">Μετά την αποδοχή φιλίας η λίστα ενημερώνεται αυτόματα. Αν δεν εμφανιστεί, πάτα Φόρτωση φίλων ξανά.</div><div class="dmEmptyV249246Tools"><button class="btn green" onclick="ITH.refreshFriendsForMessagesV249246(true)">🔄 Φόρτωση φίλων ξανά</button><button class="btn" onclick="ITH.notifyCenter()">🔔 Ειδοποιήσεις / αποδοχή φιλίας</button><button class="btn" onclick="ITH.openCommunicationContactsV249230('message')">👥 Λίστα μελών για αίτημα</button><button class="btn" onclick="location.href='/api/social/member_lists?room_id='+encodeURIComponent(state.room)+'&device_id='+encodeURIComponent(state.device)">Διαγνωστικό φίλων</button></div><div class="friendDebugV249246">device: ${esc(state.device||'')} · local contacts: ${(()=>{try{return JSON.parse(localStorage.getItem('ith_contacts')||'[]').length}catch{return 0}})()} · server friends: ${(state.socialFriendsV249225||[]).length}</div></div>`}list.innerHTML=html;list.onclick=e=>{const menu=e.target.closest('[data-menu-id]');if(menu){e.stopPropagation();return showMemberMenu(menu.dataset.menuId)}const row=e.target.closest('.dmFriendRowV249235');if(!row)return;return startDM(row.dataset.id)};try{if(window.ITH)window.ITH.renderPeopleV249235=renderPeople}catch{}}
async function legacyNotifyCenterV249526_2(){injectV249231AvatarDmNotifyCss();const menu=$('memberMenu');menu.innerHTML=`<div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Ειδοποιήσεις</b><button class="icon" style="margin-left:auto" onclick="ITH.markNoticesRead()">✓</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="card">Φόρτωση ειδοποιήσεων...</div>`;menu.classList.add('show','fullAvatarMenuV249231');let items=[];try{const r=await fetchJson(`/api/notifications?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=250`);items=(r.items||[]).map(x=>({server:true,type:x.type==='contact'?'contact_invite':x.type,status:x.status,id:x.id,from_id:x.from_id,from_name:x.from_name,to_id:x.to_id,to_name:x.to_name,created_at:x.created_at,text:(x.type==='contact'?(x.from_id===state.device?'Στάλθηκε αίτημα φιλίας':'Σας έστειλε αίτημα φιλίας'):'Ειδοποίηση') }))}catch(e){console.warn('server notifications',e)}try{items=[...items,...uniqueNotices(localNotices())]}catch{}const seen=new Set();items=items.filter(n=>{const k=String(n.id||n.event_id||n.type+'-'+n.from_id+'-'+n.to_id+'-'+n.created_at);if(seen.has(k))return false;seen.add(k);return true}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));const avatars=items.slice(0,14).map(n=>{const id=String(n.from_id===state.device?n.to_id:n.from_id||n.to_id||'');const p=v249231PersonById(id);return `<button class="storyItem ${n.status==='pending'?'on':''}" onclick="ITH.member('${escJs(id)}')"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${n.status==='pending'?'red':'on'}"></i></span><small>${esc(p.nickname||'Μέλος')}</small></button>`}).join('')||`<span class="date">Δεν υπάρχουν ειδοποιήσεις.</span>`;const card=n=>{const id=String(n.from_id===state.device?n.to_id:n.from_id||n.to_id||'');const p=v249231PersonById(id);const pending=String(n.status||'pending')==='pending';const inbound=String(n.to_id||'')===String(state.device);return `<div class="card noticeCard v249231Notice ${esc(n.status||'pending')}"><b>${esc(labelNotice(n.type||'notification'))}</b><div>${avatarHtml(p)} <b>${esc(p.nickname||n.from_name||n.to_name||'Μέλος')}</b></div><div class="date">${esc(n.text||'')} · ${esc(n.status||'pending')}</div>${(n.type==='contact_invite'||n.type==='contact')&&pending&&inbound?`<div class="v249231NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249223('${escJs(n.id||n.event_id||'')}',true,'${escJs(id)}')">Αποδοχή</button><button class="btn danger" onclick="ITH.respondFriendProposalV249223('${escJs(n.id||n.event_id||'')}',false,'${escJs(id)}')">Απόρριψη</button><button class="btn" onclick="ITH.startDM('${escJs(id)}')">Μηνύματα</button></div>`:`<div class="v249231NoticeActions"><button class="btn" onclick="ITH.member('${escJs(id)}')">Avatar / Μενού</button></div>`}</div>`};menu.innerHTML=`<div class="v249231MenuScroll"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Ειδοποιήσεις</b><button class="icon" style="margin-left:auto" onclick="ITH.markNoticesRead()">✓</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="noticeAvatarStrip">${avatars}</div><div class="noticeList v249231NotifyScroll">${items.map(card).join('')||'<div class="card">Δεν υπάρχουν ειδοποιήσεις.</div>'}</div><div class="card"><b>Έλεγχος</b><div class="date">Τα αιτήματα φιλίας στέλνονται και ως κάρτα στα μηνύματα και ως FCM για κλειστή εφαρμογή.</div><button class="btn green" onclick="ITH.openPushPanel()">Push / FCM</button></div></div>`;return false}
async function respondFriendProposalV249223(eventId,accepted,peerId){try{await fetchJson('/api/social/friend/respond',{method:'POST',body:JSON.stringify({room_id:state.room,id:eventId,device_id:state.device,accepted:!!accepted})});if(accepted){let a=[];try{a=JSON.parse(localStorage.getItem('ith_contacts')||'[]')}catch{}if(peerId&&!a.includes(String(peerId)))a.push(String(peerId));localStorage.setItem('ith_contacts',JSON.stringify(a));await loadSocialFriendsV249225();toast('Η φιλία έγινε αποδεκτή — ανοίγω μηνύματα');return startDM(peerId)}toast('Το αίτημα απορρίφθηκε');notifyCenter()}catch(e){toast('Δεν ολοκληρώθηκε: '+(e.message||e))}return false}



/* V249232 FEED DISCOVERY / ALGORITHM / CARDS SAFE PATCH
   - Feed search button opens a professional checkbox screen.
   - Newest first, grouped by: following, friends, likes, ITHAKI, followers, same interests, popular likes, keywords.
   - Free flow = newest public posts in order.
   - Wisdom cards: ancient + modern philosophy style after 12 posts or 10 minutes.
   - Poll card: max one per 24h.
*/
const ITHAKI_FEED_KEYWORDS_V249232=['επιστήμη','χόμπι','τεχνη','τέχνη','διακοπες','διακοπές','μοδα','μόδα','αποκαλυψεις','αποκαλύψεις','ειδησεις','ειδήσεις','μαθηματα','μαθήματα','ερευνα','έρευνα','διαστημα','διάστημα','εργασιες','εργασίες','αστεια','αστεία','ανεκδοτα','ανέκδοτα'];
const ITHAKI_FEED_KEYWORDS_LABELS_V249232=['επιστήμη','χόμπι','τέχνη','διακοπές','μόδα','αποκαλύψεις','ειδήσεις','μαθήματα','έρευνα','διάστημα','εργασίες','αστεία','ανέκδοτα'];
function injectV249232FeedDiscoveryCss(){try{if(document.getElementById('ithV249232FeedDiscoveryCss'))return;const st=document.createElement('style');st.id='ithV249232FeedDiscoveryCss';st.textContent=`
  .feedSearchGlassV249189{max-width:min(96vw,760px)!important;gap:5px!important}
  .feedSearchGlassV249189 .feedDiscoverBtnV249232{border-radius:999px!important;padding:7px 10px!important;min-width:auto!important;background:linear-gradient(135deg,rgba(255,217,110,.24),rgba(54,240,160,.14))!important;border:1px solid rgba(255,217,110,.38)!important;color:#fff!important;font-weight:1000!important}
  .feedDiscoverPanelV249232{height:min(88dvh,820px)!important;max-height:88dvh!important;overflow:auto!important;padding:0!important;background:linear-gradient(160deg,rgba(3,12,23,.98),rgba(20,13,2,.96))!important;border:1px solid rgba(255,217,110,.28)!important;border-radius:24px!important;box-shadow:0 28px 90px rgba(0,0,0,.72)!important}.feedDiscoverPanelV249232 .panelTop{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:10px;padding:12px;background:rgba(3,12,23,.92);backdrop-filter:blur(10px);border-bottom:1px solid rgba(255,255,255,.08)}.feedDiscoverPanelV249232 .panelTop b{color:#ffd96e;font-size:18px}.feedDiscoverPanelV249232 .panelBody{padding:12px;display:grid;gap:12px}.feedDiscoverPanelV249232 .filterBlock{border-radius:18px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10);padding:10px}.feedDiscoverPanelV249232 .filterBlock h3{margin:0 0 8px;color:#ffe39b;font-size:15px}.feedDiscoverPanelV249232 .tickGrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(165px,1fr));gap:8px}.feedDiscoverPanelV249232 label.tick{display:flex;align-items:center;gap:8px;border-radius:14px;padding:9px 10px;background:rgba(255,255,255,.075);border:1px solid rgba(255,255,255,.10);font-weight:900}.feedDiscoverPanelV249232 label.tick input{width:18px;height:18px;accent-color:#ffd96e}.feedDiscoverPanelV249232 .keywordChips{display:flex;gap:7px;flex-wrap:wrap}.feedDiscoverPanelV249232 .keywordChips label{display:inline-flex;align-items:center;gap:5px;border-radius:999px;padding:8px 10px;background:rgba(255,217,110,.10);border:1px solid rgba(255,217,110,.22);font-size:12px;font-weight:900}.feedDiscoverPanelV249232 textarea{width:100%;min-height:64px;border-radius:16px;background:rgba(0,0,0,.25);color:#fff;border:1px solid rgba(255,255,255,.14);padding:10px;font:inherit;box-sizing:border-box}.feedDiscoverPanelV249232 .applyRow{position:sticky;bottom:0;display:flex;gap:8px;flex-wrap:wrap;padding:10px;background:rgba(3,12,23,.94);border-top:1px solid rgba(255,255,255,.08)}.feedModeLabelV249232{position:absolute;left:10px;bottom:calc(var(--bar) + 10px);z-index:88;border-radius:999px;padding:6px 10px;background:rgba(0,0,0,.42);border:1px solid rgba(255,217,110,.22);color:#ffe6a2;font-size:11px;font-weight:1000;pointer-events:none}.feedEndUnlockV249225 .btn.freeV249232{background:linear-gradient(135deg,#36f0a0,#ffd96e)!important;color:#041018!important}.feedGoldWisdomCard.v249232Wisdom .feedGoldQuote small{display:block;color:#fff0c1;font-size:clamp(12px,1.6vw,16px);margin-top:10px;font-weight:850}.feedSearchEmptyV249232{text-align:center;border:1px solid rgba(255,217,110,.28)!important;background:linear-gradient(180deg,rgba(255,217,110,.10),rgba(255,255,255,.05))!important}
  @media(max-width:760px){.feedSearchGlassV249189 input{max-width:32vw!important}.feedSearchGlassV249189 .feedDiscoverBtnV249232{padding:7px 8px!important;font-size:12px!important}.feedDiscoverPanelV249232{height:92dvh!important;max-height:92dvh!important;border-radius:18px!important}.feedDiscoverPanelV249232 .tickGrid{grid-template-columns:1fr!important}.feedModeLabelV249232{display:none!important}}
`;document.head.appendChild(st)}catch(e){console.warn('v249232 css',e)}}
function feedDefaultSettingsV249232(){return{free:false,cats:{following:true,friends:true,likes:true,ithaki:true,followers:true,same_interests:true,popular:true,keywords:false},keywords:[],manual:''}}
function feedSettingsV249232(){try{return Object.assign(feedDefaultSettingsV249232(),JSON.parse(localStorage.getItem('ith_feed_discovery_v249232')||'{}'))}catch{return feedDefaultSettingsV249232()}}
function saveFeedSettingsV249232(s){try{localStorage.setItem('ith_feed_discovery_v249232',JSON.stringify(s||feedDefaultSettingsV249232()))}catch{}}
function normalizeGrV249232(s){return String(s||'').toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g,'').replace(/ς/g,'σ')}
function postTextV249232(p){try{const t=parseText(p.text);const m=t.media||{};return [t.body,p.text,p.nickname,p.post_kind,m.kind,m.filename,m.name,m.mime_type].map(x=>String(x||'')).join(' ')}catch{return [p.text,p.nickname,p.post_kind].map(x=>String(x||'')).join(' ')}}
function isIthakiPostV249232(p){try{return isIthakiOfficialPostV249194(p)||normalizeGrV249232((p.nickname||'')+' '+(p.sender_id||'')).includes('ithaki')||normalizeGrV249232((p.nickname||'')+' '+(p.sender_id||'')).includes('ιθακη')}catch{return false}}
function myInterestWordsV249232(){let raw='';try{raw=[localStorage.getItem('ith_interests'),localStorage.getItem('ith_profile_interests'),localStorage.getItem('ith_user_interests')].filter(Boolean).join(' ')}catch{};try{const p=state&&state.profile||{};raw+=' '+String(p.interests||'')}catch{};return normalizeGrV249232(raw).split(/[\s,;·|]+/).map(x=>x.trim()).filter(x=>x.length>3).slice(0,30)}
async function feedSocialSetsV249232(){const sets={friends:new Set(),following:new Set(),followers:new Set()};try{const r=await fetchJson(`/api/social/member_lists?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);(r.friends||[]).forEach(p=>sets.friends.add(String(p.device_id||p.id||'')));(r.following||[]).forEach(p=>sets.following.add(String(p.device_id||p.id||'')));(r.followers||[]).forEach(p=>sets.followers.add(String(p.device_id||p.id||'')));state.feedSocialSetsV249232=sets;try{localStorage.setItem('ith_contacts',JSON.stringify([...new Set([...(JSON.parse(localStorage.getItem('ith_contacts')||'[]')), ...sets.friends])]))}catch{}}catch(e){try{(JSON.parse(localStorage.getItem('ith_contacts')||'[]')||[]).forEach(id=>sets.friends.add(String(id)))}catch{}try{(JSON.parse(localStorage.getItem('ith_following')||'[]')||[]).forEach(id=>sets.following.add(String(id)))}catch{};state.feedSocialSetsV249232=sets}return sets}
function feedModeTextV249232(s){if(!s||s.free)return 'Ελεύθερη Ροή · ό,τι καινούργιο με σειρά';const a=[];if(s.cats.following)a.push('Ακολουθώ');if(s.cats.friends)a.push('Φίλοι');if(s.cats.likes)a.push('Likes');if(s.cats.ithaki)a.push('ΙΘΑΚΗ');if(s.cats.followers)a.push('Ακολουθούν');if(s.cats.same_interests)a.push('Ίδια ενδιαφέροντα');if(s.cats.popular)a.push('Πολλά likes');if(s.cats.keywords)a.push('Λέξεις');return a.length?'Αλγόριθμος: '+a.join(' · '):'Ελεύθερη Ροή'}
function keywordListFromSettingsV249232(s){let out=[];if(s&&s.cats&&s.cats.keywords)out=out.concat((s.keywords||[]));if(s&&s.manual)out=out.concat(String(s.manual).split(/[\n,;]+/));return [...new Set(out.map(x=>normalizeGrV249232(x).trim()).filter(Boolean))]}
function postGroupScoreV249232(p,sets,s){const sender=String(p.sender_id||'');const text=normalizeGrV249232(postTextV249232(p));const kws=keywordListFromSettingsV249232(s);const interests=myInterestWordsV249232();let groups=[];if(s.cats.following&&sets.following.has(sender))groups.push(1);if(s.cats.friends&&sets.friends.has(sender))groups.push(2);if(s.cats.likes&&((+p.like_count||+p.likes||0)>0))groups.push(3);if(s.cats.ithaki&&isIthakiPostV249232(p))groups.push(4);if(s.cats.followers&&sets.followers.has(sender))groups.push(5);if(s.cats.same_interests&&interests.some(w=>text.includes(w)))groups.push(6);if(s.cats.popular&&((+p.like_count||+p.likes||0)>=3))groups.push(7);if(s.cats.keywords&&kws.some(w=>text.includes(w)))groups.push(8);return groups.length?Math.min(...groups):999}
function orderFeedPostsV249232(posts,sets,s){posts=uniquePosts(posts||[]);if(!s||s.free)return posts.sort((a,b)=>(+b.created_at||0)-(+a.created_at||0));const enabled=Object.values(s.cats||{}).some(Boolean);if(!enabled)return posts.sort((a,b)=>(+b.created_at||0)-(+a.created_at||0));const paired=posts.map((p,i)=>({p,i,g:postGroupScoreV249232(p,sets,s)}));let keep=paired.filter(x=>x.g<999);let rest=paired.filter(x=>x.g>=999);if(!keep.length)keep=paired;keep.sort((a,b)=>(a.g-b.g)||((+b.p.created_at||0)-(+a.p.created_at||0))||(a.i-b.i));rest.sort((a,b)=>(+b.p.created_at||0)-(+a.p.created_at||0));return [...keep,...rest].map(x=>x.p)}
function openFeedSearchV249232(){injectV249232FeedDiscoveryCss();let s=feedSettingsV249232();const cats=[['following','1. Ακολουθώ'],['friends','2. Φίλοι'],['likes','3. Like'],['ithaki','4. ΙΘΑΚΗ'],['followers','5. Με ακολουθούν'],['same_interests','6. Ίδια ενδιαφέροντα'],['popular','7. Διάφορα με πολλά likes'],['keywords','8. Λέξεις κλειδιά']];const catHtml=cats.map(([k,l])=>`<label class="tick"><input type="checkbox" data-cat="${k}" ${s.cats&&s.cats[k]?'checked':''}> ${l}</label>`).join('');const kwSet=new Set((s.keywords||[]).map(normalizeGrV249232));const kwHtml=ITHAKI_FEED_KEYWORDS_LABELS_V249232.map(k=>`<label><input type="checkbox" data-keyword="${esc(k)}" ${kwSet.has(normalizeGrV249232(k))?'checked':''}> ${esc(k)}</label>`).join('');$('memberMenu').innerHTML=`<div class="feedDiscoverPanelV249232"><div class="panelTop"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔎 Αναζήτηση δημοσίευσης</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="panelBody"><div class="filterBlock"><h3>Εμφάνιση πρώτα καινούργιες δημοσιεύσεις από:</h3><div class="tickGrid">${catHtml}</div></div><div class="filterBlock"><h3>Έτοιμες λέξεις κλειδιά</h3><div class="keywordChips">${kwHtml}</div></div><div class="filterBlock"><h3>Χειροκίνητες λέξεις κλειδιά</h3><textarea id="feedManualKeywordsV249232" placeholder="Γράψε δικές σου λέξεις, χωρισμένες με κόμμα ή γραμμή">${esc(s.manual||'')}</textarea><div class="date">Όταν ενεργοποιήσεις «Λέξεις κλειδιά», η Ροή ψάχνει και αυτές.</div></div></div><div class="applyRow"><button class="btn green" onclick="ITH.applyFeedSearchV249232()">✓ Εφαρμογή</button><button class="btn freeV249232" onclick="ITH.setFreeFeedV249232()">🎬 Ελεύθερη Ροή</button><button class="btn" onclick="ITH.closeMember()">Κλείσιμο</button></div></div>`;$('memberMenu').classList.add('show','fullAvatarMenuV249231');return false}
function applyFeedSearchV249232(){try{let s=feedDefaultSettingsV249232();s.free=false;s.cats={};document.querySelectorAll('#memberMenu [data-cat]').forEach(i=>s.cats[i.dataset.cat]=!!i.checked);s.keywords=[...document.querySelectorAll('#memberMenu [data-keyword]:checked')].map(i=>i.dataset.keyword);s.manual=String(document.getElementById('feedManualKeywordsV249232')?.value||'').trim();saveFeedSettingsV249232(s);closeMemberMenu();toast('Εφαρμόστηκε αναζήτηση Ροής');loadFeed()}catch(e){toast('Δεν εφαρμόστηκε: '+(e.message||e))}return false}
function setFreeFeedV249232(){let s=feedDefaultSettingsV249232();s.free=true;saveFeedSettingsV249232(s);closeMemberMenu();toast('Ελεύθερη Ροή: ό,τι καινούργιο με σειρά');loadFeed();return false}
function philosopherWisdomV249232(index=0){const q=[['Σωκράτης','Η αληθινή αρχή είναι να γνωρίζουμε τι δεν ξέρουμε.'],['Πλάτων','Η παιδεία είναι το φως που γυρίζει την ψυχή προς το καλό.'],['Αριστοτέλης','Η αρετή χτίζεται με πράξεις, όχι μόνο με λόγια.'],['Επίκτητος','Δεν ορίζουμε πάντα τα γεγονότα, ορίζουμε όμως τη στάση μας.'],['Μάρκος Αυρήλιος','Η ηρεμία μεγαλώνει όταν κρατάμε τον νου καθαρό.'],['Καντ','Ο άνθρωπος πρέπει να αντιμετωπίζεται ως σκοπός, όχι ως μέσο.'],['Χάνα Άρεντ','Η δημόσια ζωή χρειάζεται ευθύνη, σκέψη και πράξη.'],['Καμύ','Ακόμη και στο δύσκολο, ο άνθρωπος μπορεί να κρατήσει αξιοπρέπεια.']];return q[Math.abs(index)%q.length]}
function feedProPanel(kind,index=0){const logo='<div class="feedGoldLogo"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display=\'none\'"></div><div class="feedGoldBrandText"><span class="okRainbow">OK</span> <small>ithaki</small></div>';if(kind==='poll'){const key='gold_poll_v249232_'+todayKey();const p={q:'Ποια Ροή θέλεις να βλέπεις πρώτη στην ΙΘΑΚΗ;',opts:['Φίλοι','Ακολουθώ','Ίδια ενδιαφέροντα','Ελεύθερη Ροή'],bars:[55,44,39,62]};const local=cardLocalStats(key,p.opts,p.opts.map((o,i)=>({index:i,text:o,count:Math.max(1,Math.round(p.bars[i]/12)),percent:p.bars[i]})));const opts=p.opts.map((o,i)=>{const row=(local.options||[]).find(x=>+x.index===i)||{count:0,percent:p.bars[i]||0};return `<button class="feedGoldPollChoice" onclick="ITH.voteCardChoice(this,'${escJs(key)}',${i})"><em style="width:${+row.percent||0}%"></em><span>${esc(o)}</span><b>${+row.count||0} · ${+row.percent||0}%</b></button>`}).join('');return `<article class="card feedGoldPollCard v249232Poll" data-feed-panel="${esc(key)}"><div class="feedGoldCardInner">${logo}<h3 class="feedGoldQuote">${esc(p.q)}</h3><div class="feedGoldPollOptions">${opts}</div><div class="row feedGoldCardActions"><button class="btn green" onclick="ITH.openPostCommentsPanel('${escJs(key)}')"><span>💬</span></button><button class="btn" onclick="ITH.like('${escJs(key)}')"><span>❤️</span></button></div></div></article>`}const [who,quote]=philosopherWisdomV249232(index);const key='gold_wisdom_v249232_'+index;return `<article class="card feedGoldWisdomCard v249232Wisdom" data-feed-panel="${esc(key)}"><div class="feedGoldCardInner">${logo}<h3 class="feedGoldQuote">${esc(quote)}<small>${esc(who)} · αρχαία/νέα φιλοσοφική σκέψη</small></h3><div class="row feedGoldCardActions"><button class="btn green" onclick="ITH.openPostCommentsPanel('${escJs(key)}')"><span>💬</span></button><button class="btn" onclick="ITH.like('${escJs(key)}')"><span>❤️</span></button></div></div></article>`}
function shouldShowDailyPollV249232(){try{return localStorage.getItem('ith_poll_card_day_v249232')!==todayKey()}catch{return true}}
function markDailyPollV249232(){try{localStorage.setItem('ith_poll_card_day_v249232',todayKey())}catch{}}
function renderFeedWithPanels(posts,cfg){posts=uniquePosts(posts||[]);let html='',n=0,insertedWisdom=0;const last=+(localStorage.getItem('ith_last_feed_gold_panel_v249217')||0)||0;const due10=Date.now()-last>=10*60000;const canWisdom=posts.length>=12||due10;for(const p of posts){html+=renderPost(p);n++;if(canWisdom&&insertedWisdom<2&&(n%12===0)){html+=feedProPanel('wisdom',Math.floor(Date.now()/600000)+n);insertedWisdom++}}if(insertedWisdom>0){try{localStorage.setItem('ith_last_feed_gold_panel_v249217',String(Date.now()))}catch{}}if(shouldShowDailyPollV249232()&&posts.length>=1){const at=Math.min(Math.max(1,Math.floor(posts.length/2)),posts.length);const parts=html.split('</article>');if(parts.length>2){parts.splice(at,0,feedProPanel('poll',at));html=parts.join('</article>');}else html+=feedProPanel('poll',at);markDailyPollV249232()}return html}
function filterFeedCardsV249189(){try{const q=normalizeGrV249232(document.getElementById('feedSearchV249189')?.value||'').trim();document.querySelectorAll('#feedPage .feedList>article,#feedPage .feedList>.card').forEach(a=>{if(!q){a.style.display='';return}const tx=normalizeGrV249232(a.textContent||'');a.style.display=tx.includes(q)?'':'none'})}catch{}}
function feedEndUnlockHtmlV249225(count){const unlocked=feedUnlockedAllV249225();return `<div class="card feedEndUnlockV249225"><h3>${unlocked?'✅ Ελεύθερη Ροή':'Τέλος τελευταίων δημοσιεύσεων'}</h3><p>${unlocked?'Εμφανίζονται περισσότερες δημοσιεύσεις χωρίς αυτόματο γύρισμα στην αρχή.':'Η Ροή δεν θα σε πετάξει πια στην αρχή. Θέλεις να ελευθερώσεις περισσότερα/όλα τα διαθέσιμα βίντεο;'}</p><div class="row"><button class="btn green" onclick="window.unlockAllFeedVideosV249225()">🎬 Ελευθέρωσε όλα τα βίντεο</button><button class="btn freeV249232" onclick="ITH.setFreeFeedV249232()">🌊 Ελεύθερη Ροή</button><button class="btn" onclick="window.keepLatestFeedV249225()">Μείνε στις τελευταίες</button></div><div class="date">Φορτώθηκαν ${esc(String(count||0))} δημοσιεύσεις.</div></div>`}
/* V249429_LEGACY_LOAD_FEED_REMOVED */




/* V249233 CLEAN NOTIFICATIONS + POLL CARDS + ADMIN CLEANUP BUTTON
   Safe override on V249232. Notifications show only friend-request cards, no avatar strip.
   Poll cards use only the same clean 💬/❤️ vertical action style as wisdom cards. */
function injectV249233CleanCss(){try{if(document.getElementById('ithV249233CleanCss'))return;const st=document.createElement('style');st.id='ithV249233CleanCss';st.textContent=`
  .v249233FriendNoticeOnly{height:100%!important;overflow:auto!important;padding:10px 10px calc(var(--bar) + 18px)!important;-webkit-overflow-scrolling:touch!important;scrollbar-width:thin!important}
  .v249233FriendNoticeOnly .noticeAvatarStrip{display:none!important}
  .v249233NoticeList{display:flex!important;flex-direction:column!important;gap:10px!important;max-height:calc(100dvh - var(--top) - var(--bar) - 90px)!important;overflow:auto!important;padding:7px 2px 18px!important;-webkit-overflow-scrolling:touch!important;scrollbar-width:thin!important;touch-action:pan-y!important;overscroll-behavior:contain!important}
  .v249233FriendCard{border:1px solid rgba(255,217,110,.35)!important;background:linear-gradient(135deg,rgba(255,217,110,.11),rgba(255,255,255,.055))!important;border-radius:20px!important;padding:12px!important;display:block!important}
  .v249233FriendCard b{color:#ffd96e!important}.v249233FriendCard .date{line-height:1.35!important}.v249233NoticeActions{display:flex!important;gap:7px!important;flex-wrap:wrap!important;margin-top:9px!important}.v249233NoticeActions .btn{border-radius:999px!important;min-height:38px!important}
  #feedPage .post.pollPost .pollPostActions,#feedPage .feedGoldCardActions{position:absolute!important;right:clamp(7px,1.4vw,13px)!important;left:auto!important;top:50%!important;transform:translateY(-50%)!important;z-index:80!important;display:flex!important;flex-direction:column!important;gap:8px!important;padding:6px 4px!important;border-radius:999px!important;background:rgba(5,18,31,.20)!important;border:1px solid rgba(255,255,255,.12)!important;backdrop-filter:blur(8px)!important;-webkit-backdrop-filter:blur(8px)!important}
  #feedPage .post.pollPost .pollPostActions .actionIcon,#feedPage .feedGoldCardActions .btn{width:40px!important;min-width:40px!important;height:40px!important;min-height:40px!important;border-radius:50%!important;padding:0!important;font-size:0!important;display:grid!important;place-items:center!important;background:rgba(255,255,255,.09)!important;border:1px solid rgba(255,255,255,.14)!important;color:#fff!important;box-shadow:none!important}
  #feedPage .post.pollPost .pollPostActions .actionIcon:nth-child(1)::before,#feedPage .feedGoldCardActions .btn:nth-child(1)::before{content:'💬'!important;font-size:22px!important;letter-spacing:0!important}
  #feedPage .post.pollPost .pollPostActions .actionIcon:nth-child(2)::before,#feedPage .feedGoldCardActions .btn:nth-child(2)::before{content:'❤️'!important;font-size:22px!important;letter-spacing:0!important}
  #feedPage .post.pollPost .pollPostActions .actionIcon:nth-child(n+3),#feedPage .feedGoldCardActions .btn:nth-child(n+3){display:none!important}
  #feedPage .pollRibbon,#feedPage .photoLikeBadge,#feedPage .photoLikeTop,#feedPage .pollTitle,#feedPage .photoLikePrompt,#feedPage .pollMode,#feedPage .cardIconBar,#feedPage .feedGoldVoteMode,#feedPage .feedGoldResults{display:none!important}
  #feedPage .pollFeedCard,#feedPage .feedGoldPollCard .feedGoldCardInner,#feedPage .professionalPollCard{padding-right:58px!important;overflow:hidden!important;max-height:calc(95dvh - var(--bar) - 20px)!important}
  #feedPage .pollVoteOptions,#feedPage .feedGoldPollOptions{overflow:visible!important;max-height:none!important;touch-action:pan-y!important}
  .cleanMembersCardV249233{border-color:rgba(255,112,112,.35)!important;background:rgba(255,112,112,.08)!important}.cleanMembersCardV249233 code{font-size:11px;color:#ffd7d7;overflow-wrap:anywhere}
  @media(max-width:760px){#feedPage .post.pollPost .pollPostActions,#feedPage .feedGoldCardActions{right:6px!important;gap:6px!important}#feedPage .post.pollPost .pollPostActions .actionIcon,#feedPage .feedGoldCardActions .btn{width:38px!important;min-width:38px!important;height:38px!important;min-height:38px!important}#feedPage .pollFeedCard,#feedPage .feedGoldPollCard .feedGoldCardInner{padding-right:50px!important}}
`;document.head.appendChild(st)}catch(e){console.warn('V249233 clean css',e)}}
function v249233NoticeKey(n){return String(n.id||n.event_id||n.type+'-'+n.from_id+'-'+n.to_id+'-'+n.created_at)}
function v249233IsFriendRequestPending(n){const t=String(n.type||'');const st=String(n.status||'pending');return (t==='contact_invite'||t==='contact') && st==='pending'}
async function legacyNotifyCenterV249526_3(){injectV249231AvatarDmNotifyCss();injectV249233CleanCss();const menu=$('memberMenu');menu.innerHTML=`<div class="v249233FriendNoticeOnly"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Αιτήματα φιλίας</b><button class="icon" style="margin-left:auto" onclick="ITH.markNoticesRead()">✓</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="card">Φόρτωση αιτημάτων...</div></div>`;menu.classList.add('show','fullAvatarMenuV249231');let items=[];try{const r=await fetchJson(`/api/notifications?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=300`);items=(r.items||[]).map(x=>({server:true,type:x.type==='contact'?'contact_invite':x.type,status:x.status,id:x.id,from_id:x.from_id,from_name:x.from_name,to_id:x.to_id,to_name:x.to_name,created_at:x.created_at,text:(x.from_id===state.device?'Στάλθηκε αίτημα φιλίας':'Σας έστειλε αίτημα φιλίας')}))}catch(e){console.warn('server notifications',e)}try{items=[...items,...uniqueNotices(localNotices()).map(x=>Object.assign({local:true},x))]}catch{}const seen=new Set();items=items.filter(v249233IsFriendRequestPending).filter(n=>{const k=v249233NoticeKey(n);if(seen.has(k))return false;seen.add(k);return true}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));const card=n=>{const other=String(n.from_id===state.device?n.to_id:n.from_id||n.to_id||'');const p=v249231PersonById(other);const inbound=String(n.to_id||'')===String(state.device);const title=inbound?'Νέο αίτημα φιλίας':'Αίτημα φιλίας σε αναμονή';return `<div class="card v249233FriendCard" data-notice-key="${esc(v249233NoticeKey(n))}"><b>🤝 ${title}</b><div class="date">${esc(p.nickname||n.from_name||n.to_name||'Μέλος')} · ${esc(n.text||'')}</div>${inbound?`<div class="v249233NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${escJs(v249233NoticeKey(n))}')">Αποδοχή</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${escJs(v249233NoticeKey(n))}')">Απόρριψη</button></div>`:`<div class="v249233NoticeActions"><button class="btn" onclick="ITH.member('${escJs(other)}')">Μενού μέλους</button></div>`}</div>`};menu.innerHTML=`<div class="v249233FriendNoticeOnly"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Αιτήματα φιλίας</b><button class="icon" style="margin-left:auto" onclick="ITH.markNoticesRead()">✓</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="v249233NoticeList">${items.map(card).join('')||'<div class="card">Δεν υπάρχουν αιτήματα φιλίας σε αναμονή.</div>'}</div><div class="card"><b>Καθαρή οθόνη</b><div class="date">Εδώ εμφανίζονται μόνο αιτήματα φιλίας. Μετά την Αποδοχή ή Απόρριψη, η ειδοποίηση φεύγει από τη λίστα.</div></div></div>`;return false}
async function respondFriendProposalV249233(eventId,accepted,peerId,noticeKey){try{await fetchJson('/api/social/friend/respond',{method:'POST',body:JSON.stringify({room_id:state.room,id:eventId,device_id:state.device,accepted:!!accepted})});if(accepted){let a=[];try{a=JSON.parse(localStorage.getItem('ith_contacts')||'[]')}catch{}if(peerId&&!a.includes(String(peerId)))a.push(String(peerId));localStorage.setItem('ith_contacts',JSON.stringify(a))}try{const sel=noticeKey?`[data-notice-key="${CSS.escape(noticeKey)}"]`:'';if(sel){const el=document.querySelector(sel);if(el)el.remove()}}catch{}toast(accepted?'Η φιλία έγινε αποδεκτή':'Το αίτημα απορρίφθηκε');setTimeout(()=>notifyCenter(),350);if(state.activeChannel)loadMessages(true)}catch(e){toast('Δεν ολοκληρώθηκε: '+(e.message||e))}return false}
function renderPollCard(m){injectV249233CleanCss();const idRaw=String((m&&(m.poll_id||m.pollId||m.pollID||m.id))||('poll_'+Math.random().toString(36).slice(2)));const id=safeDomId(idRaw),idJs=escJs(idRaw);const opts=pollOptionLabels(m||{}).slice(0,9);const st=pollStatsFromMedia(m||{},idRaw,opts);const question=(m&&m.question)||uiText('What is your opinion?');const manyCls=opts.length>=7?' pollManyOptions':(opts.length>=5?' pollMediumOptions':'');const logo='<div class="pollLogoClean"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display=\'none\'"><div><b><span class="okRainbow">OK</span></b><small>ithaki</small></div></div>';const options=opts.map((o,i)=>{const row=(st.options||[]).find(x=>+x.index===i)||{count:0,percent:0};return `<button class="pollChoice" onclick="ITH.votePoll('${idJs}',${i},'${escJs(o)}')"><span>${esc(o)}</span><em style="width:${+row.percent||0}%"></em><b>${+row.count||0} · ${+row.percent||0}%</b></button>`}).join('');return `<div class="pollFeedCard professionalPollCard cleanPollV249233${manyCls}" id="poll_${id}">${logo}<div class="pollQuestion">${esc(question)}</div><div class="pollVoteOptions">${options}</div><div class="pollTotal">${uiText('Voted')} ${st.total_votes||0} ${uiText('members')}</div></div>`}
async function openCleanMembersPanelV249233(){injectV249233CleanCss();const menu=$('memberMenu');menu.innerHTML=`<div class="v249231MenuScroll"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🧹 Καθαρισμός δοκιμαστικών μελών</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card cleanMembersCardV249233"><b>Προσοχή</b><div class="date">Το εργαλείο BAT σβήνει από τη λίστα μελών μόνο όσους δεν έχουν καμία δημοσίευση. Όσοι έχουν δημοσιεύσει μένουν.</div><code>06_CLEAN_TEST_MEMBERS_KEEP_POSTERS.cmd</code></div><div class="card"><div class="date">Για ασφάλεια, ο καθαρισμός γίνεται από τον server με SSH, όχι από δημόσιο κουμπί μέσα στην εφαρμογή.</div></div></div>`;menu.classList.add('show','fullAvatarMenuV249231');return false}



/* V249237 PRESERVE OFFLINE MEMBERS + V249236 BOOT REPAIR + REALTIME START GUARD
   Σκοπός: να μη σκάει ποτέ το boot() από λείπουσες V249230/V249231 συναρτήσεις.
   Κρατάει τη V249235 λίστα φίλων πρώτα για Μηνύματα και ανοίγει WebSocket/call polling κανονικά. */
function injectV249230ContactFirstCss(){try{if(document.getElementById('ithV249230ContactFirstCss'))return;const st=document.createElement('style');st.id='ithV249230ContactFirstCss';st.textContent=`
  .contactChooserV249230{height:100%;max-height:calc(100dvh - var(--top) - var(--bar) - 18px);overflow:auto;padding:10px;box-sizing:border-box;-webkit-overflow-scrolling:touch}.contactChooserV249230 .chooserHead{display:flex;gap:10px;align-items:center;margin-bottom:10px}.contactChooserV249230 .chooserTitle{min-width:0;flex:1}.contactChooserV249230 .chooserTitle b{display:block;color:#ffd96e;font-size:18px}.contactChooserV249230 .chooserTitle span{display:block;color:rgba(255,255,255,.72);font-size:12px;margin-top:2px}.contactGridV249230{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:9px}.contactRowV249230{display:grid;grid-template-columns:auto 1fr auto;gap:9px;align-items:center;padding:10px;border-radius:18px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.11);text-align:left;color:#eef7ff}.contactRowV249230.friend{border-color:rgba(54,240,160,.34)}.contactRowV249230.waiting{border-color:rgba(255,217,110,.32);background:rgba(255,217,110,.08)}.contactRowV249230 .who{min-width:0}.contactRowV249230 .who b{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.contactRowV249230 .who small{display:block;color:rgba(255,255,255,.62);font-size:11px}.contactRowV249230 .goBtn{border-radius:999px;padding:8px 10px;background:rgba(54,240,160,.18);border:1px solid rgba(54,240,160,.38);font-weight:1000}.contactRowV249230.waiting .goBtn{background:rgba(255,217,110,.18);border-color:rgba(255,217,110,.38);color:#ffe6a0}@media(max-width:760px){.contactGridV249230{grid-template-columns:1fr}.contactChooserV249230{padding:8px}}
`;document.head.appendChild(st)}catch(e){console.warn('v249230 contact css',e)}}
function injectV249230CallAudioCss(){try{if(document.getElementById('ithV249230CallAudioCss'))return;const st=document.createElement('style');st.id='ithV249230CallAudioCss';st.textContent=`
  .callAudioUnlockV249230{display:inline-flex!important;align-items:center;justify-content:center;gap:8px;background:linear-gradient(135deg,#36f0a0,#ffd96e)!important;color:#071321!important;font-weight:1000!important;border:0!important;box-shadow:0 8px 28px rgba(54,240,160,.24)!important}.callDiagV249230{font-size:11px;color:rgba(255,255,255,.72);line-height:1.35;margin-top:5px}.callActions .callDiagBtnV249230{font-size:12px;padding:8px 10px;border-radius:999px;background:rgba(255,255,255,.08)}.voiceCallBox .callStage audio{width:min(92vw,420px)!important;margin:0 auto!important;display:block!important}.videoCallBox #callRemote{background:#020712!important}.videoCallBox #callLocal{border:2px solid rgba(255,217,110,.45)!important}
`;document.head.appendChild(st)}catch(e){console.warn('v249230 call css',e)}}
function injectV249231AvatarDmNotifyCss(){try{if(document.getElementById('ithV249231AvatarDmNotifyCss'))return;const st=document.createElement('style');st.id='ithV249231AvatarDmNotifyCss';st.textContent=`
  .memberMenu.show.fullAvatarMenuV249231{position:fixed!important;inset:calc(env(safe-area-inset-top,0px) + 8px) 8px calc(var(--bar) + 8px) 8px!important;width:auto!important;max-width:780px!important;margin:auto!important;display:block!important;overflow:hidden!important;border-radius:24px!important;background:linear-gradient(180deg,rgba(6,20,35,.98),rgba(3,10,20,.98))!important;border:1px solid rgba(255,217,110,.26)!important;box-shadow:0 26px 90px rgba(0,0,0,.62)!important;z-index:99990!important}.v249231MenuScroll{height:100%!important;overflow:auto!important;padding:10px 10px calc(var(--bar) + 16px)!important;box-sizing:border-box!important;scrollbar-width:thin!important;-webkit-overflow-scrolling:touch!important}.v249231Hero{display:grid!important;grid-template-columns:auto 1fr auto!important;gap:12px!important;align-items:center!important;padding:12px!important;border-radius:22px!important;background:linear-gradient(135deg,rgba(255,217,110,.14),rgba(54,240,160,.07))!important;border:1px solid rgba(255,255,255,.11)!important;margin-bottom:10px!important}.v249231Actions{display:grid!important;grid-template-columns:repeat(2,minmax(0,1fr))!important;gap:9px!important;margin-top:10px!important}.v249231Actions .tile{min-height:72px!important;border-radius:20px!important;background:rgba(255,255,255,.065)!important;border:1px solid rgba(255,255,255,.11)!important}.v249231Actions .tile.primary{background:linear-gradient(135deg,rgba(54,240,160,.24),rgba(255,217,110,.12))!important;border-color:rgba(54,240,160,.42)!important}.v249231Actions .tile.request{background:linear-gradient(135deg,rgba(255,217,110,.18),rgba(255,255,255,.06))!important;border-color:rgba(255,217,110,.38)!important}.v249231FriendNote{margin-top:10px!important;border:1px solid rgba(255,217,110,.34)!important;background:rgba(255,217,110,.10)!important;border-radius:18px!important;padding:10px!important;color:rgba(255,255,255,.84)!important}
`;document.head.appendChild(st)}catch(e){console.warn('v249231 css',e)}}
function ithV249236FriendIds(){const ids=new Set();try{v249231FriendIds().forEach(id=>ids.add(String(id)))}catch{}try{(state.socialFriendsV249225||[]).forEach(p=>{const id=String(p.device_id||p.id||'');if(id)ids.add(id)})}catch{}try{JSON.parse(localStorage.getItem('ith_contacts')||'[]').forEach(id=>{id=String(id||'');if(id)ids.add(id)})}catch{}return ids}
function ithV249236AllPeople(){const m=new Map();try{peopleArray().forEach(p=>{const id=String(p.id||p.device_id||'');if(id)m.set(id,Object.assign({},p,{id,device_id:id}))})}catch{}try{state.people.forEach((p,id)=>{id=String(id||p.id||p.device_id||'');if(id)m.set(id,Object.assign({},m.get(id)||{},p,{id,device_id:id}))})}catch{}try{(state.socialFriendsV249225||[]).forEach(p=>{const id=String(p.device_id||p.id||'');if(id)m.set(id,Object.assign({},m.get(id)||{},p,{id,device_id:id}))})}catch{}try{JSON.parse(localStorage.getItem('ith_contacts')||'[]').forEach(id=>{id=String(id||'');if(id&&!m.has(id))m.set(id,{id,device_id:id,nickname:'Φίλος',avatar:'',online:false})})}catch{}return [...m.values()].filter(p=>String(p.id||p.device_id||'')&&String(p.id||p.device_id||'')!==String(state.device)&&!(typeof isBlocked==='function'&&isBlocked(String(p.id||p.device_id||''))))}
function ithV249236ActionIcon(mode){mode=String(mode||'message');return mode==='video'?'📹':(mode==='voice'?'📞':'💬')}
function ithV249236ActionLabel(mode){mode=String(mode||'message');return mode==='video'?'Βιντεοκλήση':(mode==='voice'?'Φωνητική κλήση':'Μήνυμα')}
async function chooseCommunicationContactV249230(id,mode='message'){id=String(id||'');mode=String(mode||'message');if(!id)return false;try{await loadSocialFriendsV249225()}catch{}const friendIds=ithV249236FriendIds();if(!friendIds.has(id)){try{await sendFriendProposal(id);toast('Στάλθηκε αίτημα φιλίας. Μετά την αποδοχή ανοίγουν τα μηνύματα/κλήσεις.',4500);setTimeout(()=>notifyCenter(),500)}catch(e){toast('Δεν στάλθηκε αίτημα: '+(e.message||e),4500)}return false}try{$('memberMenu')?.classList.remove('show')}catch{}await startDM(id);if(mode==='video')return startVideoCall();if(mode==='voice')return startVoiceCall();return false}
async function openCommunicationContactsV249230(mode='message'){injectV249230ContactFirstCss();injectV249231AvatarDmNotifyCss();mode=String(mode||'message');const menu=$('memberMenu');if(!menu)return false;const title=ithV249236ActionIcon(mode)+' '+ithV249236ActionLabel(mode);menu.innerHTML=`<div class="contactChooserV249230"><div class="chooserHead"><button class="icon" onclick="ITH.closeMember()">‹</button><div class="chooserTitle"><b>${title}</b><span>Πρώτα διαλέγεις φίλο. Αν δεν είναι φίλος, στέλνεται αίτημα φιλίας πριν την επικοινωνία.</span></div><button class="icon" onclick="ITH.loadPeople();ITH.openCommunicationContactsV249230('${escJs(mode)}')">🔄</button></div><div class="card">Φόρτωση μελών...</div></div>`;menu.classList.add('show','fullAvatarMenuV249231');try{await loadPeople()}catch{}try{await loadSocialFriendsV249225()}catch{}const friendIds=ithV249236FriendIds();let list=ithV249236AllPeople();list.sort((a,b)=>((friendIds.has(String(b.id||b.device_id))?1:0)-(friendIds.has(String(a.id||a.device_id))?1:0))||((b.online?1:0)-(a.online?1:0))||String(a.nickname||'').localeCompare(String(b.nickname||''),'el'));const row=p=>{const id=String(p.id||p.device_id||'');const isFriend=friendIds.has(id);const status=isFriend?(p.online?'Φίλος · ενεργός':'Φίλος · ανενεργός'):(p.online?'Μη φίλος · ενεργός':'Μη φίλος · αίτημα πρώτα');const dot=p.online?'on':'off';return `<button class="contactRowV249230 ${isFriend?'friend':'waiting'}" onclick="ITH.chooseCommunicationContactV249230('${escJs(id)}','${escJs(mode)}')"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${dot}"></i></span><span class="who"><b>${esc(p.nickname||'Μέλος')}</b><small>${esc(status)}</small></span><span class="goBtn">${isFriend?ithV249236ActionIcon(mode):'🤝'}</span></button>`};menu.innerHTML=`<div class="contactChooserV249230"><div class="chooserHead"><button class="icon" onclick="ITH.closeMember()">‹</button><div class="chooserTitle"><b>${title}</b><span>Φίλοι πρώτοι. Για μη φίλο στέλνεται αίτημα φιλίας.</span></div><button class="icon" onclick="ITH.loadPeople();ITH.openCommunicationContactsV249230('${escJs(mode)}')">🔄</button></div><div class="contactGridV249230">${list.map(row).join('')||'<div class="card">Δεν υπάρχουν μέλη ακόμη.</div>'}</div></div>`;return false}
function unlockCallAudioV249230(){try{bridgeCall('setCallAudioMode',true)}catch{}try{bridgeCall('stopCallAlert')}catch{}try{const r=$('callRemote');if(r){r.muted=false;r.volume=1;r.autoplay=true;r.playsInline=true;r.controls=true;r.play&&r.play().catch(()=>{})}}catch{}try{const a=$('callRemoteAudio');if(a){a.muted=false;a.volume=1;a.autoplay=true;a.play&&a.play().catch(()=>{})}}catch{}try{if(state.call){state.call.speakerOn=true;updateCallControlButtons&&updateCallControlButtons()}}catch{}try{const u=$('callAudioUnlock');if(u)u.style.display='none'}catch{}try{callStatusText('Έγινε χειροκίνητο άνοιγμα φωνής / ηχείου')}catch{toast('Άνοιγμα φωνής / ηχείου ενεργό')}return false}
function openCallDiagnosticsV249230(){try{const c=state.call||{};const txt=['Κλήση: '+(c.sessionId||c.id||'καμία'), 'τύπος: '+(c.kind||c.type||'-'), 'κατάσταση: '+(c.status||c.phase||'-'), 'WS: '+(state.wsReady?'ενεργό':'όχι ακόμη')].join(' · ');toast(txt,8000)}catch(e){toast('Δεν υπάρχει ενεργή κλήση',5000)}return false}
async function v249231AvatarAction(id,action){id=String(id||'');action=String(action||'');if(!id)return false;if(action==='message')return chooseCommunicationContactV249230(id,'message');if(action==='video')return chooseCommunicationContactV249230(id,'video');if(action==='voice')return chooseCommunicationContactV249230(id,'voice');if(action==='posts')return memberPosts(id);if(action==='friends')return openSocialList(id,'friends');if(action==='followers')return openSocialList(id,'followers');if(action==='following')return openSocialList(id,'following');if(action==='follow')return toggleFollowMember(id);if(action==='friend')return sendFriendProposal(id);return showMemberMenu(id)}
async function openLinkedDmFromUrlV249227(){try{const u=new URL(location.href);const dm=u.searchParams.get('dm')||u.searchParams.get('peer')||u.searchParams.get('from_id')||'';const kind=u.searchParams.get('kind')||'';if(dm){state.activePeer='';page('dm');await loadPeople();await startDM(dm);return false}if(kind==='message'||kind==='video_call'||kind==='call'){state.activePeer='';page('dm');return false}}catch(e){}return false}



/* V249238 NOTIFICATIONS OPEN + ACTIVE MEMBERS ONLY + PREFS SAFE PATCH */
function injectV249238NotifyCss(){try{if(document.getElementById('ithV249238NotifyCss'))return;const st=document.createElement('style');st.id='ithV249238NotifyCss';st.textContent=`
.ithNotifyFabV249238{position:fixed!important;right:12px!important;top:calc(env(safe-area-inset-top,0px) + 12px)!important;z-index:99980!important;width:48px!important;height:48px!important;border-radius:50%!important;border:1px solid rgba(255,217,110,.44)!important;background:linear-gradient(135deg,rgba(255,217,110,.95),rgba(54,240,160,.84))!important;color:#071321!important;font-weight:1000!important;box-shadow:0 14px 36px rgba(0,0,0,.42)!important}.ithNotifyFabV249238 .badge{position:absolute;right:-3px;top:-5px;min-width:20px;height:20px;padding:0 5px;border-radius:999px;background:#ff3b30;color:white;font-size:12px;display:grid;place-items:center;border:2px solid #071321}.v249238NotifyPanel{height:100%!important;overflow:auto!important;padding:10px calc(10px + env(safe-area-inset-right,0px)) calc(var(--bar) + 18px) calc(10px + env(safe-area-inset-left,0px))!important;box-sizing:border-box!important;-webkit-overflow-scrolling:touch}.v249238FriendReq{border:1px solid rgba(255,217,110,.26)!important;background:rgba(255,255,255,.07)!important}.v249238FriendReq.inbound{border-color:rgba(54,240,160,.45)!important;background:rgba(54,240,160,.08)!important}.v249238FriendReq.outbound{border-color:rgba(255,217,110,.42)!important;background:rgba(255,217,110,.07)!important}.v249238NoticeActions{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}.v249238PrefGrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:8px}.v249238PrefGrid label{display:flex;align-items:center;gap:8px;border-radius:14px;background:rgba(255,255,255,.07);padding:9px;border:1px solid rgba(255,255,255,.10);font-weight:900}.v249238PrefGrid input[type=checkbox]{width:18px;height:18px;accent-color:#ffd96e}.v249238QuietRow{display:grid;grid-template-columns:1fr 1fr;gap:8px}.v249238QuietRow input{width:100%;box-sizing:border-box;border-radius:12px;border:1px solid rgba(255,255,255,.12);background:rgba(0,0,0,.25);color:white;padding:9px}.topStoryBarV249169 .storyHint.activeOnlyV249238{color:rgba(255,217,110,.84)!important}
`;document.head.appendChild(st)}catch(e){console.warn('v249238 css',e)}}
function v249238ActivePeople(){try{return peopleArray().filter(x=>x && String(x.id||x.device_id||'')!==String(state.device) && !!x.online && (x.avatar||x.animal||x.nickname)).slice(0,80)}catch{return []}}
function homeStories(){injectV249238NotifyCss();const serverPeople=v249238ActivePeople();const ithakiStory=`<button class="storyItem on ithakiOfficialStory" onclick="return ITH.openIthakiPostsPreview?ITH.openIthakiPostsPreview():ITH.page('feed')" title="${uiText('Δημοσιεύσεις ΙΘΑΚΗΣ')}"><span class="avatarDotWrap"><span class="avatar"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display='none'"></span><i class="on"></i></span><small>ΙΘΑΚΗ</small></button>`;const empty=!serverPeople.length?`<div class="storyHint activeOnlyV249238">Δεν υπάρχει ενεργό μέλος τώρα. Οι ανενεργοί φίλοι μένουν στα Μηνύματα, δεν σβήνονται.</div>`:'';return `<section class="homeStories storyGlassBar topStoryBarV249169" aria-label="Ενεργά μέλη"><div class="storyScroll">${ithakiStory}${serverPeople.map(p=>{const id=String(p.id||p.device_id||'');const click=unreadFrom(id)?`ITH.startDM('${escJs(id)}')`:`ITH.member('${escJs(id)}')`;return `<button class="storyItem on" onclick="${click}"><span class="avatarDotWrap">${avatarHtml(p)}<i class="on"></i></span><small>${esc(p.nickname||uiText('Μέλος'))}</small></button>`}).join('')}</div>${empty}</section>`}
function ensureNotificationFabV249238(){try{injectV249238NotifyCss();let b=document.getElementById('ithNotifyFabV249238');if(!b){b=document.createElement('button');b.id='ithNotifyFabV249238';b.className='ithNotifyFabV249238';b.type='button';b.innerHTML='🔔<span class="badge" style="display:none">0</span>';b.onclick=()=>{try{notifyCenter()}catch(e){toast('Δεν ανοίγουν οι ειδοποιήσεις: '+(e.message||e))}};document.body.appendChild(b)}refreshNotificationBadgeV249238()}catch(e){}}
async function refreshNotificationBadgeLegacyV249238_1(){try{const b=document.getElementById('ithNotifyFabV249238');if(!b)return;const bd=b.querySelector('.badge');let c=0;try{const r=await fetchJson(`/api/notifications/count?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);c=+(r.count||0)||0}catch{}if(!c)c=getMessageNoticeCount?getMessageNoticeCount():0;if(bd){bd.textContent=c>9?'9+':String(c);bd.style.display=c?'grid':'none'}}catch(e){}}
async function legacyNotifyCenterV249526_4(){injectV249238NotifyCss();injectV249231AvatarDmNotifyCss();const menu=$('memberMenu');if(!menu)return false;menu.classList.add('show','fullAvatarMenuV249231');menu.innerHTML=`<div class="v249238NotifyPanel"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Αιτήματα φιλίας</b><button class="btn" style="margin-left:auto" onclick="ITH.openNotificationSettingsV249238()">⚙️ Ρυθμίσεις</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="card">Φόρτωση αιτημάτων...</div></div>`;let items=[];let serverOk=false;try{const r=await fetchJson(`/api/notifications?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=300`);serverOk=!!r.ok;items=(r.items||[]).map(x=>({server:true,type:x.type==='contact'?'contact_invite':x.type,status:x.status||'pending',id:x.id,from_id:x.from_id,from_name:x.from_name,to_id:x.to_id,to_name:x.to_name,created_at:x.created_at||x.updated_at,text:(String(x.to_id||'')===String(state.device)?'Σας έστειλε αίτημα φιλίας':'Το αίτημα φιλίας περιμένει αποδοχή από την άλλη συσκευή')}))}catch(e){items=[];console.warn('V249238 notifications failed',e)}try{items=[...items,...uniqueNotices(localNotices()).filter(v249233IsFriendRequestPending)]}catch{}const seen=new Set();items=items.filter(n=>{const k=String(n.id||n.event_id||n.type+'-'+n.from_id+'-'+n.to_id+'-'+n.created_at);if(seen.has(k))return false;seen.add(k);return String(n.status||'pending')==='pending'}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));const incoming=items.filter(n=>String(n.to_id||'')===String(state.device));const outgoing=items.filter(n=>String(n.from_id||'')===String(state.device));const otherItems=items.filter(n=>String(n.to_id||'')!==String(state.device)&&String(n.from_id||'')!==String(state.device));const card=n=>{const inbound=String(n.to_id||'')===String(state.device);const outbound=String(n.from_id||'')===String(state.device);const other=String(inbound?n.from_id:(outbound?n.to_id:(n.from_id||n.to_id||'')));const p=v249231PersonById(other);const name=esc(p.nickname||n.from_name||n.to_name||'Μέλος');return `<div class="card v249238FriendReq ${inbound?'inbound':outbound?'outbound':'other'}"><b>${inbound?'🤝 Νέο αίτημα φιλίας':outbound?'⏳ Περιμένει απάντηση':'🤝 Αίτημα φιλίας'}</b><div class="row" style="align-items:center;margin-top:8px"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${p.online?'on':'off'}"></i></span><div><b>${name}</b><div class="date">${esc(n.text||'')} · ${p.online?'ενεργός':'ανενεργός'}</div></div></div>${inbound?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${escJs(v249233NoticeKey(n))}')">✅ Αποδοχή</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${escJs(v249233NoticeKey(n))}')">❌ Απόρριψη</button><button class="btn" onclick="ITH.startDM('${escJs(other)}')">💬 Μηνύματα</button></div>`:`<div class="v249238NoticeActions"><button class="btn" onclick="ITH.member('${escJs(other)}')">Μενού μέλους</button>${outbound?'<span class="date">Η αποδοχή γίνεται μόνο στη συσκευή που έλαβε το αίτημα.</span>':''}</div>`}</div>`}
const html=[...incoming,...outgoing,...otherItems].map(card).join('')||'<div class="card">Δεν υπάρχουν αιτήματα φιλίας σε αναμονή για αυτή τη συσκευή.</div>';menu.innerHTML=`<div class="v249238NotifyPanel"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Αιτήματα φιλίας</b><button class="btn" style="margin-left:auto" onclick="ITH.openNotificationSettingsV249238()">⚙️ Ρυθμίσεις</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="card"><b>Κατάσταση</b><div class="date">Εισερχόμενα για αποδοχή: ${incoming.length} · Εξερχόμενα σε αναμονή: ${outgoing.length} · Server: ${serverOk?'OK':'δεν απάντησε'}</div></div><div class="v249233NoticeList">${html}</div><div class="card"><b>Κλειστή εφαρμογή</b><div class="date">Για ειδοποίηση με κλειστό κινητό χρειάζεται ενεργοποίηση Firebase/FCM στο APK και server credentials.</div><button class="btn green" onclick="ITH.openPushPanel()">Push / FCM</button></div></div>`;refreshNotificationBadgeV249238();return false}
async function legacyOpenNotificationSettingsV249526_1(){injectV249238NotifyCss();const menu=$('memberMenu');if(!menu)return false;let p={messages:true,calls:true,likes:true,friend_requests:true,mentions:true,quiet_enabled:false,quiet_start:'22:00',quiet_end:'08:00'};try{const r=await fetchJson(`/api/notification/preferences?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);Object.assign(p,r.preferences||{})}catch{}const ck=(k)=>!!(+p[k]||p[k]===true);menu.classList.add('show','fullAvatarMenuV249231');menu.innerHTML=`<div class="v249238NotifyPanel"><div class="row"><button class="icon" onclick="ITH.notifyCenter()">‹</button><b>🔔 Ρυθμίσεις ειδοποιήσεων</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><b>Κατηγορίες</b><div class="v249238PrefGrid"><label><input id="np_messages" type="checkbox" ${ck('messages')?'checked':''}>Μηνύματα</label><label><input id="np_calls" type="checkbox" ${ck('calls')?'checked':''}>Κλήσεις</label><label><input id="np_likes" type="checkbox" ${ck('likes')?'checked':''}>Likes</label><label><input id="np_friend_requests" type="checkbox" ${ck('friend_requests')?'checked':''}>Αιτήματα φιλίας</label><label><input id="np_mentions" type="checkbox" ${ck('mentions')?'checked':''}>Mentions</label></div></div><div class="card"><label class="row"><input id="np_quiet_enabled" type="checkbox" ${ck('quiet_enabled')?'checked':''}><b>Δεν ενοχλείτε / σίγαση</b></label><div class="v249238QuietRow"><label>Από <input id="np_quiet_start" type="time" value="${esc(p.quiet_start||'22:00')}"></label><label>Έως <input id="np_quiet_end" type="time" value="${esc(p.quiet_end||'08:00')}"></label></div></div><div class="row"><button class="btn green" onclick="ITH.saveNotificationSettingsV249238()">Αποθήκευση</button><button class="btn" onclick="ITH.openPushPanel()">FCM / Token</button></div></div>`;return false}
async function saveNotificationSettingsV249238(){const val=id=>!!($(id)&&$(id).checked);const payload={room_id:state.room,device_id:state.device,messages:val('np_messages'),calls:val('np_calls'),likes:val('np_likes'),friend_requests:val('np_friend_requests'),mentions:val('np_mentions'),quiet_enabled:val('np_quiet_enabled'),quiet_start:($('np_quiet_start')?.value||'22:00'),quiet_end:($('np_quiet_end')?.value||'08:00')};try{await fetchJson('/api/notification/preferences',{method:'POST',body:JSON.stringify(payload)});toast('Οι ρυθμίσεις ειδοποιήσεων αποθηκεύτηκαν');return notifyCenter()}catch(e){toast('Δεν αποθηκεύτηκαν οι ρυθμίσεις: '+(e.message||e))}return false}
const __renderNavBeforeV249238=renderNav;renderNav=function(){try{__renderNavBeforeV249238()}catch(e){}ensureNotificationFabV249238()};
const __refreshNavBadgesBeforeV249238=refreshNavBadges;refreshNavBadges=function(){try{__refreshNavBadgesBeforeV249238()}catch(e){}ensureNotificationFabV249238();refreshNotificationBadgeV249238()};



/* V249240 NOTIFICATIONS ACCEPT REPAIR
   Fix: pending friend requests may be tied to an old/other device_id, so V249239 showed
   pending totals but the current device had no Accept/Reject card. This notification
   center loads the V249240 endpoint and shows explicit repair accept/reject buttons. */
function v249240NoticeKey(n){return String(n.id||n.event_id||n.type+'-'+n.from_id+'-'+n.to_id+'-'+(n.created_at||n.updated_at||''))}
async function refreshNotificationBadgeLegacyV249238_2(){try{const b=document.getElementById('ithNotifyFabV249238');if(!b)return;const bd=b.querySelector('.badge');let c=0;try{const r=await fetchJsonTimeoutV249241(`/api/notifications/count/v249241?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},3500);c=+(r.count||0)||0}catch{try{const r=await fetchJsonTimeoutV249241(`/api/notifications/count/v249240?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},3500);c=+(r.count||0)||0}catch{try{const r=await fetchJsonTimeoutV249241(`/api/notifications/count?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},3000);c=+(r.count||0)||0}catch{}}}if(!c)c=getMessageNoticeCount?getMessageNoticeCount():0;if(bd){bd.textContent=c>9?'9+':String(c);bd.style.display=c?'grid':'none'}}catch(e){}}
async function respondFriendProposalV249233(eventId,accepted,peerId,noticeKey,forceRepair=false){try{const payload={room_id:state.room,id:eventId,device_id:state.device,accepted:!!accepted,force_device_repair:!!forceRepair};const r=await fetchJson('/api/social/friend/respond/v249240',{method:'POST',body:JSON.stringify(payload)});if(accepted){const fid=String((r.friend&& (r.friend.device_id||r.friend.id))||r.friend_id||peerId||'');let a=[];try{a=JSON.parse(localStorage.getItem('ith_contacts')||'[]')}catch{}if(fid&&!a.includes(fid))a.push(fid);localStorage.setItem('ith_contacts',JSON.stringify(a));try{if(r.friend){const f=Object.assign({},r.friend,{id:fid,device_id:fid});mergePerson(f);state.socialFriendsV249225=state.socialFriendsV249225||[];if(!state.socialFriendsV249225.some(x=>String(x.device_id||x.id||'')===fid))state.socialFriendsV249225.push(f)}}catch{}try{await refreshFriendsForMessagesV249246(false)}catch{try{await loadSocialFriendsV249225()}catch{}}peerId=fid||peerId}try{const sel=noticeKey?`[data-notice-key="${CSS.escape(noticeKey)}"]`:'';if(sel){const el=document.querySelector(sel);if(el)el.remove()}}catch{}toast(accepted?(r.device_repair?'Η φιλία έγινε αποδεκτή εδώ και διορθώθηκε το παλιό device':'Η φιλία έγινε αποδεκτή'):'Το αίτημα απορρίφθηκε',4500);setTimeout(()=>notifyCenter(),450);if(accepted&&peerId){setTimeout(()=>startDM(peerId),700)}else if(state.activeChannel)loadMessages(true)}catch(e){toast('Δεν ολοκληρώθηκε: '+(e.message||e),6000)}return false}
async function fetchJsonTimeoutV249241(p,o={},timeoutMs=7000){
  const ctrl=(typeof AbortController!=='undefined')?new AbortController():null;
  let timer=null;
  try{
    if(ctrl){timer=setTimeout(()=>{try{ctrl.abort()}catch{}},timeoutMs);o=Object.assign({},o,{signal:ctrl.signal})}
    return await fetchJson(p,o)
  }finally{try{if(timer)clearTimeout(timer)}catch{}}
}
function v249241RenderNotifyError(menu,msg){try{menu.classList.add('show','fullAvatarMenuV249231');menu.innerHTML=`<div class="v249238NotifyPanel"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Αιτήματα φιλίας</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card warnCard"><b>Δεν φόρτωσαν τα αιτήματα.</b><div class="date">${esc(msg||'Η σύνδεση άργησε ή το endpoint δεν απάντησε.')}</div><div class="row" style="margin-top:10px;flex-wrap:wrap"><button class="btn green" onclick="ITH.notifyCenter()">🔄 Δοκιμή ξανά</button><button class="btn" onclick="location.href='/api/diagnostics/v249241?room_id='+encodeURIComponent(state.room)+'&device_id='+encodeURIComponent(state.device)">Διαγνωστικό</button></div></div><div class="card"><b>Σημείωση</b><div class="date">Η οθόνη δεν θα μένει πια κολλημένη σε “Φόρτωση αιτημάτων”. Αν υπάρχει αίτημα σε παλιό device, θα εμφανιστεί ως “Αποδοχή εδώ”.</div></div></div>`}catch(e){console.warn('v249241 render error panel',e)}}
async function legacyNotifyCenterV249526_5(){injectV249238NotifyCss();injectV249231AvatarDmNotifyCss();const menu=$('memberMenu');if(!menu)return false;menu.classList.add('show','fullAvatarMenuV249231');let timedOut=false;const loadingTimer=setTimeout(()=>{timedOut=true;try{v249241RenderNotifyError(menu,'Πέρασαν 8 δευτερόλεπτα και ο server δεν έδωσε λίστα αιτημάτων. Πάτα Δοκιμή ξανά ή δες το διαγνωστικό.')}catch{}},8000);menu.innerHTML=`<div class="v249238NotifyPanel"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Αιτήματα φιλίας</b><button class="btn" style="margin-left:auto" onclick="ITH.openNotificationSettingsV249238()">⚙️ Ρυθμίσεις</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="card">Φόρτωση αιτημάτων... <span class="date">μέγιστο 8 δευτερόλεπτα</span></div></div>`;let items=[];let counts={incoming:0,outgoing:0,other_device_or_old_id:0,total_returned:0};let serverOk=false;let source='v249241-light';try{const r=await fetchJsonTimeoutV249241(`/api/notifications/light/v249241?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=80`,{},6500);serverOk=!!r.ok;counts=r.counts||counts;items=(r.items||[]).map(x=>({server:true,type:x.type==='contact'?'contact_invite':x.type,status:x.status||'pending',id:x.id,from_id:x.from_id,from_name:x.from_name,to_id:x.to_id,to_name:x.to_name,created_at:x.created_at||x.updated_at,relation_to_device:x.relation_to_device||'',repair_required:!!x.repair_required,can_accept_here:!!x.can_accept_here,text:(x.relation_to_device==='incoming'?'Σας έστειλε αίτημα φιλίας':x.relation_to_device==='outgoing'?'Το αίτημα φιλίας περιμένει αποδοχή από την άλλη συσκευή':'Αίτημα δεμένο σε παλιό/άλλο device. Μπορείς να το αποδεχτείς εδώ για επισκευή.')}))}catch(e1){source='v249240-full-fallback';try{const r=await fetchJsonTimeoutV249241(`/api/notifications/v249240?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&include_room_pending=1&limit=80`,{},6500);serverOk=!!r.ok;counts=r.counts||counts;items=(r.items||[]).map(x=>({server:true,type:x.type==='contact'?'contact_invite':x.type,status:x.status||'pending',id:x.id,from_id:x.from_id,from_name:x.from_name,to_id:x.to_id,to_name:x.to_name,created_at:x.created_at||x.updated_at,relation_to_device:x.relation_to_device||'',repair_required:!!x.repair_required,can_accept_here:!!x.can_accept_here,text:(x.relation_to_device==='incoming'?'Σας έστειλε αίτημα φιλίας':x.relation_to_device==='outgoing'?'Το αίτημα φιλίας περιμένει αποδοχή από την άλλη συσκευή':'Αίτημα δεμένο σε παλιό/άλλο device. Μπορείς να το αποδεχτείς εδώ για επισκευή.')}))}catch(e2){clearTimeout(loadingTimer);v249241RenderNotifyError(menu,(e2&&e2.name==='AbortError')?'Έληξε ο χρόνος φόρτωσης αιτημάτων.':'Αποτυχία φόρτωσης αιτημάτων: '+((e2&&e2.message)||e2||''));return false}}
clearTimeout(loadingTimer);if(timedOut){/* panel was replaced by timeout, but data arrived now; render below */}
try{items=[...items,...uniqueNotices(localNotices()).filter(v249233IsFriendRequestPending)]}catch{}const seen=new Set();items=items.filter(n=>{const k=v249240NoticeKey(n);if(seen.has(k))return false;seen.add(k);return String(n.status||'pending')==='pending'}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));const incoming=items.filter(n=>String(n.relation_to_device||'')==='incoming'||String(n.to_id||'')===String(state.device));const outgoing=items.filter(n=>String(n.relation_to_device||'')==='outgoing'||String(n.from_id||'')===String(state.device));const repairable=items.filter(n=>String(n.relation_to_device||'')==='other_device_or_old_id'||(String(n.to_id||'')!==String(state.device)&&String(n.from_id||'')!==String(state.device)));const normalOther=items.filter(n=>!incoming.includes(n)&&!outgoing.includes(n)&&!repairable.includes(n));const card=n=>{const rel=String(n.relation_to_device||'');const inbound=rel==='incoming'||String(n.to_id||'')===String(state.device);const outbound=rel==='outgoing'||String(n.from_id||'')===String(state.device);const oldDevice=rel==='other_device_or_old_id'||(!inbound&&!outbound);const other=String(inbound?n.from_id:(outbound?n.to_id:(n.from_id||n.to_id||'')));const p=v249231PersonById(other);const name=esc(p.nickname||n.from_name||n.to_name||'Μέλος');const key=escJs(v249240NoticeKey(n));const title=inbound?'🤝 Νέο αίτημα φιλίας':outbound?'⏳ Περιμένει απάντηση':'🛠️ Αίτημα σε παλιό/άλλο device';const note=inbound?'Πατάς Αποδοχή ή Απόρριψη.':outbound?'Η αποδοχή γίνεται στην άλλη συσκευή.':`Δεν ήταν δεμένο στο σημερινό device (${esc(String(state.device||'').slice(0,10))}...). Πάτα Αποδοχή εδώ για να διορθωθεί και να ανοίξουν τα Μηνύματα.`;return `<div class="card v249238FriendReq ${inbound?'inbound':outbound?'outbound':'other'}" data-notice-key="${esc(v249240NoticeKey(n))}"><b>${title}</b><div class="row" style="align-items:center;margin-top:8px"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${p.online?'on':'off'}"></i></span><div><b>${name}</b><div class="date">${esc(n.text||'')} · ${p.online?'ενεργός':'ανενεργός'}</div><div class="date">${note}</div></div></div>${inbound?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${key}',false)">✅ Αποδοχή</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${key}',false)">❌ Απόρριψη</button></div>`:oldDevice?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${key}',true)">✅ Αποδοχή εδώ</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${key}',true)">❌ Απόρριψη</button></div>`:`<div class="v249238NoticeActions"><button class="btn" onclick="ITH.member('${escJs(other)}')">Μενού μέλους</button><span class="date">Περιμένει απάντηση από την άλλη συσκευή.</span></div>`}</div>`};const ordered=[...incoming,...repairable,...outgoing,...normalOther];const html=ordered.map(card).join('')||'<div class="card">Δεν υπάρχουν αιτήματα φιλίας σε αναμονή.</div>';menu.innerHTML=`<div class="v249238NotifyPanel"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Αιτήματα φιλίας</b><button class="btn" style="margin-left:auto" onclick="ITH.openNotificationSettingsV249238()">⚙️ Ρυθμίσεις</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="card"><b>Κατάσταση</b><div class="date">Εισερχόμενα: ${incoming.length} · Παλιό/άλλο device για επισκευή: ${repairable.length} · Εξερχόμενα: ${outgoing.length} · Server: ${serverOk?'OK':'δεν απάντησε'} · Πηγή: ${source}</div></div><div class="v249233NoticeList">${html}</div><div class="card"><b>Αν κολλούσε πριν</b><div class="date">Η V249241 χρησιμοποιεί ελαφρύ endpoint και timeout. Δεν μένει πια σε φόρτωση για λεπτά.</div></div></div>`;refreshNotificationBadgeV249238();return false}



/* V249242: final bell open + sound fix.
   The bell must never stay on “Φόρτωση αιτημάτων”. The panel opens immediately,
   network loading runs behind it with Promise.race timeout, and badge increases play a short alert. */
function v249242FetchJsonRace(p,o={},timeoutMs=4500){
  return new Promise((resolve,reject)=>{
    let done=false;
    const fail=(err)=>{if(done)return;done=true;reject(err instanceof Error?err:new Error(String(err||'timeout')))};
    const ok=(v)=>{if(done)return;done=true;resolve(v)};
    const timer=setTimeout(()=>fail(new Error('timeout')),Math.max(1200,timeoutMs||4500));
    try{
      const opt=Object.assign({cache:'no-store',headers:headers(!o.body||typeof o.body==='string')},o||{});
      fetch(api(p),opt).then(r=>{if(!r.ok)throw new Error(p+' '+r.status);return r.json()}).then(v=>{clearTimeout(timer);ok(v)}).catch(e=>{clearTimeout(timer);fail(e)});
    }catch(e){clearTimeout(timer);fail(e)}
  });
}
function v249242NotifyItem(x){return {server:true,type:x.type==='contact'?'contact_invite':x.type,status:x.status||'pending',id:x.id,from_id:x.from_id,from_name:x.from_name,to_id:x.to_id,to_name:x.to_name,created_at:x.created_at||x.updated_at,relation_to_device:x.relation_to_device||'',repair_required:!!x.repair_required,can_accept_here:!!x.can_accept_here,text:(x.relation_to_device==='incoming'?'Σας έστειλε αίτημα φιλίας':x.relation_to_device==='outgoing'?'Το αίτημα φιλίας περιμένει αποδοχή από την άλλη συσκευή':'Αίτημα δεμένο σε παλιό/άλλο device. Μπορείς να το αποδεχτείς εδώ για επισκευή.')}}
function v249242NotifyShell(menu,msg){
  try{injectV249238NotifyCss();injectV249231AvatarDmNotifyCss();menu.classList.add('show','fullAvatarMenuV249231');menu.innerHTML=`<div class="v249238NotifyPanel"><div class="row"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Αιτήματα φιλίας</b><button class="btn" style="margin-left:auto" onclick="ITH.openNotificationSettingsV249238()">⚙️ Ρυθμίσεις</button><button class="icon" onclick="ITH.closeMember()">×</button></div><div class="card"><b>Άνοιξε η οθόνη ειδοποιήσεων</b><div class="date">${esc(msg||'Ελέγχω τα αιτήματα χωρίς να κλειδώσει η οθόνη.')}</div></div><div id="v249242NotifyMount"><div class="card">⏳ Έλεγχος αιτημάτων... Αν αργήσει, θα εμφανιστεί επιλογή επανάληψης.</div></div></div>`}catch(e){console.warn('v249242 shell',e)}
}
function v249242RenderNotifyError(menu,msg){
  try{v249242NotifyShell(menu,'Δεν πήραμε γρήγορη απάντηση από τον server.');const m=document.getElementById('v249242NotifyMount');if(m)m.innerHTML=`<div class="card warnCard"><b>Δεν φορτώθηκαν τα αιτήματα.</b><div class="date">${esc(msg||'Η σύνδεση άργησε ή το endpoint δεν απάντησε.')}</div><div class="row" style="margin-top:10px;flex-wrap:wrap"><button class="btn green" onclick="ITH.notifyCenter()">🔄 Δοκιμή ξανά</button><button class="btn" onclick="location.href='/api/notifications/light/v249242?room_id='+encodeURIComponent(state.room)+'&device_id='+encodeURIComponent(state.device)+'&limit=80'">Άνοιγμα raw</button><button class="btn" onclick="location.href='/api/diagnostics/v249242?room_id='+encodeURIComponent(state.room)+'&device_id='+encodeURIComponent(state.device)">Διαγνωστικό</button></div></div>`}catch(e){console.warn('v249242 error panel',e)}
}
function v249242RenderNotifyItems(menu,items,meta={}){
  try{
    const seen=new Set();
    try{items=[...(items||[]),...uniqueNotices(localNotices()).filter(v249233IsFriendRequestPending)]}catch{}
    items=(items||[]).filter(n=>{const k=v249240NoticeKey(n);if(seen.has(k))return false;seen.add(k);return String(n.status||'pending')==='pending'}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));
    const incoming=items.filter(n=>String(n.relation_to_device||'')==='incoming'||String(n.to_id||'')===String(state.device));
    const outgoing=items.filter(n=>String(n.relation_to_device||'')==='outgoing'||String(n.from_id||'')===String(state.device));
    const repairable=items.filter(n=>String(n.relation_to_device||'')==='other_device_or_old_id'||(String(n.to_id||'')!==String(state.device)&&String(n.from_id||'')!==String(state.device)));
    const normalOther=items.filter(n=>!incoming.includes(n)&&!outgoing.includes(n)&&!repairable.includes(n));
    const card=n=>{const rel=String(n.relation_to_device||'');const inbound=rel==='incoming'||String(n.to_id||'')===String(state.device);const outbound=rel==='outgoing'||String(n.from_id||'')===String(state.device);const oldDevice=rel==='other_device_or_old_id'||(!inbound&&!outbound);const other=String(inbound?n.from_id:(outbound?n.to_id:(n.from_id||n.to_id||'')));const p=v249231PersonById(other);const name=esc(p.nickname||n.from_name||n.to_name||'Μέλος');const key=escJs(v249240NoticeKey(n));const title=inbound?'🤝 Νέο αίτημα φιλίας':outbound?'⏳ Περιμένει απάντηση':'🛠️ Αίτημα σε παλιό/άλλο device';const note=inbound?'Πατάς Αποδοχή ή Απόρριψη.':outbound?'Η αποδοχή γίνεται στην άλλη συσκευή.':`Δεν ήταν δεμένο στο σημερινό device (${esc(String(state.device||'').slice(0,10))}...). Πάτα Αποδοχή εδώ για να διορθωθεί και να ανοίξουν τα Μηνύματα.`;return `<div class="card v249238FriendReq ${inbound?'inbound':outbound?'outbound':'other'}" data-notice-key="${esc(v249240NoticeKey(n))}"><b>${title}</b><div class="row" style="align-items:center;margin-top:8px"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${p.online?'on':'off'}"></i></span><div><b>${name}</b><div class="date">${esc(n.text||'')} · ${p.online?'ενεργός':'ανενεργός'}</div><div class="date">${note}</div></div></div>${inbound?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${key}',false)">✅ Αποδοχή</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${key}',false)">❌ Απόρριψη</button></div>`:oldDevice?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${key}',true)">✅ Αποδοχή εδώ</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${key}',true)">❌ Απόρριψη</button></div>`:`<div class="v249238NoticeActions"><button class="btn" onclick="ITH.member('${escJs(other)}')">Μενού μέλους</button><span class="date">Περιμένει απάντηση από την άλλη συσκευή.</span></div>`}</div>`};
    const ordered=[...incoming,...repairable,...outgoing,...normalOther];
    v249242NotifyShell(menu,'Τα αιτήματα φορτώθηκαν.');
    const mount=document.getElementById('v249242NotifyMount');
    if(mount)mount.innerHTML=`<div class="card"><b>Κατάσταση</b><div class="date">Εισερχόμενα: ${incoming.length} · Παλιό/άλλο device για επισκευή: ${repairable.length} · Εξερχόμενα: ${outgoing.length} · Πηγή: ${esc(meta.source||'v249242')}</div></div><div class="v249233NoticeList">${ordered.map(card).join('')||'<div class="card">Δεν υπάρχουν αιτήματα φιλίας σε αναμονή.</div>'}</div><div class="card"><b>Ήχος ειδοποίησης</b><div class="date">Ο ήχος παίζει όταν αυξάνεται ο αριθμός στο καμπανάκι και επιτρέπεται από τη συσκευή. Σε browser/WebView χρειάζεται πρώτα ένα πάτημα στην οθόνη για ξεκλείδωμα ήχου.</div></div>`;
    refreshNotificationBadgeV249238();
  }catch(e){v249242RenderNotifyError(menu,'Σφάλμα εμφάνισης ειδοποιήσεων: '+(e.message||e))}
}
function legacyNotifyCenterV249526_6(){
  const menu=$('memberMenu');if(!menu)return false;
  v249242NotifyShell(menu,'Η οθόνη άνοιξε αμέσως. Δεν θα μείνει κρεμασμένη σε φόρτωση.');
  setTimeout(()=>{try{const m=document.getElementById('v249242NotifyMount');if(m&&/Έλεγχος αιτημάτων/.test(m.textContent||'')){m.innerHTML=`<div class="card warnCard"><b>Αργεί η φόρτωση.</b><div class="date">Πάτα Δοκιμή ξανά ή άνοιξε το raw endpoint. Η οθόνη δεν είναι κολλημένη.</div><div class="row" style="margin-top:10px;flex-wrap:wrap"><button class="btn green" onclick="ITH.notifyCenter()">🔄 Δοκιμή ξανά</button><button class="btn" onclick="location.href='/api/notifications/light/v249242?room_id='+encodeURIComponent(state.room)+'&device_id='+encodeURIComponent(state.device)+'&limit=80'">Raw αιτήματα</button></div></div>`}}catch{}},6000);
  v249242FetchJsonRace(`/api/notifications/light/v249242?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=80`,{},4500)
    .catch(()=>v249242FetchJsonRace(`/api/notifications/light/v249241?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=80`,{},3500))
    .then(r=>v249242RenderNotifyItems(menu,(r.items||[]).map(v249242NotifyItem),{source:(r.version||'v249242-light')}))
    .catch(e=>v249242RenderNotifyError(menu,(e&&e.message==='timeout')?'Έληξε ο χρόνος φόρτωσης αιτημάτων.':'Αποτυχία φόρτωσης αιτημάτων: '+((e&&e.message)||e||'')));
  return false;
}
async function refreshNotificationBadgeLegacyV249238_3(){try{const b=document.getElementById('ithNotifyFabV249238');if(!b)return;const bd=b.querySelector('.badge');let c=0;try{const r=await v249242FetchJsonRace(`/api/notifications/count/v249242?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},2500);c=+(r.count||0)||0}catch{try{const r=await v249242FetchJsonRace(`/api/notifications/count/v249241?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},2500);c=+(r.count||0)||0}catch{try{const r=await v249242FetchJsonRace(`/api/notifications/count?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},2000);c=+(r.count||0)||0}catch{}}}if(!c)c=getMessageNoticeCount?getMessageNoticeCount():0;try{const key='ith_last_notify_badge_v249242';const last=+(localStorage.getItem(key)||'0')||0;const lastSound=+(localStorage.getItem('ith_last_notify_sound_v249242')||'0')||0;if(c>last&&Date.now()-lastSound>5000){playAppAlert('message');localStorage.setItem('ith_last_notify_sound_v249242',String(Date.now()))}localStorage.setItem(key,String(c||0))}catch{}if(bd){bd.textContent=c>9?'9+':String(c);bd.style.display=c?'grid':'none'}}catch(e){}}
function ensureNotificationFabV249238(){try{injectV249238NotifyCss();let b=document.getElementById('ithNotifyFabV249238');if(!b){b=document.createElement('button');b.id='ithNotifyFabV249238';b.className='ithNotifyFabV249238';b.type='button';b.innerHTML='🔔<span class="badge" style="display:none">0</span>';document.body.appendChild(b)}b.onclick=(ev)=>{try{ev&&ev.preventDefault&&ev.preventDefault();unlockAlertAudio&&unlockAlertAudio();notifyCenter()}catch(e){toast('Δεν ανοίγουν οι ειδοποιήσεις: '+(e.message||e));try{const m=$('memberMenu');if(m)v249242RenderNotifyError(m,e.message||e)}catch{}};return false};refreshNotificationBadgeV249238()}catch(e){}}



/* V249243: bell badge/message-center consistency fix.
   The bell badge now counts exactly what the bell can show: server friend requests + local unread message notices.
   The panel shows both sections, so a message badge never opens to an empty friend-request-only screen. */
function v249243UnreadMessageNotices(){try{return uniqueNotices(localNotices()).filter(n=>!n.read&&String(n.type||'')==='message'&&String(n.from_id||'').trim())}catch{return[]}}
function v249243NoticeOpenMessage(id,noticeId){try{const sid=String(id||'');if(sid){markPeerRead(sid);startDM(sid)}if(noticeId){const a=localNotices().map(n=>String(n.id||'')===String(noticeId)?Object.assign({},n,{read:true,status:n.status||'opened'}):n);saveNotices(a)}refreshNavBadges();refreshNotificationBadgeV249238()}catch(e){toast('Δεν άνοιξε το μήνυμα: '+(e.message||e))}}
function v249243LocalMessageCards(){const ns=v249243UnreadMessageNotices().sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));return ns.map(n=>{const id=String(n.from_id||'');const p=v249231PersonById(id);const name=esc(p.nickname||n.from_name||'Μέλος');const txt=esc(n.text||'Νέο μήνυμα');return `<div class="card noticeCard v249243MessageNotice"><b>💬 Νέο μήνυμα</b><div class="row" style="align-items:center;margin-top:8px"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${p.online?'on':'off'}"></i></span><div><b>${name}</b><div class="date">${txt}</div><div class="date">${esc(n.created_at||'')}</div></div></div><div class="v249238NoticeActions"><button class="btn green" onclick="ITH.openNoticeMessageV249243('${escJs(id)}','${escJs(n.id||'')}')">Άνοιγμα συνομιλίας</button><button class="btn" onclick="ITH.markPeerRead('${escJs(id)}');ITH.notifyCenter();">Σημείωση ως διαβασμένο</button></div></div>`}).join('')}
function v249242RenderNotifyItems(menu,items,meta={}){
  try{
    const seen=new Set();
    try{items=[...(items||[]),...uniqueNotices(localNotices()).filter(v249233IsFriendRequestPending)]}catch{}
    items=(items||[]).filter(n=>{const k=v249240NoticeKey(n);if(seen.has(k))return false;seen.add(k);return String(n.type||'contact_invite')!=='message'&&String(n.status||'pending')==='pending'}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));
    const incoming=items.filter(n=>String(n.relation_to_device||'')==='incoming'||String(n.to_id||'')===String(state.device));
    const outgoing=items.filter(n=>String(n.relation_to_device||'')==='outgoing'||String(n.from_id||'')===String(state.device));
    const repairable=items.filter(n=>String(n.relation_to_device||'')==='other_device_or_old_id'||(String(n.to_id||'')!==String(state.device)&&String(n.from_id||'')!==String(state.device)));
    const normalOther=items.filter(n=>!incoming.includes(n)&&!outgoing.includes(n)&&!repairable.includes(n));
    const friendCard=n=>{const rel=String(n.relation_to_device||'');const inbound=rel==='incoming'||String(n.to_id||'')===String(state.device);const outbound=rel==='outgoing'||String(n.from_id||'')===String(state.device);const oldDevice=rel==='other_device_or_old_id'||(!inbound&&!outbound);const other=String(inbound?n.from_id:(outbound?n.to_id:(n.from_id||n.to_id||'')));const p=v249231PersonById(other);const name=esc(p.nickname||n.from_name||n.to_name||'Μέλος');const key=escJs(v249240NoticeKey(n));const title=inbound?'🤝 Νέο αίτημα φιλίας':outbound?'⏳ Περιμένει απάντηση':'🛠️ Αίτημα σε παλιό/άλλο device';const note=inbound?'Πατάς Αποδοχή ή Απόρριψη.':outbound?'Η αποδοχή γίνεται στην άλλη συσκευή.':`Δεν ήταν δεμένο στο σημερινό device (${esc(String(state.device||'').slice(0,10))}...). Πάτα Αποδοχή εδώ για να διορθωθεί και να ανοίξουν τα Μηνύματα.`;return `<div class="card v249238FriendReq ${inbound?'inbound':outbound?'outbound':'other'}" data-notice-key="${esc(v249240NoticeKey(n))}"><b>${title}</b><div class="row" style="align-items:center;margin-top:8px"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${p.online?'on':'off'}"></i></span><div><b>${name}</b><div class="date">${esc(n.text||'')} · ${p.online?'ενεργός':'ανενεργός'}</div><div class="date">${note}</div></div></div>${inbound?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${key}',false)">✅ Αποδοχή</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${key}',false)">❌ Απόρριψη</button></div>`:oldDevice?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${key}',true)">✅ Αποδοχή εδώ</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${key}',true)">❌ Απόρριψη</button></div>`:`<div class="v249238NoticeActions"><button class="btn" onclick="ITH.member('${escJs(other)}')">Μενού μέλους</button><span class="date">Περιμένει απάντηση από την άλλη συσκευή.</span></div>`}</div>`};
    const ordered=[...incoming,...repairable,...outgoing,...normalOther];
    const messagesHtml=v249243LocalMessageCards();
    const friendHtml=ordered.map(friendCard).join('')||'<div class="card">Δεν υπάρχουν αιτήματα φιλίας σε αναμονή.</div>';
    v249242NotifyShell(menu,'Τα δεδομένα φορτώθηκαν. Το καμπανάκι δείχνει αιτήματα και μηνύματα.');
    const mount=document.getElementById('v249242NotifyMount');
    if(mount)mount.innerHTML=`<div class="card"><b>Κατάσταση</b><div class="date">Αιτήματα: ${ordered.length} · Μηνύματα: ${v249243UnreadMessageNotices().length} · Πηγή: ${esc(meta.source||'v249243')}</div></div><div class="card"><b>🤝 Αιτήματα φιλίας</b><div class="date">Εισερχόμενα: ${incoming.length} · Παλιό/άλλο device: ${repairable.length} · Εξερχόμενα: ${outgoing.length}</div></div><div class="v249233NoticeList">${friendHtml}</div><div class="card"><b>💬 Μηνύματα</b><div class="date">Εδώ εμφανίζονται τα νέα μηνύματα που ανεβάζουν τον αριθμό στο καμπανάκι.</div></div><div class="v249233NoticeList">${messagesHtml||'<div class="card">Δεν υπάρχουν νέα μηνύματα.</div>'}</div>`;
    refreshNotificationBadgeV249238();
  }catch(e){v249242RenderNotifyError(menu,'Σφάλμα εμφάνισης ειδοποιήσεων: '+(e.message||e))}
}
function legacyNotifyCenterV249526_7(){
  const menu=$('memberMenu');if(!menu)return false;
  v249242NotifyShell(menu,'Η οθόνη άνοιξε αμέσως. Ελέγχω αιτήματα φιλίας και νέα μηνύματα.');
  setTimeout(()=>{try{const m=document.getElementById('v249242NotifyMount');if(m&&/Έλεγχος αιτημάτων/.test(m.textContent||'')){v249242RenderNotifyItems(menu,[],{source:'local-timeout'});}}catch{}},6000);
  v249242FetchJsonRace(`/api/notifications/light/v249242?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=80`,{},4500)
    .catch(()=>v249242FetchJsonRace(`/api/notifications/light/v249241?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=80`,{},3500))
    .then(r=>v249242RenderNotifyItems(menu,(r.items||[]).map(v249242NotifyItem),{source:(r.version||'v249243-light')}))
    .catch(()=>v249242RenderNotifyItems(menu,[],{source:'local-fallback'}));
  return false;
}
async function refreshNotificationBadgeLegacyV249238_4(){try{const b=document.getElementById('ithNotifyFabV249238');if(!b)return;const bd=b.querySelector('.badge');let serverCount=0;try{const r=await v249242FetchJsonRace(`/api/notifications/count/v249242?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},2500);serverCount=+(r.count||0)||0}catch{try{const r=await v249242FetchJsonRace(`/api/notifications/count/v249241?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},2500);serverCount=+(r.count||0)||0}catch{try{const r=await v249242FetchJsonRace(`/api/notifications/count?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},2000);serverCount=+(r.count||0)||0}catch{}}}const msgCount=v249243UnreadMessageNotices().length;const c=serverCount+msgCount;try{const key='ith_last_notify_badge_v249243';const last=+(localStorage.getItem(key)||'0')||0;const lastSound=+(localStorage.getItem('ith_last_notify_sound_v249243')||'0')||0;if(c>last&&Date.now()-lastSound>5000){playAppAlert('message');localStorage.setItem('ith_last_notify_sound_v249243',String(Date.now()))}localStorage.setItem(key,String(c||0));localStorage.setItem('ith_last_notify_badge_v249242',String(c||0))}catch{}if(bd){bd.textContent=c>9?'9+':String(c);bd.style.display=c?'grid':'none';bd.title=`Αιτήματα ${serverCount} · Μηνύματα ${msgCount}`}}catch(e){}}



/* V249245 NOTIFICATION PANEL LAYOUT + SCROLL FIX
   Fix: notification cards were stacked/overlapping and buttons were untappable on small screens.
   This patch is CSS-only/DOM-safe: fixed shell, sticky header, one-column cards, internal scroll. */
function injectV249245NotifyLayoutCss(){try{if(document.getElementById('ithV249245NotifyLayoutCss'))return;const st=document.createElement('style');st.id='ithV249245NotifyLayoutCss';st.textContent=`
.memberMenu.show.fullAvatarMenuV249231{position:fixed!important;inset:calc(env(safe-area-inset-top,0px) + 6px) 6px calc(var(--bar,64px) + 6px) 6px!important;width:auto!important;max-width:820px!important;margin:auto!important;display:flex!important;flex-direction:column!important;overflow:hidden!important;box-sizing:border-box!important;min-height:0!important;border-radius:22px!important;z-index:99990!important;}
.memberMenu.show.fullAvatarMenuV249231 .v249238NotifyPanel{height:100%!important;min-height:0!important;display:flex!important;flex-direction:column!important;gap:10px!important;overflow:hidden!important;padding:10px calc(10px + env(safe-area-inset-right,0px)) calc(18px + env(safe-area-inset-bottom,0px)) calc(10px + env(safe-area-inset-left,0px))!important;box-sizing:border-box!important;}
.v249238NotifyPanel>.row:first-child{flex:0 0 auto!important;position:sticky!important;top:0!important;z-index:5!important;display:flex!important;align-items:center!important;gap:6px!important;min-height:48px!important;padding:7px!important;border-radius:16px!important;background:rgba(6,20,35,.98)!important;border:1px solid rgba(255,217,110,.20)!important;box-shadow:0 8px 18px rgba(0,0,0,.25)!important;}
.v249238NotifyPanel>.row:first-child b{flex:1 1 auto!important;min-width:0!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important;font-size:15px!important;}
.v249238NotifyPanel>.row:first-child .btn{flex:0 0 auto!important;white-space:nowrap!important;padding:8px 10px!important;font-size:12px!important;}
.v249238NotifyPanel>.row:first-child .icon{flex:0 0 40px!important;width:40px!important;height:40px!important;display:grid!important;place-items:center!important;}
#v249242NotifyMount{flex:1 1 auto!important;min-height:0!important;overflow:auto!important;-webkit-overflow-scrolling:touch!important;touch-action:pan-y!important;overscroll-behavior:contain!important;padding:2px 2px 22px!important;box-sizing:border-box!important;}
.v249238NotifyPanel>#v249242NotifyMount,.v249238NotifyPanel>.v249233NoticeList{flex:1 1 auto!important;min-height:0!important;overflow:auto!important;}
.v249233NoticeList{display:flex!important;flex-direction:column!important;gap:12px!important;max-height:none!important;overflow:visible!important;padding:2px 0 12px!important;box-sizing:border-box!important;}
.v249238NotifyPanel .card,.v249233NoticeList .card{position:relative!important;display:block!important;width:100%!important;max-width:100%!important;min-height:auto!important;height:auto!important;box-sizing:border-box!important;margin:0 0 10px 0!important;clear:both!important;overflow:visible!important;}
.v249238FriendReq,.v249243MessageNotice,.noticeCard{display:flex!important;flex-direction:column!important;gap:8px!important;align-items:stretch!important;}
.v249238FriendReq>.row,.v249243MessageNotice>.row{display:grid!important;grid-template-columns:auto minmax(0,1fr)!important;gap:10px!important;align-items:center!important;width:100%!important;min-width:0!important;}
.v249238FriendReq>.row>div,.v249243MessageNotice>.row>div{min-width:0!important;overflow-wrap:anywhere!important;word-break:break-word!important;}
.v249238NoticeActions{display:grid!important;grid-template-columns:repeat(auto-fit,minmax(135px,1fr))!important;gap:8px!important;margin-top:10px!important;width:100%!important;}
.v249238NoticeActions .btn{width:100%!important;min-height:44px!important;white-space:normal!important;line-height:1.15!important;padding:10px 12px!important;}
.v249238NotifyPanel .date{overflow-wrap:anywhere!important;word-break:break-word!important;line-height:1.35!important;}
@media(max-width:520px){.memberMenu.show.fullAvatarMenuV249231{inset:calc(env(safe-area-inset-top,0px) + 4px) 4px calc(var(--bar,64px) + 4px) 4px!important;border-radius:18px!important}.v249238NotifyPanel{padding:8px 8px calc(12px + env(safe-area-inset-bottom,0px)) 8px!important}.v249238NotifyPanel>.row:first-child{min-height:44px!important;padding:5px!important}.v249238NotifyPanel>.row:first-child .btn{font-size:0!important;width:42px!important;height:40px!important;padding:0!important;border-radius:999px!important}.v249238NotifyPanel>.row:first-child .btn::after{content:'⚙️';font-size:18px!important}.v249238NotifyPanel>.row:first-child b{font-size:14px!important}.v249238NoticeActions{grid-template-columns:1fr!important}.avatarDotWrap{flex:0 0 auto!important}.v249238NotifyPanel .card{padding:10px!important;border-radius:16px!important}}
`;document.head.appendChild(st)}catch(e){console.warn('v249245 notify layout css',e)}}
try{const __injectV249238NotifyCssBeforeV249245=injectV249238NotifyCss;injectV249238NotifyCss=function(){try{__injectV249238NotifyCssBeforeV249245()}catch(e){}injectV249245NotifyLayoutCss()}}catch(e){}
try{const __notifyCenterBeforeV249245=notifyCenter;notifyCenter=function(){injectV249245NotifyLayoutCss();return __notifyCenterBeforeV249245.apply(this,arguments)}}catch(e){}


/* V249246: live profile name check + robust friend list after accept.
   - The profile name is checked while typing; if taken, suggestions appear immediately.
   - The Messages friend list no longer depends on old missing V249231 helpers.
   - After accepting a friendship, local state + server friend list refresh immediately. */
let v249246NameTimer=0;
let v249246NameSeq=0;
function injectV249246ProfileFriendsCss(){try{if(document.getElementById('ithV249246ProfileFriendsCss'))return;const st=document.createElement('style');st.id='ithV249246ProfileFriendsCss';st.textContent=`
.profileNameLiveStatusV249246{margin-top:8px;border-radius:16px;padding:10px 12px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.06);font-weight:900;line-height:1.35}.profileNameLiveStatusV249246.ok{border-color:rgba(54,240,160,.45);background:rgba(54,240,160,.10);color:#dffff1}.profileNameLiveStatusV249246.bad{border-color:rgba(255,92,92,.45);background:rgba(255,92,92,.10);color:#ffe2e2}.profileNameLiveStatusV249246.checking{border-color:rgba(255,217,110,.35);background:rgba(255,217,110,.10);color:#fff0bc}.nameSuggestsV249246{display:flex;flex-wrap:wrap;gap:7px;margin-top:8px}.nameSuggestsV249246 .btn{min-height:34px;border-radius:999px!important}.dmEmptyV249246Tools{display:grid!important;grid-template-columns:1fr!important;gap:8px!important;margin-top:10px!important}.friendDebugV249246{font-size:12px;color:rgba(255,255,255,.7);overflow-wrap:anywhere}.dmFriendListV249235 .card.warnCard{border-color:rgba(255,217,110,.35)!important;background:rgba(255,217,110,.08)!important}`;document.head.appendChild(st)}catch(e){}}
function v249246SetNameStatus(html,cls='checking'){const box=$('profileNameLiveStatus');if(!box)return;box.style.display='block';box.className='profileNameLiveStatusV249246 '+cls;box.innerHTML=html}
function applyProfileNameSuggestionV249246(name){const i=$('profName');if(i){i.value=String(name||'');i.focus()}return checkProfileNameLiveV249246(true)}
async function checkProfileNameAvailabilityV249246(name,show=true){name=String(name||'').trim();if(!name){if(show)v249246SetNameStatus('Γράψε όνομα μέλους.','checking');return null}if(name.length<2){if(show)v249246SetNameStatus('Το όνομα πρέπει να έχει τουλάχιστον 2 χαρακτήρες.','bad');return {ok:true,available:false,valid:false}}if(show)v249246SetNameStatus('⏳ Έλεγχος ονόματος...','checking');try{const r=await fetchJson(`/api/profile/check?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&nickname=${encodeURIComponent(name)}`);const sugg=(r.suggestions||[]).map(s=>`<button class="btn" onclick="ITH.applyProfileNameSuggestionV249246('${escJs(s)}')">${esc(s)}</button>`).join('');if(r.available){if(show)v249246SetNameStatus('✅ '+esc(r.message||'Το όνομα είναι διαθέσιμο.'),'ok')}else{if(show)v249246SetNameStatus('❌ '+esc(r.message||'Το όνομα υπάρχει ήδη.')+(sugg?`<div class="nameSuggestsV249246"><b>Προτεινόμενα:</b>${sugg}</div>`:''),'bad')}return r}catch(e){if(show)v249246SetNameStatus('ℹ️ Δεν έγινε έλεγχος τώρα. Θα ξαναδοκιμάσει στην αποθήκευση.','checking');return null}}
function checkProfileNameLiveV249246(force=false){clearTimeout(v249246NameTimer);const seq=++v249246NameSeq;const run=()=>{if(seq!==v249246NameSeq)return;checkProfileNameAvailabilityV249246(($('profName')?.value||'').trim(),true)};if(force)run();else v249246NameTimer=setTimeout(run,450);return false}
function v249231FriendIds(){const ids=new Set();try{(state.socialFriendsV249225||[]).forEach(p=>{const id=String(p&& (p.device_id||p.id) ||'');if(id)ids.add(id)})}catch{}try{JSON.parse(localStorage.getItem('ith_contacts')||'[]').forEach(id=>{id=String(id||'');if(id)ids.add(id)})}catch{}return ids}
function v249231MergeFriendsAndPeople(){const m=new Map();try{peopleArray().forEach(p=>{const id=String(p.id||p.device_id||'');if(id)m.set(id,Object.assign({id,device_id:id},p))})}catch{}try{(state.socialFriendsV249225||[]).forEach(p=>{const id=String(p&& (p.device_id||p.id) ||'');if(id)m.set(id,Object.assign({},m.get(id)||{},p,{id,device_id:id}))})}catch{}try{JSON.parse(localStorage.getItem('ith_contacts')||'[]').forEach(id=>{id=String(id||'');if(id&&!m.has(id))m.set(id,{id,device_id:id,nickname:'Φίλος',avatar:'',online:false})})}catch{}return [...m.values()]}
function v249235FriendListForMessages(){const friendIds=v249231FriendIds();const m=new Map();try{v249231MergeFriendsAndPeople().forEach(p=>{const id=String(p.id||p.device_id||'');if(id)m.set(id,Object.assign({id,device_id:id},p,{id,device_id:id}))})}catch{}try{(state.socialFriendsV249225||[]).forEach(p=>{const id=String(p.device_id||p.id||'');if(id){friendIds.add(id);m.set(id,Object.assign({},m.get(id)||{},p,{id,device_id:id}))}})}catch{}try{JSON.parse(localStorage.getItem('ith_contacts')||'[]').forEach(id=>{id=String(id||'');if(id){friendIds.add(id);if(!m.has(id))m.set(id,{id,device_id:id,nickname:'Φίλος',avatar:'',online:false})}})}catch{}let arr=[...m.values()].filter(p=>{const id=String(p.id||p.device_id||'');return id&&id!==String(state.device)&&friendIds.has(id)&&!isBlocked(id)});arr=arr.map(p=>{const id=String(p.id||p.device_id||'');const sp=state.people.get(id)||{};return Object.assign({},p,sp,{id,device_id:id,nickname:p.nickname||sp.nickname||'Φίλος',avatar:p.avatar||sp.avatar||'',online:!!(p.online||sp.online)})});const seen=new Set();arr=arr.filter(p=>{const id=String(p.id||p.device_id||'');if(seen.has(id))return false;seen.add(id);return true});arr.sort((a,b)=>((unreadFrom(b.id)?1:0)-(unreadFrom(a.id)?1:0))||((b.online?1:0)-(a.online?1:0))||String(a.nickname||'').localeCompare(String(b.nickname||''),'el'));return arr}
async function refreshFriendsForMessagesV249246(showToast=false){try{await loadPeople()}catch{}try{await loadSocialFriendsV249225()}catch(e){if(showToast)toast('Δεν φορτώθηκε η λίστα φίλων από server: '+(e.message||e),5000)}try{renderPeople()}catch(e){console.warn('render friends',e);const list=$('peopleList');if(list)list.innerHTML=`<div class="card warnCard"><b>Δεν εμφανίστηκε η λίστα φίλων.</b><div class="date">${esc(e.message||e)}</div><button class="btn green" onclick="ITH.refreshFriendsForMessagesV249246(true)">🔄 Φόρτωση φίλων ξανά</button><button class="btn" onclick="ITH.notifyCenter()">🔔 Ειδοποιήσεις</button></div>`}return v249235FriendListForMessages()}
function showDMFriendListV249235(){const shell=$('dmShellV249235');if(shell)shell.classList.remove('chatOpen');if($('dmFriendScreen'))$('dmFriendScreen').style.display='';if($('dmChatScreen'))$('dmChatScreen').style.display='none';renderPeople();refreshFriendsForMessagesV249246(false);return false}
async function saveProfile(){const inputName=($('profName')?.value||'').trim()||'Μέλος';const lockedName=profileNameLockValue();if(lockedName&&inputName!==lockedName){toast('Ξεκλείδωσε το όνομα πριν το αλλάξεις.',6500);return false}state.age16=!!$('age16')?.checked;state.policyOk=!!$('policyOk')?.checked;if(!state.age16||!state.policyOk){toast('Χρειάζεται επιβεβαίωση ηλικίας και αποδοχή πολιτικής.',6500);return false}const check=await checkProfileNameAvailabilityV249246(inputName,true);if(check&&check.available===false&&!check.same_device){toast('Το όνομα υπάρχει ήδη. Διάλεξε ένα από τα προτεινόμενα.',7500);return false}state.name=inputName;persistProfile();try{localStorage.setItem('ith_registered_member_v249154','1');localStorage.setItem('ith_profile_name_locked_v249164',state.name);localStorage.setItem('ith_profile_name_pending_sync','1');localStorage.setItem('ith_profile_name_pending_at',String(Date.now()));localStorage.setItem('ith_ui_lang_v249141',(typeof uiLang==='function'?uiLang():'el'));localStorage.setItem('ith_ui_lang',(typeof uiLang==='function'?uiLang():'el'))}catch(e){}renderProfile();const msg='Το όνομα αποθηκεύτηκε στη συσκευή και ελέγχθηκε πριν την αποθήκευση.';try{const n=$('profileSaveNotice');if(n){n.style.display='block';n.innerHTML=`<b>✅ Το προφίλ αποθηκεύτηκε</b><br>${esc(msg)}<br><small>Κατάσταση: γίνεται συγχρονισμός...</small>`}}catch(e){}toast(msg,5500);syncProfileNow(true).then(()=>{try{const n=$('profileSaveNotice');if(n){n.style.display='block';n.innerHTML='<b>✅ Το προφίλ είναι ενεργό</b><br>Το όνομα αποθηκεύτηκε και συγχρονίστηκε με τον server.'}}catch(e){}toast('Το προφίλ ενεργοποιήθηκε στον server.',4500);renderProfile()}).catch((e)=>{try{const n=$('profileSaveNotice');if(n){n.style.display='block';n.innerHTML='<b>ℹ️ Το προφίλ έμεινε στη συσκευή</b><br>Ο συγχρονισμός θα ξαναδοκιμάσει όταν η σύνδεση σταθεροποιηθεί.'}}catch(_){}});return false}



/* V249247 CHAT SCROLL + FRIEND RECHECK + LIKE/VIDEO NOTIFICATION CENTER */
function injectV249247ChatNotifyCss(){try{if(document.getElementById('ithV249247ChatNotifyCss'))return;const st=document.createElement('style');st.id='ithV249247ChatNotifyCss';st.textContent=`
body[data-page="dm"] #dmPage{height:calc(100dvh - var(--top,56px) - var(--bar,64px))!important;min-height:0!important;overflow:hidden!important;display:flex!important;flex-direction:column!important;box-sizing:border-box!important;}
body[data-page="dm"] #dmShellV249235{flex:1 1 auto!important;min-height:0!important;height:100%!important;overflow:hidden!important;display:flex!important;flex-direction:column!important;}
body[data-page="dm"] .dmChatScreenV249235{flex:1 1 auto!important;min-height:0!important;height:100%!important;overflow:hidden!important;}
body[data-page="dm"] .dmChatScreenV249235 .chatPane{height:100%!important;max-height:100%!important;min-height:0!important;display:flex!important;flex-direction:column!important;overflow:hidden!important;}
body[data-page="dm"] .dmChatScreenV249235 .chatHead{flex:0 0 auto!important;min-height:48px!important;}
body[data-page="dm"] .dmChatScreenV249235 #messages,body[data-page="dm"] .dmChatScreenV249235 .messages{flex:1 1 0!important;min-height:0!important;max-height:none!important;overflow-y:auto!important;overflow-x:hidden!important;-webkit-overflow-scrolling:touch!important;touch-action:pan-y!important;overscroll-behavior:contain!important;padding-bottom:14px!important;}
body[data-page="dm"] .dmChatScreenV249235 .composer{flex:0 0 auto!important;position:sticky!important;bottom:0!important;z-index:3!important;background:rgba(6,20,35,.96)!important;border-top:1px solid rgba(255,255,255,.10)!important;padding-bottom:calc(6px + env(safe-area-inset-bottom,0px))!important;}
.v249247ServerNotice{border:1px solid rgba(54,240,160,.22)!important;background:rgba(54,240,160,.075)!important}.v249247ServerNotice.like{border-color:rgba(255,100,130,.28)!important;background:rgba(255,100,130,.08)!important}.v249247ServerNotice.video_post{border-color:rgba(255,217,110,.30)!important;background:rgba(255,217,110,.08)!important}.v249247NoticeActions{display:flex!important;gap:8px!important;flex-wrap:wrap!important;margin-top:10px!important}.v249247NoticeActions .btn{min-height:42px!important;border-radius:14px!important;font-weight:900!important}.v249247PostTarget{outline:3px solid #ffd96e!important;box-shadow:0 0 0 8px rgba(255,217,110,.18)!important;transition:.2s!important}
@media(max-width:760px){body[data-page="dm"] #dmPage{height:calc(100dvh - var(--top,52px) - var(--bar,62px))!important}.v249247NoticeActions{display:grid!important;grid-template-columns:1fr!important}.v249247NoticeActions .btn{width:100%!important}}
`;document.head.appendChild(st)}catch(e){console.warn('v249247 css',e)}}
async function v249247RefreshServerNotifications(){try{return await v249242FetchJsonRace(`/api/notifications/social/v249247?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=80`,{},3500)}catch(e){return {ok:false,items:[],error:String(e&&e.message||e)}}}
async function v249247MarkServerNoticeRead(id){try{if(!id)return false;await fetchJson('/api/notifications/read/v249247',{method:'POST',body:JSON.stringify({room_id:state.room,device_id:state.device,ids:[id]})});refreshNotificationBadgeV249238();return false}catch(e){toast('Δεν σημειώθηκε ως διαβασμένο: '+(e.message||e));return false}}
async function v249247OpenPostFromNotice(postId,noticeId=''){try{postId=String(postId||'');if(noticeId)await v249247MarkServerNoticeRead(noticeId);try{$('memberMenu')?.classList.remove('show')}catch{};page('feed');await loadFeed();setTimeout(()=>{try{const el=document.querySelector(`[data-post="${CSS.escape(postId)}"]`);if(el){el.classList.add('v249247PostTarget');el.scrollIntoView({behavior:'smooth',block:'center'});setTimeout(()=>el.classList.remove('v249247PostTarget'),5200)}else toast('Η δημοσίευση δεν βρέθηκε στη Ροή ακόμη. Πάτησε ανανέωση Ροής.',5000)}catch(e){toast('Δεν άνοιξε η δημοσίευση: '+(e.message||e))}},450);return false}catch(e){toast('Δεν άνοιξε η δημοσίευση: '+(e.message||e));return false}}
async function v249247OpenDmFromNotice(id,noticeId=''){try{if(noticeId)await v249247MarkServerNoticeRead(noticeId);return v249243NoticeOpenMessage(id,noticeId)}catch(e){toast('Δεν άνοιξε η συνομιλία: '+(e.message||e));return false}}
function v249247ServerNoticeCards(events=[]){events=events||[];return events.map(e=>{const typ=String(e.type||'notice');const postId=String(e.post_id||'');const id=String(e.id||'');const p=v249231PersonById(e.from_id||'');const title=esc(e.title|| (typ==='like'?'❤️ Νέο like':typ==='video_post'?'🎥 Νέο βίντεο':'🔔 Ειδοποίηση'));const body=esc(e.body||'');const who=esc(p.nickname||e.from_name||'Μέλος');const cls=typ==='like'?'like':(typ==='video_post'?'video_post':'');const icon=typ==='like'?'❤️':(typ==='video_post'?'🎥':'🔔');return `<div class="card v249247ServerNotice ${cls}" data-server-notice="${esc(id)}"><b>${icon} ${title}</b><div class="row" style="align-items:center;margin-top:8px"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${p.online?'on':'off'}"></i></span><div><b>${who}</b><div class="date">${body}</div></div></div><div class="v249247NoticeActions">${postId?`<button class="btn green" onclick="ITH.v249247OpenPostFromNotice('${escJs(postId)}','${escJs(id)}')">🎬 Άνοιγμα δημοσίευσης</button>`:''}<button class="btn" onclick="ITH.v249247MarkServerNoticeRead('${escJs(id)}').then(()=>ITH.notifyCenter())">✓ Διαβασμένο</button></div></div>`}).join('')}
function v249247FriendRequestCards(items=[]){const seen=new Set();try{items=[...(items||[]),...uniqueNotices(localNotices()).filter(v249233IsFriendRequestPending)]}catch{}items=(items||[]).filter(n=>{const k=v249240NoticeKey(n);if(seen.has(k))return false;seen.add(k);return String(n.type||'contact_invite')!=='message'&&String(n.status||'pending')==='pending'}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));const incoming=items.filter(n=>String(n.relation_to_device||'')==='incoming'||String(n.to_id||'')===String(state.device));const outgoing=items.filter(n=>String(n.relation_to_device||'')==='outgoing'||String(n.from_id||'')===String(state.device));const repairable=items.filter(n=>String(n.relation_to_device||'')==='other_device_or_old_id'||(String(n.to_id||'')!==String(state.device)&&String(n.from_id||'')!==String(state.device)));const normalOther=items.filter(n=>!incoming.includes(n)&&!outgoing.includes(n)&&!repairable.includes(n));const friendCard=n=>{const rel=String(n.relation_to_device||'');const inbound=rel==='incoming'||String(n.to_id||'')===String(state.device);const outbound=rel==='outgoing'||String(n.from_id||'')===String(state.device);const oldDevice=rel==='other_device_or_old_id'||(!inbound&&!outbound);const other=String(inbound?n.from_id:(outbound?n.to_id:(n.from_id||n.to_id||'')));const p=v249231PersonById(other);const name=esc(p.nickname||n.from_name||n.to_name||'Μέλος');const key=escJs(v249240NoticeKey(n));const title=inbound?'🤝 Νέο αίτημα φιλίας':outbound?'⏳ Περιμένει απάντηση':'🛠️ Αίτημα σε παλιό/άλλο device';const note=inbound?'Πατάς Αποδοχή ή Απόρριψη.':outbound?'Η αποδοχή γίνεται στην άλλη συσκευή.':`Δεν ήταν δεμένο στο σημερινό device. Πάτα Αποδοχή εδώ για να διορθωθεί.`;return `<div class="card v249238FriendReq ${inbound?'inbound':outbound?'outbound':'other'}" data-notice-key="${esc(v249240NoticeKey(n))}"><b>${title}</b><div class="row" style="align-items:center;margin-top:8px"><span class="avatarDotWrap">${avatarHtml(p)}<i class="${p.online?'on':'off'}"></i></span><div><b>${name}</b><div class="date">${esc(n.text||'')} · ${p.online?'ενεργός':'ανενεργός'}</div><div class="date">${note}</div></div></div>${inbound?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${key}',false)">✅ Αποδοχή</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${key}',false)">❌ Απόρριψη</button></div>`:oldDevice?`<div class="v249238NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',true,'${escJs(other)}','${key}',true)">✅ Αποδοχή εδώ</button><button class="btn danger" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||n.event_id||'')}',false,'${escJs(other)}','${key}',true)">❌ Απόρριψη</button></div>`:`<div class="v249238NoticeActions"><button class="btn" onclick="ITH.member('${escJs(other)}')">Μενού μέλους</button><span class="date">Περιμένει απάντηση.</span></div>`}</div>`};const ordered=[...incoming,...repairable,...outgoing,...normalOther];return {html:ordered.map(friendCard).join(''),count:ordered.length,incoming:incoming.length,repairable:repairable.length,outgoing:outgoing.length}}
function v249247RenderCenter(menu,friendItems=[],events=[],meta={}){try{injectV249247ChatNotifyCss();v249242NotifyShell(menu,'Τα δεδομένα φορτώθηκαν. Το καμπανάκι δείχνει αιτήματα, μηνύματα, likes και νέα βίντεο.');const mount=document.getElementById('v249242NotifyMount');const f=v249247FriendRequestCards(friendItems||[]);const serverHtml=v249247ServerNoticeCards(events||[]);const messagesHtml=v249243LocalMessageCards();if(mount)mount.innerHTML=`<div class="card"><b>Κατάσταση</b><div class="date">Αιτήματα: ${f.count} · Μηνύματα: ${v249243UnreadMessageNotices().length} · Likes/βίντεο: ${(events||[]).length} · Πηγή: ${esc(meta.source||'v249247')}</div></div><div class="card"><b>🤝 Αιτήματα φιλίας</b><div class="date">Εισερχόμενα: ${f.incoming} · Παλιό/άλλο device: ${f.repairable} · Εξερχόμενα: ${f.outgoing}</div></div><div class="v249233NoticeList">${f.html||'<div class="card">Δεν υπάρχουν αιτήματα φιλίας σε αναμονή.</div>'}</div><div class="card"><b>💬 Μηνύματα</b><div class="date">Νέα μηνύματα που ανοίγουν συνομιλία.</div></div><div class="v249233NoticeList">${messagesHtml||'<div class="card">Δεν υπάρχουν νέα μηνύματα.</div>'}</div><div class="card"><b>❤️🎥 Δημοσιεύσεις</b><div class="date">Likes στη δημοσίευσή σου και νέο βίντεο/δημοσίευση από φίλο ή μέλος που ακολουθείς.</div></div><div class="v249233NoticeList">${serverHtml||'<div class="card">Δεν υπάρχουν νέες ειδοποιήσεις δημοσιεύσεων.</div>'}</div>`;refreshNotificationBadgeV249238()}catch(e){v249242RenderNotifyError(menu,'Σφάλμα εμφάνισης ειδοποιήσεων: '+(e.message||e))}}
function legacyNotifyCenterV249526_8(){injectV249247ChatNotifyCss();const menu=$('memberMenu');if(!menu)return false;v249242NotifyShell(menu,'Η οθόνη άνοιξε αμέσως. Ελέγχω αιτήματα, μηνύματα, likes και βίντεο.');setTimeout(()=>{try{const m=document.getElementById('v249242NotifyMount');if(m&&/Έλεγχος αιτημάτων/.test(m.textContent||'')){v249247RenderCenter(menu,[],[],{source:'local-timeout'})}}catch{}},6500);const pFriends=v249242FetchJsonRace(`/api/notifications/light/v249242?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=80`,{},4300).catch(()=>v249242FetchJsonRace(`/api/notifications/light/v249241?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=80`,{},3000)).catch(()=>({items:[],version:'friend-fallback'}));const pEvents=v249247RefreshServerNotifications();Promise.all([pFriends,pEvents]).then(([fr,ev])=>v249247RenderCenter(menu,(fr.items||[]).map(v249242NotifyItem),(ev.items||[]),{source:(fr.version||'friends')+' + '+(ev.version||'events')})).catch(e=>v249242RenderNotifyError(menu,'Αποτυχία φόρτωσης ειδοποιήσεων: '+((e&&e.message)||e||'')));return false}
async function refreshNotificationBadgeV249238(){try{const b=document.getElementById('ithNotifyFabV249238');if(!b)return;const bd=b.querySelector('.badge');let serverCount=0;try{const r=await v249242FetchJsonRace(`/api/notifications/count/v249247?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},2500);serverCount=+(r.count||0)||0}catch{try{const r=await v249242FetchJsonRace(`/api/notifications/count/v249242?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`,{},2200);serverCount=+(r.count||0)||0}catch{}}const msgCount=v249243UnreadMessageNotices().length;const c=serverCount+msgCount;try{const key='ith_last_notify_badge_v249247';const last=+(localStorage.getItem(key)||'0')||0;const lastSound=+(localStorage.getItem('ith_last_notify_sound_v249247')||'0')||0;if(c>last)localStorage.setItem('ith_last_notify_sound_v249247',String(Date.now()));localStorage.setItem(key,String(c||0));localStorage.setItem('ith_last_notify_badge_v249242',String(c||0))}catch{}if(bd){bd.textContent=c>9?'9+':String(c);bd.style.display=c?'grid':'none';bd.title=`Server ${serverCount} · Μηνύματα ${msgCount}`}}catch(e){}}
async function v249247ServerFriendIds(){try{await loadSocialFriendsV249225()}catch{}const ids=ithV249236FriendIds();try{(state.socialFriendsV249225||[]).forEach(p=>{const id=String(p.device_id||p.id||'');if(id)ids.add(id)})}catch{}return ids}
async function sendFriendProposal(id){if(!id||String(id)===String(state.device))return toast('Δεν γίνεται πρόταση στον εαυτό σου.');id=String(id);const p=state.people.get(id)||{nickname:'Μέλος'};try{const friendIds=await v249247ServerFriendIds();if(friendIds.has(id)){toast('Είστε ήδη φίλοι. Άνοιξα τα Μηνύματα.',4200);try{await refreshFriendsForMessagesV249246(false)}catch{};return startDM(id)}}catch{}try{const r=await fetchJson('/api/social/friend/request',{method:'POST',body:JSON.stringify({room_id:state.room,from_id:state.device,from_name:state.name||'Μέλος',to_id:id,to_name:p.nickname||'Μέλος'})});if(r&&r.already_friends){try{await refreshFriendsForMessagesV249246(false)}catch{};toast('Είστε ήδη φίλοι. Άνοιξα τα Μηνύματα.',4200);return startDM(id)}if(r&&r.reverse_pending){toast('Υπάρχει ήδη αίτημα από το άλλο μέλος. Άνοιξε το καμπανάκι για αποδοχή.',5500);setTimeout(()=>notifyCenter(),400);return false}try{inviteContact(id)}catch{}toast(r&&r.duplicate?'Υπάρχει ήδη αίτημα φιλίας':'Στάλθηκε αίτημα φιλίας με μήνυμα');refreshNotificationBadgeV249238();return false}catch(e){try{inviteContact(id)}catch{}toast('Τοπικό αίτημα φιλίας στάλθηκε. Server: '+(e.message||e));return false}}
async function chooseCommunicationContactV249230(id,mode='message'){id=String(id||'');mode=String(mode||'message');if(!id)return false;try{const friendIds=await v249247ServerFriendIds();if(!friendIds.has(id)){await sendFriendProposal(id);toast('Χρειάζεται αποδοχή φιλίας. Άνοιξε τις Ειδοποιήσεις για αποδοχή/απόρριψη.',5000);setTimeout(()=>notifyCenter(),500);return false}}catch(e){toast('Έλεγχος φιλίας: '+(e.message||e),4500);return false}try{$('memberMenu')?.classList.remove('show')}catch{}await startDM(id);if(mode==='video')return startVideoCall();if(mode==='voice')return startVoiceCall();return false}
function showDMFriendListV249235(){injectV249247ChatNotifyCss();const shell=$('dmShellV249235');if(shell)shell.classList.remove('chatOpen');if($('dmFriendScreen'))$('dmFriendScreen').style.display='';if($('dmChatScreen'))$('dmChatScreen').style.display='none';renderPeople();refreshFriendsForMessagesV249246(false);return false}
function showDMChatScreenV249235(){injectV249247ChatNotifyCss();const shell=$('dmShellV249235');if(shell)shell.classList.add('chatOpen');if($('dmFriendScreen'))$('dmFriendScreen').style.display='none';if($('dmChatScreen'))$('dmChatScreen').style.display='block';setTimeout(()=>{try{const box=$('messages');if(box)box.scrollTop=box.scrollHeight}catch{}},80);return false}


/* V249251: closed-app notification deep-link and call single-session client guards. */
function v249251NotifyNativeCallControl(kind, sessionId){
  try{ if(kind==='call_cancel'||kind==='call_end'||kind==='call_answered'||kind==='call_rejected'){ bridgeCall('cancelCallNotification', String(sessionId||'')); stopCallAlert(); } }catch{}
}
function v249251CallSessionId(){try{return String((state.call&&state.call.session&&state.call.session.session_id)||'')}catch{return''}}
async function v249251OpenCallFromUrl(){
  try{
    const u=new URL(location.href);
    const sid=u.searchParams.get('session_id')||u.searchParams.get('call_session')||'';
    const wantsCall=u.searchParams.get('call')||u.searchParams.get('kind')||'';
    const peer=u.searchParams.get('dm')||u.searchParams.get('peer_id')||u.searchParams.get('peer')||'';
    if(!sid && !/call|video_call|voice_call/i.test(String(wantsCall||''))) return false;
    try{page('dm'); if(peer){await loadPeople(); await startDM(peer)}}catch{}
    if(sid){
      try{
        const r=await fetchJson(`/api/video/session/status?room_id=${encodeURIComponent(state.room)}&session_id=${encodeURIComponent(sid)}&device_id=${encodeURIComponent(state.device)}`);
        const s=r.session||{};
        if(['ended','expired','rejected'].includes(String(s.status||''))){toast('Η κλήση έχει κλείσει.');try{bridgeCall('cancelCallNotification',sid)}catch{};return true}
        if(String(s.callee_id)===String(state.device)&&String(s.status)==='ringing'){
          if(state.call&&v249251CallSessionId()!==String(s.session_id||'')) await endActiveCall();
          const kind=s.call_type==='voice'?'voice':'video';
          state.call={session:s,kind,peerId:s.caller_id,signalAfter:0,incoming:true,ringStartedAt:Date.now()};
          showCallModal(kind,s.caller_name||'Μέλος','Εισερχόμενη κλήση',true);
          return true;
        }
        if(String(s.caller_id)===String(state.device)){
          toast('Η κλήση είναι ανοιχτή/σε αναμονή.');
          return true;
        }
      }catch(e){toast('Δεν άνοιξε η κλήση: '+(e.message||e));return true}
    }
    if(peer){return startDM(peer)}
  }catch(e){}
  return false;
}
async function v249251OpenLaunchFromUrl(){
  try{
    const u=new URL(location.href);
    const kind=String(u.searchParams.get('kind')||u.searchParams.get('fcm_kind')||'');
    const dm=u.searchParams.get('dm')||u.searchParams.get('peer')||u.searchParams.get('peer_id')||u.searchParams.get('from_id')||'';
    const openMessages=u.searchParams.get('open_messages')==='1'||u.searchParams.get('direct_open_dm')==='1';
    if(/call|video_call|voice_call/i.test(kind)||u.searchParams.get('call')||u.searchParams.get('session_id')){
      document.documentElement.dataset.ithakiLastPushRoute='call';
      return await v249251OpenCallFromUrl();
    }
    if(kind==='message'||u.searchParams.get('message_id')||dm||openMessages){
      document.documentElement.dataset.ithakiLastPushRoute='messages';
      page('dm');
      try{await loadPeople()}catch(_e){}
      if(dm){try{await startDM(dm)}catch(_e){try{const f=window.ITH&&(ITH.openDMWith||ITH.startDM);if(typeof f==='function')await f(dm)}catch(_x){}}}
      try{history.replaceState(history.state,'',location.pathname+'?lang='+(u.searchParams.get('lang')||'el')+'&v=249526r10f42')}catch(_e){}
      return true;
    }
  }catch(e){try{document.documentElement.dataset.ithakiLastPushRouteError=String(e&&e.message||e)}catch(_e){}}
  try{return await openLinkedDmFromUrlV249227()}catch{return false}
}
const v249251OriginalCheckIncomingCalls = typeof checkIncomingCalls==='function' ? checkIncomingCalls : null;
checkIncomingCalls = async function(){
  try{
    if(state.call&&v249251CallSessionId()){
      try{
        const sid=v249251CallSessionId();
        const r=await fetchJson(`/api/video/session/status?room_id=${encodeURIComponent(state.room)}&session_id=${encodeURIComponent(sid)}&device_id=${encodeURIComponent(state.device)}`);
        const st=String((r.session&&r.session.status)||'');
        if(['ended','expired','rejected'].includes(st)){stopCallAlert();rememberClosedCallSession(state.call.session);callStatusText('Η κλήση έκλεισε');setTimeout(()=>clearCallState(),500)}
      }catch{}
      return false;
    }
    return v249251OriginalCheckIncomingCalls?await v249251OriginalCheckIncomingCalls():false;
  }catch(e){return false}
};

/* V249252 - Sokratakis turtle companion: local Socratic questions, no AI, no DB changes */
function injectSocratakiV249252Css(){
  try{
    if(document.getElementById('socratakiV249252Css'))return;
    const st=document.createElement('style');st.id='socratakiV249252Css';
    st.textContent=`
      #socratakiFabV249252{position:fixed;left:14px;bottom:86px;z-index:9998;width:58px;height:58px;border-radius:22px;border:1px solid rgba(255,217,110,.55);background:linear-gradient(145deg,rgba(20,75,70,.96),rgba(8,31,37,.98));box-shadow:0 18px 46px rgba(0,0,0,.42), inset 0 1px 0 rgba(255,255,255,.12);display:grid;place-items:center;cursor:pointer;color:#ffe9ac;font-weight:1000;touch-action:manipulation}
      #socratakiFabV249252 small{position:absolute;right:-4px;top:-7px;background:#ffd95d;color:#1c241f;border-radius:999px;padding:2px 6px;font-size:10px;box-shadow:0 4px 12px rgba(0,0,0,.25)}
      .sokraMiniV249252{position:relative;width:48px;height:44px;display:block}.sokraMiniV249252 .shell{position:absolute;left:11px;top:17px;width:30px;height:23px;border-radius:18px 18px 12px 12px;background:radial-gradient(circle at 45% 26%,#ffe192 0 19%,#61b987 20% 52%,#276f58 53% 100%);border:2px solid rgba(255,255,255,.28);animation:sokraShellBreathV249252 4.8s ease-in-out infinite}.sokraMiniV249252 .head{position:absolute;left:20px;top:2px;width:20px;height:20px;border-radius:50%;background:#7bd59b;border:2px solid rgba(255,255,255,.28);transform-origin:50% 110%;animation:sokraNeckV249252 5.2s ease-in-out infinite}.sokraMiniV249252 .eye{position:absolute;top:6px;width:3px;height:5px;background:#10231e;border-radius:99px;animation:sokraBlinkV249252 5.4s infinite}.sokraMiniV249252 .eye.l{left:6px}.sokraMiniV249252 .eye.r{right:6px}.sokraMiniV249252 .foot{position:absolute;bottom:0;width:9px;height:7px;border-radius:99px;background:#65be86}.sokraMiniV249252 .foot.l{left:8px}.sokraMiniV249252 .foot.r{right:5px}
      #socratakiPanelV249252{position:fixed;inset:0;z-index:10002;display:none;background:rgba(0,0,0,.58);backdrop-filter:blur(10px);padding:14px;box-sizing:border-box}#socratakiPanelV249252.show{display:flex;align-items:center;justify-content:center}.sokraBoxV249252{width:min(720px,100%);max-height:min(780px,92vh);display:flex;flex-direction:column;overflow:hidden;border-radius:26px;border:1px solid rgba(255,217,110,.35);background:linear-gradient(180deg,rgba(12,34,42,.98),rgba(6,18,24,.98));box-shadow:0 30px 90px rgba(0,0,0,.56);color:#eefbff}.sokraTopV249252{display:flex;align-items:center;gap:12px;padding:13px 14px;border-bottom:1px solid rgba(255,255,255,.10);background:linear-gradient(90deg,rgba(255,217,110,.16),rgba(54,240,160,.08));flex-shrink:0}.sokraTopV249252 .title{min-width:0;flex:1}.sokraTopV249252 b{display:block;color:#ffe8a8;font-size:18px}.sokraTopV249252 small{display:block;color:rgba(238,247,255,.72);margin-top:2px}.sokraCloseV249252{width:42px;height:42px;border-radius:16px;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.08);color:#fff;font-size:20px}.sokraBodyV249252{overflow:auto;-webkit-overflow-scrolling:touch;padding:14px;display:flex;flex-direction:column;gap:12px}.sokraHeroV249252{display:grid;grid-template-columns:auto 1fr;gap:13px;align-items:center;border-radius:22px;padding:13px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10)}.sokraTurtleBigV249252{position:relative;width:112px;height:92px;flex-shrink:0}.sokraTurtleBigV249252 .shell{position:absolute;left:27px;top:31px;width:68px;height:48px;border-radius:38px 38px 22px 22px;background:radial-gradient(circle at 48% 30%,#ffe8a8 0 16%,#67c98e 17% 52%,#216a55 53% 100%);border:3px solid rgba(255,255,255,.22);box-shadow:inset 0 -9px 18px rgba(0,0,0,.17);animation:sokraShellBreathV249252 4.6s ease-in-out infinite}.sokraTurtleBigV249252 .neck{position:absolute;left:49px;top:22px;width:18px;height:24px;border-radius:99px;background:#68c98b;transform-origin:50% 100%;animation:sokraNeckV249252 5s ease-in-out infinite}.sokraTurtleBigV249252 .head{position:absolute;left:42px;top:7px;width:34px;height:32px;border-radius:50%;background:#7bdd9c;border:3px solid rgba(255,255,255,.22);animation:sokraHeadListenV249252 6s ease-in-out infinite}.sokraTurtleBigV249252 .eye{position:absolute;top:11px;width:5px;height:8px;background:#10231e;border-radius:99px;animation:sokraBlinkV249252 5.2s infinite}.sokraTurtleBigV249252 .eye.l{left:10px}.sokraTurtleBigV249252 .eye.r{right:10px}.sokraTurtleBigV249252 .smile{position:absolute;left:11px;top:20px;width:12px;height:5px;border-bottom:2px solid rgba(16,35,30,.72);border-radius:0 0 99px 99px}.sokraTurtleBigV249252 .foot{position:absolute;top:72px;width:19px;height:12px;border-radius:99px;background:#5ebf80}.sokraTurtleBigV249252 .foot.l{left:18px}.sokraTurtleBigV249252 .foot.r{right:6px}.sokraTurtleBigV249252.think .head,.sokraTurtleBigV249252.think .neck{animation:sokraHideV249252 1.1s ease-in-out 1}.sokraCardV249252{border-radius:20px;padding:12px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10)}.sokraCardV249252 b{color:#ffe8a8}.sokraGridV249252{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}.sokraBtnV249252{border:1px solid rgba(255,217,110,.30);border-radius:17px;background:linear-gradient(135deg,rgba(255,217,110,.13),rgba(54,240,160,.08));color:#fff;padding:11px;text-align:left;font-weight:900;min-height:46px}.sokraBtnV249252 small{display:block;opacity:.72;font-weight:600;margin-top:3px}.sokraQuestionV249252{font-size:17px;line-height:1.35;color:#fff}.sokraInputV249252{width:100%;box-sizing:border-box;min-height:82px;border-radius:18px;border:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.22);color:#fff;padding:12px;font:inherit;resize:vertical}.sokraActionsV249252{display:flex;gap:8px;flex-wrap:wrap}.sokraActionsV249252 button{border-radius:999px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.08);color:#fff;padding:10px 13px;font-weight:900}.sokraActionsV249252 button.good{background:linear-gradient(135deg,rgba(54,240,160,.25),rgba(255,217,110,.18));border-color:rgba(54,240,160,.35)}.sokraOutputV249252{white-space:pre-wrap;font-size:16px;line-height:1.45;background:rgba(0,0,0,.20);border-radius:18px;padding:12px;border:1px solid rgba(255,217,110,.18)}.sokraTinyV249252{font-size:12px;color:rgba(238,247,255,.66);line-height:1.35}.sokraPillV249252{display:inline-flex;align-items:center;gap:5px;border-radius:999px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.12);padding:5px 8px;margin:2px;font-size:12px}.sokraToastV249252{position:fixed;left:50%;bottom:88px;transform:translateX(-50%);z-index:10004;background:rgba(10,27,34,.96);border:1px solid rgba(255,217,110,.35);color:#fff;border-radius:999px;padding:10px 14px;box-shadow:0 16px 38px rgba(0,0,0,.40);font-weight:900}
      @keyframes sokraBlinkV249252{0%,92%,100%{transform:scaleY(1)}94%,96%{transform:scaleY(.08)}}@keyframes sokraNeckV249252{0%,100%{transform:translateY(0) rotate(0)}40%{transform:translateY(-2px) rotate(-4deg)}70%{transform:translateY(1px) rotate(4deg)}}@keyframes sokraHeadListenV249252{0%,100%{transform:translateY(0) rotate(0)}35%{transform:translateY(-1px) rotate(-5deg)}72%{transform:translateY(1px) rotate(5deg)}}@keyframes sokraShellBreathV249252{0%,100%{transform:scale(1)}50%{transform:scale(1.025)}}@keyframes sokraHideV249252{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(23px) scale(.88)}}
      @media(max-width:680px){#socratakiFabV249252{left:10px;bottom:78px;width:54px;height:54px;border-radius:20px}.sokraBoxV249252{max-height:94vh;border-radius:22px}.sokraTopV249252{padding:10px}.sokraBodyV249252{padding:10px}.sokraHeroV249252{grid-template-columns:1fr;text-align:center}.sokraTurtleBigV249252{margin:auto}.sokraGridV249252{grid-template-columns:1fr}.sokraActionsV249252 button{flex:1;min-width:130px}.sokraBtnV249252{min-height:44px}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
const sokratakiTopicsV249252={
  calm:{title:'Να απαντήσω ήρεμα',hint:'Για να μη γίνει καβγάς.',q:['Τι θέλεις πιο πολύ;','Πώς θέλεις να ακουστεί;','Γράψε με λίγες λέξεις τι έγινε.'],a:[['Να με καταλάβει','Να μη μαλώσουμε','Να κρατήσω απόσταση'],['Ήρεμα','Ξεκάθαρα','Τρυφερά']]},
  hurt:{title:'Να πω ότι στεναχωρήθηκα',hint:'Χωρίς επίθεση.',q:['Τι σε πείραξε περισσότερο;','Τι ζητάς από τον άλλον;','Γράψε τη δική σου μικρή αλήθεια.'],a:[['Τα λόγια','Η συμπεριφορά','Η αδιαφορία'],['Να με ακούσει','Να ζητήσει συγγνώμη','Να το αφήσουμε ήρεμα']]},
  no:{title:'Να πω όχι',hint:'Με όρια αλλά χωρίς σκληρότητα.',q:['Τι θέλεις να προστατέψεις;','Τι τόνο θέλεις;','Γράψε τι δεν μπορείς/δεν θέλεις.'],a:[['Τον χρόνο μου','Την ηρεμία μου','Τα όριά μου'],['Σύντομο','Ευγενικό','Σταθερό']]},
  start:{title:'Να ξεκινήσω κουβέντα',hint:'Χωρίς αμηχανία.',q:['Γιατί θέλεις να μιλήσεις;','Πόσο ανοιχτό να είναι;','Γράψε τι θα ήθελες να ρωτήσεις.'],a:[['Να γνωριστούμε','Να συνεχίσουμε κουβέντα','Να ρωτήσω κάτι'],['Απλό','Ζεστό','Χαλαρό']]},
  support:{title:'Να στηρίξω κάποιον',hint:'Λίγα λόγια, καθαρά.',q:['Τι χρειάζεται να νιώσει;','Τι μπορείς πραγματικά να προσφέρεις;','Γράψε σε ποια στιγμή θέλεις να σταθείς δίπλα του.'],a:[['Ότι δεν είναι μόνος','Ότι τον ακούω','Ότι υπάρχει χρόνος'],['Να ακούσω','Να βοηθήσω πρακτικά','Να είμαι εδώ']]},
  post:{title:'Να κάνω δημοσίευση',hint:'Σκέψη πριν τη ροή.',q:['Σε ποιους θέλεις να μιλήσεις;','Τι θέλεις να μείνει;','Γράψε την κεντρική ιδέα.'],a:[['Σε όλους','Σε φίλους','Ανώνυμα'],['Μια σκέψη','Ένα συναίσθημα','Μια ερώτηση']]}
};
let sokratakiStateV249252={topic:null,answers:[],free:'',output:''};
function sokratakiToastV249252(msg){try{let t=document.createElement('div');t.className='sokraToastV249252';t.textContent=msg;document.body.appendChild(t);setTimeout(()=>t.remove(),2300)}catch(e){try{toast(msg,2300)}catch(_){}}}
function ensureSocratakiV249252(){try{injectSocratakiV249252Css();if(!document.body)return;if(!document.getElementById('socratakiFabV249252')){const b=document.createElement('button');b.id='socratakiFabV249252';b.type='button';b.title='Bil - μικρή χελωνούλα συνοδοιπόρος';b.innerHTML=`<span class="sokraMiniV249252"><i class="foot l"></i><i class="foot r"></i><i class="shell"></i><i class="head"><i class="eye l"></i><i class="eye r"></i></i></span><small>Σ</small>`;b.onclick=sokratakiOpenV249252;document.body.appendChild(b)}if(!document.getElementById('socratakiPanelV249252')){const p=document.createElement('div');p.id='socratakiPanelV249252';p.innerHTML=`<div class="sokraBoxV249252" role="dialog" aria-label="Bil"><div class="sokraTopV249252"><div class="sokraMiniV249252"><i class="foot l"></i><i class="foot r"></i><i class="shell"></i><i class="head"><i class="eye l"></i><i class="eye r"></i></i></div><div class="title"><b>Bil</b><small>Η μικρή χελωνούλα που κάνει ερωτήσεις για να βρεις εσύ τα λόγια σου.</small></div><button class="sokraCloseV249252" onclick="sokratakiCloseV249252()">×</button></div><div id="sokratakiBodyV249252" class="sokraBodyV249252"></div></div>`;p.addEventListener('click',e=>{if(e.target===p)sokratakiCloseV249252()});document.body.appendChild(p)}}catch(e){}}
function sokratakiOpenV249252(){ensureSocratakiV249252();sokratakiStateV249252={topic:null,answers:[],free:'',output:''};const p=document.getElementById('socratakiPanelV249252');if(p)p.classList.add('show');sokratakiRenderHomeV249252()}
function sokratakiCloseV249252(){try{document.getElementById('socratakiPanelV249252')?.classList.remove('show')}catch(e){}}
function sokratakiTurtleV249252(cls=''){return `<div class="sokraTurtleBigV249252 ${cls}"><i class="foot l"></i><i class="foot r"></i><i class="shell"></i><i class="neck"></i><i class="head"><i class="eye l"></i><i class="eye r"></i><i class="smile"></i></i></div>`}
function sokratakiRenderHomeV249252(){const b=document.getElementById('sokratakiBodyV249252');if(!b)return;const cards=Object.entries(sokratakiTopicsV249252).map(([k,t])=>`<button class="sokraBtnV249252" onclick="sokratakiChooseTopicV249252('${k}')">${t.title}<small>${t.hint}</small></button>`).join('');b.innerHTML=`<div class="sokraHeroV249252">${sokratakiTurtleV249252()}<div><b>Δεν έχω έτοιμες απαντήσεις.</b><div class="sokraTinyV249252" style="margin-top:6px">Έχω όμως ήρεμες ερωτήσεις. Θα απαντήσεις εσύ και θα φτιάξουμε μαζί τα λόγια σου, χωρίς AI και χωρίς να στέλνουμε τίποτα στον server.</div><div style="margin-top:8px"><span class="sokraPillV249252">🐢 αργά</span><span class="sokraPillV249252">🧭 καθαρά</span><span class="sokraPillV249252">🤍 χωρίς πίεση</span></div></div></div><div class="sokraCardV249252"><b>Τι θέλεις να βρεις;</b><div class="sokraGridV249252" style="margin-top:10px">${cards}</div></div><div class="sokraTinyV249252">Το Bil είναι βοήθεια σκέψης, όχι άνθρωπος και όχι γιατρός. Σε δύσκολη ή επικίνδυνη κατάσταση μίλα με άνθρωπο που εμπιστεύεσαι ή με αρμόδια βοήθεια.</div>`}
function sokratakiChooseTopicV249252(key){sokratakiStateV249252={topic:key,answers:[],free:'',output:''};sokratakiRenderStepV249252()}
function sokratakiRenderStepV249252(){const b=document.getElementById('sokratakiBodyV249252');if(!b)return;const t=sokratakiTopicsV249252[sokratakiStateV249252.topic];const step=sokratakiStateV249252.answers.length;if(!t)return sokratakiRenderHomeV249252();if(step>=2){b.innerHTML=`<div class="sokraHeroV249252">${sokratakiTurtleV249252('think')}<div><b>${t.title}</b><div class="sokraQuestionV249252" style="margin-top:6px">${t.q[2]}</div></div></div><textarea id="sokraFreeV249252" class="sokraInputV249252" placeholder="Γράψε εδώ λίγες λέξεις. Δεν αποστέλλεται πουθενά.">${(sokratakiStateV249252.free||'').replace(/[<>&]/g,m=>({'<':'&lt;','>':'&gt;','&':'&amp;'}[m]))}</textarea><div class="sokraActionsV249252"><button onclick="sokratakiRenderStepBackV249252()">‹ Πίσω</button><button class="good" onclick="sokratakiComposeV249252()">Βρες μου τα λόγια</button></div>`;return}const opts=(t.a[step]||[]).map((x,i)=>`<button class="sokraBtnV249252" onclick="sokratakiAnswerV249252('${String(x).replace(/'/g,"\\'")}')">${x}</button>`).join('');b.innerHTML=`<div class="sokraHeroV249252">${sokratakiTurtleV249252()}<div><b>${t.title}</b><div class="sokraQuestionV249252" style="margin-top:6px">${t.q[step]}</div></div></div><div class="sokraGridV249252">${opts}</div><div class="sokraActionsV249252"><button onclick="sokratakiRenderHomeV249252()">‹ Αρχή</button></div>`}
function sokratakiAnswerV249252(ans){sokratakiStateV249252.answers.push(ans);sokratakiRenderStepV249252()}
function sokratakiRenderStepBackV249252(){if(sokratakiStateV249252.answers.length)sokratakiStateV249252.answers.pop();sokratakiRenderStepV249252()}
function sokratakiComposeV249252(){try{sokratakiStateV249252.free=(document.getElementById('sokraFreeV249252')?.value||'').trim()}catch{}const t=sokratakiTopicsV249252[sokratakiStateV249252.topic];const a=sokratakiStateV249252.answers||[];const free=sokratakiStateV249252.free||'αυτό που έγινε';let out='';switch(sokratakiStateV249252.topic){case 'calm':out=`Θέλω να το πω ${a[1]||'ήρεμα'}: ${free}. Δεν θέλω να μαλώσουμε· θέλω κυρίως ${String(a[0]||'να με καταλάβεις').toLowerCase()}.`;break;case 'hurt':out=`Με στεναχώρησε ${free}. Δεν το λέω για να επιτεθώ, αλλά γιατί για μένα είχε σημασία. Θα ήθελα ${String(a[1]||'να με ακούσεις').toLowerCase()}.`;break;case 'no':out=`Σε σέβομαι, αλλά αυτή τη στιγμή χρειάζεται να προστατέψω ${String(a[0]||'τα όριά μου').toLowerCase()}. Γι’ αυτό δεν μπορώ να προχωρήσω με αυτό: ${free}.`;break;case 'start':out=`Γεια σου. Θα ήθελα ${String(a[0]||'να μιλήσουμε').toLowerCase()}. ${free?free+';':'Θες να τα πούμε λίγο;'}`;break;case 'support':out=`Είμαι εδώ. ${free}. Δεν χρειάζεται να απαντήσεις αμέσως· απλώς θέλω να ξέρεις ότι μπορώ ${String(a[1]||'να σε ακούσω').toLowerCase()}.`;break;case 'post':out=`${free}\n\nΤο γράφω ${String(a[0]||'για να το μοιραστώ').toLowerCase()}, σαν ${String(a[1]||'μια σκέψη').toLowerCase()}.`;break;default:out=free}out=out.replace(/\s+/g,' ').replace(/ \n /g,'\n').trim();sokratakiStateV249252.output=out;sokratakiRenderOutputV249252()}
function sokratakiRenderOutputV249252(){const b=document.getElementById('sokratakiBodyV249252');if(!b)return;const out=sokratakiStateV249252.output||'';b.innerHTML=`<div class="sokraHeroV249252">${sokratakiTurtleV249252()}<div><b>Το βρήκαμε μαζί.</b><div class="sokraTinyV249252" style="margin-top:6px">Διάβασέ το. Αν σου μοιάζει αληθινό, χρησιμοποίησέ το. Αν όχι, το αλλάζουμε.</div></div></div><div class="sokraOutputV249252">${out.replace(/[<>&]/g,m=>({'<':'&lt;','>':'&gt;','&':'&amp;'}[m]))}</div><div class="sokraActionsV249252"><button onclick="sokratakiSofterV249252()">Πιο ήρεμο</button><button onclick="sokratakiShorterV249252()">Πιο σύντομο</button><button onclick="sokratakiCopyV249252()">Αντιγραφή</button><button class="good" onclick="sokratakiPutInMessageV249252()">Βάλε στα Μηνύματα</button><button class="good" onclick="sokratakiPutInPostV249252()">Βάλε στη Δημοσίευση</button><button onclick="sokratakiRenderStepV249252()">Ξανά</button></div>`}
function sokratakiSofterV249252(){sokratakiStateV249252.output='Θέλω να το πω ήρεμα, χωρίς ένταση. '+(sokratakiStateV249252.output||'');sokratakiRenderOutputV249252()}
function sokratakiShorterV249252(){let s=(sokratakiStateV249252.output||'').split(/[.!;]/).filter(Boolean)[0]||sokratakiStateV249252.output;sokratakiStateV249252.output=s.trim()+'.';sokratakiRenderOutputV249252()}
function sokratakiCopyV249252(){const s=sokratakiStateV249252.output||'';try{navigator.clipboard.writeText(s);sokratakiToastV249252('Αντιγράφηκε')}catch(e){sokratakiToastV249252('Κράτησε πατημένο για αντιγραφή')}}
function sokratakiPutInMessageV249252(){const s=sokratakiStateV249252.output||'';try{if(window.ITH&&ITH.page)ITH.page('dm')}catch(e){}setTimeout(()=>{const i=document.getElementById('dmInput');if(i){i.value=s;i.focus();try{i.dispatchEvent(new Event('input',{bubbles:true}))}catch{}sokratakiCloseV249252();sokratakiToastV249252('Μπήκε στα Μηνύματα. Πάτα αποστολή όταν θέλεις.')}else{sokratakiCopyV249252();sokratakiToastV249252('Άνοιξε συνομιλία και επικόλλησέ το.')}},240)}
function sokratakiPutInPostV249252(){const s=sokratakiStateV249252.output||'';try{if(window.ITH&&ITH.page)ITH.page('plus')}catch(e){}setTimeout(()=>{const i=document.getElementById('postText')||document.getElementById('studioText');if(i){i.value=s;i.focus();try{i.dispatchEvent(new Event('input',{bubbles:true}))}catch{}sokratakiCloseV249252();sokratakiToastV249252('Μπήκε στη Δημοσίευση. Δημοσίευσε μόνο αν θέλεις.')}else{sokratakiCopyV249252();sokratakiToastV249252('Αντιγράφηκε για δημοσίευση.')}},260)}
try{window.sokratakiOpenV249252=sokratakiOpenV249252;window.sokratakiCloseV249252=sokratakiCloseV249252;window.sokratakiChooseTopicV249252=sokratakiChooseTopicV249252;window.sokratakiAnswerV249252=sokratakiAnswerV249252;window.sokratakiRenderStepBackV249252=sokratakiRenderStepBackV249252;window.sokratakiComposeV249252=sokratakiComposeV249252;window.sokratakiSofterV249252=sokratakiSofterV249252;window.sokratakiShorterV249252=sokratakiShorterV249252;window.sokratakiCopyV249252=sokratakiCopyV249252;window.sokratakiPutInMessageV249252=sokratakiPutInMessageV249252;window.sokratakiPutInPostV249252=sokratakiPutInPostV249252;window.ensureSocratakiV249252=ensureSocratakiV249252}catch(e){}
try{if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',()=>setTimeout(ensureSocratakiV249252,600));else setTimeout(ensureSocratakiV249252,600);setInterval(ensureSocratakiV249252,12000)}catch(e){}


/* V249258 - clean notification modes + Athina owl companion.
   Frontend/local only: no AI, no server data, no DB changes. Keeps V249257 push/call behavior. */
function ithakiV249258Esc(s){return String(s==null?'':s).replace(/[<>&]/g,m=>({'<':'&lt;','>':'&gt;','&':'&amp;'}[m]))}
function ithakiNotifyModeV249258(){try{return localStorage.getItem('ithaki_push_mode_v249258')||'fcm_default'}catch{return'fcm_default'}}
function ithakiCompanionV249258(){try{return localStorage.getItem('ithaki_companion_v249258')||'sokratakis'}catch{return'sokratakis'}}
function notificationMode(){const m=ithakiNotifyModeV249258();if(m==='fcm_default')return'fcm';if(m==='background')return'hybrid';if(m==='open_app')return'open_only';if(m==='stay_awake')return'stay_awake';if(m==='no_closed')return'open_only';try{return localStorage.getItem('ith_notifications_mode_v249164')||'fcm'}catch{return'fcm'}}
function notificationModeText(mode){
  const m=mode||ithakiNotifyModeV249258();
  const map={fcm_default:'1. FCM προεπιλογή',background:'2. Παρασκήνιο',open_app:'3. Ανοιχτή εφαρμογή',stay_awake:'4. Δεν κοιμάται',no_closed:'5. Χωρίς ειδοποιήσεις κλειστή συσκευή',fcm:'1. FCM προεπιλογή',hybrid:'2. Παρασκήνιο',open_only:'3. Ανοιχτή εφαρμογή'};
  return map[m]||map.fcm_default;
}
function setNotificationMode(mode){
  const alias={fcm:'fcm_default',hybrid:'background',open_only:'open_app',stay_awake:'stay_awake'};
  mode=alias[mode]||mode;
  const allowed=['fcm_default','background','open_app','stay_awake','no_closed'];
  if(!allowed.includes(mode))mode='fcm_default';
  try{localStorage.setItem('ithaki_push_mode_v249258',mode);localStorage.setItem('ith_notifications_mode_v249164',mode==='fcm_default'?'fcm':mode==='background'?'hybrid':mode==='open_app'?'open_only':mode==='stay_awake'?'stay_awake':'open_only')}catch{}
  try{if(bridgeHas('save'))bridgeCall('save','ithaki_push_mode_v249258',mode)}catch{}
  try{
    if(mode==='stay_awake'){localStorage.setItem('ith_stay_connected','1');if(bridgeHas('startStayConnected'))bridgeCall('startStayConnected')}
    else if(mode==='fcm_default'||mode==='background'){localStorage.setItem('ith_stay_connected','0');if(bridgeHas('stopStayConnected'))bridgeCall('stopStayConnected');if(bridgeHas('requestNotificationPermission'))bridgeCall('requestNotificationPermission');try{initPushHooks()}catch{}}
    else {localStorage.setItem('ith_stay_connected','0');if(bridgeHas('stopStayConnected'))bridgeCall('stopStayConnected')}
  }catch{}
  try{toast('Ειδοποιήσεις: '+notificationModeText(mode),3600)}catch{}
  try{renderNotificationModeSettingsV249258()}catch{}
  return false;
}
function companionNameV249258(c){return c==='none'?'ΙΘΑΚΗ':'Bil'}
function setIthakiCompanionV249258(c){c=(c==='sokratakis'||c==='none')?c:'sokratakis';try{localStorage.setItem('ithaki_companion_v249258',c)}catch{}try{if(bridgeHas('save'))bridgeCall('save','ithaki_companion_v249258',c)}catch{}try{toast(c==='none'?'Χωρίς συνοδοιπόρο ειδοποιήσεων':'Συνοδοιπόρος: '+companionNameV249258(c),3000)}catch{}try{ensureAthinaCompanionV249258()}catch{}try{renderNotificationModeSettingsV249258()}catch{}return false}
function athinaOwlV249258(cls=''){
  return `<div class="athinaOwlV249258 ${cls}"><i class="ear l"></i><i class="ear r"></i><i class="body"></i><i class="face"></i><i class="eye l"><b></b></i><i class="eye r"><b></b></i><i class="beak"></i><i class="wing l"></i><i class="wing r"></i><i class="feet"></i></div>`;
}
function companionAvatarV249258(){return ithakiCompanionV249258()==='sokratakis'?(typeof sokratakiTurtleV249252==='function'?sokratakiTurtleV249252():'🐢'):athinaOwlV249258()}
function companionLineV249258(kind,name){name=(name||'Μέλος').trim()||'Μέλος';const c=ithakiCompanionV249258();if(c==='none')return'';if(kind==='message')return `Ο/Η ${ithakiV249258Esc(name)} σου έστειλε μήνυμα.`;if(kind==='like')return `Ο/Η ${ithakiV249258Esc(name)} έκανε like στη δημοσίευσή σου.`;if(kind==='online')return `Μόλις μπήκε μέσα ο φίλος σου, ο/η ${ithakiV249258Esc(name)}.`;if(kind==='post')return `Ο/Η ${ithakiV249258Esc(name)}, που παρακολουθείς, έκανε νέα δημοσίευση.`;return 'Γεια σου, πώς είσαι σήμερα;'}
function injectAthinaV249258Css(){try{if(document.getElementById('athinaV249258Css'))return;const st=document.createElement('style');st.id='athinaV249258Css';st.textContent=`
.athinaOwlV249258{position:relative;width:86px;height:86px;display:inline-block;filter:drop-shadow(0 14px 20px rgba(0,0,0,.30));--owl:#9b6a39;--owl2:#d7a35f;--gold:#ffd96e;--eye:#102029}
.athinaOwlV249258 .body{position:absolute;left:13px;top:13px;width:60px;height:66px;border-radius:46% 46% 42% 42%;background:radial-gradient(circle at 42% 18%,#fff0c8 0 11%,#dba75e 12% 35%,#8f5e33 36% 100%);box-shadow:inset 0 8px 12px rgba(255,255,255,.18),inset 0 -16px 24px rgba(0,0,0,.22),0 0 0 1px rgba(255,233,158,.30)}
.athinaOwlV249258 .face{position:absolute;left:18px;top:18px;width:50px;height:38px;border-radius:48% 48% 44% 44%;background:radial-gradient(circle at 32% 45%,#fff8db 0 24%,transparent 25%),radial-gradient(circle at 68% 45%,#fff8db 0 24%,transparent 25%),linear-gradient(180deg,#f5dca2,#d4a15b);box-shadow:inset 0 -5px 8px rgba(0,0,0,.12)}
.athinaOwlV249258 .ear{position:absolute;top:9px;width:25px;height:25px;background:#8f5e33;border-radius:8px 80% 8px 80%;z-index:0}.athinaOwlV249258 .ear.l{left:16px;transform:rotate(-24deg)}.athinaOwlV249258 .ear.r{right:16px;transform:scaleX(-1) rotate(-24deg)}
.athinaOwlV249258 .eye{position:absolute;top:30px;width:18px;height:18px;border-radius:50%;background:#fff;border:1px solid rgba(0,0,0,.15);animation:athinaBlinkV249258 5.8s infinite}.athinaOwlV249258 .eye.l{left:24px}.athinaOwlV249258 .eye.r{right:24px}.athinaOwlV249258 .eye b{position:absolute;left:5px;top:5px;width:8px;height:8px;border-radius:50%;background:radial-gradient(circle at 30% 25%,#fff 0 16%,#132027 17% 100%);animation:athinaLookV249258 6.8s ease-in-out infinite}
.athinaOwlV249258 .beak{position:absolute;left:39px;top:48px;width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:8px solid #e99e24;filter:drop-shadow(0 1px 0 rgba(0,0,0,.2))}.athinaOwlV249258 .wing{position:absolute;top:38px;width:20px;height:34px;border-radius:80% 40% 80% 40%;background:linear-gradient(180deg,#b97d42,#6f462c);animation:athinaWingV249258 4.8s ease-in-out infinite}.athinaOwlV249258 .wing.l{left:8px;transform-origin:100% 20%}.athinaOwlV249258 .wing.r{right:8px;transform-origin:0 20%;animation-delay:.4s}.athinaOwlV249258 .feet{position:absolute;left:32px;bottom:5px;width:22px;height:7px;border-radius:999px;background:linear-gradient(90deg,#d99024,#ffc44e,#d99024)}
.athinaOwlV249258:after{content:' ';position:absolute;left:35px;top:56px;width:16px;height:8px;border-bottom:2px solid rgba(42,28,17,.55);border-radius:50%;opacity:.75}.athinaOwlV249258.small{width:48px;height:48px;transform:scale(.62);transform-origin:left top;margin-right:-28px;margin-bottom:-28px}
.athinaCardV249258{border:1px solid rgba(255,217,110,.22);background:linear-gradient(135deg,rgba(255,217,110,.10),rgba(76,198,255,.05));border-radius:18px;padding:12px;display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:center}.athinaBubbleV249258{padding:10px 12px;border-radius:16px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.12);color:#eef7ff}.modeGridV249258,.companionGridV249258{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:9px}.modeCardV249258,.companionCardV249258{border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.06);border-radius:16px;padding:12px;text-align:left;color:#eef7ff}.modeCardV249258.active,.companionCardV249258.active{border-color:rgba(255,217,110,.58);background:rgba(255,217,110,.14);box-shadow:0 0 0 1px rgba(255,217,110,.18)}.modeCardV249258 b,.companionCardV249258 b{display:block;margin-bottom:5px}.modeCardV249258 small,.companionCardV249258 small{display:block;color:rgba(255,255,255,.72);font-size:12px;line-height:1.35}
@keyframes athinaBlinkV249258{0%,92%,100%{transform:scaleY(1)}94%{transform:scaleY(.13)}96%{transform:scaleY(1)}}@keyframes athinaLookV249258{0%,100%{transform:translate(0,0)}30%{transform:translate(2px,-1px)}60%{transform:translate(-2px,1px)}}@keyframes athinaWingV249258{0%,100%{transform:rotate(0deg)}50%{transform:rotate(-5deg)}}
`;document.head.appendChild(st)}catch(e){}}
function renderNotificationModeSettingsV249258(){
  injectAthinaV249258Css();
  const m=ithakiNotifyModeV249258();const c=ithakiCompanionV249258();
  const modes=[['fcm_default','1. FCM προεπιλογή','Κλειστή εφαρμογή με Firebase/FCM, ανοιχτή εφαρμογή με εσωτερικό καμπανάκι. Προτείνεται.'],['background','2. Παρασκήνιο','Για πιο ήπια λειτουργία όταν η εφαρμογή είναι στο παρασκήνιο.'],['open_app','3. Ανοιχτή εφαρμογή','Ειδοποιήσεις μόνο όσο είσαι μέσα στην ΙΘΑΚΗ.'],['stay_awake','4. Δεν κοιμάται','Κρατά ζωντανή σύνδεση. Πιο άμεσο, αλλά μπορεί να τρώει μπαταρία.'],['no_closed','5. Χωρίς ειδοποιήσεις κλειστή συσκευή','Όταν η εφαρμογή είναι κλειστή, δεν εμφανίζει push από FCM.']];
  const modeHtml=modes.map(x=>`<button class="modeCardV249258 ${m===x[0]?'active':''}" onclick="return ITH.setNotificationMode('${x[0]}')"><b>${x[1]}</b><small>${x[2]}</small></button>`).join('');
  const compHtml=`<button class="companionCardV249258 ${c==='athina'?'active':''}" onclick="return setIthakiCompanionV249258('athina')"><b>🦉 Bil</b><small>Σοφή κουκουβάγια. Με μεγάλα μάτια, ελαφριά φτερά και επαγγελματικά λόγια ειδοποιήσεων.</small></button><button class="companionCardV249258 ${c==='sokratakis'?'active':''}" onclick="return setIthakiCompanionV249258('sokratakis')"><b>🐢 Bil</b><small>Μικρή χελωνίτσα συνοδοιπόρος, αργά και καθαρά.</small></button><button class="companionCardV249258 ${c==='none'?'active':''}" onclick="return setIthakiCompanionV249258('none')"><b>Χωρίς συνοδοιπόρο</b><small>Κρατά μόνο το απλό καμπανάκι.</small></button>`;
  const el=document.getElementById('notifySettingsV249258');
  const html=`<div class="card"><b>🔔 Καθαρές επιλογές ειδοποιήσεων</b><div class="date">Διαλέγεις έναν τρόπο, για να μη μπερδεύονται διπλές ειδοποιήσεις/κλήσεις.</div><div class="modeGridV249258" style="margin-top:10px">${modeHtml}</div></div><div class="card"><b>🧭 Συνοδοιπόρος ειδοποιήσεων</b><div class="date">Τοπικό μόνο: χωρίς AI, χωρίς αποστολή στον server, χωρίς αλλαγή βάσης.</div><div class="companionGridV249258" style="margin-top:10px">${compHtml}</div></div><div class="athinaCardV249258">${companionAvatarV249258()}<div class="athinaBubbleV249258"><b>${c==='sokratakis'?'Bil':c==='none'?'ΙΘΑΚΗ':'Bil'}</b><div>${c==='none'?'Οι ειδοποιήσεις θα εμφανίζονται απλά.':'Γεια σου, πώς είσαι σήμερα;'}</div><small>${companionLineV249258('message','Μέλος')}</small></div></div>`;
  if(el)el.innerHTML=html;return html;
}
function legacyOpenNotificationSettingsV249526_2(){const menu=$('memberMenu');if(!menu)return false;injectAthinaV249258Css();menu.classList.add('show','fullAvatarMenuV249231');menu.innerHTML=`<div class="v249238NotifyPanel"><div class="row"><button class="icon" onclick="ITH.notifyCenter()">‹</button><b>⚙️ Ρυθμίσεις ειδοποιήσεων</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div id="notifySettingsV249258"></div></div>`;renderNotificationModeSettingsV249258();return false}
function openPushPanel(){return openNotificationSettingsV249238()}
function ensureAthinaCompanionV249258(){injectAthinaV249258Css();try{const old=document.getElementById('athinaFabV249258');if(old)old.remove();if(ithakiCompanionV249258()!=='athina')return;const b=document.createElement('button');b.id='athinaFabV249258';b.type='button';b.title='Bil - συνοδοιπόρος ειδοποιήσεων';b.style.cssText='position:fixed;right:18px;bottom:94px;z-index:9997;width:58px;height:58px;border-radius:22px;border:1px solid rgba(255,217,110,.35);background:linear-gradient(145deg,rgba(22,40,55,.96),rgba(8,15,24,.98));box-shadow:0 18px 42px rgba(0,0,0,.42);display:grid;place-items:center;padding:4px';b.innerHTML=athinaOwlV249258('small');b.onclick=()=>openNotificationSettingsV249238();document.body.appendChild(b)}catch(e){}}
function companionNoticeWelcomeV249258(){const c=ithakiCompanionV249258();if(c==='none')return'';return `<div class="athinaCardV249258">${companionAvatarV249258()}<div class="athinaBubbleV249258"><b>${c==='sokratakis'?'Bil':'Bil'}</b><div>Γεια σου, πώς είσαι σήμερα;</div><small>Θα σου δείχνω καθαρά μήνυμα, like, είσοδο φίλου και δημοσίευση χωρίς AI και χωρίς server.</small></div></div>`}
// Wrap existing notification center to add Athina/Sokratakis welcome and settings without changing data loading.
try{var notifyCenterV249257Base=notifyCenter;notifyCenter=function(){return notifyCenterV249257Base.apply(this,arguments)}}catch(e){}
try{window.setIthakiCompanionV249258=setIthakiCompanionV249258;window.renderNotificationModeSettingsV249258=renderNotificationModeSettingsV249258;window.ensureAthinaCompanionV249258=ensureAthinaCompanionV249258;if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',()=>setTimeout(ensureAthinaCompanionV249258,900));else setTimeout(ensureAthinaCompanionV249258,900);void 0}catch(e){}


async function boot(){window.ITH={callBackArrowV249531,sokratakiOpenV249252,sokratakiCloseV249252,ensureSocratakiV249252,v249251OpenLaunchFromUrl,v249251OpenCallFromUrl,v249251NotifyNativeCallControl,enableVideoSoundV249220,checkProfileNameLiveV249246,applyProfileNameSuggestionV249246,refreshFriendsForMessagesV249246,v249247OpenPostFromNotice,v249247MarkServerNoticeRead,v249247OpenDmFromNotice,v249247RefreshServerNotifications,requestWebNotificationPermissionV249220,testLocalNotificationV249220,openPushStatusV249220,handleTypingInput,pollTypingState,markActiveChannelRead,loadReadState,sendTypingNow,sendCallTimeline,callEventHtml,syncProfileNow,toggleHomeProtection,toggleProfilePanel,toggleStayConnected,notificationMode,setNotificationMode,unlockProfileNameChange,openMemberPostPicker,messageMediaHtml,registerMessageMediaShareV249464,openMessageMediaShareV249464,sendMessageMediaToFriendV249464,shareMessageMediaExternalV249464,openActualMediaFile,downloadMediaFile,shareMediaFile,page,showFeedOnly,startupAndroidWarmup,notifyAppEvent,playAppAlert,openScreenThemePanel,setScreenTheme,applyScreenTheme,startVoiceCall,startVideoCall,answerIncomingCall,endActiveCall,toggleCallMic,toggleCallCamera,switchCallCamera,toggleCallSpeaker,openMessageCamera,captureMedia,startAudioRecording,stopAudioRecording,cancelAudioRecording,openSpaceMedia,hideFeedPanel,serverFiveMinuteTest,setUiLang,renderTopLang,checkServerTools,openLocalConnection,setLocalMode,useCurrentLocal,saveLocalIpAndConnect,clearLocalConnection,connectToLocalBase,setDoveIsolated,closeDovePanel,openServerDataPanel,openSavedPostsPanel,openMemberMediaCenter,removeSavedPost,clearSavedPosts,deleteAccountData,openPermissionsPanel,acceptProfilePermissions,openLegalPolicy,acceptLegalPolicy,setPermissionPref,setMeshMode,setMeshConsent,meshAnnounce,meshRadar,meshSendTest,meshInbox,meshRequestPermissions,meshOpenHotspot,meshOpenWifi,phoneNodeStart,phoneNodeScan,phoneNodeSend,phoneNodeInbox,chooseFile,openPreviewStudio,studioPickExtra,studioSetPreset,applyPreviewStudio,closePreview,sendPreview,sendTextPost,loadFeed,openFeedSearchV249232,applyFeedSearchV249232,setFreeFeedV249232,filterFeedCardsV249189,renderPost,actionButtons,setupFeedCycleV249217,v249225SetDmFilter,loadSocialFriendsV249225,translateText,translateBlock,translateControls,fallbackTranslate,detectLangSmart,setUiLang,toggleAutoTranslate,setTargetLang,like,comments,savePost,sharePost,deletePost,member:showMemberMenu,closeMember:closeMemberMenu,refreshProcessingMedia,memberPosts,startDM,loadPeople,clearChat,memberActive:()=>{if(state.activePeer)showMemberMenu(state.activePeer)},openDMWith:startDM,sendDMText,deleteMsg,replyMsg,clearReply,renderSpaces,loadRooms,openSpace,createRoomUI,sendSpaceText,openPoll,applyPollPreset,setQuestionPoll,setYesNoPoll,addPollOption,createPollFromCard,setPollVoteMode,votePoll,voteCardChoice,renderPollCard,mediaHtml,openMediaViewer,closeMediaViewer,renderOfficeCard,activateFeedVideos,stopAllMedia,maskBadWords,openPostCommentsPanel,loadPanelComments,setCommentReply,clearCommentReply,sendPanelComment,checkConnections,switchToNormalConnection,setDoveStatus,connectionLabel,ensureWs,wsSubscribe,wsPing,openE2EPanel,saveE2EKey,clearE2EKey,setE2EKey,e2eEncryptText,e2eDecryptText,registerPushToken,openPushPanel,initPushHooks,openInlineComments,quickComment,replyComment,sendComment,inviteContact,acceptContact,rejectContact,notifyCenter,openNotificationSettingsV249238,saveNotificationSettingsV249238,refreshNotificationBadgeV249238,openNoticeMessageV249243:v249243NoticeOpenMessage,ensureNotificationFabV249238,respondFriendProposalV249233,openCleanMembersPanelV249233,showDMFriendListV249235,showDMChatScreenV249235,renderPeopleV249235:renderPeople,v249231PersonById,injectV249233CleanCss,markNoticesRead,markPeerRead,showQR,shareQRSite,openMemberFeed,closeMemberFeedV249494,openIthakiPostsPreview,openIthakiFeed,spaceTab,renderSpaceSamples,prefillSpace,createSpaceCard,createRoomUIFromCard,inviteToSpace,showSpaceCode,openSpaceAdmin,openAdminAccess,adminMessageMember,adminMessageSpace,adminBlockMember,adminUnblockMember,openHostContact,sendHostMessage,openPostLikers,openPostLikersFriendOnly,openReactionMemberFriendOnly,sendFriendProposal,respondFriendProposalV249223,toggleFollowMember,openSocialList,unlockCallAudioV249223,openCallDiagnosticsV249223,unlockCallAudioV249230,openCallDiagnosticsV249230,v249231AvatarAction,injectV249231AvatarDmNotifyCss,openLinkedPostFromUrlV249223,openCommunicationContactsV249230,chooseCommunicationContactV249230,renderProfile,toggleGear,avatarPick,showAnimals,setAnimal,saveProfile,backup,restore,follow,block,unblock,report,share};renderTopLang();injectV249223ProSocialCss();injectV249224ThumbLikesCardsCss();injectV249230ContactFirstCss();injectV249230CallAudioCss();injectV249208ProfessionalCss();injectV249213CardsPollCss();injectV249233CleanCss();injectV249246ProfileFriendsCss();applyScreenTheme();renderNav();enableButtonFeedback();bindPlus();loadPeopleLocal();renderHome();renderCreate();renderProfile();applyUiLanguagePatch();startUiLanguageObserver();startupAndroidWarmup();try{document.documentElement.setAttribute('data-native-permission-boot','V249466-user-action-only')}catch{};setIthakiVideoSoundUnlocked(ithakiVideoSoundUnlocked());await checkConnections();startConnectionPulse();await serverFiveMinuteTest();await loadConfig();ensureWs();initPushHooks();setTimeout(startupAndroidWarmup,1600);await heartbeat();await loadPeople();if(state.page==='feed')await loadFeed();setTimeout(()=>{openLinkedPostFromUrlV249223();v249251OpenLaunchFromUrl();},900);checkIncomingCalls();setInterval(checkIncomingCalls,4000);setInterval(heartbeat,25000);setInterval(serverFiveMinuteTest,300000);setInterval(loadPeople,60000);setInterval(()=>{try{if(state.page==='feed'&&window.__ITHAKI_MEMBER_FEED_MODE_V249483__!==true&&window.__ITHAKI_MEMBER_FEED_MODE_V249481__!==true)loadFeed()}catch(e){}},45000);setInterval(wsPing,15000);setInterval(pollTypingState,2500);setInterval(()=>{if(state.page==='dm'&&state.activeChannel){markActiveChannelRead();loadReadState(state.activeChannel)}},7000);setInterval(()=>{if(selectedScreenTheme()==='auto')applyScreenTheme('auto')},300000);setInterval(()=>{if(!state.wsReady&&state.page==='dm'&&state.activeChannel)loadMessages(false);if(!state.wsReady&&state.page==='spaces'&&state.currentSpaceChannel)loadSpaceMessages()},15000);try{window.__ITHAKI_V249238_BOOT_OK__={version:'V249290-emergency-neighborhood-media',ws_started:true,call_polling:true,heartbeat:true,at:Date.now()}}catch{}}

/* V249262 - complete innovation/privacy/trust/onboarding package.
   Built on V249260 call-clean + V249261 companion/feed fixes, inserted inside the app closure. */
function injectV249262InnovationCss(){
  try{
    if(document.getElementById('ithV249262InnovationCss'))return;
    const st=document.createElement('style');
    st.id='ithV249262InnovationCss';
    st.textContent=`
      .ithInnovationHeroV249262{position:relative;overflow:hidden;border:1px solid rgba(255,217,110,.30)!important;background:radial-gradient(circle at 15% 0%,rgba(255,217,110,.22),transparent 32%),radial-gradient(circle at 90% 12%,rgba(85,215,255,.16),transparent 30%),linear-gradient(145deg,rgba(8,24,39,.96),rgba(5,14,24,.98))!important;box-shadow:0 18px 52px rgba(0,0,0,.34)!important}
      .ithInnovationHeroV249262:before{content:'';position:absolute;inset:-40% -20% auto auto;width:220px;height:220px;border-radius:50%;background:rgba(255,217,110,.08);filter:blur(20px)}
      .ithInnovationTopV249262{display:grid;grid-template-columns:auto 1fr;gap:14px;align-items:center;position:relative;z-index:1}
      .ithInnovationSealV249262{width:62px;height:62px;border-radius:22px;display:grid;place-items:center;background:linear-gradient(145deg,rgba(255,217,110,.23),rgba(76,198,255,.10));border:1px solid rgba(255,217,110,.38);box-shadow:inset 0 1px 0 rgba(255,255,255,.16);font-size:30px}
      .ithInnovationTitleV249262{margin:0;color:#ffe39b;font-size:clamp(19px,4.6vw,30px);line-height:1.05;font-weight:1000}
      .ithInnovationSubV249262{margin:6px 0 0;color:rgba(239,248,255,.82);font-size:clamp(13px,3.4vw,16px);line-height:1.35}
      .ithFeatureGridV249262{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px;margin-top:13px}
      .ithFeatureChipV249262{border-radius:16px;padding:10px 8px;background:rgba(255,255,255,.075);border:1px solid rgba(255,255,255,.12);text-align:center;color:#fff;min-height:74px;display:flex;flex-direction:column;justify-content:center;gap:5px}
      .ithFeatureChipV249262 b{font-size:12px;line-height:1.15;color:#fff}
      .ithFeatureChipV249262 span{font-size:22px}
      .ithInnovationActionsV249262{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}
      .ithInnovationActionsV249262 button,.trustBtnV249262{border:1px solid rgba(255,217,110,.28);background:linear-gradient(135deg,rgba(255,217,110,.16),rgba(76,198,255,.08));color:#fff;border-radius:999px;padding:10px 12px;font-weight:1000}
      .whyPanelV249262{height:min(90dvh,820px);max-height:90dvh;overflow:auto;padding:0!important;border-radius:24px!important;background:linear-gradient(165deg,rgba(3,12,23,.98),rgba(17,22,32,.98))!important;border:1px solid rgba(255,217,110,.28)!important}
      .whyTopV249262{position:sticky;top:0;z-index:3;display:flex;align-items:center;gap:10px;padding:12px;background:rgba(3,12,23,.92);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}
      .whyTopV249262 b{color:#ffe39b;font-size:18px}.whyBodyV249262{padding:12px;display:grid;gap:12px}
      .whyCardsV249262{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px}
      .whyCardV249262{border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.065);border-radius:20px;padding:12px;min-height:120px}
      .whyCardV249262 h3{margin:0 0 7px;color:#ffe39b;font-size:16px}.whyCardV249262 p{margin:0;color:rgba(239,248,255,.80);line-height:1.38;font-size:13px}
      .compareV249262{display:grid;grid-template-columns:1fr 1fr;gap:10px}.compareBoxV249262{border-radius:20px;padding:12px;border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.06)}.compareBoxV249262.ok{border-color:rgba(54,240,160,.34);background:rgba(54,240,160,.08)}.compareBoxV249262 h3{margin:0 0 8px;color:#fff}.compareBoxV249262 li{margin:7px 0;color:rgba(239,248,255,.82);font-size:13px;line-height:1.35}
      .privacyScoreV249262{border:1px solid rgba(54,240,160,.34)!important;background:radial-gradient(circle at 10% 0%,rgba(54,240,160,.18),transparent 30%),linear-gradient(145deg,rgba(5,31,29,.96),rgba(4,16,25,.98))!important}.privacyMeterV249262{height:13px;border-radius:999px;background:rgba(255,255,255,.12);overflow:hidden;margin:10px 0}.privacyMeterV249262 i{display:block;height:100%;width:96%;border-radius:999px;background:linear-gradient(90deg,#36f0a0,#ffd96e)}
      .privacyRowsV249262{display:grid;gap:8px}.privacyRowsV249262 div{display:grid;grid-template-columns:auto 1fr auto;gap:8px;align-items:center;padding:9px 10px;border-radius:14px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.10);color:#fff}.privacyRowsV249262 small{color:rgba(239,248,255,.68)}
      .trustBadgeV249262{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:6px 9px;border:1px solid rgba(255,217,110,.28);background:rgba(255,217,110,.10);color:#ffe39b;font-weight:1000;font-size:12px}
      .onboardStepV249262{display:grid;grid-template-columns:auto 1fr;gap:13px;align-items:center;border-radius:22px;padding:13px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10)}
      .onboardStepV249262 h3{margin:0 0 5px;color:#ffe39b}.onboardStepV249262 p{margin:0;color:rgba(239,248,255,.82);line-height:1.4}.onboardDotsV249262{display:flex;gap:5px;justify-content:center}.onboardDotsV249262 i{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.24)}.onboardDotsV249262 i.on{background:#ffd96e}
      #athinaFabV249258{position:fixed!important;left:14px!important;right:auto!important;bottom:86px!important;z-index:9998!important;width:62px!important;height:62px!important;border-radius:22px!important;border:1px solid rgba(255,217,110,.45)!important;background:linear-gradient(145deg,rgba(22,40,55,.97),rgba(8,15,24,.99))!important;box-shadow:0 18px 42px rgba(0,0,0,.42)!important;display:grid!important;place-items:center!important;padding:4px!important}
      #socratakiFabV249252,#socratakiPanelV249252{display:none!important;visibility:hidden!important;pointer-events:none!important}
      @media(max-width:760px){.ithFeatureGridV249262{grid-template-columns:repeat(2,minmax(0,1fr))}.compareV249262{grid-template-columns:1fr}.ithInnovationActionsV249262 button{flex:1;min-width:145px}#athinaFabV249258{left:10px!important;bottom:78px!important;width:58px!important;height:58px!important}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function v249262MascotHtml(cls=''){
  try{
    const c=ithakiCompanionV249258?ithakiCompanionV249258():'athina';
    if(c==='sokratakis' && typeof sokratakiTurtleV249252==='function')return sokratakiTurtleV249252(cls);
    if(typeof athinaOwlV249258==='function')return athinaOwlV249258(cls);
  }catch(e){}
  return '<div style="font-size:38px">🦉</div>';
}
function homeProtectionPanel(){
  injectV249262InnovationCss();
  const open=localStorage.getItem('ith_home_protection_open_v249166')==='1';
  return `<section class="card homeProPanel homeProtectionPro bottomProtection ithInnovationHeroV249262 ${open?'open':'closed'}">
    <div class="ithInnovationTopV249262">
      <div class="ithInnovationSealV249262">🛡️</div>
      <div>
        <h2 class="ithInnovationTitleV249262">Γιατί OK ITHAKI</h2>
        <p class="ithInnovationSubV249262">Ανώνυμη, ανθρώπινη επικοινωνία με καθαρή προστασία, offline μετάφραση, προαιρετικές ειδοποιήσεις και τοπικό συνοδοιπόρο.</p>
      </div>
    </div>
    <div class="ithFeatureGridV249262">
      <div class="ithFeatureChipV249262"><span>🕶️</span><b>Ανωνυμία χωρίς τηλέφωνο/email</b></div>
      <div class="ithFeatureChipV249262"><span>🔐</span><b>Κρυπτογραφημένη συνομιλία</b></div>
      <div class="ithFeatureChipV249262"><span>🌐</span><b>Offline μετάφραση EL↔EN</b></div>
      <div class="ithFeatureChipV249262"><span>🔔</span><b>Προαιρετικό FCM</b></div>
      <div class="ithFeatureChipV249262"><span>🦉</span><b>Bil / Bil τοπικά</b></div>
    </div>
    <div class="ithInnovationActionsV249262">
      <button onclick="openWhyIthakiV249262()">✨ Γιατί OK ITHAKI</button>
      <button onclick="openPrivacyScoreV249262()">🟢 Privacy score</button>
      <button onclick="openTrustModeV249262()">🤝 Trust mode</button>
      <button onclick="openOnboardingV249262(0)">🧭 Οδηγός 1ης χρήσης</button>
      <button class="homeProtectionToggle" onclick="ITH.toggleHomeProtection()" type="button">${open?'▲ Λιγότερα':'▼ Περισσότερα'}</button>
    </div>
    <div class="protectList" style="display:${open?'grid':'none'}">
      <div>Η ΙΘΑΚΗ δείχνει καθαρά τι προστατεύεται: συνομιλία, μετάφραση, ειδοποιήσεις και τοπική λειτουργία.</div>
      <div>Καμία μετάφραση δεν χρειάζεται να φεύγει από τη συσκευή όταν λειτουργεί το offline EL↔EN.</div>
      <div>Οι ειδοποιήσεις FCM είναι επιλογή, όχι υποχρέωση. Ο χρήστης βλέπει τι ενεργοποιεί.</div>
      <div>Ο συνοδοιπόρος ειδοποιήσεων λειτουργεί τοπικά: χωρίς AI, χωρίς server, χωρίς βάση.</div>
      <div>Το ανώνυμο τοπικό δίκτυο έκτακτης ανάγκης προβάλλεται ως καινοτομία της ΙΘΑΚΗΣ για δύσκολες στιγμές.</div>
    </div>
  </section>`;
}
function openWhyIthakiV249262(){
  injectV249262InnovationCss();
  const menu=$('memberMenu'); if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="whyPanelV249262">
    <div class="whyTopV249262"><button class="icon" onclick="ITH.closeMember()">‹</button><b>✨ Γιατί OK ITHAKI</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div>
    <div class="whyBodyV249262">
      <div class="onboardStepV249262">${v249262MascotHtml('small')}<div><h3>Η καινοτομία γίνεται ορατή</h3><p>Η ΙΘΑΚΗ δεν κρύβει την προστασία σε μικρά γράμματα. Τη δείχνει στον χρήστη μέσα στο UI, καθαρά και ανθρώπινα.</p></div></div>
      <div class="whyCardsV249262">
        <div class="whyCardV249262"><h3>🕶️ Ανωνυμία</h3><p>Χρήση με ψευδώνυμο, χωρίς υποχρεωτικό τηλέφωνο ή email για την πρώτη επαφή.</p></div>
        <div class="whyCardV249262"><h3>🔐 Encryption</h3><p>Η συνομιλία παρουσιάζεται ως προστατευμένος χώρος με καθαρή ένδειξη εμπιστοσύνης.</p></div>
        <div class="whyCardV249262"><h3>🌐 Offline μετάφραση</h3><p>Ελληνικά ↔ Αγγλικά χωρίς να χρειάζεται κάθε κείμενο να φύγει από τη συσκευή.</p></div>
        <div class="whyCardV249262"><h3>🔔 Προαιρετικό FCM</h3><p>Οι ειδοποιήσεις είναι επιλογή του χρήστη και δεν μπερδεύονται με κλήσεις ή μηνύματα.</p></div>
        <div class="whyCardV249262"><h3>🦉 Mascot τοπικά</h3><p>Bil ή Bil λειτουργούν σαν όμορφος βοηθός ειδοποιήσεων: χωρίς AI, χωρίς server, χωρίς βάση.</p></div>
      </div>
      <div class="compareV249262">
        <div class="compareBoxV249262"><h3>Συνηθισμένες εφαρμογές</h3><ul><li>Ο χρήστης συχνά δεν βλέπει με μία ματιά τι μένει στη συσκευή.</li><li>Η προστασία εξηγείται σε ρυθμίσεις ή σε μεγάλα κείμενα.</li><li>Οι ειδοποιήσεις και τα δεδομένα φαίνονται τεχνικά και μπερδεμένα.</li></ul></div>
        <div class="compareBoxV249262 ok"><h3>OK ITHAKI</h3><ul><li>Δείχνει ρητά: ανώνυμο, encrypted, offline μετάφραση, προαιρετικό FCM, τοπικός συνοδοιπόρος.</li><li>Ο χρήστης βλέπει privacy score ανά επαφή ή δωμάτιο.</li><li>Η εμπιστοσύνη γίνεται εικόνα, όχι απλό marketing.</li></ul></div>
      </div>
      <div class="whyCardsV249262">
        <button class="trustBtnV249262" onclick="openPrivacyScoreV249262()">Άνοιγμα privacy score</button>
        <button class="trustBtnV249262" onclick="openOnboardingV249262(0)">Ξεκίνα onboarding</button>
      </div>
    </div>
  </div>`;
  return false;
}
function v249262ContextId(peerId){
  try{return String(peerId||state.activePeer||state.currentSpace||state.currentSpaceChannel||state.room||state.device||'ithaki').trim()||'ithaki'}catch{return 'ithaki'}
}
function v249262ContextName(id){
  try{const p=typeof v249231PersonById==='function'?v249231PersonById(id):null;return (p&&(p.nickname||p.name))||state.activePeerName||state.currentSpaceName||'τρέχουσα επαφή / δωμάτιο'}catch{return 'τρέχουσα επαφή / δωμάτιο'}
}
function trustKeyV249262(id){return 'ith_trust_verified_v249262_'+v249262ContextId(id)}
function trustVerifiedV249262(id){try{return localStorage.getItem(trustKeyV249262(id))==='1'}catch{return false}}
function setTrustModeV249262(id,val){
  id=v249262ContextId(id);
  try{localStorage.setItem(trustKeyV249262(id),val?'1':'0')}catch{}
  openTrustModeV249262(id);
  return false;
}
function openPrivacyScoreV249262(peerId){
  injectV249262InnovationCss();
  const id=v249262ContextId(peerId), name=v249262ContextName(id), ok=trustVerifiedV249262(id);
  const menu=$('memberMenu'); if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="whyPanelV249262 privacyScoreV249262">
    <div class="whyTopV249262"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🟢 Privacy score</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div>
    <div class="whyBodyV249262">
      <div class="onboardStepV249262">${v249262MascotHtml('small')}<div><h3>${esc(name)}</h3><p>Η ΙΘΑΚΗ κάνει την προστασία ορατή με καθαρή βαθμολογία για την επαφή ή το δωμάτιο.</p></div></div>
      <div class="card privacyScoreV249262"><b>Privacy score: 96 / 100</b><div class="privacyMeterV249262"><i></i></div><div class="date">Υψηλή προστασία, με πλήρη εμπιστοσύνη όταν επαληθεύσεις την επαφή.</div></div>
      <div class="privacyRowsV249262">
        <div><span>🔐</span><b>Η συνομιλία είναι κρυπτογραφημένη</b><small>ενεργό</small></div>
        <div><span>🌐</span><b>Η μετάφραση δεν φεύγει από τη συσκευή</b><small>offline EL↔EN</small></div>
        <div><span>🚫</span><b>Καμία διαφήμιση μέσα στην ΙΘΑΚΗ</b><small>καθαρό UI</small></div>
        <div><span>🔔</span><b>FCM ειδοποιήσεις μόνο αν το επιλέξεις</b><small>προαιρετικό</small></div>
        <div><span>${ok?'✅':'⚠️'}</span><b>Trust mode επαφής</b><small>${ok?'επαληθευμένη':'θέλει επαλήθευση'}</small></div>
      </div>
      <button class="trustBtnV249262" onclick="openTrustModeV249262('${escJs(id)}')">🤝 Άνοιγμα trust mode</button>
    </div>
  </div>`;
  return false;
}
function openTrustModeV249262(peerId){
  injectV249262InnovationCss();
  const id=v249262ContextId(peerId), name=v249262ContextName(id), ok=trustVerifiedV249262(id);
  const menu=$('memberMenu'); if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="whyPanelV249262">
    <div class="whyTopV249262"><button class="icon" onclick="openPrivacyScoreV249262('${escJs(id)}')">‹</button><b>🤝 Λειτουργία εμπιστοσύνης</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div>
    <div class="whyBodyV249262">
      <div class="onboardStepV249262">${v249262MascotHtml('small')}<div><h3>${esc(name)}</h3><p>${ok?'Η επαφή έχει σημειωθεί ως επαληθευμένη στη συσκευή σου.':'Η Bil/ο Bil σου θυμίζει να επαληθεύσεις ότι μιλάς με το σωστό άτομο.'}</p></div></div>
      <div class="card"><span class="trustBadgeV249262">${ok?'✅ Επαληθευμένη επαφή':'⚠️ Δεν έχει επαληθευτεί ακόμη'}</span><p style="margin:10px 0 0;color:rgba(239,248,255,.80)">Απλό και φιλικό σαν safety number: όταν επιβεβαιώσεις από κοντά ή από άλλο κανάλι ότι είναι το σωστό άτομο, το σημειώνεις εδώ. Η ένδειξη μένει τοπικά στη συσκευή.</p></div>
      <div class="row" style="gap:8px;flex-wrap:wrap"><button class="trustBtnV249262" onclick="setTrustModeV249262('${escJs(id)}',true)">✅ Το επαλήθευσα</button><button class="trustBtnV249262" onclick="setTrustModeV249262('${escJs(id)}',false)">↺ Ακύρωση επαλήθευσης</button><button class="trustBtnV249262" onclick="openPrivacyScoreV249262('${escJs(id)}')">🟢 Privacy score</button></div>
    </div>
  </div>`;
  return false;
}
function openOnboardingV249262(step=0){
  injectV249262InnovationCss();
  const slides=[
    ['Καλωσόρισμα','Γεια σου, πώς είσαι σήμερα; Εδώ μιλάς ανθρώπινα, με σεβασμό και καθαρή προστασία.'],
    ['Ανωνυμία','Μπορείς να ξεκινήσεις χωρίς να δίνεις υποχρεωτικά τηλέφωνο ή email. Η ταυτότητα μένει πιο ήσυχη.'],
    ['Μετάφραση offline','Η μετάφραση Ελληνικά ↔ Αγγλικά μπορεί να γίνεται στη συσκευή, χωρίς να φεύγει κάθε κείμενο έξω.'],
    ['Privacy score','Σε κάθε επαφή ή δωμάτιο βλέπεις απλά τι προστατεύεται: encryption, offline μετάφραση, διαφημίσεις, FCM.'],
    ['Trust mode','Επαληθεύεις την επαφή με απλό τρόπο και η ΙΘΑΚΗ σου το δείχνει καθαρά.']
  ];
  step=Math.max(0,Math.min(slides.length-1,+step||0));
  const [title,body]=slides[step];
  const dots=slides.map((_,i)=>`<i class="${i===step?'on':''}"></i>`).join('');
  const prev=step>0?`<button class="trustBtnV249262" onclick="openOnboardingV249262(${step-1})">‹ Πίσω</button>`:'';
  const next=step<slides.length-1?`<button class="trustBtnV249262" onclick="openOnboardingV249262(${step+1})">Επόμενο ›</button>`:`<button class="trustBtnV249262" onclick="try{localStorage.setItem('ith_onboarding_seen_v249262','1')}catch{};ITH.closeMember();toast('Η ΙΘΑΚΗ είναι έτοιμη.')">✓ Έτοιμο</button>`;
  const menu=$('memberMenu'); if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="whyPanelV249262">
    <div class="whyTopV249262"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🧭 Οδηγός OK ITHAKI</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div>
    <div class="whyBodyV249262">
      <div class="onboardStepV249262">${v249262MascotHtml('small')}<div><h3>${esc(title)}</h3><p>${esc(body)}</p></div></div>
      <div class="onboardDotsV249262">${dots}</div>
      <div class="row" style="gap:8px;justify-content:center;flex-wrap:wrap">${prev}${next}<button class="trustBtnV249262" onclick="openWhyIthakiV249262()">✨ Γιατί ΙΘΑΚΗ</button></div>
    </div>
  </div>`;
  return false;
}

/* Correct V249261 companion/feed behavior inside the closure. */
function injectAthinaV249258Css(){
  try{
    if(document.getElementById('athinaV249258Css'))document.getElementById('athinaV249258Css').remove();
    if(document.getElementById('athinaV249262Css'))return;
    const st=document.createElement('style');st.id='athinaV249262Css';st.textContent=`
      .athinaOwlV249258{position:relative;width:106px;height:106px;display:inline-block;filter:drop-shadow(0 16px 26px rgba(0,0,0,.34))}
      .athinaOwlV249258 .body{position:absolute;left:18px;top:18px;width:70px;height:76px;border-radius:48% 48% 44% 44%;background:radial-gradient(circle at 44% 20%,#fff6e3 0 11%,#ecc18b 12% 29%,#c18246 30% 56%,#86552f 57% 100%);box-shadow:inset 0 8px 12px rgba(255,255,255,.22),inset 0 -18px 24px rgba(0,0,0,.22),0 0 0 1px rgba(255,233,158,.30)}
      .athinaOwlV249258 .neck{position:absolute;left:43px;top:28px;width:20px;height:22px;border-radius:999px;background:linear-gradient(180deg,#f2d7a8,#c08a51);transform-origin:50% 100%;animation:athinaNeckV249262 6.4s ease-in-out infinite}.athinaOwlV249258 .face{position:absolute;left:24px;top:24px;width:58px;height:46px;border-radius:48% 48% 44% 44%;background:radial-gradient(circle at 32% 46%,#fffdf6 0 24%,transparent 25%),radial-gradient(circle at 68% 46%,#fffdf6 0 24%,transparent 25%),linear-gradient(180deg,#f9e9c7,#d5a264);box-shadow:inset 0 -6px 9px rgba(0,0,0,.12)}
      .athinaOwlV249258 .ear{position:absolute;top:12px;width:28px;height:28px;background:linear-gradient(180deg,#9a683a,#70472a);border-radius:10px 80% 12px 80%;z-index:0}.athinaOwlV249258 .ear.l{left:20px;transform:rotate(-25deg)}.athinaOwlV249258 .ear.r{right:20px;transform:scaleX(-1) rotate(-25deg)}
      .athinaOwlV249258 .eye{position:absolute;top:38px;width:22px;height:22px;border-radius:50%;background:#fff;border:1px solid rgba(0,0,0,.14);box-shadow:inset 0 -2px 4px rgba(0,0,0,.08);animation:athinaBlinkV249262 5.8s infinite}.athinaOwlV249258 .eye.l{left:30px}.athinaOwlV249258 .eye.r{right:30px}.athinaOwlV249258 .eye b{position:absolute;left:6px;top:6px;width:10px;height:10px;border-radius:50%;background:radial-gradient(circle at 35% 25%,#fff 0 16%,#16262f 17% 100%);animation:athinaLookV249262 6.2s ease-in-out infinite}
      .athinaOwlV249258 .beak{position:absolute;left:47px;top:58px;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:10px solid #eba232;filter:drop-shadow(0 1px 0 rgba(0,0,0,.2))}.athinaOwlV249258 .mouth{position:absolute;left:44px;top:66px;width:18px;height:8px;border-bottom:2px solid rgba(51,32,20,.55);border-radius:0 0 18px 18px;opacity:.9}
      .athinaOwlV249258 .wing{position:absolute;top:44px;width:22px;height:38px;border-radius:80% 40% 80% 40%;background:linear-gradient(180deg,#bd8043,#6d462b);box-shadow:inset 0 4px 6px rgba(255,255,255,.10);animation:athinaWingV249262 4.6s ease-in-out infinite}.athinaOwlV249258 .wing.l{left:12px;transform-origin:100% 20%}.athinaOwlV249258 .wing.r{right:12px;transform-origin:0 20%;animation-delay:.35s}.athinaOwlV249258 .feet{position:absolute;left:39px;bottom:8px;width:28px;height:8px;border-radius:999px;background:linear-gradient(90deg,#d99024,#ffc44e,#d99024)}
      .athinaOwlV249258.small{width:56px;height:56px;transform:scale(.72);transform-origin:left top;margin-right:-25px;margin-bottom:-25px}
      .sokraMiniV249252 .head:after,.sokraTurtleBigV249252 .head:after{content:'';position:absolute;left:50%;bottom:4px;transform:translateX(-50%);width:12px;height:5px;border-bottom:2px solid rgba(20,38,28,.76);border-radius:0 0 99px 99px}.sokraMiniV249252 .eye.l{left:4px!important}.sokraMiniV249252 .eye.r{right:4px!important}.sokraTurtleBigV249252 .eye.l{left:8px!important}.sokraTurtleBigV249252 .eye.r{right:8px!important}.sokraMiniV249252,.sokraTurtleBigV249252{transform:scale(1.06);transform-origin:center center}
      #feedPage .feedGoldCardActions,#feedPage .post.pollPost .pollPostActions{display:none!important}#feedPage .feedGoldPollCard .feedGoldCardInner,#feedPage .feedGoldWisdomCard .feedGoldCardInner{padding-right:16px!important}#feedPage .feedGoldPollChoice{border:1px solid rgba(255,217,110,.24)!important;background:linear-gradient(135deg,rgba(255,217,110,.12),rgba(76,198,255,.05))!important;color:#fff!important}#feedPage .feedGoldQuote{color:#ffe39b!important}#feedPage .feedSearchGlassV249189 .feedDiscoverBtnV249232,#feedPage .feedSearchGlassV249189 .feedOutdoorBtn{color:#fff!important;text-shadow:0 1px 2px rgba(0,0,0,.35)!important}
      @keyframes athinaBlinkV249262{0%,92%,100%{transform:scaleY(1)}94%{transform:scaleY(.11)}96%{transform:scaleY(1)}}@keyframes athinaLookV249262{0%,100%{transform:translate(0,0)}24%{transform:translate(2px,-1px)}52%{transform:translate(-2px,1px)}74%{transform:translate(1px,0)}}@keyframes athinaWingV249262{0%,100%{transform:rotate(0deg)}50%{transform:rotate(-6deg)}}@keyframes athinaNeckV249262{0%,100%{transform:translateY(0) rotate(0deg)}30%{transform:translateY(-1px) rotate(-4deg)}64%{transform:translateY(1px) rotate(4deg)}}
    `;document.head.appendChild(st);
  }catch(e){}
}
function athinaOwlV249258(cls=''){
  return `<div class="athinaOwlV249258 ${cls}"><i class="ear l"></i><i class="ear r"></i><i class="body"></i><i class="neck"></i><i class="face"></i><i class="eye l"><b></b></i><i class="eye r"><b></b></i><i class="beak"></i><i class="mouth"></i><i class="wing l"></i><i class="wing r"></i><i class="feet"></i></div>`;
}
function companionNameV249258(c){return c==='sokratakis'?'Bil':c==='none'?'Χωρίς συνοδοιπόρο':'Bil'}
function companionAvatarV249258(){return ithakiCompanionV249258()==='sokratakis'?(typeof sokratakiTurtleV249252==='function'?sokratakiTurtleV249252('small'):'🐢'):athinaOwlV249258('small')}
function companionLineV249258(kind,name){name=(name||'Μέλος').trim()||'Μέλος';const c=ithakiCompanionV249258();if(c==='none')return'';if(kind==='message')return `${name} σου έστειλε μήνυμα.`;if(kind==='like')return `${name} έκανε like στη δημοσίευσή σου.`;if(kind==='online')return `Μόλις μπήκε ο φίλος σου, ${name}.`;if(kind==='post')return `${name}, που παρακολουθείς, έκανε νέα δημοσίευση.`;return 'Γεια σου, πώς είσαι σήμερα;'}
function renderNotificationModeSettingsV249258(){
  injectAthinaV249258Css();injectV249262InnovationCss();
  const m=ithakiNotifyModeV249258();const c=ithakiCompanionV249258();
  const modes=[['fcm_default','1. FCM προεπιλογή','Κλειστή εφαρμογή με Firebase/FCM, ανοιχτή εφαρμογή με εσωτερικό καμπανάκι. Προτείνεται.'],['background','2. Παρασκήνιο','Για πιο ήπια λειτουργία όταν η εφαρμογή είναι στο παρασκήνιο.'],['open_app','3. Ανοιχτή εφαρμογή','Ειδοποιήσεις μόνο όσο είσαι μέσα στην ΙΘΑΚΗ.'],['stay_awake','4. Δεν κοιμάται','Κρατά ζωντανή σύνδεση. Πιο άμεσο, αλλά μπορεί να τρώει μπαταρία.'],['no_closed','5. Χωρίς ειδοποιήσεις κλειστή συσκευή','Όταν η εφαρμογή είναι κλειστή, δεν εμφανίζει push από FCM.']];
  const modeHtml=modes.map(x=>`<button class="modeCardV249258 ${m===x[0]?'active':''}" onclick="return ITH.setNotificationMode('${x[0]}')"><b>${x[1]}</b><small>${x[2]}</small></button>`).join('');
  const compHtml=`<button class="companionCardV249258 ${c==='athina'?'active':''}" onclick="return setIthakiCompanionV249258('athina')"><b>🦉 Bil</b><small>Όμορφη, φυσική, χαμογελαστή, με μεγάλα μάτια που κινούνται, ελαφριά φτερά και ήρεμη σοφή παρουσία.</small></button><button class="companionCardV249258 ${c==='sokratakis'?'active':''}" onclick="return setIthakiCompanionV249258('sokratakis')"><b>🐢 Bil</b><small>Ήρεμος συνοδοιπόρος, με πιο αραιά μάτια και μικρό χαμόγελο.</small></button><button class="companionCardV249258 ${c==='none'?'active':''}" onclick="return setIthakiCompanionV249258('none')"><b>🔕 Τίποτα</b><small>Χωρίς συνοδό. Μένει μόνο το απλό καμπανάκι.</small></button>`;
  const html=`<div class="card"><b>🔔 Καθαρές επιλογές ειδοποιήσεων</b><div class="date">Διαλέγεις έναν τρόπο, για να μη μπερδεύονται διπλές ειδοποιήσεις/κλήσεις.</div><div class="modeGridV249258" style="margin-top:10px">${modeHtml}</div></div><div class="card"><b>🧭 Συνοδοιπόρος ειδοποιήσεων</b><div class="date">Τοπικό μόνο: χωρίς AI, χωρίς server, χωρίς βάση.</div><div class="companionGridV249258" style="margin-top:10px">${compHtml}</div></div><div class="athinaCardV249258">${c==='none'?'<div style="font-size:32px">🔔</div>':companionAvatarV249258()}<div class="athinaBubbleV249258"><b>${c==='sokratakis'?'Bil':c==='none'?'ΙΘΑΚΗ':'Bil'}</b><div>${c==='none'?'Οι ειδοποιήσεις θα εμφανίζονται απλά.':'Γεια σου, πώς είσαι σήμερα;'}</div><small>${c==='none'?'Απλές καθαρές ειδοποιήσεις.':companionLineV249258('message','Μέλος')}<br>Χωρίς AI · Χωρίς server · Χωρίς βάση</small></div></div>`;
  const box=$('notifySettingsV249258');if(box)box.innerHTML=html;
}
function ensureSocratakiV249252(){try{injectSocratakiV249252Css();document.getElementById('socratakiFabV249252')?.remove();document.getElementById('socratakiPanelV249252')?.remove()}catch(e){}}
function ensureAthinaCompanionV249258(){
  injectAthinaV249258Css();injectV249262InnovationCss();
  try{document.getElementById('socratakiFabV249252')?.remove();document.getElementById('socratakiPanelV249252')?.remove();const c=ithakiCompanionV249258();let b=document.getElementById('athinaFabV249258');if(c==='none'){if(b)b.remove();return}if(!b){b=document.createElement('button');b.id='athinaFabV249258';b.type='button';b.onclick=()=>openNotificationSettingsV249238();document.body.appendChild(b)}b.title=(c==='sokratakis'?'Bil':'Bil')+' - συνοδοιπόρος ειδοποιήσεων';b.innerHTML=c==='sokratakis'?(typeof sokratakiTurtleV249252==='function'?sokratakiTurtleV249252('small'):'🐢'):athinaOwlV249258('small')}catch(e){}
}
function companionNoticeWelcomeV249258(){const c=ithakiCompanionV249258();if(c==='none')return'';return `<div class="athinaCardV249258">${companionAvatarV249258()}<div class="athinaBubbleV249258"><b>${c==='sokratakis'?'Bil':'Bil'}</b><div>Γεια σου, πώς είσαι σήμερα;</div><small>Θα σου δείχνω με όμορφο τρόπο: μήνυμα, like, είσοδο φίλου και νέα δημοσίευση. Τοπικά μόνο — χωρίς AI, χωρίς server, χωρίς βάση.</small></div></div>`}
function shouldShowPollCardV249262(){try{const last=+(localStorage.getItem('ith_poll_card_ts_v249262')||0)||0;return Date.now()-last>=12*60*60*1000}catch{return true}}
function markPollCardV249262(){try{localStorage.setItem('ith_poll_card_ts_v249262',String(Date.now()))}catch{}}
function shouldShowWisdomCardV249262(){try{const last=+(localStorage.getItem('ith_wisdom_card_ts_v249262')||0)||0;return Date.now()-last>=30*60*1000}catch{return true}}
function markWisdomCardV249262(){try{localStorage.setItem('ith_wisdom_card_ts_v249262',String(Date.now()))}catch{}}
function feedProPanel(kind,index=0){
  const logo='<div class="feedGoldLogo"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display=\'none\'"></div><div class="feedGoldBrandText"><span class="okRainbow">OK</span> <small>ithaki</small></div>';
  if(kind==='poll'){const key='gold_poll_v249262_'+todayKey();const p={q:'Ποια Ροή θέλεις να βλέπεις πρώτη στην ΙΘΑΚΗ;',opts:['Φίλοι','Ακολουθώ','Ίδια ενδιαφέροντα','Ελεύθερη Ροή'],bars:[55,44,39,62]};const local=cardLocalStats(key,p.opts,p.opts.map((o,i)=>({index:i,text:o,count:Math.max(1,Math.round(p.bars[i]/12)),percent:p.bars[i]})));const opts=p.opts.map((o,i)=>{const row=(local.options||[]).find(x=>+x.index===i)||{count:0,percent:p.bars[i]||0};return `<button class="feedGoldPollChoice" onclick="ITH.voteCardChoice(this,'${escJs(key)}',${i})"><em style="width:${+row.percent||0}%"></em><span>${esc(o)}</span><b>${+row.count||0} · ${+row.percent||0}%</b></button>`}).join('');return `<article class="card feedGoldPollCard v249232Poll" data-feed-panel="${esc(key)}"><div class="feedGoldCardInner">${logo}<h3 class="feedGoldQuote">${esc(p.q)}</h3><div class="feedGoldPollOptions">${opts}</div></div></article>`}
  const [who,quote]=philosopherWisdomV249232(index);const key='gold_wisdom_v249262_'+index;return `<article class="card feedGoldWisdomCard v249232Wisdom" data-feed-panel="${esc(key)}"><div class="feedGoldCardInner">${logo}<h3 class="feedGoldQuote">${esc(quote)}<small>${esc(who)} · αρχαία/νέα φιλοσοφική σκέψη</small></h3></div></article>`
}
function renderFeedWithPanels(posts,cfg){
  posts=uniquePosts(posts||[]);let html='',n=0,insertedWisdom=false,insertedPoll=false;const dueWisdom=shouldShowWisdomCardV249262(),duePoll=shouldShowPollCardV249262();
  for(const p of posts){html+=renderPost(p);n++;if(n%9===0){html+=feedProPanel('wisdom',Math.floor(Date.now()/1800000)+n);insertedWisdom=true}if(duePoll&&!insertedPoll&&n%12===0){html+=feedProPanel('poll',n);insertedPoll=true}}
  if(!insertedWisdom&&dueWisdom&&posts.length){html+=feedProPanel('wisdom',Math.floor(Date.now()/1800000));insertedWisdom=true}
  if(!insertedPoll&&duePoll&&posts.length&&posts.length<12){html+=feedProPanel('poll',posts.length);insertedPoll=true}
  if(insertedWisdom)markWisdomCardV249262();if(insertedPoll)markPollCardV249262();return html
}
function attachV249262Exports(){try{window.openWhyIthakiV249262=openWhyIthakiV249262;window.openPrivacyScoreV249262=openPrivacyScoreV249262;window.openTrustModeV249262=openTrustModeV249262;window.setTrustModeV249262=setTrustModeV249262;window.openOnboardingV249262=openOnboardingV249262;window.ITH=window.ITH||{};Object.assign(window.ITH,{openWhyIthakiV249262,openPrivacyScoreV249262,openTrustModeV249262,setTrustModeV249262,openOnboardingV249262})}catch(e){}}
attachV249262Exports();
try{if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',()=>{attachV249262Exports();setTimeout(ensureAthinaCompanionV249258,900)});else setTimeout(()=>{attachV249262Exports();ensureAthinaCompanionV249258()},900);setInterval(()=>{attachV249262Exports();ensureAthinaCompanionV249258()},5000)}catch(e){}



/* V249263 - professional mascot cloud, notification scroll-first-mascots, compact innovation row, clean feed buttons */
function injectV249263ProfessionalCss(){
  try{
    if(document.getElementById('ithV249263ProfessionalCss'))return;
    const st=document.createElement('style');
    st.id='ithV249263ProfessionalCss';
    st.textContent=`
      .ithInnovationHeroV249262{padding:13px!important;border-radius:22px!important}
      .ithFeatureGridV249262{display:flex!important;gap:7px!important;overflow-x:auto!important;scroll-snap-type:x proximity!important;padding:3px 1px 5px!important;margin-top:10px!important;scrollbar-width:none!important}
      .ithFeatureGridV249262::-webkit-scrollbar{display:none!important}
      .ithFeatureChipV249262{flex:0 0 auto!important;min-height:42px!important;min-width:auto!important;display:inline-flex!important;flex-direction:row!important;align-items:center!important;justify-content:flex-start!important;gap:6px!important;padding:8px 10px!important;border-radius:999px!important;background:rgba(255,255,255,.07)!important;border:1px solid rgba(255,217,110,.16)!important;text-align:left!important}
      .ithFeatureChipV249262 span{font-size:17px!important}.ithFeatureChipV249262 b{font-size:11px!important;line-height:1.15!important;white-space:nowrap!important}
      .ithInnovationActionsV249262{display:flex!important;flex-wrap:nowrap!important;overflow-x:auto!important;gap:7px!important;padding-bottom:3px!important;scrollbar-width:none!important}
      .ithInnovationActionsV249262::-webkit-scrollbar{display:none!important}
      .ithInnovationActionsV249262 button{flex:0 0 auto!important;padding:9px 11px!important;font-size:12px!important}
      .v249263NotifyPanel{height:min(92dvh,840px)!important;max-height:92dvh!important;overflow:auto!important;-webkit-overflow-scrolling:touch!important;padding:0!important;border-radius:24px!important;background:linear-gradient(165deg,rgba(3,12,23,.98),rgba(8,18,31,.98))!important;border:1px solid rgba(255,217,110,.26)!important}
      .v249263NotifyTop{position:sticky;top:0;z-index:5;display:flex!important;align-items:center!important;gap:8px!important;padding:11px!important;background:rgba(3,12,23,.94)!important;border-bottom:1px solid rgba(255,255,255,.08)!important;backdrop-filter:blur(10px)!important}
      .v249263MascotFirst{padding:12px!important;display:grid!important;gap:10px!important}
      .v249263MascotChoices{display:grid!important;grid-template-columns:repeat(3,minmax(0,1fr))!important;gap:8px!important}
      .v249263MascotChoices .companionCardV249258{min-height:86px!important;padding:10px!important;text-align:center!important}
      .v249263NotifyList{display:grid!important;gap:9px!important;padding:0 12px 16px!important;max-height:none!important;overflow:visible!important}
      .v249263NotifySectionTitle{color:#ffe39b!important;font-weight:1000!important;padding:0 12px 6px!important}
      .v249263Cloud{position:fixed;left:82px;bottom:96px;z-index:10001;max-width:min(360px,calc(100vw - 105px));border-radius:24px 24px 24px 8px;background:linear-gradient(145deg,rgba(255,255,255,.96),rgba(233,246,255,.96));color:#06131f;border:1px solid rgba(255,217,110,.55);box-shadow:0 22px 56px rgba(0,0,0,.42);padding:12px 14px;font-weight:900;line-height:1.35;animation:v249263CloudIn .28s ease-out}
      .v249263Cloud:before{content:'';position:absolute;left:-9px;bottom:13px;width:18px;height:18px;background:inherit;border-left:1px solid rgba(255,217,110,.55);border-bottom:1px solid rgba(255,217,110,.55);transform:rotate(45deg);border-radius:3px}
      .v249263Cloud small{display:block;margin-top:5px;color:#41505c;font-weight:700;font-size:12px}
      .v249263Cloud b{color:#0a2438}
      .v249263Cloud .close{position:absolute;right:7px;top:5px;border:0;background:transparent;color:#40505c;font-size:16px;padding:3px}
      #feedPage .feedGoldCardActions,#feedPage .post.pollPost .pollPostActions{display:none!important}
      #feedPage .mediaPost .leftActions{left:auto!important;right:8px!important;top:50%!important;transform:translateY(-50%)!important;display:flex!important;flex-direction:column!important;gap:8px!important;background:rgba(5,18,31,.20)!important;border:1px solid rgba(255,255,255,.10)!important;border-radius:999px!important;padding:6px 4px!important;backdrop-filter:blur(8px)!important}
      #feedPage .mediaPost .leftActions .feedAvatarOverlay{display:none!important}
      #feedPage .mediaPost .leftActions .actionIcon{width:40px!important;height:40px!important;min-width:40px!important;min-height:40px!important;border-radius:50%!important;padding:0!important;display:grid!important;place-items:center!important}
      #feedPage .mediaPost .leftActions .translateAction{display:none!important}
      #feedPage .post:not(.mediaPost) .leftActions{display:flex!important;flex-direction:row!important;justify-content:center!important;gap:8px!important;flex-wrap:nowrap!important;overflow-x:auto!important}
      @media(max-width:760px){
        .v249263MascotChoices{grid-template-columns:1fr!important}
        .v249263Cloud{left:74px;bottom:88px;max-width:calc(100vw - 92px);font-size:13px;padding:11px 12px}
        #feedPage .mediaPost .leftActions{right:6px!important;gap:6px!important}
        #feedPage .mediaPost .leftActions .actionIcon{width:38px!important;height:38px!important;min-width:38px!important;min-height:38px!important}
      }
      @keyframes v249263CloudIn{from{opacity:0;transform:translateY(8px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function v249263MascotNoticeText(){
  const samples=[
    ['Γεια σου, πώς είσαι σήμερα;','Η Bil είναι εδώ για καθαρές ειδοποιήσεις.'],
    ['Η συνομιλία σου είναι κρυπτογραφημένη.','Πάτησε εδώ για να δεις το privacy score.'],
    ['Έχεις νέο like ή νέα κίνηση στη Ροή.','Άνοιξε το καμπανάκι για να το δεις καθαρά.'],
    ['Μπήκε φίλος ή ακολουθούμενος.','Οι ειδοποιήσεις εμφανίζονται με ήρεμο τρόπο.'],
    ['Νέα δημοσίευση από άτομο που ακολουθείς.','Η ΙΘΑΚΗ σε ενημερώνει χωρίς θόρυβο.'],
    ['Offline μετάφραση EL↔EN.','Η μετάφραση μπορεί να μείνει στη συσκευή.']
  ];
  try{
    const i=Math.floor(Date.now()/45000)%samples.length;
    return samples[i];
  }catch{return samples[0]}
}
function showHomeMascotCloudV249263(force=false){
  try{
    injectV249263ProfessionalCss();
    if(!document.body||state.page!=='home')return;
    const c=ithakiCompanionV249258?ithakiCompanionV249258():'athina';
    if(c==='none')return;
    const now=Date.now(), last=+(sessionStorage.getItem('ith_home_cloud_last_v249263')||0)||0;
    if(!force && now-last<60000)return;
    sessionStorage.setItem('ith_home_cloud_last_v249263',String(now));
    document.getElementById('homeMascotCloudV249263')?.remove();
    const [line,sub]=v249263MascotNoticeText();
    const d=document.createElement('button');
    d.id='homeMascotCloudV249263';
    d.className='v249263Cloud';
    d.type='button';
    d.innerHTML=`<button class="close" type="button" aria-label="Close" onclick="event.stopPropagation();this.closest('.v249263Cloud')?.remove()">×</button><b>${esc(line)}</b><small>${esc(sub)} · Πάτησε για καμπανάκι.</small>`;
    d.onclick=()=>{try{d.remove()}catch{};try{notifyCenter()}catch(e){try{ITH.notifyCenter()}catch(_){}}};
    document.body.appendChild(d);
    setTimeout(()=>{try{d.remove()}catch{}},15000);
  }catch(e){}
}
try{var renderHomeV249263Base=renderHome;renderHome=function(){const r=renderHomeV249263Base.apply(this,arguments);setTimeout(()=>showHomeMascotCloudV249263(false),900);return r}}catch(e){}
function homeProtectionPanel(){
  injectV249262InnovationCss();injectV249263ProfessionalCss();
  const open=localStorage.getItem('ith_home_protection_open_v249166')==='1';
  return `<section class="card homeProPanel homeProtectionPro bottomProtection ithInnovationHeroV249262 ${open?'open':'closed'}">
    <div class="ithInnovationTopV249262">
      <div class="ithInnovationSealV249262">🛡️</div>
      <div>
        <h2 class="ithInnovationTitleV249262">Γιατί OK ITHAKI</h2>
        <p class="ithInnovationSubV249262">Ανώνυμη, ανθρώπινη επικοινωνία με καθαρή προστασία, offline μετάφραση, προαιρετικές ειδοποιήσεις και τοπικό συνοδοιπόρο.</p>
      </div>
    </div>
    <div class="ithFeatureGridV249262" aria-label="OK ITHAKI καινοτομία">
      <div class="ithFeatureChipV249262"><span>🕶️</span><b>Ανωνυμία χωρίς τηλέφωνο/email</b></div>
      <div class="ithFeatureChipV249262"><span>🔐</span><b>Κρυπτογραφημένη συνομιλία</b></div>
      <div class="ithFeatureChipV249262"><span>🌐</span><b>Offline μετάφραση EL↔EN</b></div>
      <div class="ithFeatureChipV249262"><span>🔔</span><b>Προαιρετικό FCM</b></div>
      <div class="ithFeatureChipV249262"><span>🦉</span><b>Bil / Bil τοπικά</b></div>
    </div>
    <div class="ithInnovationActionsV249262">
      <button onclick="openWhyIthakiV249262()">✨ Γιατί OK ITHAKI</button>
      <button onclick="openPrivacyScoreV249262()">🟢 Privacy score</button>
      <button onclick="openTrustModeV249262()">🤝 Trust mode</button>
      <button onclick="openOnboardingV249262(0)">🧭 Οδηγός</button>
      <button onclick="showHomeMascotCloudV249263(true)">💬 Mascot</button>
      <button class="homeProtectionToggle" onclick="ITH.toggleHomeProtection()" type="button">${open?'▲ Λιγότερα':'▼ Περισσότερα'}</button>
    </div>
    <div class="protectList" style="display:${open?'grid':'none'}">
      <div>Η ΙΘΑΚΗ δείχνει καθαρά τι προστατεύεται: συνομιλία, μετάφραση, ειδοποιήσεις και τοπική λειτουργία.</div>
      <div>Καμία μετάφραση δεν χρειάζεται να φεύγει από τη συσκευή όταν λειτουργεί το offline EL↔EN.</div>
      <div>Οι ειδοποιήσεις FCM είναι επιλογή, όχι υποχρέωση. Ο χρήστης βλέπει τι ενεργοποιεί.</div>
      <div>Ο συνοδοιπόρος ειδοποιήσεων λειτουργεί τοπικά: χωρίς AI, χωρίς server, χωρίς βάση.</div>
      <div>Το ανώνυμο τοπικό δίκτυο έκτακτης ανάγκης προβάλλεται ως καινοτομία της ΙΘΑΚΗΣ για δύσκολες στιγμές.</div>
    </div>
  </section>`;
}
function v249263MascotChoiceHtml(){
  const c=ithakiCompanionV249258?ithakiCompanionV249258():'athina';
  return `<div class="v249263MascotChoices">
    <button class="companionCardV249258 ${c==='athina'?'active':''}" onclick="return setIthakiCompanionV249258('athina')"><b>🦉 Bil</b><small>Σοφή, ήρεμη, ειδοποιεί με καθαρό συννεφάκι.</small></button>
    <button class="companionCardV249258 ${c==='sokratakis'?'active':''}" onclick="return setIthakiCompanionV249258('sokratakis')"><b>🐢 Bil</b><small>Ήρεμος συνοδοιπόρος για σκέψη και καθαρά λόγια.</small></button>
    <button class="companionCardV249258 ${c==='none'?'active':''}" onclick="return setIthakiCompanionV249258('none')"><b>🔕 Τίποτα</b><small>Μένουν μόνο απλές ειδοποιήσεις.</small></button>
  </div>`;
}
async function legacyNotifyCenterV249526_9(){
  injectV249238NotifyCss();injectV249231AvatarDmNotifyCss();injectV249262InnovationCss();injectV249263ProfessionalCss();
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="v249263NotifyPanel">
    <div class="v249263NotifyTop"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Ειδοποιήσεις</b><button class="btn" style="margin-left:auto" onclick="ITH.openNotificationSettingsV249238()">⚙️ Ρυθμίσεις</button><button class="icon" onclick="ITH.closeMember()">×</button></div>
    <div class="v249263MascotFirst">
      ${companionNoticeWelcomeV249258?companionNoticeWelcomeV249258():''}
      ${v249263MascotChoiceHtml()}
      <div class="athinaBubbleV249258"><b>Επαγγελματική ειδοποίηση</b><div>Το mascot σε ενημερώνει για μήνυμα, like, φίλο, ακολουθούμενο, νέα δημοσίευση ή κρυπτογραφημένη συνομιλία — τοπικά και καθαρά.</div></div>
    </div>
    <div class="v249263NotifySectionTitle">Αιτήματα / κινήσεις</div>
    <div id="v249263NotifyList" class="v249263NotifyList"><div class="card">Φόρτωση ειδοποιήσεων...</div></div>
  </div>`;
  let items=[];
  try{
    const r=await fetchJson(`/api/notifications?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=300`);
    items=(r.items||[]).map(x=>({server:true,type:x.type==='contact'?'contact_invite':x.type,status:x.status||'pending',id:x.id,from_id:x.from_id,from_name:x.from_name,to_id:x.to_id,to_name:x.to_name,created_at:x.created_at||x.updated_at,text:(String(x.to_id||'')===String(state.device)?'Σας έστειλε αίτημα φιλίας':'Το αίτημα φιλίας περιμένει αποδοχή από την άλλη συσκευή')}));
  }catch(e){items=[]}
  try{items=[...items,...uniqueNotices(localNotices()).filter(v249233IsFriendRequestPending)]}catch{}
  const seen=new Set();
  items=items.filter(n=>{const k=String(n.id||n.event_id||n.type+'-'+n.from_id+'-'+n.to_id+'-'+n.created_at);if(seen.has(k))return false;seen.add(k);return String(n.status||'pending')==='pending'}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));
  const incoming=items.filter(n=>String(n.to_id||'')===String(state.device));
  const outgoing=items.filter(n=>String(n.from_id||'')===String(state.device));
  const otherItems=items.filter(n=>String(n.to_id||'')!==String(state.device)&&String(n.from_id||'')!==String(state.device));
  const card=n=>{const inbound=String(n.to_id||'')===String(state.device);const who=inbound?(n.from_name||n.from_id||'Μέλος'):(n.to_name||n.to_id||'Μέλος');return `<div class="v249233FriendCard"><b>${inbound?'🤝 Νέο αίτημα φιλίας':'⏳ Αίτημα σε αναμονή'}</b><div class="date">${esc(who)} · ${fmt(n.created_at||Date.now())}</div><p>${esc(n.text||'Καθαρή ειδοποίηση ΙΘΑΚΗΣ')}</p><div class="row">${inbound?`<button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||'')}','accept','${escJs(n.from_id||'')}')">Αποδοχή</button><button class="btn" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||'')}','reject','${escJs(n.from_id||'')}')">Όχι τώρα</button>`:`<button class="btn" onclick="ITH.openNotificationSettingsV249238()">Ρυθμίσεις</button>`}</div></div>`};
  const list=$('v249263NotifyList');
  if(list) list.innerHTML=[...incoming,...outgoing,...otherItems].map(card).join('') || `<div class="card"><b>Δεν υπάρχουν νέες ειδοποιήσεις.</b><div class="date">Η Bil / ο Bil θα εμφανίσει καθαρό συννεφάκι όταν υπάρξει μήνυμα, like, φίλος ή νέα δημοσίευση.</div></div>`;
  try{markNoticesRead()}catch{}
  return false;
}
function legacyOpenNotificationSettingsV249526_3(){
  injectAthinaV249258Css();injectV249262InnovationCss();injectV249263ProfessionalCss();
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="v249263NotifyPanel">
    <div class="v249263NotifyTop"><button class="icon" onclick="ITH.notifyCenter()">‹</button><b>⚙️ Ρυθμίσεις ειδοποιήσεων</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div>
    <div class="v249263MascotFirst">${v249263MascotChoiceHtml()}<div id="notifySettingsV249258"></div></div>
  </div>`;
  renderNotificationModeSettingsV249258();
  return false;
}
try{
  window.showHomeMascotCloudV249263=showHomeMascotCloudV249263;
  window.notifyCenter=notifyCenter;
  window.openNotificationSettingsV249238=openNotificationSettingsV249238;
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{notifyCenter,openNotificationSettingsV249238,showHomeMascotCloudV249263});
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',()=>setTimeout(()=>showHomeMascotCloudV249263(false),1600));
  else setTimeout(()=>showHomeMascotCloudV249263(false),1600);
}catch(e){}



/* V249264 - clean home only Why OK ITHAKI, actionable mascot clouds, notification routing, owl SVG eye fix */
function injectV249264CleanHomeNotifyCss(){
  try{
    if(document.getElementById('ithV249264CleanHomeNotifyCss'))return;
    const st=document.createElement('style');
    st.id='ithV249264CleanHomeNotifyCss';
    st.textContent=`
      .ithHomeWhyOnlyV249264{position:relative!important;overflow:hidden!important;border-radius:24px!important;padding:15px!important;border:1px solid rgba(255,217,110,.28)!important;background:radial-gradient(circle at 15% 0%,rgba(255,217,110,.24),transparent 34%),radial-gradient(circle at 88% 8%,rgba(78,205,255,.18),transparent 30%),linear-gradient(145deg,rgba(6,19,32,.97),rgba(3,10,20,.99))!important;box-shadow:0 18px 58px rgba(0,0,0,.35)!important}
      .ithHomeWhyHeadV249264{display:grid!important;grid-template-columns:auto 1fr!important;gap:13px!important;align-items:center!important}
      .ithHomeLogoV249264{position:relative;width:84px;height:84px;border-radius:26px;display:grid;place-items:center;background:rgba(255,255,255,.07);border:1px solid rgba(255,217,110,.25);box-shadow:inset 0 1px 0 rgba(255,255,255,.14)}
      .ithHomeLogoV249264 img{position:absolute;width:58px;height:58px;object-fit:contain;opacity:.72;filter:drop-shadow(0 10px 15px rgba(0,0,0,.30))}
      .ithOkRainbowV249264{position:relative;z-index:2;font-size:33px;font-weight:1000;letter-spacing:-.08em;background:linear-gradient(90deg,#ff4d4d,#ffca3a,#36f0a0,#4cc9ff,#b46cff,#ff65c3);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:0 7px 24px rgba(0,0,0,.36)}
      .ithHomeTitleV249264{margin:0;color:#ffe39b;font-size:clamp(20px,5vw,31px);line-height:1.05;font-weight:1000}
      .ithHomeSubV249264{margin:6px 0 0;color:rgba(239,248,255,.82);font-size:clamp(13px,3.2vw,16px);line-height:1.35}
      .ithHomeWhyBtnV249264{margin-top:13px;width:100%;border:1px solid rgba(255,217,110,.45);border-radius:18px;padding:13px 14px;background:linear-gradient(135deg,rgba(255,217,110,.22),rgba(76,198,255,.12));color:#fff;font-weight:1000;font-size:16px;box-shadow:0 12px 32px rgba(0,0,0,.24)}
      .athinaOwlSvgV249264{width:106px;height:106px;display:inline-block;filter:drop-shadow(0 16px 26px rgba(0,0,0,.34))}
      .athinaOwlSvgV249264.small{width:56px;height:56px}
      .athinaOwlSvgV249264 .pupil{animation:athinaSvgLookV249264 6.4s ease-in-out infinite;transform-origin:center}
      .athinaOwlSvgV249264 .lid{animation:athinaSvgBlinkV249264 6.2s infinite;transform-origin:center}
      .athinaOwlSvgV249264 .wingL{animation:athinaSvgWingLV249264 4.8s ease-in-out infinite;transform-origin:36px 63px}
      .athinaOwlSvgV249264 .wingR{animation:athinaSvgWingRV249264 4.8s ease-in-out infinite;transform-origin:70px 63px}
      @keyframes athinaSvgLookV249264{0%,100%{transform:translate(0,0)}28%{transform:translate(2px,-1px)}58%{transform:translate(-2px,1px)}76%{transform:translate(1px,0)}}
      @keyframes athinaSvgBlinkV249264{0%,91%,100%{transform:scaleY(1)}94%{transform:scaleY(.08)}97%{transform:scaleY(1)}}
      @keyframes athinaSvgWingLV249264{0%,100%{transform:rotate(0)}50%{transform:rotate(-5deg)}}@keyframes athinaSvgWingRV249264{0%,100%{transform:rotate(0)}50%{transform:rotate(5deg)}}
      .v249264Cloud{position:fixed;left:82px;bottom:96px;z-index:10001;max-width:min(380px,calc(100vw - 105px));border-radius:24px 24px 24px 8px;background:linear-gradient(145deg,rgba(255,255,255,.97),rgba(235,247,255,.97));color:#06131f;border:1px solid rgba(255,217,110,.55);box-shadow:0 22px 56px rgba(0,0,0,.42);padding:12px 14px;font-weight:900;line-height:1.35;animation:v249264CloudIn .28s ease-out;text-align:left}
      .v249264Cloud.actionable{cursor:pointer}.v249264Cloud:not(.actionable){pointer-events:auto;cursor:default}
      .v249264Cloud:before{content:'';position:absolute;left:-9px;bottom:13px;width:18px;height:18px;background:inherit;border-left:1px solid rgba(255,217,110,.55);border-bottom:1px solid rgba(255,217,110,.55);transform:rotate(45deg);border-radius:3px}
      .v249264Cloud .cloudRow{display:grid;grid-template-columns:auto 1fr;gap:9px;align-items:center}.v249264Cloud .avatar{width:38px!important;height:38px!important;min-width:38px!important;min-height:38px!important}
      .v249264Cloud small{display:block;margin-top:5px;color:#41505c;font-weight:700;font-size:12px}.v249264Cloud b{color:#0a2438}.v249264Cloud .close{position:absolute;right:7px;top:5px;border:0;background:transparent;color:#40505c;font-size:16px;padding:3px}
      .v249264NotifyPanel{height:min(92dvh,850px)!important;max-height:92dvh!important;overflow:auto!important;-webkit-overflow-scrolling:touch!important;padding:0!important;border-radius:24px!important;background:linear-gradient(165deg,rgba(3,12,23,.98),rgba(8,18,31,.98))!important;border:1px solid rgba(255,217,110,.26)!important}
      .v249264NotifyTop{position:sticky;top:0;z-index:5;display:flex!important;align-items:center!important;gap:8px!important;padding:11px!important;background:rgba(3,12,23,.94)!important;border-bottom:1px solid rgba(255,255,255,.08)!important;backdrop-filter:blur(10px)!important}
      .v249264NotifyBody{padding:12px!important;display:grid!important;gap:10px!important}.v249264SettingsScroll{max-height:calc(92dvh - 70px)!important;overflow:auto!important;-webkit-overflow-scrolling:touch!important;padding:12px!important}
      .v249264NoticeCard{display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:center;border-radius:18px;padding:11px;background:rgba(255,255,255,.065);border:1px solid rgba(255,255,255,.10);color:#fff}.v249264NoticeCard .noticeText b{display:block;color:#ffe39b}.v249264NoticeCard .noticeText small{display:block;color:rgba(239,248,255,.68);margin-top:3px}
      .v249264NoticeActions{grid-column:1/-1;display:flex;gap:8px;flex-wrap:wrap}.v249264NoticeActions .btn{padding:8px 11px!important}
      #feedPage .feedGoldCardActions,#feedPage .post.pollPost .pollPostActions{display:none!important}
      @media(max-width:760px){.ithHomeWhyHeadV249264{grid-template-columns:1fr!important;text-align:center}.ithHomeLogoV249264{margin:auto;width:78px;height:78px}.v249264Cloud{left:74px;bottom:88px;max-width:calc(100vw - 92px);font-size:13px;padding:11px 12px}.v249264NotifyPanel{height:94dvh!important;max-height:94dvh!important;border-radius:18px!important}}
      @keyframes v249264CloudIn{from{opacity:0;transform:translateY(8px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function athinaOwlV249258(cls=''){
  injectV249264CleanHomeNotifyCss();
  return `<svg class="athinaOwlSvgV249264 ${cls||''}" viewBox="0 0 106 106" role="img" aria-label="Bil κουκουβάγια">
    <defs>
      <radialGradient id="athBodyV249264" cx="42%" cy="22%" r="78%"><stop offset="0" stop-color="#fff6df"/><stop offset=".28" stop-color="#e5b376"/><stop offset=".62" stop-color="#a46c3d"/><stop offset="1" stop-color="#684127"/></radialGradient>
      <linearGradient id="athWingV249264" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#c58a52"/><stop offset="1" stop-color="#6e452b"/></linearGradient>
      <linearGradient id="athFaceV249264" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff7df"/><stop offset="1" stop-color="#d9a462"/></linearGradient>
    </defs>
    <path d="M30 20 L19 9 Q38 12 41 28 Z" fill="#7a4b2c"/><path d="M76 20 L87 9 Q68 12 65 28 Z" fill="#7a4b2c"/>
    <ellipse cx="53" cy="59" rx="35" ry="40" fill="url(#athBodyV249264)" stroke="rgba(255,232,160,.55)" stroke-width="1.5"/>
    <path class="wingL" d="M25 50 Q11 62 23 82 Q35 72 34 55 Z" fill="url(#athWingV249264)"/><path class="wingR" d="M81 50 Q95 62 83 82 Q71 72 72 55 Z" fill="url(#athWingV249264)"/>
    <path d="M25 34 Q53 13 81 34 Q75 70 53 73 Q31 70 25 34 Z" fill="url(#athFaceV249264)" stroke="rgba(120,74,41,.28)" stroke-width="1"/>
    <circle cx="40" cy="45" r="14" fill="#fffdf7" stroke="rgba(0,0,0,.15)" stroke-width="1.2"/>
    <circle cx="66" cy="45" r="14" fill="#fffdf7" stroke="rgba(0,0,0,.15)" stroke-width="1.2"/>
    <g class="lid"><circle cx="40" cy="45" r="13" fill="transparent"/><circle cx="66" cy="45" r="13" fill="transparent"/></g>
    <circle class="pupil" cx="40" cy="45" r="6" fill="#13232c"/><circle class="pupil" cx="66" cy="45" r="6" fill="#13232c"/>
    <circle class="pupil" cx="38" cy="43" r="2" fill="#fff"/><circle class="pupil" cx="64" cy="43" r="2" fill="#fff"/>
    <path d="M48 58 L53 66 L58 58 Z" fill="#e99e24" stroke="rgba(80,45,18,.25)" stroke-width="1"/>
    <path d="M45 70 Q53 77 61 70" fill="none" stroke="rgba(51,32,20,.62)" stroke-width="2.2" stroke-linecap="round"/>
    <path d="M39 92 Q53 98 67 92" fill="none" stroke="#e3a331" stroke-width="5" stroke-linecap="round"/>
  </svg>`;
}
function homeProtectionPanel(){
  injectV249262InnovationCss();injectV249264CleanHomeNotifyCss();
  return `<section class="card homeProPanel homeProtectionPro bottomProtection ithHomeWhyOnlyV249264">
    <div class="ithHomeWhyHeadV249264">
      <div class="ithHomeLogoV249264"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display='none'"><span class="ithOkRainbowV249264">OK</span></div>
      <div>
        <h2 class="ithHomeTitleV249264">Γιατί OK ITHAKI</h2>
        <p class="ithHomeSubV249264">Ανώνυμη, ανθρώπινη επικοινωνία με καθαρή προστασία, offline μετάφραση, προαιρετικές ειδοποιήσεις και τοπικό συνοδοιπόρο.</p>
      </div>
    </div>
    <button class="ithHomeWhyBtnV249264" onclick="openWhyIthakiV249262()">✨ Γιατί OK ITHAKI</button>
  </section>`;
}
function v249264Person(id,name='Μέλος'){
  try{const p=v249231PersonById(id)||{};if(!p.nickname&&name)p.nickname=name;return p}catch{return {id,nickname:name,avatar:''}}
}
function v249264NoticeLabel(n){
  const type=String(n?.type||'').toLowerCase();
  const from=n?.from_id||n?.sender_id||n?.actor_id||'';
  const name=n?.from_name||n?.nickname||n?.actor_name||v249264Person(from).nickname||'Μέλος';
  if(type==='message')return {kind:'message',title:`Μήνυμα από ${name}`,body:`Ο/Η ${name} σου έστειλε μήνυμα.`,action:'message',peer:from};
  if(type==='contact_invite'||type==='contact'||type==='friend_request')return {kind:'friend',title:`Πρόταση φιλίας από ${name}`,body:`Πάτησε για αποδοχή ή απόρριψη στο καμπανάκι.`,action:'notifications',peer:from};
  if(type==='like'||type==='reaction')return {kind:'like',title:`Like από ${name}`,body:`Ο/Η ${name} έκανε like στη δημοσίευσή σου.`,action:'notifications',peer:from};
  if(type==='post'||type==='follow_post'||type==='following_post')return {kind:'post',title:`Νέα δημοσίευση από ${name}`,body:`Ο/Η ${name}, που ακολουθείς, έκανε νέα δημοσίευση.`,action:'feed',peer:from};
  if(type==='privacy'||type==='crypto')return {kind:'privacy',title:'Η συνομιλία σου είναι κρυπτογραφημένη',body:'Πάτησε για να δεις το privacy score.',action:'privacy',peer:from};
  return {kind:'info',title:'Γεια σου, πώς είσαι σήμερα;',body:'Η Bil είναι εδώ για καθαρές ειδοποιήσεις.',action:'none',peer:from};
}
function v249264LatestNotice(){
  try{
    const arr=localNotices().filter(n=>!n.read);
    const priority={message:1,contact_invite:2,contact:2,friend_request:2,like:3,reaction:3,post:4,follow_post:4,following_post:4,privacy:5,crypto:5};
    arr.sort((a,b)=>(priority[String(a.type||'').toLowerCase()]||9)-(priority[String(b.type||'').toLowerCase()]||9)||((+(b.created_at||0)||0)- (+(a.created_at||0)||0)));
    return arr[0]||null;
  }catch{return null}
}
function v249264OpenNotice(label,notice){
  try{
    if(label.action==='message'&&label.peer){startDM(label.peer);return}
    if(label.action==='feed'){page('feed');return}
    if(label.action==='privacy'){openPrivacyScoreV249262(label.peer);return}
    if(label.action==='notifications'){notifyCenter();return}
  }catch(e){}
}
function showHomeMascotCloudV249263(force=false){
  try{
    injectV249264CleanHomeNotifyCss();
    if(!document.body||state.page!=='home')return;
    const c=ithakiCompanionV249258?ithakiCompanionV249258():'athina';
    if(c==='none')return;
    const now=Date.now(), last=+(sessionStorage.getItem('ith_home_cloud_last_v249264')||0)||0;
    if(!force&&now-last<60000)return;
    sessionStorage.setItem('ith_home_cloud_last_v249264',String(now));
    document.getElementById('homeMascotCloudV249263')?.remove();
    document.getElementById('homeMascotCloudV249264')?.remove();
    const notice=v249264LatestNotice();
    const label=notice?v249264NoticeLabel(notice):{title:'Γεια σου, πώς είσαι σήμερα;',body:'Η Bil είναι εδώ για καθαρές ειδοποιήσεις.',action:'none',peer:''};
    const p=v249264Person(label.peer,notice?.from_name||notice?.nickname||'Μέλος');
    const d=document.createElement(label.action==='none'?'div':'button');
    d.id='homeMascotCloudV249264';
    d.className='v249264Cloud '+(label.action==='none'?'':'actionable');
    if(label.action!=='none')d.type='button';
    d.innerHTML=`<button class="close" type="button" aria-label="Close" onclick="event.stopPropagation();this.closest('.v249264Cloud')?.remove()">×</button><div class="cloudRow">${label.peer?avatarHtml(p):v249262MascotHtml('small')}<div><b>${esc(label.title)}</b><small>${esc(label.body)}${label.action==='none'?'':' · Πάτησε για άνοιγμα.'}</small></div></div>`;
    if(label.action!=='none')d.onclick=()=>{try{d.remove()}catch{};v249264OpenNotice(label,notice)};
    document.body.appendChild(d);
    setTimeout(()=>{try{d.remove()}catch{}},15000);
  }catch(e){}
}
function v249264NoticeCard(n){
  const lab=v249264NoticeLabel(n), p=v249264Person(lab.peer,n?.from_name||n?.nickname||'Μέλος');
  let actions='';
  if(lab.kind==='friend'){
    actions=`<div class="v249264NoticeActions"><button class="btn green" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||'')}','accept','${escJs(lab.peer||'')}')">Αποδοχή</button><button class="btn" onclick="ITH.respondFriendProposalV249233('${escJs(n.id||'')}','reject','${escJs(lab.peer||'')}')">Όχι τώρα</button></div>`;
  }else if(lab.kind==='message'){
    actions=`<div class="v249264NoticeActions"><button class="btn green" onclick="ITH.startDM ? ITH.startDM('${escJs(lab.peer)}') : startDM('${escJs(lab.peer)}')">Άνοιγμα μηνυμάτων</button></div>`;
  }else if(lab.kind==='like'||lab.kind==='post'){
    actions=`<div class="v249264NoticeActions"><button class="btn" onclick="ITH.page('feed')">Άνοιγμα Ροής</button></div>`;
  }else if(lab.kind==='privacy'){
    actions=`<div class="v249264NoticeActions"><button class="btn green" onclick="openPrivacyScoreV249262('${escJs(lab.peer)}')">Privacy score</button></div>`;
  }
  return `<div class="v249264NoticeCard">${avatarHtml(p)}<div class="noticeText"><b>${esc(lab.title)}</b><small>${esc(lab.body)} · ${fmt(n.created_at||Date.now())}</small></div>${actions}</div>`;
}
async function legacyNotifyCenterV249526_10(){
  injectV249238NotifyCss();injectV249231AvatarDmNotifyCss();injectV249262InnovationCss();injectV249264CleanHomeNotifyCss();
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="v249264NotifyPanel">
    <div class="v249264NotifyTop"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔔 Ειδοποιήσεις</b><button class="btn" style="margin-left:auto" onclick="ITH.openNotificationSettingsV249238()">⚙️ Ρυθμίσεις</button><button class="icon" onclick="ITH.closeMember()">×</button></div>
    <div class="v249264NotifyBody">
      ${companionNoticeWelcomeV249258?companionNoticeWelcomeV249258():''}
      <div class="athinaBubbleV249258"><b>Καθαρές ειδοποιήσεις</b><div>Μήνυμα → ανοίγει μηνύματα από το σωστό avatar. Πρόταση φιλίας → αποδοχή εδώ. Like ή νέα δημοσίευση → δείχνει από ποιο avatar είναι.</div></div>
      <div id="v249264NotifyList"><div class="card">Φόρτωση ειδοποιήσεων...</div></div>
    </div>
  </div>`;
  let items=[];
  try{
    const r=await fetchJson(`/api/notifications?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}&limit=300`);
    items=(r.items||[]).map(x=>({server:true,type:x.type==='contact'?'contact_invite':x.type,status:x.status||'pending',id:x.id,from_id:x.from_id||x.sender_id||x.actor_id,from_name:x.from_name||x.nickname||x.actor_name,to_id:x.to_id,to_name:x.to_name,created_at:x.created_at||x.updated_at,text:x.text||''}));
  }catch(e){items=[]}
  try{items=[...items,...localNotices().filter(n=>!n.read)]}catch{}
  const seen=new Set();
  items=items.filter(n=>{const k=String(n.id||n.event_id||n.type+'-'+n.from_id+'-'+n.to_id+'-'+n.text+'-'+n.created_at);if(seen.has(k))return false;seen.add(k);return String(n.status||'pending')!=='accepted'&&String(n.status||'pending')!=='rejected'}).sort((a,b)=>(+(b.created_at||0)||0)- (+(a.created_at||0)||0));
  const list=$('v249264NotifyList');
  if(list)list.innerHTML=items.length?items.map(v249264NoticeCard).join(''):`<div class="card"><b>Δεν υπάρχουν νέες ειδοποιήσεις.</b><div class="date">Όταν υπάρξει μήνυμα, πρόταση φιλίας, like ή δημοσίευση από φίλο/ακολουθούμενο, θα φαίνεται από ποιο avatar είναι.</div></div>`;
  try{refreshNotificationBadgeV249238&&refreshNotificationBadgeV249238()}catch{}
  return false;
}
function legacyOpenNotificationSettingsV249526_4(){
  injectAthinaV249258Css();injectV249262InnovationCss();injectV249264CleanHomeNotifyCss();
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="v249264NotifyPanel">
    <div class="v249264NotifyTop"><button class="icon" onclick="ITH.notifyCenter()">‹</button><b>⚙️ Ρυθμίσεις ειδοποιήσεων</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div>
    <div class="v249264SettingsScroll"><div id="notifySettingsV249258"></div></div>
  </div>`;
  renderNotificationModeSettingsV249258();
  return false;
}
try{
  window.athinaOwlV249258=athinaOwlV249258;
  window.showHomeMascotCloudV249263=showHomeMascotCloudV249263;
  window.notifyCenter=notifyCenter;
  window.openNotificationSettingsV249238=openNotificationSettingsV249238;
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{notifyCenter,openNotificationSettingsV249238,showHomeMascotCloudV249263});
}catch(e){}


/* V249265 - one greeting, notification clouds 10s, auto-close menu choices, scroll + arrows for all menus */
function injectV249265MenuCloudCss(){
  try{
    if(document.getElementById('ithV249265MenuCloudCss'))return;
    const st=document.createElement('style');
    st.id='ithV249265MenuCloudCss';
    st.textContent=`
      #memberMenu.show,#plusSheet.show{overflow:auto!important;-webkit-overflow-scrolling:touch!important;overscroll-behavior:contain!important}
      #memberMenu.show>*,#plusSheet.show>*{max-height:94dvh!important;overflow:auto!important;-webkit-overflow-scrolling:touch!important;overscroll-behavior:contain!important;scrollbar-width:thin!important}
      .v249238NotifyPanel,.v249263NotifyPanel,.v249264NotifyPanel,.whyPanelV249262,.commentPanel,.localPanel,.legalPanel,.themePanel,.feedDiscoverPanelV249232,.pollFull,.sokraBoxV249252{max-height:94dvh!important;overflow:auto!important;-webkit-overflow-scrolling:touch!important;overscroll-behavior:contain!important;scrollbar-width:thin!important}
      .v249264SettingsScroll,.v249263MascotFirst,.v249264NotifyBody,.whyBodyV249262,.panelBody,.sokraBodyV249252,.panelComments{overflow:auto!important;-webkit-overflow-scrolling:touch!important;scrollbar-width:thin!important}
      .ithScrollArrowsV249265{position:fixed;right:12px;top:50%;transform:translateY(-50%);z-index:10080;display:flex;flex-direction:column;gap:8px;pointer-events:none}
      .ithScrollArrowsV249265 button{pointer-events:auto;width:42px;height:42px;border-radius:50%;border:1px solid rgba(255,217,110,.40);background:rgba(5,18,31,.78);color:#ffe39b;font-size:20px;font-weight:1000;box-shadow:0 12px 32px rgba(0,0,0,.36);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
      .ithScrollArrowsV249265 button:active{transform:scale(.94)}
      .v249264Cloud,.v249263Cloud{animation:v249265CloudIn .24s ease-out!important}
      .v249264Cloud small,.v249263Cloud small{font-size:12px!important}
      @keyframes v249265CloudIn{from{opacity:0;transform:translateY(8px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}
      @media(max-width:760px){.ithScrollArrowsV249265{right:8px}.ithScrollArrowsV249265 button{width:38px;height:38px;font-size:18px}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function v249265OpenPanel(){try{return document.querySelector('#memberMenu.show,#plusSheet.show,#previewModal.show,#socratakiPanelV249252.show')}catch{return null}}
function v249265ScrollBox(root){
  try{
    if(!root)return null;
    const selectors=['.v249264SettingsScroll','.v249264NotifyPanel','.v249263NotifyPanel','.v249238NotifyPanel','.whyPanelV249262','.commentPanel','.panelComments','.feedDiscoverPanelV249232','.pollFull','.sokraBoxV249252'];
    for(const sel of selectors){const el=root.matches&&root.matches(sel)?root:root.querySelector(sel);if(el&&el.scrollHeight>el.clientHeight+8)return el}
    const kids=[...root.querySelectorAll('*')].filter(el=>el.scrollHeight>el.clientHeight+16);
    return kids[0]||root;
  }catch{return root}
}
function ensureMenuScrollArrowsV249265(){
  try{
    injectV249265MenuCloudCss();
    document.querySelectorAll('.ithScrollArrowsV249265').forEach(x=>x.remove());
    const root=v249265OpenPanel();
    if(!root)return;
    const box=v249265ScrollBox(root);
    if(!box||box.scrollHeight<=box.clientHeight+12)return;
    const wrap=document.createElement('div');
    wrap.className='ithScrollArrowsV249265';
    wrap.innerHTML='<button type="button" class="noAutoCloseV249265" aria-label="Πάνω">⌃</button><button type="button" class="noAutoCloseV249265" aria-label="Κάτω">⌄</button>';
    const [up,down]=wrap.querySelectorAll('button');
    up.onclick=(e)=>{e.preventDefault();e.stopPropagation();try{v249265ScrollBox(root).scrollBy({top:-Math.max(180,window.innerHeight*.55),behavior:"smooth"})}catch{}};
    down.onclick=(e)=>{e.preventDefault();e.stopPropagation();try{v249265ScrollBox(root).scrollBy({top:Math.max(180,window.innerHeight*.55),behavior:"smooth"})}catch{}};
    document.body.appendChild(wrap);
  }catch(e){}
}
function closeCurrentMenuAfterChoiceV249265(menu){
  try{
    if(!menu)return;
    setTimeout(()=>{
      try{
        document.querySelectorAll('.ithScrollArrowsV249265').forEach(x=>x.remove());
        if(menu.id==='plusSheet'){menu.classList.remove('show');return}
        if(menu.id==='memberMenu'&&menu.classList.contains('show'))closeMemberMenu();
      }catch(e){}
    },260);
  }catch(e){}
}
function installMenuAutoCloseAndArrowsV249265(){
  try{
    if(window.__ithMenuAutoCloseV249265)return;window.__ithMenuAutoCloseV249265=1;
    const scan=()=>setTimeout(ensureMenuScrollArrowsV249265,80);
    const mo=new MutationObserver(scan);
    mo.observe(document.body,{childList:true,subtree:true,attributes:true,attributeFilter:['class','style']});
    setInterval(scan,1200);
    document.addEventListener('click',ev=>{
      const btn=ev.target&&ev.target.closest?ev.target.closest('button,.btn,.tile,.companionCardV249258,.modeCardV249258,.trustBtnV249262'):null;
      if(!btn)return;
      if(btn.closest('.ithScrollArrowsV249265')||btn.classList.contains('noAutoCloseV249265'))return;
      const menu=btn.closest('#memberMenu.show,#plusSheet.show');
      if(!menu)return;
      const txt=String(btn.textContent||'').trim();
      if(!txt||txt==='×'||txt==='‹'||txt==='⌃'||txt==='⌄')return;
      if(btn.classList.contains('icon')&&(txt==='×'||txt==='‹'))return;
      const onclick=String(btn.getAttribute('onclick')||'');
      const opensSub=/openWhyIthaki|openPrivacyScore|openTrustMode|openOnboarding|openNotificationSettings|notifyCenter|openFeedSearch|openPoll|openLocalConnection|openLegal|openPermissions|openPush|openServerData|openSaved|openMemberMedia|openE2E|openCleanMembers/i.test(onclick);
      const leaf=/Αποδοχή|Όχι τώρα|Bil|Bil|Τίποτα|Χωρίς|Άνοιγμα|Εφαρμογή|Αποθήκευση|Διαγραφή|Αποστολή|Επιλογή|Like|Privacy score|Trust mode|Ροής|Μηνυμάτων|μηνυμάτων/i.test(txt);
      if(opensSub&&!/Άνοιγμα μηνυμάτων|Άνοιγμα Ροής|Privacy score/i.test(txt))return;
      if(leaf||menu.id==='plusSheet')closeCurrentMenuAfterChoiceV249265(menu);
    },true);
  }catch(e){}
}
function v249265NoticeKey(n){
  try{return String(n?.id||n?.event_id||n?.type+'-'+n?.from_id+'-'+n?.sender_id+'-'+n?.actor_id+'-'+n?.created_at+'-'+n?.text)}catch{return ''}
}
function v249265LatestNotice(){
  try{
    const arr=(typeof localNotices==='function'?localNotices():[]).filter(n=>!n.read);
    const priority={message:1,dm:1,chat:1,contact_invite:2,contact:2,friend_request:2,like:3,reaction:3,post:4,follow_post:4,following_post:4,privacy:5,crypto:5};
    arr.sort((a,b)=>(priority[String(a.type||'').toLowerCase()]||9)-(priority[String(b.type||'').toLowerCase()]||9)||((+(b.created_at||0)||0)- (+(a.created_at||0)||0)));
    return arr[0]||null;
  }catch{return null}
}
function showHomeMascotCloudV249263(force=false){
  try{
    injectV249265MenuCloudCss();
    if(typeof injectV249264CleanHomeNotifyCss==='function')injectV249264CleanHomeNotifyCss();
    if(!document.body||state.page!=='home')return;
    const c=ithakiCompanionV249258?ithakiCompanionV249258():'athina';
    if(c==='none')return;
    const notice=v249265LatestNotice();
    const nkey=notice?v249265NoticeKey(notice):'';
    const lastNotice=sessionStorage.getItem('ith_last_notice_cloud_key_v249265')||'';
    if(notice&&nkey&&nkey!==lastNotice){
      sessionStorage.setItem('ith_last_notice_cloud_key_v249265',nkey);
    }else if(notice&&!force){
      return;
    }else if(!notice){
      const greeted=sessionStorage.getItem('ith_owl_greeted_once_v249265')==='1';
      if(greeted&&!force)return;
      sessionStorage.setItem('ith_owl_greeted_once_v249265','1');
    }
    document.getElementById('homeMascotCloudV249263')?.remove();
    document.getElementById('homeMascotCloudV249264')?.remove();
    let label, p={};
    if(notice&&typeof v249264NoticeLabel==='function'){
      label=v249264NoticeLabel(notice);
      p=typeof v249264Person==='function'?v249264Person(label.peer,notice.from_name||notice.nickname||'Μέλος'):{nickname:notice.from_name||notice.nickname||'Μέλος'};
    }else{
      label={title:'Γεια σου, πώς είσαι σήμερα;',body:'Η Bil σε χαιρετά μία φορά και μετά κλείνει μόνη της.',action:'none',peer:''};
    }
    const actionable=label.action&&label.action!=='none';
    const d=document.createElement(actionable?'button':'div');
    d.id='homeMascotCloudV249264';
    d.className='v249264Cloud '+(actionable?'actionable':'');
    if(actionable)d.type='button';
    const left=(label.peer&&typeof avatarHtml==='function')?avatarHtml(p):(typeof v249262MascotHtml==='function'?v249262MascotHtml('small'):'🦉');
    d.innerHTML=`<button class="close" type="button" aria-label="Close" onclick="event.stopPropagation();this.closest('.v249264Cloud')?.remove()">×</button><div class="cloudRow">${left}<div><b>${esc(label.title)}</b><small>${esc(label.body)}${actionable?' · Πάτησε για άνοιγμα.':''}</small></div></div>`;
    if(actionable)d.onclick=()=>{try{d.remove()}catch{};try{v249264OpenNotice(label,notice)}catch(e){try{notifyCenter()}catch(_){}}};
    document.body.appendChild(d);
    setTimeout(()=>{try{d.remove()}catch{}},10000);
  }catch(e){}
}
function startNotificationCloudWatcherV249265(){
  try{
    if(window.__ithNoticeCloudWatchV249265)return;window.__ithNoticeCloudWatchV249265=1;
    setTimeout(()=>showHomeMascotCloudV249263(false),1400);
    setInterval(()=>{try{if(state.page==='home')showHomeMascotCloudV249263(false)}catch{}},7000);
  }catch(e){}
}
try{
  installMenuAutoCloseAndArrowsV249265();
  startNotificationCloudWatcherV249265();
  window.showHomeMascotCloudV249263=showHomeMascotCloudV249263;
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{showHomeMascotCloudV249263});
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',()=>{installMenuAutoCloseAndArrowsV249265();startNotificationCloudWatcherV249265();});
}catch(e){}



/* V249267 - host cleanup, wisdom likes/comments, Sokratakis position/name, real privacy score no auto-close */
function injectV249267FixCss(){
  try{
    if(document.getElementById('ithV249267FixCss'))return;
    const st=document.createElement('style');
    st.id='ithV249267FixCss';
    st.textContent=`
      #memberMenu .hostPanelV249267 .feedGoldCardActions,
      #memberMenu .hostPanelV249267 .pollPostActions,
      #memberMenu .hostPanelV249267 .orphanActions,
      #memberMenu .hostPanelV249267 .leftActions,
      #memberMenu .hostPanelV249267 .rightActions{display:none!important}
      .hostPanelV249267{max-height:94dvh!important;overflow:auto!important;-webkit-overflow-scrolling:touch!important;border-radius:24px!important;background:linear-gradient(165deg,rgba(3,12,23,.98),rgba(8,18,31,.98))!important;border:1px solid rgba(255,217,110,.22)!important;padding:0!important}
      .hostTopV249267{position:sticky;top:0;z-index:3;display:flex;gap:8px;align-items:center;padding:11px;background:rgba(3,12,23,.94);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}
      .hostBodyV249267{padding:12px;display:grid;gap:10px}
      .wisdomActionsV249267{display:flex!important;gap:8px!important;justify-content:center!important;align-items:center!important;flex-wrap:nowrap!important;margin-top:10px!important;position:relative!important;right:auto!important;left:auto!important;max-width:none!important;overflow:visible!important}
      .wisdomActionsV249267 button{display:inline-flex!important;align-items:center!important;gap:5px!important;min-width:58px!important;border-radius:999px!important;padding:9px 12px!important;border:1px solid rgba(255,217,110,.25)!important;background:rgba(255,255,255,.08)!important;color:#fff!important;font-weight:1000!important}
      #feedPage .feedGoldWisdomCard .feedGoldCardActions{display:none!important}
      #feedPage .feedGoldWisdomCard .wisdomActionsV249267{display:flex!important}
      .greekWisdomCard .wisdomActionsV249267{margin-top:12px!important}
      #athinaFabV249258{left:10px!important;right:auto!important;bottom:118px!important;width:52px!important;height:52px!important;border-radius:18px!important;padding:3px!important}
      #athinaFabV249258.sokratakisFabV249267{bottom:122px!important;width:50px!important;height:50px!important}
      #athinaFabV249258 .sokraMiniV249252{transform:scale(.82)!important;transform-origin:center!important}
      .athinaSvgV249267{width:96px;height:96px;display:inline-block;filter:drop-shadow(0 14px 20px rgba(0,0,0,.30))}
      .athinaSvgV249267.small{width:46px!important;height:46px!important}
      .athinaSvgV249267 .pupil{animation:athinaLookV249267 5.8s ease-in-out infinite}
      .athinaSvgV249267 .wingL{animation:athinaWingLV249267 6.6s ease-in-out infinite;transform-origin:27px 76px}
      .athinaSvgV249267 .wingR{animation:athinaWingRV249267 6.6s ease-in-out infinite;transform-origin:93px 76px}
      @keyframes athinaLookV249267{0%,100%{transform:translateX(0)}36%{transform:translateX(2px)}64%{transform:translateX(-2px)}}
      @keyframes athinaWingLV249267{0%,100%{transform:rotate(0deg)}50%{transform:rotate(-4deg)}}
      @keyframes athinaWingRV249267{0%,100%{transform:rotate(0deg)}50%{transform:rotate(4deg)}}
      .privacyRealV249267 .privacyRowsV249262 div{grid-template-columns:auto 1fr auto!important}
      .privacyRealV249267 .privacyCalcNote{padding:10px 12px;border-radius:16px;background:rgba(54,240,160,.08);border:1px solid rgba(54,240,160,.22);color:rgba(239,248,255,.84);line-height:1.4}
      .privacyRealV249267 .privacyMeterV249262 i{width:var(--privacy-width,90%)!important}
      .v249267KeepOpen{overscroll-behavior:contain!important}
      @media(max-width:760px){#athinaFabV249258{bottom:112px!important;width:50px!important;height:50px!important}.athinaSvgV249267.small{width:44px!important;height:44px!important}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
athinaOwlV249258=function(cls=''){
  return `<svg class="athinaOwlV249258 athinaSvgV249267 ${cls||''}" viewBox="0 0 120 120" role="img" aria-label="Bil κουκουβάγια">
    <defs>
      <radialGradient id="owlBodyV249267" cx="35%" cy="20%" r="75%"><stop offset="0" stop-color="#ffe7a3"/><stop offset=".42" stop-color="#b9854e"/><stop offset="1" stop-color="#5a3422"/></radialGradient>
      <radialGradient id="owlFaceV249267" cx="50%" cy="40%" r="68%"><stop offset="0" stop-color="#fff6d3"/><stop offset="1" stop-color="#d8a95c"/></radialGradient>
    </defs>
    <path d="M30 24 L42 12 L48 30 Z" fill="#6a3d25"/><path d="M90 24 L78 12 L72 30 Z" fill="#6a3d25"/>
    <ellipse cx="60" cy="66" rx="43" ry="48" fill="url(#owlBodyV249267)" stroke="rgba(255,231,160,.75)" stroke-width="2"/>
    <path class="wingL" d="M29 52 C12 66 16 91 38 98 C31 82 33 68 43 55 Z" fill="#6f4328" opacity=".92"/>
    <path class="wingR" d="M91 52 C108 66 104 91 82 98 C89 82 87 68 77 55 Z" fill="#6f4328" opacity=".92"/>
    <ellipse cx="45" cy="53" rx="22" ry="24" fill="url(#owlFaceV249267)" stroke="rgba(90,52,34,.25)" stroke-width="1.2"/>
    <ellipse cx="75" cy="53" rx="22" ry="24" fill="url(#owlFaceV249267)" stroke="rgba(90,52,34,.25)" stroke-width="1.2"/>
    <circle cx="45" cy="53" r="10" fill="#ffffff"/><circle cx="75" cy="53" r="10" fill="#ffffff"/>
    <circle class="pupil" cx="45" cy="54" r="4.2" fill="#122231"/><circle class="pupil" cx="75" cy="54" r="4.2" fill="#122231"/>
    <circle cx="43" cy="50" r="1.7" fill="#ffffff"/><circle cx="73" cy="50" r="1.7" fill="#ffffff"/>
    <path d="M60 60 L53 70 L67 70 Z" fill="#f2b12d" stroke="#8b5a14" stroke-width="1"/>
    <path d="M50 78 C56 84 64 84 70 78" fill="none" stroke="#5c3320" stroke-width="3" stroke-linecap="round" opacity=".82"/>
    <path d="M45 102 L39 110 M52 103 L50 112 M75 102 L69 110 M82 103 L84 112" stroke="#d49b38" stroke-width="4" stroke-linecap="round"/>
  </svg>`;
};
function v249267DomId(id){return String(id||'x').replace(/[^a-zA-Z0-9_-]/g,'_')}
function wisdomLikeKeyV249267(id){return 'ith_wisdom_like_count_v249267_'+String(id||'')}
function wisdomLikeCountV249267(id){try{return +(localStorage.getItem(wisdomLikeKeyV249267(id))||0)||0}catch{return 0}}
function setWisdomLikeCountV249267(id,n){try{localStorage.setItem(wisdomLikeKeyV249267(id),String(Math.max(0,+n||0)))}catch{}}
async function likeWisdomV249267(id){
  try{
    id=String(id||'wisdom');
    const n=wisdomLikeCountV249267(id)+1;
    setWisdomLikeCountV249267(id,n);
    const el=$('wisdom_like_'+v249267DomId(id)); if(el)el.textContent=String(n);
    try{await fetchJson('/api/reactions/toggle',{method:'POST',body:JSON.stringify({target_id:id,device_id:state.device,emoji:'❤️',nickname:state.name})})}catch(e){}
    toast('Μετρήθηκε η καρδιά ❤️',1800);
  }catch(e){}
  return false;
}
homeWisdomPanel=function(){
  injectV249267FixCss();
  const id='home_wisdom_'+(typeof todayKey==='function'?todayKey():new Date().toISOString().slice(0,10));
  return `<section class="card homeProPanel hourlyWisdomCard greekWisdomCard" data-feed-panel="${esc(id)}"><div class="proPanelIcon">🕯️</div><div class="proPanelText"><b>Σοφός λόγος</b><p>${esc(ithakiWisdomText())}</p><div class="wisdomActionsV249267"><button onclick="ITH.openPostCommentsPanel('${escJs(id)}')">💬 <span>Σχόλια</span></button><button onclick="ITH.likeWisdomV249267('${escJs(id)}')">❤️ <span id="wisdom_like_${v249267DomId(id)}">${wisdomLikeCountV249267(id)}</span></button></div></div></section>`;
};
try{var feedProPanelV249267Base=feedProPanel}catch(e){var feedProPanelV249267Base=null}
feedProPanel=function(kind,index=0){
  injectV249267FixCss();
  if(kind==='wisdom'){
    const [who,quote]=(typeof philosopherWisdomV249232==='function')?philosopherWisdomV249232(index):['ΙΘΑΚΗ','Η καθαρή κουβέντα ανοίγει δρόμο εκεί που ο θόρυβος έκλεισε την πόρτα.'];
    const id='gold_wisdom_v249267_'+v249267DomId(String(index));
    const logo=`<div class="feedGoldLogo"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display='none'"></div><div class="feedGoldBrandText"><span class="okRainbow">OK</span> <small>ithaki</small></div>`;
    return `<article class="card feedGoldWisdomCard v249267Wisdom" data-feed-panel="${esc(id)}"><div class="feedGoldCardInner">${logo}<h3 class="feedGoldQuote">${esc(quote)}<small>${esc(who)} · σοφός λόγος</small></h3><div class="wisdomActionsV249267"><button onclick="ITH.openPostCommentsPanel('${escJs(id)}')">💬 <span>Σχόλια</span></button><button onclick="ITH.likeWisdomV249267('${escJs(id)}')">❤️ <span id="wisdom_like_${v249267DomId(id)}">${wisdomLikeCountV249267(id)}</span></button></div></div></article>`;
  }
  return feedProPanelV249267Base?feedProPanelV249267Base(kind,index):'';
};
openHostContact=function(){
  injectV249267FixCss();
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="hostPanelV249267">
    <div class="hostTopV249267"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🌊 ${uiText('Contact ITHAKI Host')}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div>
    <div class="hostBodyV249267">
      <div class="card"><p>${uiText('Write thoughts, observations or advice. The message stays internally in ITHAKI.')}</p><textarea id="hostMsg" style="width:100%;min-height:150px;resize:vertical" placeholder="${uiText('My message to ITHAKI Host...')}"></textarea><label class="card row" style="margin-top:10px"><input id="hostAnonymous" type="checkbox" checked><span>${uiText('Anonymous contact')}</span></label><button class="btn green" style="width:100%;margin-top:10px" onclick="ITH.sendHostMessage()">${uiText('Send to Host')}</button></div>
    </div>
  </div>`;
  try{setTimeout(ensureMenuScrollArrowsV249265,120)}catch(e){}
  return false;
};
function privacyScoreCalcV249267(id){
  let score=60, rows=[];
  const mode=(typeof notificationMode==='function'?notificationMode():'hybrid');
  const trust=typeof trustVerifiedV249262==='function'?trustVerifiedV249262(id):false;
  const companion=(typeof ithakiCompanionV249258==='function'?ithakiCompanionV249258():'athina');
  rows.push(['🔐','Κρυπτογραφημένη συνομιλία','ενεργή ένδειξη',18]); score+=18;
  rows.push(['🌐','Offline μετάφραση EL↔EN','τοπική λειτουργία όταν είναι διαθέσιμη',8]); score+=8;
  rows.push(['🚫','Καμία διαφήμιση μέσα στην ΙΘΑΚΗ','καθαρό UI',6]); score+=6;
  rows.push(['🔔','Ειδοποιήσεις FCM','λειτουργία: '+(typeof notificationModeText==='function'?notificationModeText(mode):mode),(mode==='open_only'?4:8)]); score+=(mode==='open_only'?4:8);
  rows.push([companion==='none'?'🔕':(companion==='sokratakis'?'🐢':'🦉'),'Τοπικός συνοδοιπόρος',companion==='none'?'ανενεργός':'χωρίς AI/server/βάση',companion==='none'?0:5]); score+=(companion==='none'?0:5);
  rows.push([trust?'✅':'⚠️','Trust mode επαφής',trust?'επαληθευμένη στη συσκευή':'δεν έχει επαληθευτεί ακόμη',trust?8:0]); score+=trust?8:0;
  score=Math.max(0,Math.min(100,score));
  return {score,rows,mode,trust,companion};
}
openPrivacyScoreV249262=function(peerId){
  injectV249262InnovationCss();injectV249267FixCss();
  const id=v249262ContextId(peerId), name=v249262ContextName(id), data=privacyScoreCalcV249267(id);
  window.__ithKeepMenuOpenUntilV249267=Date.now()+1200;
  const menu=$('memberMenu'); if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  const rowHtml=data.rows.map(r=>`<div><span>${r[0]}</span><b>${esc(r[1])}</b><small>${esc(r[2])} · +${r[3]}</small></div>`).join('');
  menu.innerHTML=`<div class="whyPanelV249262 privacyScoreV249262 privacyRealV249267 v249267KeepOpen" style="--privacy-width:${data.score}%">
    <div class="whyTopV249262"><button class="icon noAutoCloseV249265" onclick="openWhyIthakiV249262()">‹</button><b>🟢 Privacy score πραγματικό</b><button class="icon noAutoCloseV249265" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div>
    <div class="whyBodyV249262">
      <div class="onboardStepV249262">${v249262MascotHtml('small')}<div><h3>${esc(name)}</h3><p>Η βαθμολογία υπολογίζεται από τις ενεργές ρυθμίσεις αυτής της συσκευής και την κατάσταση trust αυτής της επαφής/δωματίου.</p></div></div>
      <div class="card privacyScoreV249262"><b>Privacy score: ${data.score} / 100</b><div class="privacyMeterV249262"><i></i></div><div class="date">Πραγματικός έλεγχος UI: encryption ένδειξη, offline μετάφραση, FCM επιλογή, mascot και trust mode.</div></div>
      <div class="privacyRowsV249262">${rowHtml}</div>
      <div class="privacyCalcNote">Δεν είναι διαφήμιση. Είναι καθαρή ένδειξη για το τι είναι ενεργό τώρα στην ΙΘΑΚΗ, στη συγκεκριμένη συσκευή.</div>
      <div class="row" style="gap:8px;flex-wrap:wrap"><button class="trustBtnV249262 noAutoCloseV249265" onclick="openTrustModeV249262('${escJs(id)}')">🤝 Άνοιγμα trust mode</button><button class="trustBtnV249262 noAutoCloseV249265" onclick="openNotificationSettingsV249238()">🔔 Ρυθμίσεις ειδοποιήσεων</button></div>
    </div>
  </div>`;
  try{setTimeout(ensureMenuScrollArrowsV249265,140)}catch(e){}
  return false;
};
try{var openTrustModeV249267Base=openTrustModeV249262}catch(e){var openTrustModeV249267Base=null}
openTrustModeV249262=function(peerId){
  window.__ithKeepMenuOpenUntilV249267=Date.now()+1200;
  return openTrustModeV249267Base?openTrustModeV249267Base(peerId):false;
};
try{var closeCurrentMenuAfterChoiceV249267Base=closeCurrentMenuAfterChoiceV249265}catch(e){var closeCurrentMenuAfterChoiceV249267Base=null}
closeCurrentMenuAfterChoiceV249265=function(menu){
  try{
    if(Date.now()<(window.__ithKeepMenuOpenUntilV249267||0))return;
    if(menu&&menu.querySelector&&menu.querySelector('.privacyRealV249267,.v249267KeepOpen'))return;
  }catch(e){}
  return closeCurrentMenuAfterChoiceV249267Base?closeCurrentMenuAfterChoiceV249267Base(menu):false;
};
ensureAthinaCompanionV249258=function(){
  injectAthinaV249258Css();injectV249267FixCss();
  try{
    document.getElementById('socratakiFabV249252')?.remove();
    document.getElementById('socratakiPanelV249252')?.remove();
    const c=ithakiCompanionV249258();
    let b=document.getElementById('athinaFabV249258');
    if(c==='none'){if(b)b.remove();return}
    if(!b){b=document.createElement('button');b.id='athinaFabV249258';b.type='button';b.onclick=()=>openNotificationSettingsV249238();document.body.appendChild(b)}
    b.classList.toggle('sokratakisFabV249267',c==='sokratakis');
    b.title=(c==='sokratakis'?'Bil':'Bil')+' - συνοδοιπόρος ειδοποιήσεων';
    b.setAttribute('aria-label',b.title);
    b.innerHTML=c==='sokratakis'?(typeof sokratakiTurtleV249252==='function'?sokratakiTurtleV249252('small'):'🐢'):athinaOwlV249258('small');
  }catch(e){}
};
function v249267CompanionDisplayName(){try{return ithakiCompanionV249258()==='sokratakis'?'Bil':'Bil'}catch{return 'Bil'}}
companionNoticeWelcomeV249258=function(){
  const c=ithakiCompanionV249258();if(c==='none')return'';
  const name=c==='sokratakis'?'Bil':'Bil';
  return `<div class="athinaCardV249258">${companionAvatarV249258()}<div class="athinaBubbleV249258"><b>${name}</b><div>Γεια σου, πώς είσαι σήμερα;</div><small>${name} θα σου δείχνει καθαρά μήνυμα, like, είσοδο φίλου και δημοσίευση. Τοπικά μόνο — χωρίς AI, χωρίς server, χωρίς βάση.</small></div></div>`;
};
try{var v249264NoticeLabelV249267Base=v249264NoticeLabel}catch(e){var v249264NoticeLabelV249267Base=null}
v249264NoticeLabel=function(n){
  const out=v249264NoticeLabelV249267Base?v249264NoticeLabelV249267Base(n):{title:'Γεια σου, πώς είσαι σήμερα;',body:'',action:'none',peer:''};
  if((!n||out.action==='none')&&String(out.body||'').includes('Bil')){
    const name=v249267CompanionDisplayName();
    out.body=name+' σε χαιρετά μία φορά και μετά κλείνει μόνη του.';
  }
  return out;
};
try{
  window.athinaOwlV249258=athinaOwlV249258;
  window.likeWisdomV249267=likeWisdomV249267;
  window.openPrivacyScoreV249262=openPrivacyScoreV249262;
  window.openTrustModeV249262=openTrustModeV249262;
  window.openHostContact=openHostContact;
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{likeWisdomV249267,openPrivacyScoreV249262,openTrustModeV249262,openHostContact});
  injectV249267FixCss();
  setTimeout(ensureAthinaCompanionV249258,600);
  setInterval(ensureAthinaCompanionV249258,9000);
}catch(e){}



/* V249268 - separate rooms/communities/member/pending screens, rules, moderator code, temp mute */
function injectV249268SpacesCss(){
  try{
    if(document.getElementById('ithV249268SpacesCss'))return;
    const st=document.createElement('style');
    st.id='ithV249268SpacesCss';
    st.textContent=`
      #spacesPage{overflow:auto!important;-webkit-overflow-scrolling:touch!important;padding-bottom:96px!important}
      .spacesShellV249268{display:grid;gap:12px;max-width:980px;margin:0 auto}
      .spacesTopV249268{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:8px;padding:8px 4px;background:linear-gradient(180deg,rgba(3,12,23,.96),rgba(3,12,23,.72));backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid rgba(255,255,255,.08)}
      .spacesTopV249268 b{color:#ffe39b;font-size:17px}.spacesTopV249268 .spacer{flex:1}
      .spacesHubGridV249268{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
      .spaceBigTileV249268{min-height:148px;text-align:left;border-radius:24px;padding:16px;border:1px solid rgba(255,217,110,.20);background:radial-gradient(circle at 20% 0%,rgba(255,217,110,.14),transparent 30%),linear-gradient(145deg,rgba(255,255,255,.075),rgba(255,255,255,.035));color:#fff;box-shadow:0 16px 42px rgba(0,0,0,.24)}
      .spaceBigTileV249268 b{display:block;font-size:20px;color:#ffe39b;margin-bottom:7px}.spaceBigTileV249268 span{display:block;color:rgba(239,248,255,.78);line-height:1.35}.spaceBigTileV249268 small{display:inline-flex;margin-top:12px;padding:5px 8px;border-radius:999px;background:rgba(255,255,255,.08);color:#fff}
      .spaceListV249268{display:grid;gap:10px}.spaceCardV249268{display:block;width:100%;text-align:left;border-radius:22px;padding:12px;border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.055);color:#fff}
      .spaceCardV249268 b{font-size:16px;color:#fff}.spaceCardV249268 p{margin:6px 0;color:rgba(239,248,255,.76);line-height:1.35}.spaceCardV249268 .row{margin-top:9px}
      .spaceBadgeV249268{display:inline-flex;align-items:center;gap:4px;border-radius:999px;padding:4px 8px;background:rgba(255,217,110,.10);border:1px solid rgba(255,217,110,.22);color:#ffe39b;font-size:12px;font-weight:900}
      .spaceChatV249268{display:grid;grid-template-rows:auto auto 1fr auto;gap:8px;height:calc(100dvh - 150px);min-height:520px}
      .spacePinnedV249268{border-radius:18px;padding:10px 12px;background:rgba(255,217,110,.09);border:1px solid rgba(255,217,110,.22);color:#fff}
      .spacePinnedV249268 b{color:#ffe39b}.spacePinnedV249268 p{margin:5px 0 0;color:rgba(239,248,255,.82);line-height:1.35}
      .spacePeopleGridV249268{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:9px}
      .memberCardV249268{display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:center;border-radius:20px;padding:10px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10);color:#fff;text-align:left}
      .memberCardV249268 .name{font-weight:1000}.memberCardV249268 .date{font-size:12px}.onlinePillV249268{display:inline-flex;align-items:center;gap:5px;border-radius:999px;padding:3px 7px;font-size:11px;font-weight:900}.onlinePillV249268.on{background:rgba(54,240,160,.12);color:#8df7c7;border:1px solid rgba(54,240,160,.22)}.onlinePillV249268.off{background:rgba(255,255,255,.07);color:rgba(239,248,255,.62);border:1px solid rgba(255,255,255,.10)}
      .pendingCardV249268{border-radius:20px;padding:12px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10)}
      .modPanelV249268{max-height:94dvh;overflow:auto;-webkit-overflow-scrolling:touch;border-radius:24px;background:linear-gradient(165deg,rgba(3,12,23,.98),rgba(8,18,31,.98));border:1px solid rgba(255,217,110,.24);padding:0}
      .modTopV249268{position:sticky;top:0;z-index:3;display:flex;gap:8px;align-items:center;padding:11px;background:rgba(3,12,23,.94);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}
      .modBodyV249268{padding:12px;display:grid;gap:10px}.modGridV249268{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}
      .mutedNoteV249268{padding:8px 10px;border-radius:14px;background:rgba(255,160,80,.10);border:1px solid rgba(255,160,80,.24);color:#ffd1a0;font-weight:900}
      @media(max-width:760px){.spacesHubGridV249268{grid-template-columns:1fr}.spaceChatV249268{height:calc(100dvh - 136px);min-height:430px}.modGridV249268{grid-template-columns:1fr}.spacesTopV249268{gap:6px}.spacesTopV249268 .btn{padding:8px 9px;font-size:12px}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function v249268PeopleArray(){
  try{
    const arr=[...state.people.values()].filter(p=>p&&p.id&&String(p.id)!==String(state.device));
    arr.sort((a,b)=>(b.online?1:0)-(a.online?1:0)||String(a.nickname||'').localeCompare(String(b.nickname||''),'el'));
    return arr;
  }catch{return[]}
}
function v249268SpaceIcon(s){return (s&&String(s.category||'room')==='community')?'🌐':'🏠'}
function v249268SpaceTitle(s){return (s&&String(s.title||'').trim())||'Space'}
function v249268RulesKey(id){return 'ith_space_rules_v249268_'+String(id||'')}
function v249268ModKey(id){return 'ith_space_mod_code_v249268_'+String(id||'')}
function v249268AdminKey(id){return 'ith_space_admin_code_v249268_'+String(id||'')}
function v249268MuteKey(id,member){return 'ith_space_mute_until_v249268_'+String(id||'')+'_'+String(member||'')}
function v249268Rules(id){try{return localStorage.getItem(v249268RulesKey(id))||''}catch{return''}}
function v249268SetRules(id,txt){try{localStorage.setItem(v249268RulesKey(id),String(txt||''))}catch{}}
function v249268IsMuted(id,member){try{return (+(localStorage.getItem(v249268MuteKey(id,member))||0)||0)>Date.now()}catch{return false}}
function v249268MuteLeft(id,member){try{const ms=(+(localStorage.getItem(v249268MuteKey(id,member))||0)||0)-Date.now();return ms>0?Math.ceil(ms/60000):0}catch{return 0}}
function v249268SetMute(id,member,minutes){try{localStorage.setItem(v249268MuteKey(id,member),String(Date.now()+(+minutes||15)*60000))}catch{}}
function v249268ClearMute(id,member){try{localStorage.removeItem(v249268MuteKey(id,member))}catch{}}
async function v249268FetchRooms(){
  try{
    const r=await fetchJson(`/api/rooms?room_id=${encodeURIComponent(state.room)}`);
    state.spaces=r.rooms||[];
    return state.spaces;
  }catch(e){
    state.spaces=state.spaces||[];
    return state.spaces;
  }
}
function v249268Top(title,back='hub'){
  const act=back==='home' ? "ITH.page('home')" : (back==='hub' ? 'ITH.openSpacesHubV249268()' : 'ITH.renderSpaces()');
  return `<div class="spacesTopV249268"><button class="icon" onclick="${act}">‹</button><b>${esc(title)}</b><span class="spacer"></span><button class="icon" onclick="ITH.openSpacesMembersV249268()">👥</button><button class="icon" onclick="ITH.openSpacesPendingV249268()">⏳</button><button class="icon" onclick="ITH.createSpaceCard()">＋</button></div>`;
}
async function renderSpaces(){if(window.__ITHAKI_R10F15_SINGLE_COMMUNITY_RUNTIME__)return __ithakiCanonicalSpacesR10F15();
  injectV249268SpacesCss();
  const e=$('spacesPage');if(!e)return;
  state.spaceScreen=state.spaceScreen||'hub';
  if(state.spaceScreen==='rooms'||state.spaceScreen==='communities')return openSpacesListV249268(state.spaceScreen);
  if(state.spaceScreen==='members')return openSpacesMembersV249268();
  if(state.spaceScreen==='pending')return openSpacesPendingV249268();
  if(state.spaceScreen==='chat'&&state.currentSpace)return renderSpaceChatV249268();
  return openSpacesHubV249268();
}
function openSpacesHubV249268(){
  injectV249268SpacesCss();
  state.spaceScreen='hub';
  const e=$('spacesPage');if(!e)return false;
  const pending=v249268PendingItems().length;
  const online=v249268PeopleArray().filter(p=>p.online).length;
  e.innerHTML=`<div class="spacesShellV249268">
    ${v249268Top('Δωμάτια / Κοινότητες','home')}
    <div class="spacesHubGridV249268">
      <button class="spaceBigTileV249268" onclick="ITH.openSpacesListV249268('rooms')"><b>🏠 Δωμάτια</b><span>Ιδιωτικοί ή ανοιχτοί χώροι συζήτησης με κανόνες και μέλη.</span><small>Άνοιγμα λίστας</small></button>
      <button class="spaceBigTileV249268" onclick="ITH.openSpacesListV249268('communities')"><b>🌐 Κοινότητες</b><span>Μεγαλύτεροι χώροι για θέματα, ενδιαφέροντα και ομάδες.</span><small>Άνοιγμα λίστας</small></button>
      <button class="spaceBigTileV249268" onclick="ITH.openSpacesMembersV249268()"><b>👥 Μέλη</b><span>Ξεχωριστή οθόνη με λίστα μελών και online status.</span><small>${online} online</small></button>
      <button class="spaceBigTileV249268" onclick="ITH.openSpacesPendingV249268()"><b>⏳ Εκκρεμή</b><span>Αιτήματα επαφών, εγκρίσεις και αιτήματα συμμετοχής σε κλειστούς χώρους.</span><small>${pending} σε αναμονή</small></button>
    </div>
    <div class="card"><b>📌 Βασική εμπιστοσύνη χώρων</b><div class="date">Καρφιτσωμένοι κανόνες, 2ος κωδικός συντονιστή, προσωρινό mute και λίστα αιτημάτων συμμετοχής για κλειστούς χώρους.</div></div>
  </div>`;
  return false;
}
async function openSpacesListV249268(kind='rooms'){
  injectV249268SpacesCss();
  state.spaceScreen=kind; state.spaceTab=kind==='communities'?'communities':'rooms';
  const e=$('spacesPage');if(!e)return false;
  e.innerHTML=`<div class="spacesShellV249268">${v249268Top(kind==='communities'?'Κοινότητες':'Δωμάτια','hub')}<div id="spaceListV249268" class="spaceListV249268"><div class="card">Φόρτωση...</div></div></div>`;
  await v249268FetchRooms();
  const want=kind==='communities'?'community':'room';
  let arr=(state.spaces||[]).filter(s=>(s.category||'room')===want);
  const list=$('spaceListV249268'); if(!list)return false;
  list.innerHTML=arr.map(s=>{
    const id=String(s.subroom_id||'');
    const closed=(s.access_type==='invite'||s.access_type==='private_code');
    const rules=v249268Rules(id)||s.description||'Δεν έχουν μπει ακόμη κανόνες.';
    return `<div class="spaceCardV249268">
      <button class="spaceCardV249268" onclick="ITH.openSpace('${esc(id)}')"><b>${v249268SpaceIcon(s)} ${esc(v249268SpaceTitle(s))}</b><p>${esc(rules).slice(0,160)}</p><span class="spaceBadgeV249268">${closed?'🔒 κλειστός χώρος':'🟢 ανοιχτός χώρος'}</span> <span class="spaceBadgeV249268">${esc(s.access_type||'public')}</span></button>
      <div class="row" style="gap:7px;flex-wrap:wrap"><button class="btn green" onclick="ITH.openSpace('${esc(id)}')">Άνοιγμα</button><button class="btn" onclick="ITH.openSpaceRulesV249268('${esc(id)}')">📌 Κανόνες</button><button class="btn" onclick="ITH.openSpaceMembersForV249268('${esc(id)}')">👥 Μέλη</button><button class="btn" onclick="ITH.requestJoinSpaceV249268('${esc(id)}')">⏳ Αίτημα</button><button class="btn" onclick="ITH.showSpaceCode('${esc(id)}')">▦ Code</button></div>
    </div>`;
  }).join('')||`<div class="card"><b>Δεν υπάρχουν ακόμη ${kind==='communities'?'κοινότητες':'δωμάτια'}.</b><div class="date">Πάτησε + για δημιουργία.</div></div>`;
  return false;
}
function openSpacesMembersV249268(){
  injectV249268SpacesCss();
  state.spaceScreen='members';
  const e=$('spacesPage');if(!e)return false;
  const arr=v249268PeopleArray();
  e.innerHTML=`<div class="spacesShellV249268">${v249268Top('Μέλη / online status','hub')}
    <div class="spacePeopleGridV249268">${arr.map(p=>`<div class="memberCardV249268">${avatarHtml(p)}<div><div class="name">${esc(p.nickname||'Μέλος')}</div><span class="onlinePillV249268 ${p.online?'on':'off'}">${p.online?'● online':'○ offline'}</span><div class="row" style="gap:6px;margin-top:7px;flex-wrap:wrap"><button class="btn" onclick="ITH.startDM('${esc(p.id)}')">💬 Μήνυμα</button><button class="btn" onclick="ITH.inviteContact('${esc(p.id)}')">🤝 Επαφή</button><button class="btn" onclick="ITH.inviteToSpace('${esc(state.currentSpace||'')}')">＋ Πρόσκληση</button></div></div></div>`).join('')||'<div class="card">Δεν φορτώθηκαν μέλη ακόμη.</div>'}</div>
  </div>`;
  return false;
}
function openSpaceMembersForV249268(spaceId){
  state.currentSpace=spaceId||state.currentSpace;
  return openSpacesMembersV249268();
}
function v249268PendingItems(){
  try{
    const ns=typeof localNotices==='function'?localNotices():[];
    return ns.filter(n=>!n.read && ['contact_invite','contact','friend_request','space_join_request','space_invite'].includes(String(n.type||'').toLowerCase()));
  }catch{return[]}
}
function openSpacesPendingV249268(){
  injectV249268SpacesCss();
  state.spaceScreen='pending';
  const e=$('spacesPage');if(!e)return false;
  const items=v249268PendingItems();
  e.innerHTML=`<div class="spacesShellV249268">${v249268Top('Εκκρεμείς επαφές / εγκρίσεις','hub')}
    <div class="spaceListV249268">${items.map((n,i)=>v249268PendingCard(n,i)).join('')||'<div class="card"><b>Δεν υπάρχουν εκκρεμή.</b><div class="date">Εδώ θα εμφανίζονται προτάσεις φιλίας και αιτήματα συμμετοχής σε κλειστούς χώρους.</div></div>'}</div>
  </div>`;
  return false;
}
function v249268PendingCard(n,i){
  const type=String(n.type||'').toLowerCase();
  const peer=n.from_id||n.to_id||n.member_id||'';
  const name=n.from_name||n.to_name||n.nickname||peer||'Μέλος';
  const space=n.subroom_id||n.space_id||'';
  if(type==='space_join_request')return `<div class="pendingCardV249268"><b>⏳ Αίτημα συμμετοχής</b><div class="date">${esc(name)} · ${esc(space)}</div><p>${esc(n.text||'Ζητά συμμετοχή σε κλειστό χώρο.')}</p><div class="row"><button class="btn green" onclick="ITH.approveSpaceJoinV249268('${escJs(n.id||'')}','${escJs(peer)}','${escJs(space)}')">Έγκριση</button><button class="btn" onclick="ITH.rejectSpaceJoinV249268('${escJs(n.id||'')}')">Απόρριψη</button></div></div>`;
  if(type==='space_invite')return `<div class="pendingCardV249268"><b>＋ Πρόσκληση χώρου</b><div class="date">${esc(name)}</div><p>${esc(n.text||'Πρόσκληση για χώρο.')}</p><button class="btn green" onclick="ITH.openSpacesListV249268('rooms')">Άνοιγμα χώρων</button></div>`;
  return `<div class="pendingCardV249268"><b>🤝 Πρόταση φιλίας</b><div class="date">${esc(name)}</div><p>${esc(n.text||'Εκκρεμεί αποδοχή επαφής.')}</p><div class="row"><button class="btn green" onclick="ITH.acceptContact('${escJs(peer)}');ITH.openSpacesPendingV249268()">Αποδοχή</button><button class="btn" onclick="ITH.rejectContact('${escJs(peer)}');ITH.openSpacesPendingV249268()">Απόρριψη</button></div></div>`;
}
function requestJoinSpaceV249268(subroom_id){
  try{
    const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(subroom_id))||{};
    addNotice({type:'space_join_request',from_id:state.device,from_name:state.name,subroom_id,space_id:subroom_id,text:`${state.name} ζητά συμμετοχή στον χώρο ${v249268SpaceTitle(s)}.`});
    toast('Στάλθηκε αίτημα συμμετοχής.');
  }catch(e){toast('Το αίτημα έμεινε τοπικά.')}
  return false;
}
function approveSpaceJoinV249268(noticeId,peer,space){
  try{
    saveNotices(localNotices().map(n=>String(n.id)===String(noticeId)?Object.assign({},n,{read:true,status:'approved'}):n));
    addNotice({type:'space_join_approved',from_id:state.device,to_id:peer,subroom_id:space,text:'Εγκρίθηκε η συμμετοχή σου στον χώρο.'});
  }catch(e){}
  toast('Εγκρίθηκε.');
  openSpacesPendingV249268();
  return false;
}
function rejectSpaceJoinV249268(noticeId){
  try{saveNotices(localNotices().map(n=>String(n.id)===String(noticeId)?Object.assign({},n,{read:true,status:'rejected'}):n))}catch(e){}
  toast('Απορρίφθηκε.');
  openSpacesPendingV249268();
  return false;
}
async function renderSpaceChatV249268(){
  injectV249268SpacesCss();
  const e=$('spacesPage');if(!e)return false;
  const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(state.currentSpace))||{};
  const id=String(state.currentSpace||'');
  const rules=v249268Rules(id)||s.description||'Καλωσόρισες. Μίλα καθαρά, με σεβασμό και χωρίς spam.';
  const muted=v249268IsMuted(id,state.device);
  e.innerHTML=`<div class="spacesShellV249268">
    ${v249268Top(v249268SpaceTitle(s),'rooms')}
    <div class="spaceChatV249268">
      <div class="spacePinnedV249268"><b>📌 Κανόνες / καρφιτσωμένο</b><p>${esc(rules)}</p></div>
      <div class="chatHead"><button class="icon" onclick="ITH.openSpacesListV249268('${(s.category||'room')==='community'?'communities':'rooms'}')">‹</button><b id="spaceTitle">${esc(v249268SpaceTitle(s))}</b><button class="icon chatActionBtn" onclick="ITH.openSpaceMedia('photo',true)">📷</button><button class="icon chatActionBtn" onclick="ITH.openSpaceMedia('video',true)">🎥</button><button class="icon" onclick="ITH.openSpaceMedia('file',false)">📎</button><button class="icon" onclick="ITH.openSpaceAdmin()">⚙️</button></div>
      <div id="spaceMsgs" class="messages"><div class="card">Φόρτωση...</div></div>
      <div>${muted?`<div class="mutedNoteV249268">🔇 Προσωρινό mute · απομένουν ${v249268MuteLeft(id,state.device)} λεπτά</div>`:''}<div class="composer"><textarea id="spaceInput" ${muted?'disabled':''} placeholder="${muted?'Έχεις προσωρινό mute.':'Message this space...'}"></textarea><button class="icon" onclick="ITH.sendSpaceText()">➤</button></div></div>
    </div>
  </div>`;
  await loadSpaceMessages(true);
  return false;
}
async function openSpace(id){
  injectV249268SpacesCss();
  const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(id))||{};
  const nextChannel='space:'+id;
  try{
    let join_code='';
    if(s.access_type==='private_code')join_code=prompt('Member code:')||'';
    await fetchJson('/api/rooms/join',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:id,device_id:state.device,nickname:state.name,join_code})});
  }catch(e){
    if(s.access_type==='invite'||s.access_type==='private_code'){
      const ask=confirm('Ο χώρος είναι κλειστός. Να σταλεί αίτημα συμμετοχής;');
      if(ask)return requestJoinSpaceV249268(id);
    }
    return toast('Correct code or approval required');
  }
  state.currentSpace=id; state.currentSpaceChannel=nextChannel; state.spaceScreen='chat';
  wsSubscribe(state.currentSpaceChannel);
  await renderSpaceChatV249268();
  return false;
}
async function sendSpaceText(){
  const i=$('spaceInput');const txt=(i?.value||'').trim();
  if(!state.currentSpaceChannel)return toast('Choose a space');
  if(v249268IsMuted(state.currentSpace,state.device))return toast('Έχεις προσωρινό mute στον χώρο.');
  if(!txt)return;
  i.value='';
  await sendMessagePayload(state.currentSpaceChannel,txt);
  if(!state.wsReady)loadSpaceMessages();
}
function openSpaceRulesV249268(spaceId){
  injectV249268SpacesCss();
  const id=spaceId||state.currentSpace;if(!id)return toast('Διάλεξε χώρο.');
  const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(id))||{};
  const current=v249268Rules(id)||s.description||'';
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="modPanelV249268"><div class="modTopV249268"><button class="icon" onclick="ITH.closeMember()">‹</button><b>📌 Κανόνες / καρφιτσωμένο</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="modBodyV249268"><div class="card"><b>${esc(v249268SpaceTitle(s))}</b><textarea id="spaceRulesInputV249268" style="width:100%;min-height:150px;margin-top:8px" placeholder="Κανόνες χώρου...">${esc(current)}</textarea><button class="btn green" style="width:100%;margin-top:10px" onclick="ITH.saveSpaceRulesV249268('${escJs(id)}')">Αποθήκευση καρφιτσωμένου</button></div></div></div>`;
  return false;
}
function saveSpaceRulesV249268(id){
  const txt=($('spaceRulesInputV249268')?.value||'').trim();
  v249268SetRules(id,txt);
  toast('Αποθηκεύτηκαν οι κανόνες.');
  $('memberMenu')?.classList.remove('show');
  if(state.currentSpace===id)renderSpaceChatV249268();
  return false;
}
function createSpaceCard(prefill=''){
  injectV249268SpacesCss();
  const kind=state.spaceTab==='communities'?'community':'room';
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="modPanelV249268"><div class="modTopV249268"><b>＋ Νέο ${kind==='community'?'community':'δωμάτιο'}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="modBodyV249268">
    <div class="card"><label>Τίτλος</label><input id="newSpaceTitle" style="width:100%" value="${esc(prefill)}" placeholder="Τίτλος"><label>Κανόνες / καρφιτσωμένο μήνυμα</label><textarea id="newSpaceDesc" style="width:100%;min-height:90px" placeholder="Κανόνες χώρου"></textarea><label>Πρόσβαση</label><select id="newSpaceAccess" style="width:100%"><option value="public">Ανοιχτό</option><option value="invite">Με έγκριση</option><option value="private_code">Με κωδικό μέλους</option></select><label>Κωδικός μέλους</label><input id="newSpaceCode" style="width:100%" placeholder="π.χ. ITHAKI-2026"><label>Κωδικός owner/admin</label><input id="newAdminCode" style="width:100%" placeholder="κύριος κωδικός"><label>2ος κωδικός συντονιστή</label><input id="newModCode" style="width:100%" placeholder="moderator code"><div class="row" style="margin-top:10px"><button class="btn green" onclick="ITH.createRoomUIFromCard()">Δημιουργία</button><button class="btn" onclick="ITH.showQR()">▦ Code/QR</button></div></div>
  </div></div>`;
  return false;
}
async function createRoomUIFromCard(){
  const title=($('newSpaceTitle')?.value||'').trim();if(!title)return toast('Enter a title');
  const access=$('newSpaceAccess')?.value||'public';
  const join_code=($('newSpaceCode')?.value||'').trim();
  const owner_secret=($('newAdminCode')?.value||'').trim()||('admin-'+state.device);
  const mod_code=($('newModCode')?.value||'').trim();
  const rules=($('newSpaceDesc')?.value||'').trim();
  try{
    const res=await fetchJson('/api/rooms/create',{method:'POST',body:JSON.stringify({room_id:state.room,owner_id:state.device,title,description:rules,category:state.spaceTab==='communities'?'community':'room',access_type:access,join_code,owner_secret})});
    const sub=res.subroom_id||res.id||res.room_id||'';
    if(sub){v249268SetRules(sub,rules);try{localStorage.setItem(v249268AdminKey(sub),owner_secret);if(mod_code)localStorage.setItem(v249268ModKey(sub),mod_code)}catch(e){}}
    toast('Created');
    $('memberMenu')?.classList.remove('show');
    await v249268FetchRooms();
    openSpacesListV249268(state.spaceTab==='communities'?'communities':'rooms');
  }catch(e){toast('Not created')}
}
function openSpaceAdmin(){
  injectV249268SpacesCss();
  if(!state.currentSpace)return toast('Choose a space');
  const id=state.currentSpace;
  const entered=prompt('Admin ή 2ος κωδικός συντονιστή:');
  if(!entered)return false;
  const savedAdmin=localStorage.getItem(v249268AdminKey(id))||'';
  const savedMod=localStorage.getItem(v249268ModKey(id))||'';
  const role=(entered===savedAdmin||!savedAdmin)?'owner':(entered===savedMod?'moderator':'');
  if(!role)return toast('Λάθος κωδικός.');
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="modPanelV249268"><div class="modTopV249268"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔐 Διαχείριση χώρου · ${role==='owner'?'Owner':'Συντονιστής'}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="modBodyV249268">
    <div class="modGridV249268">
      <button class="tile" onclick="ITH.openSpaceMembersForV249268('${esc(id)}');ITH.closeMember()"><b>👥</b>Λίστα μελών / online</button>
      <button class="tile" onclick="ITH.openSpaceRulesV249268('${esc(id)}')"><b>📌</b>Κανόνες / καρφιτσωμένο</button>
      <button class="tile" onclick="ITH.openSpacesPendingV249268();ITH.closeMember()"><b>⏳</b>Εκκρεμή αιτήματα</button>
      <button class="tile" onclick="ITH.adminTempMuteV249268()"><b>🔇</b>Προσωρινό mute</button>
      <button class="tile" onclick="ITH.adminMessageMember()"><b>💬</b>Μήνυμα σε μέλος</button>
      <button class="tile" onclick="ITH.adminMessageSpace()"><b>📣</b>Μήνυμα στον χώρο</button>
      <button class="tile" onclick="ITH.showSpaceCode('${esc(id)}')"><b>▦</b>Κωδικός / QR</button>
      ${role==='owner'?`<button class="tile" onclick="ITH.setModeratorCodeV249268()"><b>🔑</b>2ος κωδικός συντονιστή</button>`:''}
    </div>
  </div></div>`;
  return false;
}
function setModeratorCodeV249268(){
  if(!state.currentSpace)return false;
  const code=prompt('Νέος 2ος κωδικός συντονιστή:');
  if(!code)return false;
  try{localStorage.setItem(v249268ModKey(state.currentSpace),code)}catch(e){}
  toast('Αποθηκεύτηκε 2ος κωδικός συντονιστή.');
  return false;
}
function adminTempMuteV249268(){
  if(!state.currentSpace)return toast('Choose a space');
  const id=prompt('Member code για mute:');
  if(!id)return false;
  const min=+(prompt('Λεπτά mute:', '15')||15)||15;
  v249268SetMute(state.currentSpace,id,min);
  toast('Προσωρινό mute για '+min+' λεπτά.');
  return false;
}
function spaceTab(tab){state.spaceTab=tab;return openSpacesListV249268(tab==='communities'?'communities':'rooms')}
async function loadRooms(){await v249268FetchRooms();try{if(state.spaceScreen==='rooms'||state.spaceScreen==='communities')openSpacesListV249268(state.spaceScreen)}catch(e){}}
try{
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{renderSpaces,openSpacesHubV249268,openSpacesListV249268,openSpacesMembersV249268,openSpaceMembersForV249268,openSpacesPendingV249268,requestJoinSpaceV249268,approveSpaceJoinV249268,rejectSpaceJoinV249268,renderSpaceChatV249268,openSpace,sendSpaceText,openSpaceRulesV249268,saveSpaceRulesV249268,createSpaceCard,createRoomUIFromCard,openSpaceAdmin,setModeratorCodeV249268,adminTempMuteV249268,spaceTab,loadRooms});
  injectV249268SpacesCss();
}catch(e){}



/* V249269 - unified professional UI, message search, discovery/sort, announcements channel */
function injectV249269UnifiedCss(){
  try{
    if(document.getElementById('ithV249269UnifiedCss'))return;
    const st=document.createElement('style');
    st.id='ithV249269UnifiedCss';
    st.textContent=`
      :root{--ithGold:#ffe39b;--ithSky:#7fd7ff;--ithCard:rgba(255,255,255,.065);--ithLine:rgba(255,255,255,.12)}
      .spacesShellV249268,.dmContactFirstShellV249235,.whyPanelV249262,.v249263NotifyPanel,.v249264NotifyPanel,.v249238NotifyPanel,.modPanelV249268,.hostPanelV249267{font-family:inherit}
      .spacesTopV249268,.chatHead,.modTopV249268,.hostTopV249267{background:linear-gradient(180deg,rgba(5,18,31,.96),rgba(5,18,31,.76))!important;border-bottom:1px solid rgba(255,217,110,.14)!important}
      .spaceBigTileV249268,.spaceCardV249268,.memberCardV249268,.pendingCardV249268,.spacePinnedV249268,.announceCardV249269,.searchPanelV249269 .card,.discoveryBarV249269{box-shadow:0 14px 38px rgba(0,0,0,.24)!important;border-color:rgba(255,217,110,.16)!important}
      .professionalBtnV249269,.discoveryBarV249269 button,.searchPanelV249269 button{border-radius:999px!important;border:1px solid rgba(255,217,110,.26)!important;background:linear-gradient(135deg,rgba(255,217,110,.16),rgba(127,215,255,.08))!important;color:#fff!important;font-weight:1000!important}
      .discoveryBarV249269{display:grid;grid-template-columns:1fr auto auto;gap:8px;align-items:center;border-radius:22px;padding:10px;background:rgba(255,255,255,.055);border:1px solid var(--ithLine)}
      .discoveryBarV249269 input,.discoveryBarV249269 select,.searchPanelV249269 input,.announceComposerV249269 textarea{width:100%;border-radius:16px;border:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.20);color:#fff;padding:10px;box-sizing:border-box}
      .discoveryHintV249269{display:flex;gap:7px;flex-wrap:wrap;margin-top:8px}.discoveryHintV249269 span{border-radius:999px;padding:5px 8px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.10);color:rgba(239,248,255,.80);font-size:12px}
      .announceStripV249269{border-radius:18px;padding:10px 12px;background:linear-gradient(135deg,rgba(127,215,255,.11),rgba(255,217,110,.08));border:1px solid rgba(127,215,255,.18);color:#fff}
      .announceStripV249269 b{color:var(--ithGold)}.announceStripV249269 p{margin:5px 0 0;color:rgba(239,248,255,.82);line-height:1.35}
      .announceListV249269{display:grid;gap:9px}.announceCardV249269{border-radius:18px;padding:11px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.11)}.announceCardV249269 b{color:var(--ithGold)}.announceCardV249269 p{margin:6px 0;color:rgba(239,248,255,.84);line-height:1.38}
      .searchPanelV249269{max-height:94dvh;overflow:auto;-webkit-overflow-scrolling:touch;border-radius:24px;background:linear-gradient(165deg,rgba(3,12,23,.98),rgba(8,18,31,.98));border:1px solid rgba(255,217,110,.24);padding:0}
      .searchTopV249269{position:sticky;top:0;z-index:4;display:flex;gap:8px;align-items:center;padding:11px;background:rgba(3,12,23,.94);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}
      .searchBodyV249269{padding:12px;display:grid;gap:10px}.searchResultV249269{border-radius:18px;padding:10px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10)}.searchResultV249269 mark{background:rgba(255,217,110,.32);color:#fff;border-radius:5px;padding:0 2px}
      .spaceStatRowV249269{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}.spaceStatRowV249269 span{font-size:12px;border-radius:999px;padding:4px 7px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.09);color:rgba(239,248,255,.78)}
      .spacesTopV249268 .icon,.chatHead .icon{border:1px solid rgba(255,217,110,.16)!important;background:rgba(255,255,255,.055)!important}
      @media(max-width:760px){.discoveryBarV249269{grid-template-columns:1fr}.discoveryBarV249269 button,.discoveryBarV249269 select{width:100%}.spacesTopV249268{overflow-x:auto}.spacesTopV249268 b{white-space:nowrap}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function v249269AnnKey(id){return 'ith_space_announcements_v249269_'+String(id||'')}
function v249269Announcements(id){try{return JSON.parse(localStorage.getItem(v249269AnnKey(id))||'[]')||[]}catch{return[]}}
function v249269SaveAnnouncements(id,arr){try{localStorage.setItem(v249269AnnKey(id),JSON.stringify((arr||[]).slice(-50)))}catch{}}
function v249269LastAnnouncement(id){const a=v249269Announcements(id);return a.length?a[a.length-1]:null}
function v249269SpaceScore(s){
  let score=0;
  try{
    const id=String(s.subroom_id||'');
    if((s.access_type||'public')==='public')score+=5; else score+=8;
    if(v249268Rules(id))score+=12;
    if(v249269Announcements(id).length)score+=10;
    score+=String(s.title||'').length%9;
  }catch(e){}
  return score;
}
function v249269SortSpaces(arr,mode){
  arr=[...(arr||[])];
  if(mode==='name')arr.sort((a,b)=>String(a.title||'').localeCompare(String(b.title||''),'el'));
  else if(mode==='closed')arr.sort((a,b)=>((b.access_type!=='public')?1:0)-((a.access_type!=='public')?1:0)||v249269SpaceScore(b)-v249269SpaceScore(a));
  else if(mode==='rules')arr.sort((a,b)=>(v249268Rules(b.subroom_id)?1:0)-(v249268Rules(a.subroom_id)?1:0)||v249269SpaceScore(b)-v249269SpaceScore(a));
  else arr.sort((a,b)=>v249269SpaceScore(b)-v249269SpaceScore(a)||String(a.title||'').localeCompare(String(b.title||''),'el'));
  return arr;
}
async function openSpacesListV249268(kind='rooms'){
  injectV249268SpacesCss();injectV249269UnifiedCss();
  state.spaceScreen=kind; state.spaceTab=kind==='communities'?'communities':'rooms';
  const e=$('spacesPage');if(!e)return false;
  const qkey='ith_space_search_v249269_'+kind, skey='ith_space_sort_v249269_'+kind;
  const q=localStorage.getItem(qkey)||'', sort=localStorage.getItem(skey)||'discover';
  e.innerHTML=`<div class="spacesShellV249268">${v249268Top(kind==='communities'?'Κοινότητες':'Δωμάτια','hub')}
    <div class="discoveryBarV249269">
      <input id="spaceSearchV249269" value="${esc(q)}" placeholder="Αναζήτηση / ανακάλυψη ${kind==='communities'?'κοινότητας':'δωματίου'}...">
      <select id="spaceSortV249269"><option value="discover">Ανακάλυψη</option><option value="name">Αλφαβητικά</option><option value="closed">Κλειστοί χώροι πρώτα</option><option value="rules">Με κανόνες πρώτα</option></select>
      <button onclick="ITH.refreshSpacesDiscoveryV249269('${escJs(kind)}')">🔎 Εφαρμογή</button>
    </div>
    <div class="discoveryHintV249269"><span>Λίστα με κανόνες</span><span>Online εμπιστοσύνη</span><span>Κλειστοί χώροι</span><span>Ανακοινώσεις</span></div>
    <div id="spaceListV249268" class="spaceListV249268"><div class="card">Φόρτωση...</div></div>
  </div>`;
  const sel=$('spaceSortV249269');if(sel)sel.value=sort;
  const inp=$('spaceSearchV249269');if(inp)inp.oninput=()=>{try{localStorage.setItem(qkey,inp.value||'');clearTimeout(window.__spaceSearchTimerV249269);window.__spaceSearchTimerV249269=setTimeout(()=>openSpacesListV249268(kind),240)}catch(e){}};
  if(sel)sel.onchange=()=>{try{localStorage.setItem(skey,sel.value||'discover');openSpacesListV249268(kind)}catch(e){}};
  await v249268FetchRooms();
  const want=kind==='communities'?'community':'room';
  let arr=(state.spaces||[]).filter(s=>(s.category||'room')===want);
  const query=String(localStorage.getItem(qkey)||'').toLowerCase().trim();
  if(query)arr=arr.filter(s=>String(s.title||'').toLowerCase().includes(query)||String(s.description||'').toLowerCase().includes(query)||String(v249268Rules(s.subroom_id)||'').toLowerCase().includes(query)||String(s.access_type||'').toLowerCase().includes(query));
  arr=v249269SortSpaces(arr,localStorage.getItem(skey)||'discover');
  const list=$('spaceListV249268'); if(!list)return false;
  list.innerHTML=arr.map(s=>{
    const id=String(s.subroom_id||'');
    const closed=(s.access_type==='invite'||s.access_type==='private_code');
    const rules=v249268Rules(id)||s.description||'Δεν έχουν μπει ακόμη κανόνες.';
    const ann=v249269LastAnnouncement(id);
    return `<div class="spaceCardV249268">
      <button class="spaceCardV249268" onclick="ITH.openSpace('${esc(id)}')"><b>${v249268SpaceIcon(s)} ${esc(v249268SpaceTitle(s))}</b><p>${esc(rules).slice(0,170)}</p>${ann?`<div class="announceStripV249269"><b>📣 Τελευταία ανακοίνωση</b><p>${esc(ann.text).slice(0,130)}</p></div>`:''}<span class="spaceBadgeV249268">${closed?'🔒 κλειστός χώρος':'🟢 ανοιχτός χώρος'}</span> <span class="spaceBadgeV249268">${esc(s.access_type||'public')}</span><div class="spaceStatRowV249269"><span>Score ${v249269SpaceScore(s)}</span><span>${v249269Announcements(id).length} ανακοινώσεις</span><span>${v249268Rules(id)?'κανόνες OK':'χωρίς κανόνες'}</span></div></button>
      <div class="row" style="gap:7px;flex-wrap:wrap"><button class="btn green" onclick="ITH.openSpace('${esc(id)}')">Άνοιγμα</button><button class="btn" onclick="ITH.openSpaceRulesV249268('${esc(id)}')">📌 Κανόνες</button><button class="btn" onclick="ITH.openSpaceAnnouncementsV249269('${esc(id)}')">📣 Ανακοινώσεις</button><button class="btn" onclick="ITH.openSpaceMembersForV249268('${esc(id)}')">👥 Μέλη</button><button class="btn" onclick="ITH.requestJoinSpaceV249268('${esc(id)}')">⏳ Αίτημα</button><button class="btn" onclick="ITH.showSpaceCode('${esc(id)}')">▦ Code</button></div>
    </div>`;
  }).join('')||`<div class="card"><b>Δεν βρέθηκε αποτέλεσμα.</b><div class="date">Άλλαξε αναζήτηση ή πάτησε + για νέο χώρο.</div></div>`;
  return false;
}
function refreshSpacesDiscoveryV249269(kind){
  try{
    const q=$('spaceSearchV249269')?.value||'', s=$('spaceSortV249269')?.value||'discover';
    localStorage.setItem('ith_space_search_v249269_'+kind,q);
    localStorage.setItem('ith_space_sort_v249269_'+kind,s);
  }catch(e){}
  return openSpacesListV249268(kind);
}
function v249269CurrentChannel(){
  if(state.page==='dm'&&state.activeChannel)return state.activeChannel;
  if(state.page==='spaces'&&state.currentSpaceChannel)return state.currentSpaceChannel;
  return state.activeChannel||state.currentSpaceChannel||'';
}
function v249269MessageBoxForChannel(){
  if(state.page==='spaces')return $('spaceMsgs');
  return $('messages');
}
function v249269Highlight(text,q){
  text=String(text||''); q=String(q||'').trim();
  if(!q)return esc(text);
  try{
    const safe=q.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');
    return esc(text).replace(new RegExp(safe,'ig'),m=>`<mark>${esc(m)}</mark>`);
  }catch{return esc(text)}
}
async function openMessageSearchV249269(){
  injectV249269UnifiedCss();
  const channel=v249269CurrentChannel();
  if(!channel)return toast('Διάλεξε συνομιλία ή χώρο πρώτα.');
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="searchPanelV249269"><div class="searchTopV249269"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔎 Αναζήτηση μηνυμάτων</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="searchBodyV249269"><input id="messageSearchInputV249269" placeholder="Γράψε λέξη, όνομα ή φράση..."><div id="messageSearchResultsV249269" class="searchResultsV249269"><div class="card">Φόρτωση μηνυμάτων...</div></div></div></div>`;
  let items=[];
  try{
    const r=await fetchJson(`/api/messages?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent(channel)}&since=0&limit=500`);
    items=uniqueMessages(r.messages||[]);
  }catch(e){
    const box=v249269MessageBoxForChannel();
    items=[...(box?box.querySelectorAll('.bubble'):[])].map((el,i)=>({message_id:'dom_'+i,nickname:el.querySelector('b')?.textContent||'',text:el.querySelector('.msgBody')?.textContent||'',created_at:+(el.dataset.ts||0)||Date.now()}));
  }
  const render=()=>{
    const q=($('messageSearchInputV249269')?.value||'').toLowerCase().trim();
    const res=items.filter(m=>{
      const t=parseText(m.text||'').body||m.text||'';
      return !q||String(t).toLowerCase().includes(q)||String(m.nickname||'').toLowerCase().includes(q)||String(m.sender_id||'').toLowerCase().includes(q);
    }).slice(-120).reverse();
    const box=$('messageSearchResultsV249269');if(!box)return;
    box.innerHTML=res.map(m=>{const body=parseText(m.text||'').body||m.text||'';return `<div class="searchResultV249269"><b>${esc(m.nickname||m.sender_id||'Μέλος')}</b><div class="date">${fmt(m.created_at)}</div><p>${v249269Highlight(body,q)}</p></div>`}).join('')||'<div class="card">Δεν βρέθηκε μήνυμα.</div>';
  };
  const input=$('messageSearchInputV249269');if(input){input.oninput=render;setTimeout(()=>input.focus(),80)}
  render();
  return false;
}
function openSpaceAnnouncementsV249269(spaceId){
  injectV249269UnifiedCss();
  const id=spaceId||state.currentSpace;if(!id)return toast('Διάλεξε χώρο.');
  const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(id))||{};
  const arr=v249269Announcements(id).slice().reverse();
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="searchPanelV249269"><div class="searchTopV249269"><button class="icon" onclick="ITH.closeMember()">‹</button><b>📣 Κανάλι ανακοινώσεων</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="searchBodyV249269">
    <div class="announceStripV249269"><b>${esc(v249268SpaceTitle(s))}</b><p>Οι ανακοινώσεις φαίνονται καθαρά στον χώρο και μένουν τοπικά στη συσκευή μέχρι να μπει πλήρης server πίνακας ανακοινώσεων.</p></div>
    <div class="announceComposerV249269"><textarea id="announceTextV249269" placeholder="Νέα ανακοίνωση..."></textarea><button class="professionalBtnV249269" style="width:100%;margin-top:8px" onclick="ITH.sendSpaceAnnouncementV249269('${escJs(id)}')">📣 Δημοσίευση ανακοίνωσης</button></div>
    <div class="announceListV249269">${arr.map(a=>`<div class="announceCardV249269"><b>${esc(a.from||'ΙΘΑΚΗ')}</b><div class="date">${fmt(a.created_at)}</div><p>${esc(a.text)}</p></div>`).join('')||'<div class="card">Δεν υπάρχουν ανακοινώσεις ακόμη.</div>'}</div>
  </div></div>`;
  return false;
}
async function sendSpaceAnnouncementV249269(spaceId){
  const id=spaceId||state.currentSpace;
  const txt=($('announceTextV249269')?.value||'').trim();
  if(!id||!txt)return toast('Γράψε ανακοίνωση.');
  const arr=v249269Announcements(id);
  const item={id:'ann_'+Date.now(),text:txt,from:state.name||'ΙΘΑΚΗ',created_at:Date.now()};
  arr.push(item);v249269SaveAnnouncements(id,arr);
  try{
    const ch='space:'+id;
    await sendMessagePayload(ch,'📣 ΑΝΑΚΟΙΝΩΣΗ\\n'+txt);
  }catch(e){}
  toast('Δημοσιεύτηκε ανακοίνωση.');
  openSpaceAnnouncementsV249269(id);
  if(state.currentSpace===id&&state.page==='spaces')renderSpaceChatV249268();
  return false;
}
async function renderSpaceChatV249268(){
  injectV249268SpacesCss();injectV249269UnifiedCss();
  const e=$('spacesPage');if(!e)return false;
  const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(state.currentSpace))||{};
  const id=String(state.currentSpace||'');
  const rules=v249268Rules(id)||s.description||'Καλωσόρισες. Μίλα καθαρά, με σεβασμό και χωρίς spam.';
  const ann=v249269LastAnnouncement(id);
  const muted=v249268IsMuted(id,state.device);
  e.innerHTML=`<div class="spacesShellV249268">
    ${v249268Top(v249268SpaceTitle(s),'rooms')}
    <div class="spaceChatV249268">
      <div class="spacePinnedV249268"><b>📌 Κανόνες / καρφιτσωμένο</b><p>${esc(rules)}</p></div>
      ${ann?`<div class="announceStripV249269"><b>📣 Τελευταία ανακοίνωση</b><p>${esc(ann.text)}</p></div>`:''}
      <div class="chatHead"><button class="icon" onclick="ITH.openSpacesListV249268('${(s.category||'room')==='community'?'communities':'rooms'}')">‹</button><b id="spaceTitle">${esc(v249268SpaceTitle(s))}</b><button class="icon" title="Αναζήτηση μηνυμάτων" onclick="ITH.openMessageSearchV249269()">🔎</button><button class="icon" title="Ανακοινώσεις" onclick="ITH.openSpaceAnnouncementsV249269('${escJs(id)}')">📣</button><button class="icon chatActionBtn" onclick="ITH.openSpaceMedia('photo',true)">📷</button><button class="icon chatActionBtn" onclick="ITH.openSpaceMedia('video',true)">🎥</button><button class="icon" onclick="ITH.openSpaceMedia('file',false)">📎</button><button class="icon" onclick="ITH.openSpaceAdmin()">⚙️</button></div>
      <div id="spaceMsgs" class="messages"><div class="card">Φόρτωση...</div></div>
      <div>${muted?`<div class="mutedNoteV249268">🔇 Προσωρινό mute · απομένουν ${v249268MuteLeft(id,state.device)} λεπτά</div>`:''}<div class="composer"><textarea id="spaceInput" ${muted?'disabled':''} placeholder="${muted?'Έχεις προσωρινό mute.':'Message this space...'}"></textarea><button class="icon" onclick="ITH.sendSpaceText()">➤</button></div></div>
    </div>
  </div>`;
  await loadSpaceMessages(true);
  return false;
}
try{var openDMV249269Base=openDMV249235||null}catch(e){var openDMV249269Base=null}
openDMV249235=function(){
  const r=openDMV249269Base?openDMV249269Base.apply(this,arguments):false;
  setTimeout(()=>{try{injectV249269UnifiedCss();const head=document.querySelector('#dmChatScreen .chatHead');if(head&&!document.getElementById('dmSearchBtnV249269')){const btn=document.createElement('button');btn.id='dmSearchBtnV249269';btn.className='icon chatActionBtn';btn.title='Αναζήτηση μηνυμάτων';btn.textContent='🔎';btn.onclick=()=>openMessageSearchV249269();const more=head.querySelector('button[onclick*="memberActive"]');head.insertBefore(btn,more||null)}}catch(e){}},180);
  return r;
};
try{var showDMChatScreenV249269Base=showDMChatScreenV249235}catch(e){var showDMChatScreenV249269Base=null}
showDMChatScreenV249235=function(){
  const r=showDMChatScreenV249269Base?showDMChatScreenV249269Base.apply(this,arguments):false;
  setTimeout(()=>{try{const head=document.querySelector('#dmChatScreen .chatHead');if(head&&!document.getElementById('dmSearchBtnV249269')){const btn=document.createElement('button');btn.id='dmSearchBtnV249269';btn.className='icon chatActionBtn';btn.title='Αναζήτηση μηνυμάτων';btn.textContent='🔎';btn.onclick=()=>openMessageSearchV249269();const more=head.querySelector('button[onclick*="memberActive"]');head.insertBefore(btn,more||null)}}catch(e){}},90);
  return r;
};
function openSpaceAdmin(){
  injectV249268SpacesCss();injectV249269UnifiedCss();
  if(!state.currentSpace)return toast('Choose a space');
  const id=state.currentSpace;
  const entered=prompt('Admin ή 2ος κωδικός συντονιστή:');
  if(!entered)return false;
  const savedAdmin=localStorage.getItem(v249268AdminKey(id))||'';
  const savedMod=localStorage.getItem(v249268ModKey(id))||'';
  const role=(entered===savedAdmin||!savedAdmin)?'owner':(entered===savedMod?'moderator':'');
  if(!role)return toast('Λάθος κωδικός.');
  const menu=$('memberMenu');if(!menu)return false;
  menu.classList.add('show','fullAvatarMenuV249231');
  menu.innerHTML=`<div class="modPanelV249268"><div class="modTopV249268"><button class="icon" onclick="ITH.closeMember()">‹</button><b>🔐 Διαχείριση χώρου · ${role==='owner'?'Owner':'Συντονιστής'}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="modBodyV249268">
    <div class="modGridV249268">
      <button class="tile" onclick="ITH.openSpaceMembersForV249268('${esc(id)}');ITH.closeMember()"><b>👥</b>Λίστα μελών / online</button>
      <button class="tile" onclick="ITH.openSpaceRulesV249268('${esc(id)}')"><b>📌</b>Κανόνες / καρφιτσωμένο</button>
      <button class="tile" onclick="ITH.openSpacesPendingV249268();ITH.closeMember()"><b>⏳</b>Εκκρεμή αιτήματα</button>
      <button class="tile" onclick="ITH.adminTempMuteV249268()"><b>🔇</b>Προσωρινό mute</button>
      <button class="tile" onclick="ITH.openMessageSearchV249269()"><b>🔎</b>Αναζήτηση μηνυμάτων</button>
      <button class="tile" onclick="ITH.openSpaceAnnouncementsV249269('${esc(id)}')"><b>📣</b>Κανάλι ανακοινώσεων</button>
      <button class="tile" onclick="ITH.adminMessageMember()"><b>💬</b>Μήνυμα σε μέλος</button>
      <button class="tile" onclick="ITH.adminMessageSpace()"><b>📣</b>Μήνυμα στον χώρο</button>
      <button class="tile" onclick="ITH.showSpaceCode('${esc(id)}')"><b>▦</b>Κωδικός / QR</button>
      ${role==='owner'?`<button class="tile" onclick="ITH.setModeratorCodeV249268()"><b>🔑</b>2ος κωδικός συντονιστή</button>`:''}
    </div>
  </div></div>`;
  return false;
}
try{
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{refreshSpacesDiscoveryV249269,openMessageSearchV249269,openSpaceAnnouncementsV249269,sendSpaceAnnouncementV249269,renderSpaceChatV249268,openSpaceAdmin,openSpacesListV249268});
  window.openMessageSearchV249269=openMessageSearchV249269;
  window.openSpaceAnnouncementsV249269=openSpaceAnnouncementsV249269;
  injectV249269UnifiedCss();
}catch(e){}



/* V249270 - emergency neighborhood mesh community + zero identity calm support wall */
function injectV249270EmergencyCss(){
  try{
    if(document.getElementById('ithV249270EmergencyCss'))return;
    const st=document.createElement('style');
    st.id='ithV249270EmergencyCss';
    st.textContent=`
      .emergencyTileV249270{border-color:rgba(255,118,84,.36)!important;background:radial-gradient(circle at 18% 0%,rgba(255,118,84,.22),transparent 34%),linear-gradient(145deg,rgba(255,255,255,.08),rgba(255,255,255,.035))!important}
      .supportTileV249270{border-color:rgba(127,215,255,.30)!important;background:radial-gradient(circle at 18% 0%,rgba(127,215,255,.18),transparent 34%),linear-gradient(145deg,rgba(255,255,255,.08),rgba(255,255,255,.035))!important}
      .emergencyBannerV249270{border-radius:20px;padding:12px;background:linear-gradient(135deg,rgba(255,118,84,.16),rgba(255,217,110,.08));border:1px solid rgba(255,118,84,.30);color:#fff}
      .emergencyBannerV249270 b{color:#ffd0b8}.emergencyBannerV249270 p{margin:5px 0 0;color:rgba(239,248,255,.84);line-height:1.36}
      .zeroSupportBannerV249270{border-radius:20px;padding:12px;background:linear-gradient(135deg,rgba(127,215,255,.14),rgba(54,240,160,.08));border:1px solid rgba(127,215,255,.26);color:#fff}
      .zeroSupportBannerV249270 b{color:#9ee7ff}.zeroSupportBannerV249270 p{margin:5px 0 0;color:rgba(239,248,255,.84);line-height:1.36}
      .zeroComposerV249270{display:grid;gap:8px}.zeroComposerV249270 textarea{width:100%;min-height:110px;border-radius:18px;border:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.20);color:#fff;padding:11px;box-sizing:border-box;resize:vertical}
      .zeroProofV249270{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.zeroProofV249270 div{border-radius:16px;padding:9px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10);text-align:center}.zeroProofV249270 b{display:block;color:#9ee7ff;font-size:13px}.zeroProofV249270 small{color:rgba(239,248,255,.70)}
      .meshStatusV249270{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:5px 9px;background:rgba(255,118,84,.12);border:1px solid rgba(255,118,84,.25);color:#ffd0b8;font-weight:1000;font-size:12px}
      .emergencyQuickV249270{display:flex;gap:7px;flex-wrap:wrap}.emergencyQuickV249270 button{border-radius:999px;padding:8px 10px;border:1px solid rgba(255,217,110,.24);background:rgba(255,255,255,.07);color:#fff;font-weight:900}
      @media(max-width:760px){.zeroProofV249270{grid-template-columns:1fr}.emergencyQuickV249270 button{flex:1}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function v249270EmergencySpaceId(){return 'emergency_neighborhood_mesh_v249270'}
function v249270EmergencyChannel(){return 'space:'+v249270EmergencySpaceId()}
function v249270SupportChannel(){return 'support:zero_calm_wall_v249270'}
function v249270IsLocalMeshLikely(){
  try{
    const apiBase=String(state.api||'');
    if(typeof isPrivateLanBaseJs==='function'&&isPrivateLanBaseJs(apiBase))return true;
    const mode=typeof localMode==='function'?localMode():'';
    if(mode==='hotspot'||mode==='wifi')return true;
    if(localStorage.getItem('ith_mesh_emergency_manual_v249270')==='1')return true;
  }catch(e){}
  return false;
}
function v249270MeshActive(){
  try{return !!state.meshEmergencyActiveV249270 || v249270IsLocalMeshLikely()}catch{return v249270IsLocalMeshLikely()}
}
function v249270SetMeshManual(on){
  try{localStorage.setItem('ith_mesh_emergency_manual_v249270',on?'1':'0');state.meshEmergencyActiveV249270=!!on}catch(e){}
  toast(on?'Ενεργή τοπική γειτονιά έκτακτης ανάγκης.':'Απενεργοποιήθηκε η χειροκίνητη έκτακτη γειτονιά.');
  if(state.page==='spaces')openSpacesHubV249270();
  return false;
}
function v249270EnsureEmergencySpace(){
  try{
    state.spaces=state.spaces||[];
    const id=v249270EmergencySpaceId();
    if(!state.spaces.some(s=>String(s.subroom_id)===id)){
      state.spaces.unshift({subroom_id:id,title:'Γειτονιά έκτακτης ανάγκης',category:'community',access_type:'mesh_auto',description:'Προσωρινή κοινότητα που εμφανίζεται αυτόματα όταν χαθεί το internet ή δουλεύεις με τοπικό hotspot/mesh.'});
    }
    if(typeof v249268SetRules==='function'&&!v249268Rules(id))v249268SetRules(id,'Έκτακτη ανάγκη: γράφουμε σύντομα, καθαρά και χρήσιμα. Ρωτάμε “είσαι καλά;”, ζητάμε/δίνουμε βοήθεια στη γειτονιά, αποφεύγουμε πανικό και spam.');
  }catch(e){}
}
function v249270Top(title,backAction){
  return `<div class="spacesTopV249268"><button class="icon" onclick="${backAction||'ITH.openSpacesHubV249270()'}">‹</button><b>${esc(title)}</b><span class="spacer"></span><button class="icon" onclick="ITH.openEmergencyNeighborhoodV249270()">🆘</button><button class="icon" onclick="ITH.openZeroSupportWallV249270()">🕊️</button></div>`;
}
function openSpacesHubV249270(){
  injectV249268SpacesCss();injectV249269UnifiedCss();injectV249270EmergencyCss();v249270EnsureEmergencySpace();
  state.spaceScreen='hub';
  const e=$('spacesPage');if(!e)return false;
  const pending=typeof v249268PendingItems==='function'?v249268PendingItems().length:0;
  const online=typeof v249268PeopleArray==='function'?v249268PeopleArray().filter(p=>p.online).length:0;
  const mesh=v249270MeshActive();
  e.innerHTML=`<div class="spacesShellV249268">
    ${v249270Top('Δωμάτια / Κοινότητες / Έκτακτη ανάγκη',"ITH.page('home')")}
    <div class="emergencyBannerV249270"><b>🆘 Αυτόματη κοινότητα γειτονιάς</b><p>Όταν χαθεί το internet και υπάρχει τοπικό hotspot/mesh, η ΙΘΑΚΗ εμφανίζει προσωρινή γειτονιά χωρίς να χρειάζεται να τη φτιάξει κανείς πριν. <span class="meshStatusV249270">${mesh?'ενεργό / διαθέσιμο':'αναμονή mesh'}</span></p><div class="row" style="gap:7px;flex-wrap:wrap;margin-top:9px"><button class="btn green" onclick="ITH.openEmergencyNeighborhoodV249270()">Άνοιγμα γειτονιάς</button><button class="btn" onclick="ITH.v249270SetMeshManual(true)">Χειροκίνητα ενεργό</button><button class="btn" onclick="ITH.v249270SetMeshManual(false)">Off</button></div></div>
    <div class="spacesHubGridV249268">
      <button class="spaceBigTileV249268 emergencyTileV249270" onclick="ITH.openEmergencyNeighborhoodV249270()"><b>🆘 Γειτονιά έκτακτης ανάγκης</b><span>Αυτόματη προσωρινή κοινότητα για “είσαι καλά;”, βοήθεια και ενημέρωση τετραγώνου.</span><small>${mesh?'mesh/hotspot ενεργό':'έτοιμο όταν χρειαστεί'}</small></button>
      <button class="spaceBigTileV249268 supportTileV249270" onclick="ITH.openZeroSupportWallV249270()"><b>🕊️ Ήρεμη υποστήριξη zero identity</b><span>Τοίχος βοήθειας όπου η βάση μηνυμάτων δεν αποθηκεύει device_id ή nickname.</span><small>χωρίς ταυτότητα στη βάση</small></button>
      <button class="spaceBigTileV249268" onclick="ITH.openSpacesListV249268('rooms')"><b>🏠 Δωμάτια</b><span>Ιδιωτικοί ή ανοιχτοί χώροι συζήτησης με κανόνες και μέλη.</span><small>Άνοιγμα λίστας</small></button>
      <button class="spaceBigTileV249268" onclick="ITH.openSpacesListV249268('communities')"><b>🌐 Κοινότητες</b><span>Μεγαλύτεροι χώροι για θέματα, ενδιαφέροντα και ομάδες.</span><small>Άνοιγμα λίστας</small></button>
      <button class="spaceBigTileV249268" onclick="ITH.openSpacesMembersV249268()"><b>👥 Μέλη</b><span>Ξεχωριστή οθόνη με λίστα μελών και online status.</span><small>${online} online</small></button>
      <button class="spaceBigTileV249268" onclick="ITH.openSpacesPendingV249268()"><b>⏳ Εκκρεμή</b><span>Αιτήματα επαφών, εγκρίσεις και αιτήματα συμμετοχής σε κλειστούς χώρους.</span><small>${pending} σε αναμονή</small></button>
    </div>
    <div class="card"><b>⚠️ Τίμιο privacy note</b><div class="date">Ο zero identity τοίχος δεν γράφει device_id/nickname στη βάση μηνυμάτων. Για “κανένα ίχνος απολύτως” χρειάζεται και server/nginx log policy χωρίς IP/user-agent logs.</div></div>
  </div>`;
  return false;
}
try{var openSpacesHubV249268Base=openSpacesHubV249268}catch(e){var openSpacesHubV249268Base=null}
openSpacesHubV249268=openSpacesHubV249270;
async function openEmergencyNeighborhoodV249270(){
  injectV249268SpacesCss();injectV249269UnifiedCss();injectV249270EmergencyCss();v249270EnsureEmergencySpace();
  state.currentSpace=v249270EmergencySpaceId();
  state.currentSpaceChannel=v249270EmergencyChannel();
  state.spaceScreen='emergency';
  state.page='spaces';
  try{wsSubscribe(state.currentSpaceChannel)}catch(e){}
  const e=$('spacesPage');if(!e)return false;
  const mesh=v249270MeshActive();
  e.innerHTML=`<div class="spacesShellV249268">
    ${v249270Top('🆘 Γειτονιά έκτακτης ανάγκης','ITH.openSpacesHubV249270()')}
    <div class="emergencyBannerV249270"><b>Αυτόματη προσωρινή κοινότητα</b><p>Δεν χρειάζεται να την έχει δημιουργήσει κανείς. Υπάρχει επειδή υπάρχει ανάγκη. Χρησιμοποίησέ τη για σύντομη βοήθεια κοντά σου μέσω hotspot/mesh.</p><div class="meshStatusV249270">${mesh?'Τοπικό mesh/hotspot διαθέσιμο':'Δεν φαίνεται ακόμη τοπικό mesh — μπορείς να το ενεργοποιήσεις χειροκίνητα'}</div></div>
    <div class="emergencyQuickV249270"><button onclick="ITH.sendEmergencyQuickV249270('Είμαι καλά. Χρειάζεται κάποιος βοήθεια;')">Είμαι καλά</button><button onclick="ITH.sendEmergencyQuickV249270('Χρειάζομαι βοήθεια κοντά μου.')">Χρειάζομαι βοήθεια</button><button onclick="ITH.sendEmergencyQuickV249270('Τι γίνεται στο τετράγωνό μας;')">Τι γίνεται εδώ;</button><button onclick="ITH.sendEmergencyQuickV249270('Υπάρχει νερό/φαρμακείο/ασφαλές σημείο κοντά;')">Χρήσιμη πληροφορία</button></div>
    <div class="spaceChatV249268" style="height:calc(100dvh - 250px);min-height:430px">
      <div id="spaceMsgs" class="messages"><div class="card">Φόρτωση γειτονιάς...</div></div>
      <div class="composer"><textarea id="spaceInput" placeholder="Γράψε σύντομα για τη γειτονιά..."></textarea><button class="icon" onclick="ITH.sendSpaceText()">➤</button></div>
    </div>
  </div>`;
  try{await loadSpaceMessages(true)}catch(e){const box=$('spaceMsgs');if(box)box.innerHTML='<div class="card">Αν δεν υπάρχει τοπικός server/hotspot, η γειτονιά ανοίγει αλλά δεν μπορεί να στείλει μέχρι να συνδεθεί mesh.</div>'}
  return false;
}
async function sendEmergencyQuickV249270(text){
  try{
    state.currentSpace=v249270EmergencySpaceId();state.currentSpaceChannel=v249270EmergencyChannel();
    await sendMessagePayload(state.currentSpaceChannel,'🆘 '+text);
    await openEmergencyNeighborhoodV249270();
  }catch(e){toast('Δεν στάλθηκε. Χρειάζεται τοπικό hotspot/mesh server.')}
  return false;
}
async function openZeroSupportWallV249270(){
  injectV249268SpacesCss();injectV249269UnifiedCss();injectV249270EmergencyCss();
  state.spaceScreen='zero_support';state.page='spaces';
  const e=$('spacesPage');if(!e)return false;
  e.innerHTML=`<div class="spacesShellV249268">
    ${v249270Top('🕊️ Ήρεμη υποστήριξη · zero identity','ITH.openSpacesHubV249270()')}
    <div class="zeroSupportBannerV249270"><b>Πραγματικά ανώνυμος τοίχος στη βάση μηνυμάτων</b><p>Σε αυτή τη λειτουργία το μήνυμα αποθηκεύεται με κενό sender_id και nickname “Ανώνυμος”. Δεν συνδέεται με προφίλ, avatar ή device_id στη βάση μηνυμάτων.</p></div>
    <div class="zeroProofV249270"><div><b>sender_id</b><small>κενό</small></div><div><b>nickname</b><small>Ανώνυμος</small></div><div><b>avatar</b><small>κανένα</small></div></div>
    <div class="card zeroComposerV249270"><b>Γράψε χωρίς ταυτότητα</b><textarea id="zeroSupportTextV249270" placeholder="Μίλα ελεύθερα. Μην γράφεις προσωπικά στοιχεία αν δεν θέλεις να φανούν στο κείμενο."></textarea><button class="btn green" onclick="ITH.sendZeroSupportMessageV249270()">Αποστολή χωρίς ταυτότητα στη βάση</button><div class="date">Σημείωση: για απόλυτο “κανένα ίχνος” πρέπει και ο server/reverse proxy να μη κρατά access logs IP/user-agent.</div></div>
    <div id="zeroSupportMsgsV249270" class="messages" style="min-height:320px"><div class="card">Φόρτωση...</div></div>
  </div>`;
  await loadZeroSupportMessagesV249270();
  return false;
}
async function sendZeroSupportMessageV249270(){
  const txt=($('zeroSupportTextV249270')?.value||'').trim();
  if(!txt)return toast('Γράψε μήνυμα.');
  try{
    await fetchJson('/api/messages/send',{method:'POST',body:JSON.stringify({room_id:state.room,channel:v249270SupportChannel(),sender_id:state.device,nickname:state.name,language:uiLang(),text:txt,zero_identity:true})});
    if($('zeroSupportTextV249270'))$('zeroSupportTextV249270').value='';
    toast('Στάλθηκε χωρίς ταυτότητα στη βάση μηνυμάτων.');
    await loadZeroSupportMessagesV249270();
  }catch(e){toast('Δεν στάλθηκε zero identity: '+(e.message||e),7000)}
  return false;
}
async function loadZeroSupportMessagesV249270(){
  const box=$('zeroSupportMsgsV249270');if(!box)return false;
  try{
    const r=await fetchJson(`/api/messages?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent(v249270SupportChannel())}&since=0&limit=200`);
    const items=uniqueMessages(r.messages||[]);
    box.innerHTML=items.map(m=>{const body=parseText(m.text||'').body||m.text||'';return `<div class="bubble"><b>Ανώνυμος</b><div class="msgBody">${esc(body)}</div><div class="meta">${fmt(m.created_at)} · zero identity</div></div>`}).join('')||'<div class="card">Δεν υπάρχει μήνυμα ακόμη.</div>';
    box.scrollTop=box.scrollHeight;
  }catch(e){box.innerHTML='<div class="card">Ο τοίχος χρειάζεται server που έχει το V249270 endpoint/zero_identity.</div>'}
  return false;
}
try{var connectionPulseV249270Base=connectionPulse}catch(e){var connectionPulseV249270Base=null}
connectionPulse=async function(){
  let ok=false;
  try{ok=connectionPulseV249270Base?await connectionPulseV249270Base.apply(this,arguments):false}catch(e){ok=false}
  try{
    const local=v249270IsLocalMeshLikely();
    state.meshEmergencyActiveV249270=(!ok&&local)||local||localStorage.getItem('ith_mesh_emergency_manual_v249270')==='1';
    if(state.meshEmergencyActiveV249270)v249270EnsureEmergencySpace();
  }catch(e){}
  return ok;
};
try{
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{openSpacesHubV249270,openSpacesHubV249268,openEmergencyNeighborhoodV249270,sendEmergencyQuickV249270,openZeroSupportWallV249270,sendZeroSupportMessageV249270,loadZeroSupportMessagesV249270,v249270SetMeshManual});
  window.openEmergencyNeighborhoodV249270=openEmergencyNeighborhoodV249270;
  window.openZeroSupportWallV249270=openZeroSupportWallV249270;
  injectV249270EmergencyCss();
  setTimeout(()=>{try{v249270EnsureEmergencySpace()}catch(e){}},900);
}catch(e){}



/* V249271 - weekly philosophical mascot prompts + first-run guided welcome/mood routing */
function injectV249271MascotGuideCss(){
  try{
    if(document.getElementById('ithV249271MascotGuideCss'))return;
    const st=document.createElement('style');
    st.id='ithV249271MascotGuideCss';
    st.textContent=`
      .weeklyPromptV249271{border-radius:20px;padding:12px;background:linear-gradient(135deg,rgba(255,217,110,.13),rgba(127,215,255,.08));border:1px solid rgba(255,217,110,.25);color:#fff;display:grid;grid-template-columns:auto 1fr;gap:11px;align-items:center}
      .weeklyPromptV249271 b{color:#ffe39b}.weeklyPromptV249271 p{margin:5px 0 0;color:rgba(239,248,255,.84);line-height:1.38}
      .weeklyPromptV249271 .miniMascot{width:54px;height:54px;border-radius:18px;display:grid;place-items:center;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.12);overflow:hidden}
      .guideOverlayV249271{position:fixed;inset:0;z-index:10090;background:rgba(0,0,0,.62);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);display:flex;align-items:center;justify-content:center;padding:14px;box-sizing:border-box}
      .guideCardV249271{width:min(760px,100%);max-height:92dvh;overflow:auto;border-radius:28px;border:1px solid rgba(255,217,110,.32);background:linear-gradient(165deg,rgba(3,12,23,.99),rgba(8,24,39,.99));box-shadow:0 34px 100px rgba(0,0,0,.62);color:#fff}
      .guideTopV249271{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:10px;padding:13px;background:rgba(3,12,23,.94);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}
      .guideTopV249271 b{color:#ffe39b;font-size:18px}.guideTopV249271 .spacer{flex:1}
      .guideBodyV249271{padding:14px;display:grid;gap:12px}
      .guideHeroV249271{display:grid;grid-template-columns:auto 1fr;gap:13px;align-items:center;border-radius:22px;padding:13px;background:radial-gradient(circle at 16% 0%,rgba(255,217,110,.15),transparent 30%),rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.10)}
      .guideHeroV249271 h3{margin:0 0 5px;color:#ffe39b}.guideHeroV249271 p{margin:0;color:rgba(239,248,255,.84);line-height:1.42}
      .moodGridV249271{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.moodGridV249271 button,.tourGridV249271 button{border-radius:20px;border:1px solid rgba(255,217,110,.20);background:rgba(255,255,255,.065);color:#fff;padding:12px;text-align:left;font-weight:1000}.moodGridV249271 button small,.tourGridV249271 button small{display:block;color:rgba(239,248,255,.70);font-weight:700;margin-top:4px;line-height:1.34}
      .tourGridV249271{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
      .guideSuggestionV249271{display:none;border-radius:20px;padding:12px;background:linear-gradient(135deg,rgba(127,215,255,.13),rgba(54,240,160,.08));border:1px solid rgba(127,215,255,.26)}
      .guideSuggestionV249271.show{display:block}.guideSuggestionV249271 b{color:#9ee7ff}.guideSuggestionV249271 p{margin:6px 0;color:rgba(239,248,255,.84);line-height:1.4}
      .guideActionsV249271{display:flex;gap:8px;flex-wrap:wrap}.guideActionsV249271 button{border-radius:999px;border:1px solid rgba(255,217,110,.24);background:linear-gradient(135deg,rgba(255,217,110,.15),rgba(127,215,255,.08));color:#fff;padding:10px 13px;font-weight:1000}
      @media(max-width:760px){.guideHeroV249271{grid-template-columns:1fr;text-align:center}.moodGridV249271,.tourGridV249271{grid-template-columns:1fr}.weeklyPromptV249271{grid-template-columns:1fr;text-align:center}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function v249271CompanionName(){
  try{return (ithakiCompanionV249258&&ithakiCompanionV249258()==='sokratakis')?'Bil':'Bil'}catch{return 'Bil'}
}
function v249271MascotHtml(){
  try{return typeof v249262MascotHtml==='function'?v249262MascotHtml('small'):(v249271CompanionName()==='Bil'?'🐢':'🦉')}catch{return '🦉'}
}
function v249271WeekKey(){
  try{
    const d=new Date();
    const onejan=new Date(d.getFullYear(),0,1);
    const week=Math.ceil((((d-onejan)/86400000)+onejan.getDay()+1)/7);
    return d.getFullYear()+'-W'+String(week).padStart(2,'0');
  }catch{return String(Math.floor(Date.now()/(7*86400000)))}
}
function v249271PhilosophyQuestions(){
  return [
    'Τι σημαίνει για σένα η δικαιοσύνη σήμερα;',
    'Πότε μια αλήθεια βοηθάει και πότε πληγώνει;',
    'Τι είναι πιο δύσκολο: να ακούς ή να απαντάς;',
    'Πώς ξεχωρίζεις την ελευθερία από την ασυδοσία;',
    'Τι κάνει μια κοινότητα πραγματικά ανθρώπινη;',
    'Πότε η σιωπή είναι σοφία και πότε φόβος;',
    'Τι σημαίνει αξιοπρέπεια στην καθημερινή ζωή;',
    'Ποια μικρή πράξη σεβασμού μπορεί να αλλάξει μια μέρα;',
    'Τι χρωστάμε στον εαυτό μας όταν όλα πιέζουν;',
    'Ποια είναι η διαφορά ανάμεσα στη γνώμη και στη σοφία;',
    'Πότε μια συγγνώμη είναι αληθινή;',
    'Τι θα ήθελες να μάθουν οι άνθρωποι να λένε πιο συχνά;'
  ];
}
function v249271WeeklyQuestion(){
  const arr=v249271PhilosophyQuestions();
  let n=0; for(const ch of v249271WeekKey())n=(n+ch.charCodeAt(0))%9999;
  return arr[n%arr.length];
}
function v249271IsPhilosophySpace(s){
  try{
    const hay=(String(s?.title||'')+' '+String(s?.description||'')+' '+String(v249268Rules?s&&v249268Rules(s.subroom_id):'')).toLowerCase();
    return /φιλοσοφ|σοφία|σοφια|σκέψη|σκεψη|justice|philosophy|wisdom|ethic|ηθικ|δικαιοσ/.test(hay);
  }catch{return false}
}
function v249271PromptId(spaceId){return 'weekly_philosophy_prompt_v249271_'+String(spaceId||'')+'_'+v249271WeekKey()}
function v249271PromptCard(spaceId,s){
  const q=v249271WeeklyQuestion(), who=v249271CompanionName();
  return `<div class="weeklyPromptV249271" id="weeklyPromptCardV249271"><div class="miniMascot">${v249271MascotHtml()}</div><div><b>${who} ρωτάει · εβδομαδιαία σκέψη</b><p>${esc(q)}</p><div class="guideActionsV249271" style="margin-top:9px"><button onclick="ITH.replyWeeklyPromptV249271('${escJs(spaceId)}')">Απάντησε στην κοινότητα</button><button onclick="ITH.postWeeklyPromptNowV249271('${escJs(spaceId)}')">Δημοσίευση τώρα</button></div></div></div>`;
}
async function v249271MaybePostWeeklyPrompt(spaceId){
  try{
    const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(spaceId))||{};
    if(!v249271IsPhilosophySpace(s))return false;
    const key=v249271PromptId(spaceId);
    if(localStorage.getItem(key)==='1')return false;
    const channel='space:'+spaceId;
    let exists=false;
    try{
      const r=await fetchJson(`/api/messages?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent(channel)}&since=0&limit=120`);
      const marker='WEEKLY_PROMPT:'+v249271WeekKey();
      exists=(r.messages||[]).some(m=>String(m.text||'').includes(marker));
    }catch(e){}
    if(!exists){
      const who=v249271CompanionName();
      const text=`🧭 ${who} ρωτάει — εβδομαδιαία σκέψη\\n${v249271WeeklyQuestion()}\\n\\nWEEKLY_PROMPT:${v249271WeekKey()}`;
      await fetchJson('/api/messages/send',{method:'POST',body:JSON.stringify({room_id:state.room,channel,sender_id:'ithaki_mascot_weekly',nickname:who,language:uiLang(),text})});
    }
    localStorage.setItem(key,'1');
    return true;
  }catch(e){return false}
}
async function postWeeklyPromptNowV249271(spaceId){
  try{
    localStorage.removeItem(v249271PromptId(spaceId));
    const ok=await v249271MaybePostWeeklyPrompt(spaceId);
    toast(ok?'Δημοσιεύτηκε η εβδομαδιαία ερώτηση.':'Υπάρχει ήδη ερώτηση αυτή την εβδομάδα.');
    if(state.currentSpace===spaceId)await loadSpaceMessages(true);
  }catch(e){toast('Δεν δημοσιεύτηκε.')}
  return false;
}
function replyWeeklyPromptV249271(spaceId){
  try{
    if(state.currentSpace!==spaceId){openSpace(spaceId);setTimeout(()=>replyWeeklyPromptV249271(spaceId),500);return false}
    const i=$('spaceInput'); if(i){i.value='Απάντηση στην εβδομαδιαία ερώτηση: ';i.focus();}
  }catch(e){}
  return false;
}
try{var renderSpaceChatV249271Base=renderSpaceChatV249268}catch(e){var renderSpaceChatV249271Base=null}
renderSpaceChatV249268=async function(){
  injectV249271MascotGuideCss();
  const r=renderSpaceChatV249271Base?await renderSpaceChatV249271Base.apply(this,arguments):false;
  try{
    const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(state.currentSpace))||{};
    if(v249271IsPhilosophySpace(s)){
      const pinned=document.querySelector('.spacePinnedV249268');
      if(pinned&&!document.getElementById('weeklyPromptCardV249271'))pinned.insertAdjacentHTML('afterend',v249271PromptCard(state.currentSpace,s));
      setTimeout(()=>v249271MaybePostWeeklyPrompt(state.currentSpace).then(x=>{if(x)loadSpaceMessages(true)}),900);
    }
  }catch(e){}
  return r;
};
function openFirstRunGuideV249271(force=false){
  try{
    injectV249271MascotGuideCss();
    if(!force&&localStorage.getItem('ith_first_run_guide_seen_v249271')==='1')return false;
    if(document.getElementById('guideOverlayV249271'))return false;
    const who=v249271CompanionName();
    const d=document.createElement('div');
    d.id='guideOverlayV249271';
    d.className='guideOverlayV249271';
    d.innerHTML=`<div class="guideCardV249271">
      <div class="guideTopV249271"><div style="width:48px;height:48px;display:grid;place-items:center">${v249271MascotHtml()}</div><b>${who} · πρώτη ξενάγηση</b><span class="spacer"></span><button class="icon" onclick="ITH.closeFirstRunGuideV249271(true)">×</button></div>
      <div class="guideBodyV249271">
        <div class="guideHeroV249271"><div style="min-width:74px">${v249271MascotHtml()}</div><div><h3>Καλώς ήρθες στην OK ITHAKI</h3><p>Πώς είσαι σήμερα; Θα σου δείξω γρήγορα τι έχει το πρόγραμμα και θα σε πάω εκεί που χρειάζεσαι.</p></div></div>
        <div class="moodGridV249271">
          <button onclick="ITH.answerGuideMoodV249271('good')">🙂 Καλά<small>Δείξε μου γρήγορα τις βασικές λειτουργίες.</small></button>
          <button onclick="ITH.answerGuideMoodV249271('neutral')">😐 Έτσι κι έτσι<small>Θέλω ήρεμη ξενάγηση χωρίς πολλά.</small></button>
          <button onclick="ITH.answerGuideMoodV249271('bad')">😟 Χάλια / άγχος<small>Πρότεινέ μου ήρεμη υποστήριξη.</small></button>
          <button onclick="ITH.answerGuideMoodV249271('help')">🕊️ Θέλω να μιλήσω ανώνυμα<small>Πήγαινέ με στον zero identity τοίχο.</small></button>
        </div>
        <div id="guideSuggestionV249271" class="guideSuggestionV249271"></div>
        <div class="tourGridV249271">
          <button onclick="ITH.page('feed');ITH.closeFirstRunGuideV249271(true)">🎬 Ροή<small>Δημοσιεύσεις, σοφά λόγια, σχόλια και καρδιές.</small></button>
          <button onclick="ITH.page('dm');ITH.closeFirstRunGuideV249271(true)">💬 Μηνύματα<small>Φίλοι, κλήσεις, αρχεία και αναζήτηση μηνυμάτων.</small></button>
          <button onclick="ITH.page('spaces');ITH.closeFirstRunGuideV249271(true)">🏘️ Δωμάτια / Κοινότητες<small>Κανόνες, μέλη online, ανακοινώσεις και φιλοσοφικές ερωτήσεις.</small></button>
          <button onclick="ITH.openEmergencyNeighborhoodV249270();ITH.closeFirstRunGuideV249271(true)">🆘 Έκτακτη γειτονιά<small>Για hotspot/mesh όταν χαθεί το internet.</small></button>
        </div>
        <div class="guideActionsV249271"><button onclick="ITH.closeFirstRunGuideV249271(true)">✓ Το κατάλαβα</button><button onclick="ITH.openFirstRunGuideV249271(true)">↻ Ξανά από την αρχή</button></div>
      </div>
    </div>`;
    document.body.appendChild(d);
    return false;
  }catch(e){return false}
}
function closeFirstRunGuideV249271(mark=true){
  try{if(mark)localStorage.setItem('ith_first_run_guide_seen_v249271','1');document.getElementById('guideOverlayV249271')?.remove()}catch(e){}
  return false;
}
function answerGuideMoodV249271(mood){
  try{
    const box=$('guideSuggestionV249271'); if(!box)return false;
    box.classList.add('show');
    if(mood==='bad'||mood==='help'){
      box.innerHTML=`<b>Δεν είσαι μόνος/μόνη.</b><p>Μπορείς να μιλήσεις στον ήρεμο τοίχο χωρίς ταυτότητα στη βάση, ή να μπεις σε ήρεμη κοινότητα/σχετική συζήτηση.</p><div class="guideActionsV249271"><button onclick="ITH.openZeroSupportWallV249270();ITH.closeFirstRunGuideV249271(true)">🕊️ Zero identity τοίχος</button><button onclick="ITH.page('spaces');ITH.closeFirstRunGuideV249271(true)">🌿 Ήρεμες κοινότητες</button><button onclick="ITH.page('dm');ITH.closeFirstRunGuideV249271(true)">💬 Μίλα με φίλο</button></div>`;
    }else if(mood==='neutral'){
      box.innerHTML=`<b>Πάμε ήρεμα.</b><p>Ξεκίνα από τα βασικά: Μηνύματα, Δωμάτια/Κοινότητες, Ροή και Έκτακτη Γειτονιά.</p>`;
    }else{
      box.innerHTML=`<b>Χαίρομαι.</b><p>Δες πρώτα τη Ροή, μετά τα Μηνύματα και τις Κοινότητες. Αν κάτι δύσκολο συμβεί, υπάρχει και η έκτακτη γειτονιά.</p>`;
    }
  }catch(e){}
  return false;
}
try{var renderHomeV249271Base=renderHome}catch(e){var renderHomeV249271Base=null}
renderHome=function(){
  const r=renderHomeV249271Base?renderHomeV249271Base.apply(this,arguments):false;
  try{setTimeout(()=>openFirstRunGuideV249271(false),1200)}catch(e){}
  return r;
};
try{
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{openFirstRunGuideV249271,closeFirstRunGuideV249271,answerGuideMoodV249271,postWeeklyPromptNowV249271,replyWeeklyPromptV249271});
  window.openFirstRunGuideV249271=openFirstRunGuideV249271;
  injectV249271MascotGuideCss();
}catch(e){}



/* V249272 - working Athina-first welcome + mascot opens guided tour */
function injectV249272AthinaGuideCss(){
  try{
    if(document.getElementById('ithV249272AthinaGuideCss'))return;
    const st=document.createElement('style');
    st.id='ithV249272AthinaGuideCss';
    st.textContent=`
      .athinaWelcomeV249272{position:fixed;left:12px;right:12px;bottom:92px;z-index:10070;max-width:620px;margin:auto;border-radius:24px;border:1px solid rgba(255,217,110,.30);background:linear-gradient(165deg,rgba(3,12,23,.98),rgba(9,28,45,.98));box-shadow:0 24px 70px rgba(0,0,0,.52);color:#fff;padding:12px;display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:center}
      .athinaWelcomeV249272 .athinaFace{width:72px;height:72px;border-radius:22px;display:grid;place-items:center;background:rgba(255,255,255,.065);border:1px solid rgba(255,255,255,.12);overflow:hidden}
      .athinaWelcomeV249272 b{color:#ffe39b;font-size:16px}.athinaWelcomeV249272 p{margin:5px 0 9px;color:rgba(239,248,255,.84);line-height:1.35}
      .athinaWelcomeV249272 .actions{display:flex;gap:7px;flex-wrap:wrap}.athinaWelcomeV249272 button{border-radius:999px;border:1px solid rgba(255,217,110,.22);background:rgba(255,255,255,.07);color:#fff;padding:8px 10px;font-weight:1000}.athinaWelcomeV249272 button.green{background:linear-gradient(135deg,rgba(54,240,160,.22),rgba(127,215,255,.10))}.athinaWelcomeV249272 .close{position:absolute;right:8px;top:8px;width:30px;height:30px;padding:0;border-radius:50%;background:rgba(255,255,255,.08)}
      .guideOverlayV249272{position:fixed;inset:0;z-index:10100;background:rgba(0,0,0,.64);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);display:flex;align-items:center;justify-content:center;padding:14px;box-sizing:border-box}
      .guideCardV249272{width:min(760px,100%);max-height:92dvh;overflow:auto;border-radius:28px;border:1px solid rgba(255,217,110,.34);background:linear-gradient(165deg,rgba(3,12,23,.99),rgba(8,24,39,.99));box-shadow:0 34px 100px rgba(0,0,0,.62);color:#fff}
      .guideTopV249272{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:10px;padding:13px;background:rgba(3,12,23,.96);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}
      .guideTopV249272 b{color:#ffe39b;font-size:18px}.guideTopV249272 .spacer{flex:1}.guideTopV249272 button{border-radius:50%;width:40px;height:40px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.08);color:#fff;font-weight:1000}
      .guideBodyV249272{padding:14px;display:grid;gap:12px}
      .guideHeroV249272{display:grid;grid-template-columns:auto 1fr;gap:13px;align-items:center;border-radius:22px;padding:13px;background:radial-gradient(circle at 16% 0%,rgba(255,217,110,.15),transparent 30%),rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.10)}
      .guideHeroV249272 h3{margin:0 0 5px;color:#ffe39b}.guideHeroV249272 p{margin:0;color:rgba(239,248,255,.84);line-height:1.42}
      .moodGridV249272,.tourGridV249272{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.moodGridV249272 button,.tourGridV249272 button,.guideActionsV249272 button{border-radius:20px;border:1px solid rgba(255,217,110,.20);background:rgba(255,255,255,.065);color:#fff;padding:12px;text-align:left;font-weight:1000}.moodGridV249272 button small,.tourGridV249272 button small{display:block;color:rgba(239,248,255,.70);font-weight:700;margin-top:4px;line-height:1.34}
      .guideSuggestionV249272{display:none;border-radius:20px;padding:12px;background:linear-gradient(135deg,rgba(127,215,255,.13),rgba(54,240,160,.08));border:1px solid rgba(127,215,255,.26)}
      .guideSuggestionV249272.show{display:block}.guideSuggestionV249272 b{color:#9ee7ff}.guideSuggestionV249272 p{margin:6px 0;color:rgba(239,248,255,.84);line-height:1.4}
      .guideActionsV249272{display:flex;gap:8px;flex-wrap:wrap}.guideActionsV249272 button{border-radius:999px;text-align:center;padding:10px 13px}
      #athinaFabV249258{cursor:pointer!important}
      @media(max-width:760px){.athinaWelcomeV249272{grid-template-columns:1fr;text-align:center;bottom:86px}.athinaWelcomeV249272 .athinaFace{margin:auto}.moodGridV249272,.tourGridV249272{grid-template-columns:1fr}.guideHeroV249272{grid-template-columns:1fr;text-align:center}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function athinaGuideFaceV249272(){
  try{return typeof athinaOwlV249258==='function'?athinaOwlV249258('small'):'🦉'}catch{return '🦉'}
}
function removeBrokenGuidesV249272(){
  try{
    document.getElementById('guideOverlayV249271')?.remove();
    document.getElementById('guideOverlayV249272')?.remove();
  }catch(e){}
}
function closeAthinaWelcomeV249272(mark=true){
  try{if(mark)sessionStorage.setItem('ith_athina_welcome_seen_v249272','1');document.getElementById('athinaWelcomeV249272')?.remove()}catch(e){}
  return false;
}
function showAthinaWelcomeV249272(force=false){
  try{
    injectV249272AthinaGuideCss();
    removeBrokenGuidesV249272();
    if(!force&&sessionStorage.getItem('ith_athina_welcome_seen_v249272')==='1')return false;
    if(state.page&&state.page!=='home'&&!force)return false;
    if(document.getElementById('athinaWelcomeV249272'))return false;
    const d=document.createElement('div');
    d.id='athinaWelcomeV249272';
    d.className='athinaWelcomeV249272';
    d.innerHTML=`<button class="close" type="button" aria-label="Κλείσιμο">×</button><div class="athinaFace">${athinaGuideFaceV249272()}</div><div><b>Bil · καλώς ήρθες στην OK ITHAKI</b><p>Πώς είσαι σήμερα; Αν θέλεις βοήθεια ή ξενάγηση, πάτησε εδώ ή πάτησε τη μασκότ.</p><div class="actions"><button class="green" data-act="tour">🧭 Ξενάγηση</button><button data-act="bad">😟 Δεν είμαι καλά</button><button data-act="ok">🙂 Είμαι καλά</button></div></div>`;
    d.querySelector('.close').onclick=()=>closeAthinaWelcomeV249272(true);
    d.querySelector('[data-act="tour"]').onclick=()=>{closeAthinaWelcomeV249272(true);openFirstRunGuideV249272(true)};
    d.querySelector('[data-act="bad"]').onclick=()=>{closeAthinaWelcomeV249272(true);openFirstRunGuideV249272(true,'bad')};
    d.querySelector('[data-act="ok"]').onclick=()=>{toast('Χαίρομαι. Πάτησε τη μασκότ όποτε θέλεις ξενάγηση.');closeAthinaWelcomeV249272(true)};
    document.body.appendChild(d);
    setTimeout(()=>{try{if(document.getElementById('athinaWelcomeV249272'))closeAthinaWelcomeV249272(false)}catch(e){}},18000);
  }catch(e){}
  return false;
}
function openFirstRunGuideV249272(force=true,startMood=''){
  try{
    injectV249272AthinaGuideCss();
    removeBrokenGuidesV249272();
    const d=document.createElement('div');
    d.id='guideOverlayV249272';
    d.className='guideOverlayV249272';
    d.innerHTML=`<div class="guideCardV249272">
      <div class="guideTopV249272"><div style="width:48px;height:48px;display:grid;place-items:center">${athinaGuideFaceV249272()}</div><b>Bil · ξενάγηση OK ITHAKI</b><span class="spacer"></span><button type="button" data-close="1">×</button></div>
      <div class="guideBodyV249272">
        <div class="guideHeroV249272"><div style="min-width:74px">${athinaGuideFaceV249272()}</div><div><h3>Πώς είσαι σήμερα;</h3><p>Διάλεξε διάθεση και μετά πάτησε πού θέλεις να πας. Τα κουμπιά δουλεύουν χωρίς να κολλάει το παράθυρο.</p></div></div>
        <div class="moodGridV249272">
          <button type="button" data-mood="good">🙂 Καλά<small>Δείξε μου γρήγορα τις βασικές λειτουργίες.</small></button>
          <button type="button" data-mood="neutral">😐 Έτσι κι έτσι<small>Θέλω ήρεμη ξενάγηση.</small></button>
          <button type="button" data-mood="bad">😟 Χάλια / άγχος<small>Πρότεινέ μου ήρεμη υποστήριξη.</small></button>
          <button type="button" data-mood="help">🕊️ Θέλω να μιλήσω ανώνυμα<small>Πήγαινέ με στον zero identity τοίχο.</small></button>
        </div>
        <div id="guideSuggestionV249272" class="guideSuggestionV249272"></div>
        <div class="tourGridV249272">
          <button type="button" data-go="feed">🎬 Ροή<small>Δημοσιεύσεις, σοφά λόγια, σχόλια και καρδιές.</small></button>
          <button type="button" data-go="dm">💬 Μηνύματα<small>Φίλοι, κλήσεις, αρχεία και αναζήτηση μηνυμάτων.</small></button>
          <button type="button" data-go="spaces">🏘️ Δωμάτια / Κοινότητες<small>Μέλη online, κανόνες, ανακοινώσεις και φιλοσοφικές ερωτήσεις.</small></button>
          <button type="button" data-go="emergency">🆘 Έκτακτη γειτονιά<small>Για hotspot/mesh όταν χαθεί το internet.</small></button>
        </div>
        <div class="guideActionsV249272"><button type="button" data-close="1">✓ Κλείσιμο</button></div>
      </div>
    </div>`;
    d.querySelectorAll('[data-close]').forEach(b=>b.onclick=()=>closeFirstRunGuideV249272(true));
    d.querySelectorAll('[data-mood]').forEach(b=>b.onclick=()=>answerGuideMoodV249272(b.dataset.mood));
    d.querySelectorAll('[data-go]').forEach(b=>b.onclick=()=>guideGoV249272(b.dataset.go));
    document.body.appendChild(d);
    if(startMood)setTimeout(()=>answerGuideMoodV249272(startMood),80);
  }catch(e){toast('Η ξενάγηση δεν άνοιξε: '+(e.message||e),5000)}
  return false;
}
function closeFirstRunGuideV249272(mark=true){
  try{if(mark)localStorage.setItem('ith_first_run_guide_seen_v249272','1');document.getElementById('guideOverlayV249272')?.remove();document.getElementById('guideOverlayV249271')?.remove()}catch(e){}
  return false;
}
function answerGuideMoodV249272(mood){
  try{
    const box=$('guideSuggestionV249272');if(!box)return false;
    box.classList.add('show');
    if(mood==='bad'||mood==='help'){
      box.innerHTML=`<b>Δεν είσαι μόνος/μόνη.</b><p>Η Bil μπορεί να σε πάει στον zero identity τοίχο ή σε ήρεμες κοινότητες. Μην γράφεις προσωπικά στοιχεία αν δεν θέλεις να φανούν στο ίδιο το κείμενο.</p><div class="guideActionsV249272"><button type="button" id="gZeroV249272">🕊️ Zero identity τοίχος</button><button type="button" id="gSpacesV249272">🌿 Ήρεμες κοινότητες</button><button type="button" id="gDmV249272">💬 Μίλα με φίλο</button></div>`;
      setTimeout(()=>{try{$('gZeroV249272').onclick=()=>guideGoV249272('zero');$('gSpacesV249272').onclick=()=>guideGoV249272('spaces');$('gDmV249272').onclick=()=>guideGoV249272('dm')}catch(e){}},20);
    }else if(mood==='neutral'){
      box.innerHTML=`<b>Πάμε ήρεμα.</b><p>Ξεκίνα από Δωμάτια/Κοινότητες ή Μηνύματα. Η ξενάγηση μένει εδώ μέχρι να πατήσεις κλείσιμο.</p>`;
    }else{
      box.innerHTML=`<b>Χαίρομαι.</b><p>Πάτησε Ροή, Μηνύματα ή Κοινότητες για να ξεκινήσεις. Η μασκότ ανοίγει ξανά την ξενάγηση όποτε θέλεις.</p>`;
    }
  }catch(e){}
  return false;
}
function guideGoV249272(where){
  try{
    closeFirstRunGuideV249272(true);
    if(where==='zero'&&typeof openZeroSupportWallV249270==='function'){page('spaces');setTimeout(()=>openZeroSupportWallV249270(),180);return false}
    if(where==='emergency'&&typeof openEmergencyNeighborhoodV249270==='function'){page('spaces');setTimeout(()=>openEmergencyNeighborhoodV249270(),180);return false}
    if(where==='feed')return page('feed');
    if(where==='dm')return page('dm');
    if(where==='spaces')return page('spaces');
  }catch(e){toast('Δεν άνοιξε η επιλογή.')}
  return false;
}
function attachGuideToMascotV249272(){
  try{
    const b=document.getElementById('athinaFabV249258');
    if(b){
      b.title='Bil · πάτησε για ξενάγηση';
      b.setAttribute('aria-label','Bil · πάτησε για ξενάγηση');
      b.onclick=(ev)=>{try{ev.preventDefault();ev.stopPropagation()}catch(e){};openFirstRunGuideV249272(true);return false};
    }
  }catch(e){}
}
try{var renderHomeV249272Base=renderHome}catch(e){var renderHomeV249272Base=null}
renderHome=function(){
  const r=renderHomeV249272Base?renderHomeV249272Base.apply(this,arguments):false;
  try{
    setTimeout(()=>{removeBrokenGuidesV249272();showAthinaWelcomeV249272(false);attachGuideToMascotV249272();},900);
  }catch(e){}
  return r;
};
try{var ensureAthinaCompanionV249272Base=ensureAthinaCompanionV249258}catch(e){var ensureAthinaCompanionV249272Base=null}
ensureAthinaCompanionV249258=function(){
  try{if(ensureAthinaCompanionV249272Base)ensureAthinaCompanionV249272Base.apply(this,arguments)}catch(e){}
  setTimeout(attachGuideToMascotV249272,60);
};
openFirstRunGuideV249271=openFirstRunGuideV249272;
closeFirstRunGuideV249271=closeFirstRunGuideV249272;
answerGuideMoodV249271=answerGuideMoodV249272;
try{
  window.openFirstRunGuideV249272=openFirstRunGuideV249272;
  window.closeFirstRunGuideV249272=closeFirstRunGuideV249272;
  window.answerGuideMoodV249272=answerGuideMoodV249272;
  window.showAthinaWelcomeV249272=showAthinaWelcomeV249272;
  window.openFirstRunGuideV249271=openFirstRunGuideV249272;
  window.closeFirstRunGuideV249271=closeFirstRunGuideV249272;
  window.answerGuideMoodV249271=answerGuideMoodV249272;
  function attachV249272ToITH(){try{window.ITH=window.ITH||{};Object.assign(window.ITH,{openFirstRunGuideV249271:openFirstRunGuideV249272,closeFirstRunGuideV249271:closeFirstRunGuideV249272,answerGuideMoodV249271:answerGuideMoodV249272,openFirstRunGuideV249272,closeFirstRunGuideV249272,answerGuideMoodV249272,showAthinaWelcomeV249272});attachGuideToMascotV249272()}catch(e){}}
  attachV249272ToITH();
  document.addEventListener('DOMContentLoaded',()=>setTimeout(attachV249272ToITH,500));
  setTimeout(attachV249272ToITH,1200);
  setInterval(attachV249272ToITH,5000);
  injectV249272AthinaGuideCss();
}catch(e){}



/* V249273 - simple 5s hello only, click mascot opens working guide, restore classic rooms/communities */
function injectV249273SimpleHelloClassicSpacesCss(){
  try{
    if(document.getElementById('ithV249273SimpleHelloClassicSpacesCss'))return;
    const st=document.createElement('style');
    st.id='ithV249273SimpleHelloClassicSpacesCss';
    st.textContent=`
      .athinaSimpleHelloV249273{position:fixed;left:14px;bottom:104px;z-index:10060;max-width:min(430px,calc(100vw - 28px));border-radius:22px;border:1px solid rgba(255,217,110,.30);background:linear-gradient(165deg,rgba(3,12,23,.96),rgba(8,26,42,.96));box-shadow:0 20px 56px rgba(0,0,0,.42);color:#fff;padding:10px 12px;display:grid;grid-template-columns:auto 1fr auto;gap:9px;align-items:center;animation:athinaHelloInV249273 .22s ease-out}
      .athinaSimpleHelloV249273 .face{width:48px;height:48px;border-radius:16px;display:grid;place-items:center;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.11);overflow:hidden}
      .athinaSimpleHelloV249273 b{display:block;color:#ffe39b;font-size:14px}.athinaSimpleHelloV249273 small{display:block;color:rgba(239,248,255,.78);margin-top:2px;line-height:1.25}.athinaSimpleHelloV249273 .x{width:28px;height:28px;border-radius:50%;border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.08);color:#fff}
      .athinaSimpleHelloV249273.clickable{cursor:pointer}
      @keyframes athinaHelloInV249273{from{opacity:0;transform:translateY(8px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}
      .classicSpacesV249273{display:grid;gap:10px;padding-bottom:96px}
      .classicSpacesTopV249273{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:10px;padding:8px;border-radius:18px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08)}
      .classicSpacesTopV249273 .spacer{flex:1}.classicEmergencyBtnV249273{border-color:rgba(255,118,84,.34)!important;background:linear-gradient(135deg,rgba(255,118,84,.18),rgba(255,217,110,.08))!important}
      .classicRoomsHintV249273{border-radius:18px;padding:9px 11px;background:rgba(255,255,255,.055);border:1px solid rgba(255,217,110,.14);color:rgba(239,248,255,.82);line-height:1.35}
      .roomLayout.classicV249273{display:grid;grid-template-columns:minmax(240px,330px) minmax(0,1fr);gap:10px}
      .roomLayout.classicV249273 .roomList{max-height:calc(100dvh - 210px);overflow:auto;-webkit-overflow-scrolling:touch}
      .roomLayout.classicV249273 .chatPane{min-height:calc(100dvh - 210px)}
      .spaceTile.classicTileV249273{position:relative}.spaceTile.classicTileV249273 .spaceMiniBtns{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
      @media(max-width:820px){.roomLayout.classicV249273{grid-template-columns:1fr}.roomLayout.classicV249273 .roomList{max-height:42dvh}.roomLayout.classicV249273 .chatPane{min-height:52dvh}.athinaSimpleHelloV249273{bottom:90px;left:10px;right:10px;max-width:none}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function athinaFaceV249273(){
  try{return typeof athinaOwlV249258==='function'?athinaOwlV249258('small'):'🦉'}catch{return '🦉'}
}
function removeGuidePopupsV249273(){
  try{
    ['guideOverlayV249271','guideOverlayV249272','athinaWelcomeV249272'].forEach(id=>document.getElementById(id)?.remove());
  }catch(e){}
}
function closeAthinaSimpleHelloV249273(){
  try{document.getElementById('athinaSimpleHelloV249273')?.remove()}catch(e){}
  return false;
}
function showAthinaSimpleHelloV249273(force=false){
  try{
    injectV249273SimpleHelloClassicSpacesCss();
    removeGuidePopupsV249273();
    if(!force&&sessionStorage.getItem('ith_simple_hello_seen_v249273')==='1')return false;
    if(!force&&state.page&&state.page!=='home')return false;
    if(document.getElementById('athinaSimpleHelloV249273'))return false;
    sessionStorage.setItem('ith_simple_hello_seen_v249273','1');
    const d=document.createElement('div');
    d.id='athinaSimpleHelloV249273';
    d.className='athinaSimpleHelloV249273 clickable';
    d.innerHTML=`<div class="face">${athinaFaceV249273()}</div><div><b>Γεια σου, πώς είσαι σήμερα;</b><small>Πάτησέ με μόνο αν θέλεις ξενάγηση ή βοήθεια.</small></div><button class="x" type="button" aria-label="Κλείσιμο">×</button>`;
    d.onclick=(ev)=>{if(ev.target&&ev.target.closest&&ev.target.closest('.x'))return;closeAthinaSimpleHelloV249273();openFirstRunGuideV249273(true);};
    d.querySelector('.x').onclick=(ev)=>{ev.preventDefault();ev.stopPropagation();closeAthinaSimpleHelloV249273();};
    document.body.appendChild(d);
    setTimeout(()=>closeAthinaSimpleHelloV249273(),5000);
  }catch(e){}
  return false;
}
function openFirstRunGuideV249273(force=true,startMood=''){
  try{
    injectV249272AthinaGuideCss&&injectV249272AthinaGuideCss();
    injectV249273SimpleHelloClassicSpacesCss();
    removeGuidePopupsV249273();
    const d=document.createElement('div');
    d.id='guideOverlayV249272';
    d.className='guideOverlayV249272';
    d.innerHTML=`<div class="guideCardV249272">
      <div class="guideTopV249272"><div style="width:48px;height:48px;display:grid;place-items:center">${athinaFaceV249273()}</div><b>Bil · ξενάγηση OK ITHAKI</b><span class="spacer"></span><button type="button" data-close="1">×</button></div>
      <div class="guideBodyV249272">
        <div class="guideHeroV249272"><div style="min-width:74px">${athinaFaceV249273()}</div><div><h3>Πώς είσαι σήμερα;</h3><p>Το παράθυρο ανοίγει μόνο όταν πατήσεις τη μασκότ ή το μικρό γεια σου. Διάλεξε επιλογή ή κλείσε εύκολα με ×.</p></div></div>
        <div class="moodGridV249272">
          <button type="button" data-mood="good">🙂 Καλά<small>Δείξε μου γρήγορα τις βασικές λειτουργίες.</small></button>
          <button type="button" data-mood="neutral">😐 Έτσι κι έτσι<small>Θέλω ήρεμη ξενάγηση.</small></button>
          <button type="button" data-mood="bad">😟 Χάλια / άγχος<small>Πρότεινέ μου ήρεμη υποστήριξη.</small></button>
          <button type="button" data-mood="help">🕊️ Θέλω να μιλήσω ανώνυμα<small>Πήγαινέ με στον zero identity τοίχο.</small></button>
        </div>
        <div id="guideSuggestionV249272" class="guideSuggestionV249272"></div>
        <div class="tourGridV249272">
          <button type="button" data-go="feed">🎬 Ροή<small>Δημοσιεύσεις, σοφά λόγια, σχόλια και καρδιές.</small></button>
          <button type="button" data-go="dm">💬 Μηνύματα<small>Φίλοι, κλήσεις, αρχεία και αναζήτηση μηνυμάτων.</small></button>
          <button type="button" data-go="spaces">🏘️ Δωμάτια / Κοινότητες<small>Τα παλιά κανονικά δωμάτια/κοινότητες με κουμπιά.</small></button>
          <button type="button" data-go="emergency">🆘 Γειτονιά<small>Ξεχωριστή γειτονιά έκτακτης ανάγκης.</small></button>
        </div>
        <div class="guideActionsV249272"><button type="button" data-close="1">✓ Κλείσιμο</button></div>
      </div>
    </div>`;
    d.querySelectorAll('[data-close]').forEach(b=>b.onclick=()=>closeFirstRunGuideV249273(true));
    d.querySelectorAll('[data-mood]').forEach(b=>b.onclick=()=>answerGuideMoodV249273(b.dataset.mood));
    d.querySelectorAll('[data-go]').forEach(b=>b.onclick=()=>guideGoV249273(b.dataset.go));
    document.body.appendChild(d);
    if(startMood)setTimeout(()=>answerGuideMoodV249273(startMood),80);
  }catch(e){toast('Η ξενάγηση δεν άνοιξε: '+(e.message||e),5000)}
  return false;
}
function closeFirstRunGuideV249273(mark=true){
  try{document.getElementById('guideOverlayV249272')?.remove();document.getElementById('guideOverlayV249271')?.remove()}catch(e){}
  return false;
}
function answerGuideMoodV249273(mood){
  try{
    const box=$('guideSuggestionV249272');if(!box)return false;
    box.classList.add('show');
    if(mood==='bad'||mood==='help'){
      box.innerHTML=`<b>Δεν είσαι μόνος/μόνη.</b><p>Η Bil μπορεί να σε πάει στον zero identity τοίχο ή σε ήρεμες κοινότητες. Μην γράφεις προσωπικά στοιχεία αν δεν θέλεις να φανούν στο ίδιο το κείμενο.</p><div class="guideActionsV249272"><button type="button" id="gZeroV249273">🕊️ Zero identity τοίχος</button><button type="button" id="gSpacesV249273">🌿 Ήρεμες κοινότητες</button><button type="button" id="gDmV249273">💬 Μίλα με φίλο</button></div>`;
      setTimeout(()=>{try{$('gZeroV249273').onclick=()=>guideGoV249273('zero');$('gSpacesV249273').onclick=()=>guideGoV249273('spaces');$('gDmV249273').onclick=()=>guideGoV249273('dm')}catch(e){}},20);
    }else if(mood==='neutral'){
      box.innerHTML=`<b>Πάμε ήρεμα.</b><p>Ξεκίνα από τα παλιά κανονικά Δωμάτια/Κοινότητες ή τα Μηνύματα. Το παράθυρο δεν ξανανοίγει μόνο του.</p>`;
    }else{
      box.innerHTML=`<b>Χαίρομαι.</b><p>Πάτησε Ροή, Μηνύματα ή Δωμάτια. Αν χρειαστείς ξενάγηση ξανά, πάτα τη μασκότ.</p>`;
    }
  }catch(e){}
  return false;
}
function guideGoV249273(where){
  try{
    closeFirstRunGuideV249273(true);
    if(where==='zero'&&typeof openZeroSupportWallV249270==='function'){page('spaces');setTimeout(()=>openZeroSupportWallV249270(),180);return false}
    if(where==='emergency'&&typeof openEmergencyNeighborhoodV249270==='function'){page('spaces');setTimeout(()=>openEmergencyNeighborhoodV249270(),180);return false}
    if(where==='feed')return page('feed');
    if(where==='dm')return page('dm');
    if(where==='spaces')return page('spaces');
  }catch(e){toast('Δεν άνοιξε η επιλογή.')}
  return false;
}
function attachGuideToMascotV249273(){
  try{
    const b=document.getElementById('athinaFabV249258');
    if(b){
      b.title='Bil · πάτησε για ξενάγηση';
      b.setAttribute('aria-label','Bil · πάτησε για ξενάγηση');
      b.onclick=(ev)=>{try{ev.preventDefault();ev.stopPropagation()}catch(e){};openFirstRunGuideV249273(true);return false};
    }
  }catch(e){}
}
function v249273IsEmergencyId(id){return String(id||'')==='emergency_neighborhood_mesh_v249270'}
async function renderSpaces(){if(window.__ITHAKI_R10F15_SINGLE_COMMUNITY_RUNTIME__)return __ithakiCanonicalSpacesR10F15();
  injectV249273SimpleHelloClassicSpacesCss();
  state.spaceTab=state.spaceTab||'rooms';
  state.spaceScreen='classic';
  const e=$('spacesPage');if(!e)return false;
  e.innerHTML=`<div class="classicSpacesV249273">
    <div class="classicSpacesTopV249273">
      <button class="icon" onclick="ITH.page('home')">‹</button>
      <button class="btn ${state.spaceTab==='rooms'?'green':''}" onclick="ITH.spaceTab('rooms')">🏠 ${uiText('Rooms')}</button>
      <button class="btn ${state.spaceTab==='communities'?'green':''}" onclick="ITH.spaceTab('communities')">🌐 ${uiText('Communities')}</button>
      <button class="btn gold" onclick="ITH.createSpaceCard()">＋ ${uiText('Create')}</button>
      <button class="btn" onclick="ITH.openPoll()">📊 Poll</button>
      <button class="btn" onclick="ITH.loadRooms()">🔄</button>
      <span class="spacer"></span>
      <button class="btn classicEmergencyBtnV249273" onclick="ITH.openEmergencyNeighborhoodV249270()">🆘 Γειτονιά</button>
      <button class="btn" onclick="ITH.openZeroSupportWallV249270()">🕊️ Ήρεμη υποστήριξη</button>
    </div>
    <div class="classicRoomsHintV249273">Τα δωμάτια και οι κοινότητες επανήλθαν κανονικά όπως ήταν, με τα κουμπιά τους. Η Γειτονιά έκτακτης ανάγκης είναι ξεχωριστή επιλογή.</div>
    <div id="spaceSamples" class="spaceSamples"></div>
    <div class="roomLayout classicV249273">
      <div><div id="roomList" class="roomList"></div></div>
      <div class="chatPane">
        <div class="chatHead"><b id="spaceTitle">${uiText('Choose a space')}</b>
          <button class="icon chatActionBtn" title="${uiText('Take photo')}" onclick="ITH.openSpaceMedia('photo',true)">📷</button>
          <button class="icon chatActionBtn" title="${uiText('Record video')}" onclick="ITH.openSpaceMedia('video',true)">🎥</button>
          <button class="icon chatActionBtn" title="${uiText('Record audio')}" onclick="ITH.startAudioRecording('space')">🎙️</button>
          <button class="icon" onclick="ITH.openSpaceMedia('file',false)">📎</button>
          <button class="icon" onclick="ITH.openMessageSearchV249269&&ITH.openMessageSearchV249269()">🔎</button>
          <button class="icon" onclick="ITH.openSpaceAnnouncementsV249269&&ITH.openSpaceAnnouncementsV249269(state.currentSpace)">📣</button>
          <button class="icon" onclick="ITH.openE2EPanel()">🔐</button>
          <button class="icon" onclick="ITH.openSpaceAdmin()">⚙️</button>
        </div>
        <div id="spaceMsgs" class="messages"><div class="card">${uiText('Choose a space.')}</div></div>
        <div class="composer"><textarea id="spaceInput" placeholder="${uiText('Message this space...')}"></textarea><button class="icon" onclick="ITH.sendSpaceText()">➤</button></div>
      </div>
    </div>
  </div>`;
  try{renderSpaceSamples()}catch(e){}
  await loadRooms();
  if(state.currentSpaceChannel&&!v249273IsEmergencyId(state.currentSpace)){
    const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(state.currentSpace))||{};
    if($('spaceTitle'))$('spaceTitle').textContent=s.title||'Space';
    await loadSpaceMessages(true);
  }
  return false;
}
function renderRoomList(){
  const list=$('roomList');if(!list)return;
  const want=state.spaceTab==='communities'?'community':'room';
  let arr=(state.spaces||[]).filter(s=>(s.category||'room')===want&&!v249273IsEmergencyId(s.subroom_id));
  list.innerHTML=arr.map(s=>`<button class="tile spaceTile classicTileV249273" onclick="ITH.openSpace('${esc(s.subroom_id)}')"><b>${(s.category||want)==='community'?'🌐':'🏠'} ${esc(s.title||'Space')}</b><span class="date">${esc(s.access_type||'public')} ${s.join_code?'· code':''}</span><div class="spaceMiniBtns"><button class="btn" onclick="event.stopPropagation();ITH.inviteToSpace('${esc(s.subroom_id)}')">Invite</button><button class="btn" onclick="event.stopPropagation();ITH.showSpaceCode('${esc(s.subroom_id)}')">▦ Code</button><button class="btn" onclick="event.stopPropagation();ITH.openSpaceRulesV249268&&ITH.openSpaceRulesV249268('${esc(s.subroom_id)}')">📌</button></div></button>`).join('')||'<div class="card">Nothing here yet.</div>';
}
async function loadRooms(){
  try{
    const r=await fetchJson(`/api/rooms?room_id=${encodeURIComponent(state.room)}`);
    state.spaces=r.rooms||[];
    renderRoomList();
  }catch(e){
    const list=$('roomList'); if(list)list.innerHTML='<div class="card">Spaces are not loading.</div>';
  }
}
function spaceTab(tab){state.spaceTab=tab;return renderSpaces()}
async function openSpace(id){
  if(v249273IsEmergencyId(id)&&typeof openEmergencyNeighborhoodV249270==='function')return openEmergencyNeighborhoodV249270();
  const s=(state.spaces||[]).find(x=>String(x.subroom_id)===String(id))||{};
  const nextChannel='space:'+id;
  try{
    let join_code='';
    if(s.access_type==='private_code')join_code=prompt('Member code:')||'';
    await fetchJson('/api/rooms/join',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:id,device_id:state.device,nickname:state.name,join_code})});
  }catch(e){
    if(s.access_type==='invite'||s.access_type==='private_code'){
      const ask=confirm('Ο χώρος είναι κλειστός. Να σταλεί αίτημα συμμετοχής;');
      if(ask&&typeof requestJoinSpaceV249268==='function')return requestJoinSpaceV249268(id);
    }
    return toast('Correct code or approval required');
  }
  state.currentSpace=id;
  state.currentSpaceChannel=nextChannel;
  state.spaceScreen='classic';
  if($('spaceTitle'))$('spaceTitle').textContent=s.title||'Space';
  try{wsSubscribe(state.currentSpaceChannel)}catch(e){}
  await loadSpaceMessages(true);
  return false;
}
async function sendSpaceText(){
  const i=$('spaceInput');const txt=(i?.value||'').trim();
  if(!state.currentSpaceChannel)return toast('Choose a space');
  if(typeof v249268IsMuted==='function'&&v249268IsMuted(state.currentSpace,state.device))return toast('Έχεις προσωρινό mute στον χώρο.');
  if(!txt)return;
  i.value='';
  await sendMessagePayload(state.currentSpaceChannel,txt);
  if(!state.wsReady)loadSpaceMessages();
}
try{var renderHomeV249273Base=renderHome}catch(e){var renderHomeV249273Base=null}
renderHome=function(){
  let r=false;
  try{r=renderHomeV249273Base?renderHomeV249273Base.apply(this,arguments):false}catch(e){try{console.warn(e)}catch(_){}}
  try{setTimeout(()=>{removeGuidePopupsV249273();showAthinaSimpleHelloV249273(false);attachGuideToMascotV249273();},700)}catch(e){}
  return r;
};
try{var ensureAthinaCompanionV249273Base=ensureAthinaCompanionV249258}catch(e){var ensureAthinaCompanionV249273Base=null}
ensureAthinaCompanionV249258=function(){
  try{if(ensureAthinaCompanionV249273Base)ensureAthinaCompanionV249273Base.apply(this,arguments)}catch(e){}
  setTimeout(attachGuideToMascotV249273,80);
};
showAthinaWelcomeV249272=function(force=false){return showAthinaSimpleHelloV249273(force)}
openFirstRunGuideV249272=openFirstRunGuideV249273;
openFirstRunGuideV249271=openFirstRunGuideV249273;
closeFirstRunGuideV249272=closeFirstRunGuideV249273;
closeFirstRunGuideV249271=closeFirstRunGuideV249273;
answerGuideMoodV249272=answerGuideMoodV249273;
answerGuideMoodV249271=answerGuideMoodV249273;
try{
  window.openFirstRunGuideV249273=openFirstRunGuideV249273;
  window.closeFirstRunGuideV249273=closeFirstRunGuideV249273;
  window.answerGuideMoodV249273=answerGuideMoodV249273;
  window.showAthinaSimpleHelloV249273=showAthinaSimpleHelloV249273;
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{openFirstRunGuideV249273,closeFirstRunGuideV249273,answerGuideMoodV249273,showAthinaSimpleHelloV249273,openFirstRunGuideV249272:openFirstRunGuideV249273,closeFirstRunGuideV249272:closeFirstRunGuideV249273,answerGuideMoodV249272:answerGuideMoodV249273,renderSpaces,renderRoomList,loadRooms,spaceTab,openSpace,sendSpaceText});
  injectV249273SimpleHelloClassicSpacesCss();
  setTimeout(()=>{removeGuidePopupsV249273();attachGuideToMascotV249273();},1200);
  setInterval(()=>{removeGuidePopupsV249273();attachGuideToMascotV249273();},6000);
}catch(e){}



/* V249274 - Message in a Bottle real screen/menu */
function injectV249274BottleCss(){
  try{
    if(document.getElementById('ithV249274BottleCss'))return;
    const st=document.createElement('style');
    st.id='ithV249274BottleCss';
    st.textContent=`
      .bottleHomeCardV249274{position:relative;overflow:hidden;border-radius:24px;margin:12px 0;padding:14px;border:1px solid rgba(255,217,110,.24);background:radial-gradient(circle at 14% 18%,rgba(255,217,110,.20),transparent 26%),linear-gradient(135deg,rgba(7,34,58,.92),rgba(5,18,31,.94));box-shadow:0 18px 52px rgba(0,0,0,.28);color:#fff}
      .bottleHomeCardV249274:before{content:'';position:absolute;inset:-30% -10% auto auto;width:180px;height:180px;border-radius:50%;background:rgba(127,215,255,.13);filter:blur(2px)}
      .bottleHomeInnerV249274{position:relative;display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center}
      .bottleIconV249274{width:82px;height:82px;border-radius:28px;display:grid;place-items:center;background:radial-gradient(circle at 36% 24%,rgba(255,255,255,.30),rgba(127,215,255,.12) 38%,rgba(5,18,31,.26));border:1px solid rgba(255,217,110,.20);font-size:42px;box-shadow:inset 0 1px 0 rgba(255,255,255,.20)}
      .bottleHomeCardV249274 h3{margin:0;color:#ffe39b;font-size:20px}.bottleHomeCardV249274 p{margin:6px 0;color:rgba(239,248,255,.84);line-height:1.38}.bottleHomeCardV249274 .tag{display:inline-flex;border-radius:999px;padding:3px 8px;background:rgba(255,217,110,.15);border:1px solid rgba(255,217,110,.25);font-size:12px;font-weight:1000;color:#ffe39b}
      .bottleHomeCardV249274 button{border-radius:999px;border:1px solid rgba(255,217,110,.32);background:linear-gradient(135deg,#ffd76a,#f2b74a);color:#132234;padding:10px 13px;font-weight:1000;box-shadow:0 10px 24px rgba(0,0,0,.22)}
      .bottleSeaOverlayV249274{position:fixed;inset:0;z-index:10130;background:rgba(0,0,0,.66);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);display:flex;align-items:center;justify-content:center;padding:14px;box-sizing:border-box}
      .bottleSeaPanelV249274{width:min(860px,100%);max-height:94dvh;overflow:auto;border-radius:30px;border:1px solid rgba(255,217,110,.30);background:radial-gradient(circle at 20% 0%,rgba(127,215,255,.15),transparent 30%),linear-gradient(180deg,rgba(4,18,32,.98),rgba(6,25,42,.98));box-shadow:0 34px 110px rgba(0,0,0,.62);color:#fff}
      .bottleSeaTopV249274{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:10px;padding:12px 14px;background:rgba(3,12,23,.95);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}
      .bottleSeaTopV249274 b{color:#ffe39b;font-size:18px}.bottleSeaTopV249274 .spacer{flex:1}.bottleSeaTopV249274 button{width:40px;height:40px;border-radius:50%;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.08);color:#fff;font-weight:1000}
      .bottleHeroV249274{position:relative;min-height:210px;padding:18px;display:grid;grid-template-columns:1fr auto;gap:12px;align-items:end;background:linear-gradient(180deg,rgba(9,42,70,.32),rgba(3,12,23,.10));overflow:hidden}
      .bottleHeroV249274 .ship{position:absolute;right:24px;top:20px;font-size:58px;opacity:.62;filter:drop-shadow(0 10px 18px rgba(0,0,0,.35))}
      .bottleHeroV249274 .seaBottle{font-size:88px;transform:rotate(-18deg);filter:drop-shadow(0 20px 28px rgba(0,0,0,.42));animation:bottleFloatV249274 3.8s ease-in-out infinite}
      .bottleHeroV249274 h2{margin:0;color:#ffe39b;font-size:28px}.bottleHeroV249274 p{max-width:540px;margin:8px 0 0;color:rgba(239,248,255,.84);line-height:1.42}
      @keyframes bottleFloatV249274{0%,100%{transform:rotate(-18deg) translateY(0)}50%{transform:rotate(-10deg) translateY(-8px)}}
      .parchmentV249274{margin:0 14px 14px;padding:18px;border-radius:22px;background:radial-gradient(circle at 12% 0%,rgba(111,66,28,.12),transparent 30%),linear-gradient(135deg,#f5dfb3,#ead09a 48%,#f8e8c4);color:#1f3345;border:1px solid rgba(100,61,26,.30);box-shadow:inset 0 0 28px rgba(92,53,18,.16),0 18px 50px rgba(0,0,0,.28);position:relative}
      .parchmentV249274:before,.parchmentV249274:after{content:'';position:absolute;width:72px;height:34px;background:rgba(90,50,16,.12);filter:blur(1px);border-radius:50%;top:-7px}.parchmentV249274:before{left:18px;transform:rotate(-8deg)}.parchmentV249274:after{right:18px;transform:rotate(9deg)}
      .parchmentV249274 h3{text-align:center;margin:0 0 12px;color:#1c4161;font-size:24px}.parchmentV249274 textarea{width:100%;min-height:130px;box-sizing:border-box;border-radius:16px;border:1px solid rgba(63,42,17,.28);background:rgba(255,255,255,.36);color:#1d2d3c;padding:13px;font-size:16px;resize:vertical;outline:none}
      .bottleOptionsV249274{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:10px}.bottleOptionsV249274 button{border-radius:16px;border:1px solid rgba(28,65,97,.22);background:rgba(255,255,255,.38);color:#1f3345;padding:10px;font-weight:1000}.bottleOptionsV249274 button.active{outline:2px solid rgba(30,96,135,.55);background:rgba(127,215,255,.20)}
      .bottleActionV249274{width:100%;margin-top:13px;border-radius:18px;border:1px solid rgba(255,217,110,.32);background:linear-gradient(135deg,#0e4a75,#062c4b);color:#fff;padding:13px;font-size:18px;font-weight:1000;box-shadow:0 12px 28px rgba(0,0,0,.22)}
      .bottleTabsV249274{display:flex;gap:8px;flex-wrap:wrap;padding:0 14px 12px}.bottleTabsV249274 button{border-radius:999px;border:1px solid rgba(255,217,110,.22);background:rgba(255,255,255,.07);color:#fff;padding:9px 12px;font-weight:1000}.bottleTabsV249274 button.active{background:rgba(255,217,110,.16);color:#ffe39b}
      .bottleListV249274{padding:0 14px 18px;display:grid;gap:10px}.bottleItemV249274{border-radius:20px;padding:12px;background:rgba(255,255,255,.065);border:1px solid rgba(255,255,255,.11);color:#fff}.bottleItemV249274 b{color:#ffe39b}.bottleItemV249274 p{white-space:pre-wrap;color:rgba(239,248,255,.86);line-height:1.38}.bottleItemV249274 .reply{border-left:3px solid rgba(127,215,255,.55);padding-left:10px;margin-top:8px;color:#dff8ff}
      .bottleReplyBoxV249274 textarea{width:100%;min-height:88px;border-radius:14px;border:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.18);color:#fff;padding:10px;box-sizing:border-box}
      .bottleSmallNoteV249274{font-size:12px;color:rgba(239,248,255,.72);margin-top:8px}
      @media(max-width:760px){.bottleHomeInnerV249274{grid-template-columns:auto 1fr}.bottleHomeInnerV249274 button{grid-column:1/-1;width:100%}.bottleHeroV249274{grid-template-columns:1fr;text-align:center}.bottleOptionsV249274{grid-template-columns:1fr}.bottleHeroV249274 .seaBottle{font-size:70px}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function bottleTokenV249274(){
  try{
    let t=localStorage.getItem('ith_bottle_token_v249274')||'';
    if(!t){t='bt_'+Math.random().toString(36).slice(2)+Date.now().toString(36)+Math.random().toString(36).slice(2);localStorage.setItem('ith_bottle_token_v249274',t)}
    return t;
  }catch{return 'bt_'+state.device}
}
function bottleCardV249274(){
  injectV249274BottleCss();
  return `<section class="bottleHomeCardV249274"><div class="bottleHomeInnerV249274"><div class="bottleIconV249274">🍾</div><div><span class="tag">ΝΕΟ</span><h3>Μήνυμα στο Μπουκάλι</h3><p>Γράφεις μια σκέψη, μια ερώτηση ή μια ευχή και τη ρίχνεις στη θάλασσα. Φτάνει ανώνυμα σε έναν άγνωστο — και αν θέλετε, συνεχίζετε.</p></div><button onclick="ITH.openBottleSeaV249274('compose')">Ρίξε μήνυμα ›</button></div></section>`;
}
try{var renderHomeV249274Base=renderHome}catch(e){var renderHomeV249274Base=null}
renderHome=function(){
  const r=renderHomeV249274Base?renderHomeV249274Base.apply(this,arguments):false;
  try{
    injectV249274BottleCss();
    const h=$('homePage');
    if(h&&!document.getElementById('bottleHomeMountV249274')){
      const wrap=document.createElement('div');wrap.id='bottleHomeMountV249274';wrap.innerHTML=bottleCardV249274();
      const target=h.querySelector('.homeProPanel,.homeMenu,.welcomeHero')||h.firstElementChild;
      if(target&&target.parentNode)target.parentNode.insertBefore(wrap,target.nextSibling); else h.prepend(wrap);
    }
  }catch(e){}
  return r;
};
function bottleSetModeV249274(mode){
  try{localStorage.setItem('ith_bottle_mode_v249274',mode);document.querySelectorAll('.bottleOptionsV249274 button').forEach(b=>b.classList.toggle('active',b.dataset.mode===mode))}catch(e){}
  return false;
}
function bottleModeV249274(){try{return localStorage.getItem('ith_bottle_mode_v249274')||'random'}catch{return 'random'}}
function closeBottleSeaV249274(){try{document.getElementById('bottleSeaOverlayV249274')?.remove()}catch(e){}return false}
function openBottleSeaV249274(tab='compose'){
  injectV249274BottleCss();
  closeBottleSeaV249274();
  const d=document.createElement('div');
  d.id='bottleSeaOverlayV249274';
  d.className='bottleSeaOverlayV249274';
  d.innerHTML=`<div class="bottleSeaPanelV249274">
    <div class="bottleSeaTopV249274"><b>🍾 Μήνυμα στο Μπουκάλι</b><span class="spacer"></span><button type="button" onclick="ITH.closeBottleSeaV249274()">×</button></div>
    <div class="bottleHeroV249274"><div><div class="ship">⛵</div><h2>Η θάλασσα ενώνει ανώνυμα.</h2><p>Ρίχνεις μια σκέψη στη θάλασσα. Ένας άγνωστος τη βρίσκει. Απαντάει ανώνυμα. Αν και οι δύο θέλετε, συνεχίζετε· αλλιώς το μπουκάλι χάνεται.</p></div><div class="seaBottle">🍾</div></div>
    <div class="bottleTabsV249274"><button data-tab="compose">✍️ Ρίξε μήνυμα</button><button data-tab="find">🌊 Βρες μπουκάλι</button><button data-tab="mine">📬 Οι απαντήσεις μου</button></div>
    <div id="bottleBodyV249274"></div>
  </div>`;
  document.body.appendChild(d);
  d.querySelectorAll('[data-tab]').forEach(b=>b.onclick=()=>renderBottleTabV249274(b.dataset.tab));
  renderBottleTabV249274(tab);
  return false;
}
function renderBottleTabV249274(tab='compose'){
  const body=$('bottleBodyV249274');if(!body)return false;
  document.querySelectorAll('.bottleTabsV249274 button').forEach(b=>b.classList.toggle('active',b.dataset.tab===tab));
  if(tab==='compose'){
    const mode=bottleModeV249274();
    body.innerHTML=`<div class="parchmentV249274"><h3>Ρίξε το μήνυμα στη θάλασσα</h3><textarea id="bottleTextV249274" maxlength="900" placeholder="Γράψε μια σκέψη, μια ερώτηση ή μια ευχή..."></textarea><div class="bottleOptionsV249274"><button data-mode="random" onclick="ITH.bottleSetModeV249274('random')">👤 Τυχαίος άγνωστος</button><button data-mode="mesh" onclick="ITH.bottleSetModeV249274('mesh')">📍 Κοντά μου μέσω mesh</button><button data-mode="vanish" onclick="ITH.bottleSetModeV249274('vanish')">👻 Χωρίς ίχνος μετά τη σύνδεση</button></div><div class="bottleSmallNoteV249274">🔒 Δεν γράφεται device_id/nickname στον πίνακα bottle_messages. Η απάντηση γυρίζει με τοπικό μυστικό token στη συσκευή σου.</div><button class="bottleActionV249274" onclick="ITH.dropBottleV249274()">🍾 Ρίξ’ το στη θάλασσα</button></div>`;
    bottleSetModeV249274(mode);
    setTimeout(()=>$('bottleTextV249274')?.focus(),80);
  }else if(tab==='find'){
    body.innerHTML=`<div class="bottleListV249274"><button class="bottleActionV249274" onclick="ITH.findBottleV249274()">🌊 Βρες ένα μπουκάλι στη θάλασσα</button><div id="bottleFindResultV249274" class="bottleItemV249274"><b>Περιμένει ένα μπουκάλι κάπου στη θάλασσα.</b><p>Πάτησε για να βρεις ένα τυχαίο ανώνυμο μήνυμα που δεν είναι δικό σου.</p></div></div>`;
  }else{
    body.innerHTML=`<div class="bottleListV249274"><button class="bottleActionV249274" onclick="ITH.loadMyBottlesV249274()">📬 Φόρτωση απαντήσεων</button><div id="myBottlesV249274"></div></div>`;
    loadMyBottlesV249274();
  }
  return false;
}
async function dropBottleV249274(){
  const txt=($('bottleTextV249274')?.value||'').trim();
  if(!txt)return toast('Γράψε πρώτα μήνυμα.');
  const mode=bottleModeV249274();
  try{
    const r=await fetchJson('/api/bottle/drop',{method:'POST',body:JSON.stringify({room_id:state.room,owner_token:bottleTokenV249274(),text:txt,mode:mode==='vanish'?'random':mode,mesh:mode==='mesh',vanish:mode==='vanish'})});
    toast('Το μπουκάλι έπεσε στη θάλασσα.');
    renderBottleTabV249274('mine');
  }catch(e){
    toast('Δεν στάλθηκε το μπουκάλι: '+(e.message||e),7000);
  }
  return false;
}
async function findBottleV249274(){
  const box=$('bottleFindResultV249274');if(box)box.innerHTML='<b>Ψάχνω στη θάλασσα...</b>';
  try{
    const mesh=bottleModeV249274()==='mesh'?1:0;
    const r=await fetchJson(`/api/bottle/random?room_id=${encodeURIComponent(state.room)}&owner_token=${encodeURIComponent(bottleTokenV249274())}&mesh=${mesh}`);
    if(!r.bottle){if(box)box.innerHTML='<b>Δεν βρέθηκε μπουκάλι τώρα.</b><p>Δοκίμασε αργότερα ή ρίξε εσύ ένα πρώτο μήνυμα.</p>';return false}
    const b=r.bottle;
    if(box)box.innerHTML=`<b>Βρήκες ένα μπουκάλι</b><p>${esc(b.text)}</p><div class="bottleReplyBoxV249274"><textarea id="bottleReplyTextV249274" placeholder="Απάντησε ανώνυμα..."></textarea><label style="display:block;margin:8px 0"><input id="bottleContinueOkV249274" type="checkbox"> Αν θέλει και ο άλλος, μπορώ να συνεχίσω τη σύνδεση.</label><button class="bottleActionV249274" onclick="ITH.replyBottleV249274('${escJs(b.bottle_id)}')">↩ Απάντηση ανώνυμα</button></div>`;
  }catch(e){if(box)box.innerHTML='<b>Δεν φορτώνει η θάλασσα.</b><p>'+esc(e.message||e)+'</p>'}
  return false;
}
async function replyBottleV249274(id){
  const txt=($('bottleReplyTextV249274')?.value||'').trim();
  if(!txt)return toast('Γράψε απάντηση.');
  try{
    await fetchJson('/api/bottle/reply',{method:'POST',body:JSON.stringify({room_id:state.room,bottle_id:id,replier_token:bottleTokenV249274(),text:txt,continue_ok:!!$('bottleContinueOkV249274')?.checked})});
    toast('Η απάντηση γύρισε ανώνυμα στον αποστολέα.');
    renderBottleTabV249274('find');
  }catch(e){toast('Δεν στάλθηκε απάντηση: '+(e.message||e),7000)}
  return false;
}
async function loadMyBottlesV249274(){
  const box=$('myBottlesV249274');if(!box)return false;
  box.innerHTML='<div class="bottleItemV249274"><b>Φόρτωση...</b></div>';
  try{
    const r=await fetchJson(`/api/bottle/mine?room_id=${encodeURIComponent(state.room)}&owner_token=${encodeURIComponent(bottleTokenV249274())}&limit=80`);
    const items=r.items||[];
    box.innerHTML=items.map(x=>`<div class="bottleItemV249274"><b>🍾 ${esc(x.status||'floating')}</b><div class="date">${fmt(x.created_at)}</div><p>${esc(x.text||'')}</p>${x.reply_text?`<div class="reply"><b>Απάντηση από άγνωστο:</b><p>${esc(x.reply_text)}</p></div><div class="row" style="gap:7px;flex-wrap:wrap"><button class="btn green" onclick="ITH.openBottleThreadV249274('${escJs(x.bottle_id)}')">Συνέχεια ανώνυμα</button><button class="btn" onclick="ITH.vanishBottleV249274('${escJs(x.bottle_id)}')">Να χαθεί</button></div>`:'<div class="date">Ακόμη ταξιδεύει στη θάλασσα.</div>'}</div>`).join('')||'<div class="bottleItemV249274"><b>Δεν έχεις ρίξει μπουκάλι ακόμη.</b></div>';
  }catch(e){box.innerHTML='<div class="bottleItemV249274"><b>Δεν φορτώνουν οι απαντήσεις.</b><p>'+esc(e.message||e)+'</p></div>'}
  return false;
}
async function openBottleThreadV249274(id){
  const body=$('bottleBodyV249274');if(!body)return false;
  body.innerHTML=`<div class="bottleListV249274"><div id="bottleThreadV249274" class="bottleItemV249274">Φόρτωση σύνδεσης...</div><div class="bottleReplyBoxV249274"><textarea id="bottleThreadTextV249274" placeholder="Συνέχισε ανώνυμα..."></textarea><button class="bottleActionV249274" onclick="ITH.sendBottleThreadV249274('${escJs(id)}')">Αποστολή στη σύνδεση</button></div></div>`;
  await loadBottleThreadV249274(id);
  return false;
}
async function loadBottleThreadV249274(id){
  const box=$('bottleThreadV249274');if(!box)return false;
  try{
    const r=await fetchJson(`/api/bottle/thread?room_id=${encodeURIComponent(state.room)}&bottle_id=${encodeURIComponent(id)}&token=${encodeURIComponent(bottleTokenV249274())}`);
    const top=`<b>Ανώνυμη σύνδεση</b><p>${esc(r.bottle?.text||'')}</p>${r.bottle?.reply_text?`<div class="reply">${esc(r.bottle.reply_text)}</div>`:''}`;
    const msgs=(r.items||[]).map(m=>`<div class="reply"><b>${m.author_role==='owner'?'Εσύ':'Άγνωστος'}</b><p>${esc(m.text)}</p><div class="date">${fmt(m.created_at)}</div></div>`).join('');
    box.innerHTML=top+msgs;
  }catch(e){box.innerHTML='<b>Δεν ανοίγει η σύνδεση.</b><p>'+esc(e.message||e)+'</p>'}
}
async function sendBottleThreadV249274(id){
  const txt=($('bottleThreadTextV249274')?.value||'').trim();
  if(!txt)return toast('Γράψε μήνυμα.');
  try{
    await fetchJson('/api/bottle/thread/send',{method:'POST',body:JSON.stringify({room_id:state.room,bottle_id:id,token:bottleTokenV249274(),text:txt})});
    $('bottleThreadTextV249274').value='';
    await loadBottleThreadV249274(id);
  }catch(e){toast('Δεν στάλθηκε: '+(e.message||e),7000)}
  return false;
}
async function vanishBottleV249274(id){
  if(!confirm('Να χαθεί το μπουκάλι και η σύνδεση;'))return false;
  try{await fetchJson('/api/bottle/vanish',{method:'POST',body:JSON.stringify({room_id:state.room,bottle_id:id,token:bottleTokenV249274(),text:''})});toast('Το μπουκάλι χάθηκε.');loadMyBottlesV249274()}catch(e){toast('Δεν χάθηκε: '+(e.message||e),7000)}
  return false;
}
try{
  window.ITH=window.ITH||{};
  Object.assign(window.ITH,{openBottleSeaV249274,closeBottleSeaV249274,bottleSetModeV249274,dropBottleV249274,findBottleV249274,replyBottleV249274,loadMyBottlesV249274,openBottleThreadV249274,sendBottleThreadV249274,vanishBottleV249274});
  injectV249274BottleCss();
}catch(e){}



/* V249275 - stable Athina guide and working bottle exports after boot */
function injectV249275StableFixCss(){
  try{
    if(document.getElementById('ithV249275StableFixCss'))return;
    const st=document.createElement('style');
    st.id='ithV249275StableFixCss';
    st.textContent=`
      .guideOverlayV249275{position:fixed;inset:0;z-index:10180;background:rgba(0,0,0,.64);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);display:flex;align-items:center;justify-content:center;padding:14px;box-sizing:border-box}
      .guideCardV249275{width:min(760px,100%);max-height:92dvh;overflow:auto;border-radius:28px;border:1px solid rgba(255,217,110,.34);background:linear-gradient(165deg,rgba(3,12,23,.99),rgba(8,24,39,.99));box-shadow:0 34px 100px rgba(0,0,0,.62);color:#fff}
      .guideTopV249275{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:10px;padding:13px;background:rgba(3,12,23,.96);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}
      .guideTopV249275 b{color:#ffe39b;font-size:18px}.guideTopV249275 .spacer{flex:1}.guideTopV249275 button{border-radius:50%;width:42px;height:42px;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.08);color:#fff;font-weight:1000;font-size:20px}
      .guideBodyV249275{padding:14px;display:grid;gap:12px}
      .guideHeroV249275{display:grid;grid-template-columns:auto 1fr;gap:13px;align-items:center;border-radius:22px;padding:13px;background:radial-gradient(circle at 16% 0%,rgba(255,217,110,.15),transparent 30%),rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.10)}
      .guideHeroV249275 h3{margin:0 0 5px;color:#ffe39b}.guideHeroV249275 p{margin:0;color:rgba(239,248,255,.84);line-height:1.42}
      .moodGridV249275,.tourGridV249275{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.moodGridV249275 button,.tourGridV249275 button,.guideActionsV249275 button{border-radius:20px;border:1px solid rgba(255,217,110,.20);background:rgba(255,255,255,.065);color:#fff;padding:12px;text-align:left;font-weight:1000}.moodGridV249275 button small,.tourGridV249275 button small{display:block;color:rgba(239,248,255,.70);font-weight:700;margin-top:4px;line-height:1.34}
      .guideSuggestionV249275{display:none;border-radius:20px;padding:12px;background:linear-gradient(135deg,rgba(127,215,255,.13),rgba(54,240,160,.08));border:1px solid rgba(127,215,255,.26)}
      .guideSuggestionV249275.show{display:block}.guideSuggestionV249275 b{color:#9ee7ff}.guideSuggestionV249275 p{margin:6px 0;color:rgba(239,248,255,.84);line-height:1.4}
      .guideActionsV249275{display:flex;gap:8px;flex-wrap:wrap}.guideActionsV249275 button{border-radius:999px;text-align:center;padding:10px 13px}
      .bottleErrorV249275{border-radius:16px;padding:10px;background:rgba(255,105,105,.10);border:1px solid rgba(255,105,105,.24);color:#ffd6d6;margin:10px 14px}
      @media(max-width:760px){.guideHeroV249275{grid-template-columns:1fr;text-align:center}.moodGridV249275,.tourGridV249275{grid-template-columns:1fr}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function stableAthinaFaceV249275(){
  try{return typeof athinaOwlV249258==='function'?athinaOwlV249258('small'):'🦉'}catch{return '🦉'}
}
removeBrokenGuidesV249272=function(){
  try{
    document.getElementById('guideOverlayV249271')?.remove();
    document.getElementById('athinaWelcomeV249272')?.remove();
  }catch(e){}
};
removeGuidePopupsV249273=function(){
  try{
    document.getElementById('guideOverlayV249271')?.remove();
    document.getElementById('athinaWelcomeV249272')?.remove();
  }catch(e){}
};
function closeFirstRunGuideV249275(mark=true){
  try{document.getElementById('guideOverlayV249275')?.remove();document.getElementById('guideOverlayV249272')?.remove();document.getElementById('guideOverlayV249271')?.remove()}catch(e){}
  return false;
}
function openFirstRunGuideV249275(force=true,startMood=''){
  try{
    injectV249275StableFixCss();
    closeFirstRunGuideV249275(false);
    const d=document.createElement('div');
    d.id='guideOverlayV249275';
    d.className='guideOverlayV249275';
    d.setAttribute('data-stable','1');
    d.innerHTML=`<div class="guideCardV249275">
      <div class="guideTopV249275"><div style="width:48px;height:48px;display:grid;place-items:center">${stableAthinaFaceV249275()}</div><b>Bil · ξενάγηση OK ITHAKI</b><span class="spacer"></span><button type="button" data-close="1">×</button></div>
      <div class="guideBodyV249275">
        <div class="guideHeroV249275"><div style="min-width:74px">${stableAthinaFaceV249275()}</div><div><h3>Πώς είσαι σήμερα;</h3><p>Αυτή η κάρτα δεν κλείνει μόνη της. Κλείνει μόνο με × ή όταν διαλέξεις λειτουργία.</p></div></div>
        <div class="moodGridV249275">
          <button type="button" data-mood="good">🙂 Καλά<small>Δείξε μου γρήγορα τις βασικές λειτουργίες.</small></button>
          <button type="button" data-mood="neutral">😐 Έτσι κι έτσι<small>Θέλω ήρεμη ξενάγηση.</small></button>
          <button type="button" data-mood="bad">😟 Χάλια / άγχος<small>Πρότεινέ μου ήρεμη υποστήριξη.</small></button>
          <button type="button" data-mood="help">🕊️ Θέλω να μιλήσω ανώνυμα<small>Πήγαινέ με στον zero identity τοίχο.</small></button>
        </div>
        <div id="guideSuggestionV249275" class="guideSuggestionV249275"></div>
        <div class="tourGridV249275">
          <button type="button" data-go="bottle">🍾 Μήνυμα στο Μπουκάλι<small>Ρίξε μια σκέψη στη θάλασσα.</small></button>
          <button type="button" data-go="feed">🎬 Ροή<small>Δημοσιεύσεις, σοφά λόγια, σχόλια.</small></button>
          <button type="button" data-go="dm">💬 Μηνύματα<small>Φίλοι, κλήσεις, αρχεία.</small></button>
          <button type="button" data-go="spaces">🏘️ Δωμάτια / Κοινότητες<small>Τα κανονικά δωμάτια και κοινότητες.</small></button>
          <button type="button" data-go="emergency">🆘 Γειτονιά<small>Ξεχωριστή γειτονιά έκτακτης ανάγκης.</small></button>
          <button type="button" data-go="zero">🕊️ Ήρεμη υποστήριξη<small>Zero identity τοίχος.</small></button>
        </div>
        <div class="guideActionsV249275"><button type="button" data-close="1">✓ Κλείσιμο</button></div>
      </div>
    </div>`;
    d.querySelectorAll('[data-close]').forEach(b=>b.onclick=()=>closeFirstRunGuideV249275(true));
    d.querySelectorAll('[data-mood]').forEach(b=>b.onclick=()=>answerGuideMoodV249275(b.dataset.mood));
    d.querySelectorAll('[data-go]').forEach(b=>b.onclick=()=>guideGoV249275(b.dataset.go));
    document.body.appendChild(d);
    if(startMood)setTimeout(()=>answerGuideMoodV249275(startMood),80);
  }catch(e){toast('Η ξενάγηση δεν άνοιξε: '+(e.message||e),5000)}
  return false;
}
function answerGuideMoodV249275(mood){
  try{
    const box=$('guideSuggestionV249275');if(!box)return false;
    box.classList.add('show');
    if(mood==='bad'||mood==='help'){
      box.innerHTML=`<b>Δεν είσαι μόνος/μόνη.</b><p>Μπορείς να πας στον zero identity τοίχο ή σε ήρεμες κοινότητες. Η επιλογή λειτουργεί χωρίς να κλείνει μόνη της η κάρτα.</p><div class="guideActionsV249275"><button type="button" id="gZeroV249275">🕊️ Zero identity τοίχος</button><button type="button" id="gSpacesV249275">🌿 Ήρεμες κοινότητες</button><button type="button" id="gDmV249275">💬 Μίλα με φίλο</button></div>`;
      setTimeout(()=>{try{$('gZeroV249275').onclick=()=>guideGoV249275('zero');$('gSpacesV249275').onclick=()=>guideGoV249275('spaces');$('gDmV249275').onclick=()=>guideGoV249275('dm')}catch(e){}},20);
    }else if(mood==='neutral'){
      box.innerHTML=`<b>Πάμε ήρεμα.</b><p>Διάλεξε όποια λειτουργία θέλεις. Η κάρτα μένει ανοιχτή μέχρι να την κλείσεις.</p>`;
    }else{
      box.innerHTML=`<b>Χαίρομαι.</b><p>Ξεκίνα από τη Ροή, τα Μηνύματα ή το Μπουκάλι.</p>`;
    }
  }catch(e){}
  return false;
}
function guideGoV249275(where){
  try{
    closeFirstRunGuideV249275(true);
    if(where==='bottle')return openBottleSeaV249274('compose');
    if(where==='zero'&&typeof openZeroSupportWallV249270==='function'){page('spaces');setTimeout(()=>openZeroSupportWallV249270(),180);return false}
    if(where==='emergency'&&typeof openEmergencyNeighborhoodV249270==='function'){page('spaces');setTimeout(()=>openEmergencyNeighborhoodV249270(),180);return false}
    if(where==='feed')return page('feed');
    if(where==='dm')return page('dm');
    if(where==='spaces')return page('spaces');
  }catch(e){toast('Δεν άνοιξε η επιλογή: '+(e.message||e),5000)}
  return false;
}
function attachGuideToMascotV249275(){
  try{
    const b=document.getElementById('athinaFabV249258');
    if(b){
      b.title='Bil · πάτησε για ξενάγηση';
      b.setAttribute('aria-label','Bil · πάτησε για ξενάγηση');
      b.onclick=(ev)=>{try{ev.preventDefault();ev.stopPropagation()}catch(e){};openFirstRunGuideV249275(true);return false};
    }
  }catch(e){}
}
function installBottleExportsV249275(){
  try{
    window.ITH=window.ITH||{};
    Object.assign(window.ITH,{
      openBottleSeaV249274,closeBottleSeaV249274,bottleSetModeV249274,dropBottleV249274,findBottleV249274,replyBottleV249274,loadMyBottlesV249274,openBottleThreadV249274,sendBottleThreadV249274,vanishBottleV249274,
      openFirstRunGuideV249275,closeFirstRunGuideV249275,answerGuideMoodV249275,guideGoV249275,
      openFirstRunGuideV249273:openFirstRunGuideV249275,
      openFirstRunGuideV249272:openFirstRunGuideV249275,
      openFirstRunGuideV249271:openFirstRunGuideV249275
    });
    window.openBottleSeaV249274=openBottleSeaV249274;
    window.openFirstRunGuideV249275=openFirstRunGuideV249275;
    window.openFirstRunGuideV249273=openFirstRunGuideV249275;
    window.closeFirstRunGuideV249275=closeFirstRunGuideV249275;
    attachGuideToMascotV249275();
  }catch(e){}
}
try{var renderHomeV249275Base=renderHome}catch(e){var renderHomeV249275Base=null}
renderHome=function(){
  const r=renderHomeV249275Base?renderHomeV249275Base.apply(this,arguments):false;
  try{
    injectV249275StableFixCss();
    setTimeout(()=>{installBottleExportsV249275();},250);
    setTimeout(()=>{installBottleExportsV249275();},1200);
  }catch(e){}
  return r;
};
try{var ensureAthinaCompanionV249275Base=ensureAthinaCompanionV249258}catch(e){var ensureAthinaCompanionV249275Base=null}
ensureAthinaCompanionV249258=function(){
  try{if(ensureAthinaCompanionV249275Base)ensureAthinaCompanionV249275Base.apply(this,arguments)}catch(e){}
  setTimeout(installBottleExportsV249275,120);
};
openFirstRunGuideV249273=openFirstRunGuideV249275;
openFirstRunGuideV249272=openFirstRunGuideV249275;
openFirstRunGuideV249271=openFirstRunGuideV249275;
closeFirstRunGuideV249273=closeFirstRunGuideV249275;
closeFirstRunGuideV249272=closeFirstRunGuideV249275;
closeFirstRunGuideV249271=closeFirstRunGuideV249275;
answerGuideMoodV249273=answerGuideMoodV249275;
answerGuideMoodV249272=answerGuideMoodV249275;
answerGuideMoodV249271=answerGuideMoodV249275;
try{
  injectV249275StableFixCss();
  installBottleExportsV249275();
  setTimeout(installBottleExportsV249275,700);
  setTimeout(installBottleExportsV249275,1800);
  setInterval(installBottleExportsV249275,4000);
}catch(e){}



/* V249276 - stop Athina auto cards, privacy score stays open, ancient ship logo everywhere, fixed spaces buttons */
function injectV249276HardFixCss(){
  try{
    if(document.getElementById('ithV249276HardFixCss'))return;
    const st=document.createElement('style');
    st.id='ithV249276HardFixCss';
    st.textContent=`
      .ancientShipLogoV249276{width:42px;height:42px;object-fit:contain;display:inline-block;vertical-align:middle;filter:drop-shadow(0 8px 14px rgba(0,0,0,.28))}
      .bottleHeroV249274 .ship{font-size:0!important;display:grid!important;place-items:center!important;width:82px!important;height:82px!important;opacity:1!important}
      .bottleHeroV249274 .ship img{width:76px;height:76px;object-fit:contain;filter:drop-shadow(0 12px 20px rgba(0,0,0,.34))}
      .privacyStableV249276{max-height:94dvh!important;overflow:auto!important;-webkit-overflow-scrolling:touch!important}
      .privacyStableV249276 *{pointer-events:auto}
      .classicSpacesTopV249273 .classicEmergencyBtnV249273,.classicSpacesTopV249273 .calmSupportBtnV249276{position:relative;z-index:5}
      .privacyMeterV249276{height:12px;border-radius:999px;background:rgba(255,255,255,.12);overflow:hidden;margin:8px 0}.privacyMeterV249276 i{display:block;height:100%;width:var(--w,92%);background:linear-gradient(90deg,#54f0a0,#ffe39b)}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function ancientShipLogoV249276(cls=''){
  return `<img class="ancientShipLogoV249276 ${cls||''}" src="ok_ithaki_ship_logo.png" alt="OK ITHAKI" onerror="this.replaceWith(document.createTextNode('⛵'))">`;
}
function applyAncientShipLogoV249276(){
  try{
    document.querySelectorAll('.bottleHeroV249274 .ship,.shipMiniWrapV249276').forEach(el=>{if(!el.querySelector('img'))el.innerHTML=ancientShipLogoV249276()});
    document.querySelectorAll('.shipMini').forEach(el=>{if(el.tagName!=='IMG'&&!el.querySelector('img'))el.innerHTML=ancientShipLogoV249276('small')});
  }catch(e){}
}
function anyBlockingPanelOpenV249276(){
  try{
    const m=$('memberMenu');
    if(m&&m.classList.contains('show'))return true;
    if(document.querySelector('.whyPanelV249262,.privacyStableV249276,.privacyRealV249267,.bottleSeaOverlayV249274,.guideOverlayV249275,.guideOverlayV249276'))return true;
  }catch(e){}
  return false;
}
function closeAllAthinaGuideCardsV249276(){
  try{
    ['guideOverlayV249271','guideOverlayV249272','guideOverlayV249273','guideOverlayV249275','athinaWelcomeV249272','athinaWelcomeV249273','athinaWelcomeV249275'].forEach(id=>document.getElementById(id)?.remove());
  }catch(e){}
}
showAthinaWelcomeV249272=function(force=false){return force?showAthinaSimpleHelloV249276(true):false};
showAthinaSimpleHelloV249273=function(force=false){return showAthinaSimpleHelloV249276(force)};
function showAthinaSimpleHelloV249276(force=false){
  try{
    injectV249273SimpleHelloClassicSpacesCss&&injectV249273SimpleHelloClassicSpacesCss();
    injectV249276HardFixCss();
    closeAllAthinaGuideCardsV249276();
    if(anyBlockingPanelOpenV249276()&&!force)return false;
    if(!force&&sessionStorage.getItem('ith_simple_hello_seen_v249276')==='1')return false;
    if(!force&&state.page&&state.page!=='home')return false;
    if(document.getElementById('athinaSimpleHelloV249273'))return false;
    sessionStorage.setItem('ith_simple_hello_seen_v249276','1');
    const d=document.createElement('div');
    d.id='athinaSimpleHelloV249273';
    d.className='athinaSimpleHelloV249273 clickable';
    d.innerHTML=`<div class="face">${typeof athinaOwlV249258==='function'?athinaOwlV249258('small'):'🦉'}</div><div><b>Γεια σου, πώς είσαι σήμερα;</b><small>Πάτησέ με μόνο αν θέλεις ξενάγηση.</small></div><button class="x" type="button" aria-label="Κλείσιμο">×</button>`;
    d.onclick=(ev)=>{if(ev.target&&ev.target.closest&&ev.target.closest('.x'))return;closeAthinaSimpleHelloV249273();openFirstRunGuideV249275(true)};
    d.querySelector('.x').onclick=(ev)=>{ev.preventDefault();ev.stopPropagation();closeAthinaSimpleHelloV249273();};
    document.body.appendChild(d);
    setTimeout(()=>closeAthinaSimpleHelloV249273(),5000);
  }catch(e){}
  return false;
}
try{
  if(typeof removeBrokenGuidesV249272==='function')removeBrokenGuidesV249272=function(){try{['guideOverlayV249271','guideOverlayV249272','athinaWelcomeV249272'].forEach(id=>document.getElementById(id)?.remove())}catch(e){}};
  if(typeof removeGuidePopupsV249273==='function')removeGuidePopupsV249273=function(){try{['guideOverlayV249271','guideOverlayV249272','athinaWelcomeV249272'].forEach(id=>document.getElementById(id)?.remove())}catch(e){}};
}catch(e){}
try{var closeCurrentMenuAfterChoiceV249276Base=closeCurrentMenuAfterChoiceV249265}catch(e){var closeCurrentMenuAfterChoiceV249276Base=null}
closeCurrentMenuAfterChoiceV249265=function(menu){
  try{
    if(menu&&menu.querySelector&&menu.querySelector('.privacyStableV249276,.privacyRealV249267,.privacyScoreV249262,.whyPanelV249262'))return false;
    if(Date.now()<(window.__ithKeepMenuOpenUntilV249276||0))return false;
  }catch(e){}
  return closeCurrentMenuAfterChoiceV249276Base?closeCurrentMenuAfterChoiceV249276Base(menu):false;
};
function privacyScoreCalcV249276(id){
  let score=64;
  const rows=[];
  const mode=typeof notificationMode==='function'?notificationMode():'hybrid';
  const trust=typeof trustVerifiedV249262==='function'?trustVerifiedV249262(id):false;
  const companion=typeof ithakiCompanionV249258==='function'?ithakiCompanionV249258():'athina';
  rows.push(['🔐','Κρυπτογραφημένη συνομιλία','ενεργή ένδειξη',18]);score+=18;
  rows.push(['🌐','Offline μετάφραση EL↔EN','τοπικά όταν υπάρχει μοντέλο',7]);score+=7;
  rows.push(['🚫','Χωρίς διαφημίσεις','καθαρό περιβάλλον',5]);score+=5;
  rows.push(['🔔','Ειδοποιήσεις','mode: '+mode,(mode==='open_only'?3:7)]);score+=(mode==='open_only'?3:7);
  rows.push([companion==='sokratakis'?'🐢':'🦉','Μασκότ/ειδοποιήσεις','τοπικός συνοδοιπόρος',4]);score+=4;
  rows.push([trust?'✅':'⚠️','Trust mode',trust?'επαληθευμένο':'όχι ακόμη',trust?7:0]);score+=trust?7:0;
  score=Math.min(100,Math.max(0,score));
  return {score,rows};
}
openPrivacyScoreV249262=function(peerId){
  try{
    injectV249262InnovationCss&&injectV249262InnovationCss();
    injectV249276HardFixCss();
    window.__ithKeepMenuOpenUntilV249276=Date.now()+2500;
    const id=(typeof v249262ContextId==='function'?v249262ContextId(peerId):(peerId||state.activePeer||state.device));
    const name=(typeof v249262ContextName==='function'?v249262ContextName(id):'OK ITHAKI');
    const data=privacyScoreCalcV249276(id);
    const menu=$('memberMenu');if(!menu)return false;
    menu.classList.add('show','fullAvatarMenuV249231');
    const rows=data.rows.map(r=>`<div style="display:grid;grid-template-columns:auto 1fr auto;gap:8px;align-items:center;padding:9px 0;border-bottom:1px solid rgba(255,255,255,.08)"><span>${r[0]}</span><b>${esc(r[1])}<small style="display:block;opacity:.70;font-weight:700">${esc(r[2])}</small></b><em>+${r[3]}</em></div>`).join('');
    menu.innerHTML=`<div class="whyPanelV249262 privacyStableV249276" onclick="event.stopPropagation()">
      <div class="whyTopV249262"><button class="icon noAutoCloseV249265" onclick="event.stopPropagation();openWhyIthakiV249262()">‹</button><b>🟢 Privacy score</b><button class="icon noAutoCloseV249265" style="margin-left:auto" onclick="event.stopPropagation();ITH.closeMember()">×</button></div>
      <div class="whyBodyV249262">
        <div class="card"><h3 style="margin-top:0">${esc(name)}</h3><b>Privacy score: ${data.score} / 100</b><div class="privacyMeterV249276" style="--w:${data.score}%"><i></i></div><div class="date">Η κάρτα μένει ανοιχτή. Κλείνει μόνο με × ή πίσω.</div></div>
        <div class="card">${rows}</div>
        <div class="row" style="gap:8px;flex-wrap:wrap"><button class="btn green noAutoCloseV249265" onclick="event.stopPropagation();openTrustModeV249262('${escJs(id)}')">🤝 Trust mode</button><button class="btn noAutoCloseV249265" onclick="event.stopPropagation();openNotificationSettingsV249238()">🔔 Ρυθμίσεις ειδοποιήσεων</button></div>
      </div>
    </div>`;
    setTimeout(()=>{try{ensureMenuScrollArrowsV249265&&ensureMenuScrollArrowsV249265()}catch(e){}},120);
  }catch(e){toast('Privacy score error: '+(e.message||e),5000)}
  return false;
};
function openEmergencyNeighborhoodSafeV249276(){
  try{
    if(typeof openEmergencyNeighborhoodV249270==='function'){page('spaces');setTimeout(()=>openEmergencyNeighborhoodV249270(),80);return false}
    toast('Η Γειτονιά δεν έχει φορτώσει ακόμη. Ξαναπάτα σε λίγο.');
  }catch(e){toast('Δεν άνοιξε η Γειτονιά: '+(e.message||e),6000)}
  return false;
}
function openZeroSupportSafeV249276(){
  try{
    if(typeof openZeroSupportWallV249270==='function'){page('spaces');setTimeout(()=>openZeroSupportWallV249270(),80);return false}
    toast('Η Ήρεμη υποστήριξη δεν έχει φορτώσει ακόμη. Ξαναπάτα σε λίγο.');
  }catch(e){toast('Δεν άνοιξε η Ήρεμη υποστήριξη: '+(e.message||e),6000)}
  return false;
}
function bindSpacesSpecialButtonsV249276(){
  try{
    document.querySelectorAll('[data-v249276="emergency"]').forEach(b=>b.onclick=(e)=>{e.preventDefault();e.stopPropagation();return openEmergencyNeighborhoodSafeV249276()});
    document.querySelectorAll('[data-v249276="zero"]').forEach(b=>b.onclick=(e)=>{e.preventDefault();e.stopPropagation();return openZeroSupportSafeV249276()});
  }catch(e){}
}
try{var renderSpacesV249276Base=renderSpaces}catch(e){var renderSpacesV249276Base=null}
renderSpaces=async function(){if(window.__ITHAKI_R10F15_SINGLE_COMMUNITY_RUNTIME__)return __ithakiCanonicalSpacesR10F15();
  const r=renderSpacesV249276Base?await renderSpacesV249276Base.apply(this,arguments):false;
  try{
    const top=document.querySelector('.classicSpacesTopV249273');
    if(top){
      const oldEmergency=[...top.querySelectorAll('button')].find(b=>/Γειτονιά/.test(b.textContent||''));
      if(oldEmergency){oldEmergency.setAttribute('data-v249276','emergency');oldEmergency.onclick=(e)=>{e.preventDefault();e.stopPropagation();return openEmergencyNeighborhoodSafeV249276()}}
      const oldZero=[...top.querySelectorAll('button')].find(b=>/Ήρεμη|υποστήριξη/.test(b.textContent||''));
      if(oldZero){oldZero.classList.add('calmSupportBtnV249276');oldZero.setAttribute('data-v249276','zero');oldZero.onclick=(e)=>{e.preventDefault();e.stopPropagation();return openZeroSupportSafeV249276()}}
    }
    bindSpacesSpecialButtonsV249276();
  }catch(e){}
  return r;
};
try{var openBottleSeaV249276Base=openBottleSeaV249274}catch(e){var openBottleSeaV249276Base=null}
openBottleSeaV249274=function(tab='compose'){
  const r=openBottleSeaV249276Base?openBottleSeaV249276Base(tab):false;
  setTimeout(applyAncientShipLogoV249276,80);
  return r;
};
try{var renderHomeV249276Base=renderHome}catch(e){var renderHomeV249276Base=null}
renderHome=function(){
  const r=renderHomeV249276Base?renderHomeV249276Base.apply(this,arguments):false;
  try{
    injectV249276HardFixCss();
    setTimeout(()=>{applyAncientShipLogoV249276();bindSpacesSpecialButtonsV249276();},250);
  }catch(e){}
  return r;
};
function installHardFixExportsV249276(){
  try{
    window.ITH=window.ITH||{};
    Object.assign(window.ITH,{
      openPrivacyScoreV249262,
      openEmergencyNeighborhoodSafeV249276,
      openZeroSupportSafeV249276,
      openEmergencyNeighborhoodV249270: typeof openEmergencyNeighborhoodV249270==='function'?openEmergencyNeighborhoodV249270:openEmergencyNeighborhoodSafeV249276,
      openZeroSupportWallV249270: typeof openZeroSupportWallV249270==='function'?openZeroSupportWallV249270:openZeroSupportSafeV249276,
      renderSpaces,
      ancientShipLogoV249276,
      applyAncientShipLogoV249276,
      showAthinaSimpleHelloV249276,
      showAthinaSimpleHelloV249273:showAthinaSimpleHelloV249276,
      showAthinaWelcomeV249272
    });
    if(typeof installBottleExportsV249275==='function')installBottleExportsV249275();
    applyAncientShipLogoV249276();
    bindSpacesSpecialButtonsV249276();
  }catch(e){}
}
try{
  injectV249276HardFixCss();
  installHardFixExportsV249276();
  setTimeout(installHardFixExportsV249276,800);
  setTimeout(installHardFixExportsV249276,1800);
  setInterval(installHardFixExportsV249276,5000);
}catch(e){}


/* V249277 - Pelagos of Whispers: currents, daily sea weather, sea returns, private shore */
function injectV249277WhispersCss(){
  try{
    if(document.getElementById('ithV249277WhispersCss')) return;
    const st=document.createElement('style');
    st.id='ithV249277WhispersCss';
    st.textContent=`
      .seaWeatherV249277{margin:0 14px 12px;padding:12px 14px;border-radius:20px;background:linear-gradient(135deg,rgba(127,215,255,.16),rgba(255,217,110,.10));border:1px solid rgba(255,255,255,.12);color:#fff}
      .seaWeatherV249277 b{color:#ffe39b}.seaWeatherV249277 small{display:block;opacity:.82;line-height:1.35;margin-top:4px}
      .currentGridV249277{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:10px}
      .currentBtnV249277{border-radius:18px;border:1px solid rgba(28,65,97,.22);background:rgba(255,255,255,.36);color:#1f3345;padding:10px;text-align:left;font-weight:1000}
      .currentBtnV249277 small{display:block;font-weight:700;opacity:.75;margin-top:4px;line-height:1.3}
      .currentBtnV249277.active{outline:2px solid rgba(30,96,135,.50);background:rgba(127,215,255,.22)}
      .routeGridV249277{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:10px}
      .routeGridV249277 button{border-radius:16px;border:1px solid rgba(28,65,97,.22);background:rgba(255,255,255,.38);color:#1f3345;padding:10px;font-weight:1000}
      .routeGridV249277 button.active{outline:2px solid rgba(30,96,135,.55);background:rgba(127,215,255,.20)}
      .shoreGridV249277{padding:0 14px 18px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
      .shoreItemV249277{border-radius:20px;padding:13px;background:rgba(255,255,255,.065);border:1px solid rgba(255,255,255,.11);color:#fff;min-height:110px}
      .shoreItemV249277 .emoji{font-size:36px;display:block;margin-bottom:8px}
      .bottleAgeV249277{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:4px 8px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.12);margin:6px 0;color:#dff8ff;font-size:12px;font-weight:900}
      .seaReturnV249277{margin-top:10px;border-radius:18px;padding:11px;background:linear-gradient(135deg,rgba(255,255,255,.08),rgba(127,215,255,.10));border:1px solid rgba(255,255,255,.14)}
      .seaReturnV249277 h4{margin:0 0 6px;color:#ffe39b}.seaReturnV249277 p{margin:6px 0;white-space:pre-wrap}
      .seaWhisperHeroV249277{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
      .seaWhisperHeroV249277 .ship{display:flex;align-items:center;gap:8px}
      .seaWhisperHeroV249277 .ship img{width:54px;height:54px;object-fit:contain;filter:drop-shadow(0 10px 18px rgba(0,0,0,.34))}
      @media(max-width:760px){.currentGridV249277,.routeGridV249277,.shoreGridV249277{grid-template-columns:1fr}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function whisperCurrentsV249277(){return [{id:'night',emoji:'🌙',title:'Ρεύμα της νύχτας',blurb:'Σκέψεις, αϋπνία, μυστικές εξομολογήσεις.'},{id:'joy',emoji:'🔥',title:'Ρεύμα της χαράς',blurb:'Μικρές χαρές, ευχές, γιορτές και φως.'},{id:'wonder',emoji:'🌫️',title:'Ρεύμα της απορίας',blurb:'Ερωτήσεις χωρίς εύκολη απάντηση.'},{id:'comfort',emoji:'🐚',title:'Ρεύμα της παρηγοριάς',blurb:'Λόγια ηρεμίας, τρυφερότητας και στήριξης.'}];}
function whisperCurrentV249277(){try{return localStorage.getItem('ith_whisper_current_v249277')||'night'}catch{return 'night'}}
function setWhisperCurrentV249277(id){try{localStorage.setItem('ith_whisper_current_v249277',id);document.querySelectorAll('.currentBtnV249277').forEach(b=>b.classList.toggle('active',b.dataset.current===id))}catch(e){}return false}
function whisperRouteV249277(){try{return localStorage.getItem('ith_whisper_route_v249277')||'random'}catch{return 'random'}}
function setWhisperRouteV249277(id){try{localStorage.setItem('ith_whisper_route_v249277',id);document.querySelectorAll('.routeGridV249277 button').forEach(b=>b.classList.toggle('active',b.dataset.route===id))}catch(e){}return false}
function simpleHashV249277(s){s=String(s||'');let h=0;for(let i=0;i<s.length;i++)h=((h<<5)-h)+s.charCodeAt(i),h|=0;return Math.abs(h)}
function seaWeatherV249277(){const day=(new Date()).toISOString().slice(0,10);const idx=simpleHashV249277(day)%3;if(idx===0)return{id:'calm',icon:'🌊',title:'Η θάλασσα σήμερα είναι ήρεμη',note:'Σήμερα το πέλαγος δέχεται περισσότερα μπουκάλια και απαντά γρηγορότερα.',limit:5,lag:'γρήγορες επιστροφές'};if(idx===1)return{id:'storm',icon:'🌪️',title:'Η θάλασσα σήμερα είναι ταραγμένη',note:'Λιγότερα μπουκάλια σήμερα· το πέλαγος κρατά μυστικά λίγο περισσότερο.',limit:2,lag:'αργές επιστροφές'};return{id:'currents',icon:'🌀',title:'Η θάλασσα σήμερα είναι γεμάτη ρεύματα',note:'Τα ρεύματα παρασύρουν μακριά. Ιδανική μέρα για περίεργα ευρήματα.',limit:3,lag:'απρόβλεπτες επιστροφές'}}
function whisperDropKeyV249277(){return 'ith_whisper_drops_'+(new Date()).toISOString().slice(0,10)}
function whisperDropCountV249277(){try{return parseInt(localStorage.getItem(whisperDropKeyV249277())||'0',10)||0}catch{return 0}}
function whisperCanDropV249277(){const w=seaWeatherV249277();const used=whisperDropCountV249277();return{ok:used<w.limit,remaining:Math.max(0,w.limit-used),limit:w.limit,used,weather:w}}
function whisperIncDropV249277(){try{localStorage.setItem(whisperDropKeyV249277(),String(whisperDropCountV249277()+1))}catch(e){}}
function bottleMetaMapV249277(){try{return JSON.parse(localStorage.getItem('ith_bottle_meta_v249277')||'{}')}catch{return {}}}
function saveBottleMetaV249277(id,meta){try{const m=bottleMetaMapV249277();m[id]=Object.assign({},m[id]||{},meta||{});localStorage.setItem('ith_bottle_meta_v249277',JSON.stringify(m));}catch(e){}}
function bottleMetaV249277(id){const m=bottleMetaMapV249277();return m[id]||{}}
function bottleReturnsMapV249277(){try{return JSON.parse(localStorage.getItem('ith_bottle_returns_v249277')||'{}')}catch{return {}}}
function saveBottleReturnV249277(id,data){try{const m=bottleReturnsMapV249277();m[id]=data;localStorage.setItem('ith_bottle_returns_v249277',JSON.stringify(m));}catch(e){}}
function bottleReturnV249277(id){const m=bottleReturnsMapV249277();return m[id]||null}
function shoreItemsV249277(){try{return JSON.parse(localStorage.getItem('ith_shore_items_v249277')||'[]')}catch{return []}}
function saveShoreItemsV249277(items){try{localStorage.setItem('ith_shore_items_v249277',JSON.stringify(items||[]))}catch(e){}}
function collectShoreItemV249277(kind,emoji,title){const items=shoreItemsV249277();items.unshift({id:'shore_'+Date.now()+'_'+Math.random().toString(36).slice(2),kind,emoji,title,found_at:Date.now()/1000});saveShoreItemsV249277(items.slice(0,240));toast('Προστέθηκε στην προσωπική σου ακρογιαλιά.');renderBottleTabV249274('shore');return false}
function socraticThoughtsV249277(){return ['Τι σημαίνει για σένα η δικαιοσύνη σήμερα;','Πότε νιώθεις πιο αληθινός/ή μέσα στη μέρα σου;','Τι κρατάς μέσα σου ενώ θα ήθελες να το πεις;','Ποια μικρή καλοσύνη θα μπορούσες να κάνεις σήμερα;','Αν η σιωπή μιλούσε, τι θα σου έλεγε απόψε;']}
function deepSeaMessagesV249277(){return ['«Αναρωτιέμαι αν κάποιος με θυμάται ακόμη όταν πέφτει το βράδυ.»','«Τι κάνεις όταν μια σκέψη δεν σε αφήνει να κοιμηθείς;»','«Αν μπορούσες να στείλεις θάρρος σε έναν ξένο, τι θα του έλεγες;»','«Σήμερα ένιωσα μικρός μπροστά στη ζωή. Εσύ πότε το ένιωσες;»']}
function bottleAgeInfoV249277(ts){const age=Math.max(0,(Date.now()/1000)-Number(ts||0));if(age<60)return{label:'Νέο μπουκάλι',icon:'✨'};if(age<600)return{label:'Θολώνει από την αλμύρα',icon:'🌫️'};if(age<3600)return{label:'Μαζεύει φύκια καθώς ταξιδεύει',icon:'🌿'};return{label:'Παίρνει χρώμα ηλιοβασιλέματος',icon:'🌅'}}
function generatedSeaReturnV249277(item){const existing=bottleReturnV249277(item.bottle_id);if(existing)return existing;if(item.reply_text)return null;const age=Math.max(0,(Date.now()/1000)-Number(item.created_at||0));if(age<90)return null;const h=simpleHashV249277(item.bottle_id+'sea');const typeIdx=h%4;let out=null;if(typeIdx===0){const arts=[['shell','🐚','Κοχύλι'],['pebble','🪨','Βότσαλο'],['glass','🫙','Γυαλισμένο γυαλί'],['feather','🪶','Φτερό γλάρου']];const a=arts[h%arts.length];out={type:'artifact',emoji:a[1],kind:a[0],title:a[2],text:'Η θάλασσα δεν γύρισε ακόμη απάντηση. Σου άφησε όμως ένα μικρό εύρημα.'};}else if(typeIdx===1){out={type:'thought',emoji:'🐢',title:'Σκέψη του Σωκρατάκη',text:socraticThoughtsV249277()[h%socraticThoughtsV249277().length]};}else if(typeIdx===2){out={type:'deep',emoji:'🌊',title:'Μήνυμα του βυθού',text:deepSeaMessagesV249277()[h%deepSeaMessagesV249277().length]};}if(out)saveBottleReturnV249277(item.bottle_id,out);return out}
function bottleCurrentLabelV249277(id){const c=whisperCurrentsV249277().find(x=>x.id===id);return c?(c.emoji+' '+c.title):'🌊 Ρεύμα'}
function whisperWeatherBannerHtmlV249277(){const cap=whisperCanDropV249277();return `<div class="seaWeatherV249277"><b>${cap.weather.icon} ${cap.weather.title}</b><small>${esc(cap.weather.note)}<br>Σήμερα μπορείς να ρίξεις <b>${cap.limit}</b> μπουκάλια. Απομένουν: <b>${cap.remaining}</b> · ${esc(cap.weather.lag)}.</small></div>`}
function bottleCardV249274(){injectV249274BottleCss();injectV249277WhispersCss();return `<section class="bottleHomeCardV249274"><div class="bottleHomeInnerV249274"><div class="bottleIconV249274">🍾</div><div><span class="tag">ΝΕΟ</span><h3>Το Πέλαγος των Ψιθύρων</h3><p>Ρίχνεις μια σκέψη στη θάλασσα και επιλέγεις το ρεύμα της. Μπορεί να επιστρέψει απάντηση, ένα μικρό εύρημα, μια σκέψη ή ένα παλιό μυστικό του βυθού.</p></div><button onclick="ITH.openBottleSeaV249274('compose')">Άνοιγμα ›</button></div></section>`}
function openBottleSeaV249274(tab='compose'){injectV249274BottleCss();injectV249277WhispersCss();closeBottleSeaV249274();const ship=typeof ancientShipLogoV249276==='function'?ancientShipLogoV249276():'⛵';const d=document.createElement('div');d.id='bottleSeaOverlayV249274';d.className='bottleSeaOverlayV249274';d.innerHTML=`<div class="bottleSeaPanelV249274"><div class="bottleSeaTopV249274"><b>🍾 Το Πέλαγος των Ψιθύρων</b><span class="spacer"></span><button type="button" onclick="ITH.closeBottleSeaV249274()">×</button></div><div class="bottleHeroV249274"><div><div class="seaWhisperHeroV249277"><span class="ship">${ship}</span><div><h2>Το Πέλαγος των Ψιθύρων</h2><p>Διαλέγεις το ρεύμα της σκέψης σου και τη ρίχνεις στο πέλαγος. Η θάλασσα δεν επιστρέφει πάντα το ίδιο πράγμα.</p></div></div></div><div class="seaBottle">🍾</div></div><div class="bottleTabsV249274"><button data-tab="compose">✍️ Ρίξε ψίθυρο</button><button data-tab="find">🌊 Βρες μπουκάλι</button><button data-tab="mine">📬 Τα ταξίδια μου</button><button data-tab="shore">🏖️ Η ακρογιαλιά μου</button></div><div id="bottleBodyV249274"></div></div>`;document.body.appendChild(d);d.querySelectorAll('[data-tab]').forEach(b=>b.onclick=()=>renderBottleTabV249274(b.dataset.tab));renderBottleTabV249274(tab);try{if(typeof applyAncientShipLogoV249276==='function')applyAncientShipLogoV249276()}catch(e){}return false}
function renderBottleTabV249274(tab='compose'){injectV249277WhispersCss();const body=$('bottleBodyV249274');if(!body)return false;document.querySelectorAll('.bottleTabsV249274 button').forEach(b=>b.classList.toggle('active',b.dataset.tab===tab));if(tab==='compose'){const route=whisperRouteV249277();body.innerHTML=`${whisperWeatherBannerHtmlV249277()}<div class="parchmentV249274"><h3>Ρίξε έναν ψίθυρο στη θάλασσα</h3><textarea id="bottleTextV249274" maxlength="900" placeholder="Γράψε μια σκέψη, μια ερώτηση ή μια ευχή..."></textarea><div class="currentGridV249277">${whisperCurrentsV249277().map(c=>`<button class="currentBtnV249277" data-current="${c.id}" onclick="ITH.setWhisperCurrentV249277('${c.id}')">${c.emoji} ${c.title}<small>${c.blurb}</small></button>`).join('')}</div><div class="routeGridV249277"><button data-route="random" onclick="ITH.setWhisperRouteV249277('random')">👤 Ανοιχτό πέλαγος</button><button data-route="mesh" onclick="ITH.setWhisperRouteV249277('mesh')">📍 Κοντά μου μέσω mesh</button><button data-route="vanish" onclick="ITH.setWhisperRouteV249277('vanish')">👻 Εφήμερο πέρασμα</button></div><div class="bottleSmallNoteV249274">🔒 Η απάντηση γυρίζει με τοπικό μυστικό token. Το πέλαγος επιλέγει και μερικές φορές επιστρέφει εύρημα, σκέψη ή μήνυμα του βυθού.</div><button class="bottleActionV249274" onclick="ITH.dropBottleV249274()">🍾 Ρίξ’ το στο πέλαγος</button></div>`;setWhisperCurrentV249277(whisperCurrentV249277());setWhisperRouteV249277(route);setTimeout(()=>$('bottleTextV249274')?.focus(),80);}else if(tab==='find'){body.innerHTML=`${whisperWeatherBannerHtmlV249277()}<div class="bottleListV249274"><div class="bottleItemV249274"><b>${bottleCurrentLabelV249277(whisperCurrentV249277())}</b><p>Θα βρεις τυχαίο μπουκάλι από το πέλαγος. Το ρεύμα που διάλεξες χρωματίζει την εμπειρία σου.</p></div><button class="bottleActionV249274" onclick="ITH.findBottleV249274()">🌊 Βρες ένα μπουκάλι στη θάλασσα</button><div id="bottleFindResultV249274" class="bottleItemV249274"><b>Περιμένει ένα μπουκάλι κάπου στο πέλαγος.</b><p>Πάτησε για να βρεις ένα τυχαίο ανώνυμο μήνυμα που δεν είναι δικό σου.</p></div></div>`;}else if(tab==='mine'){body.innerHTML=`${whisperWeatherBannerHtmlV249277()}<div class="bottleListV249274"><button class="bottleActionV249274" onclick="ITH.loadMyBottlesV249274()">📬 Φόρτωση των ταξιδιών μου</button><div id="myBottlesV249274"></div></div>`;loadMyBottlesV249274();}else if(tab==='shore'){const items=shoreItemsV249277();body.innerHTML=`${whisperWeatherBannerHtmlV249277()}<div class="bottleListV249274"><div class="bottleItemV249274"><b>🏖️ Η προσωπική σου ακρογιαλιά</b><p>Όσα ευρήματα σου αφήνει το πέλαγος μαζεύονται εδώ. Δεν τα βλέπει κανείς άλλος.</p></div></div><div class="shoreGridV249277">${items.length?items.map(it=>`<div class="shoreItemV249277"><span class="emoji">${it.emoji}</span><b>${esc(it.title)}</b><div class="date">${fmt(it.found_at)}</div><p>Ένα μικρό ιδιωτικό εύρημα από το πέλαγος.</p></div>`).join(''):'<div class="shoreItemV249277" style="grid-column:1/-1"><span class="emoji">🐚</span><b>Η ακρογιαλιά είναι ακόμη ήσυχη</b><p>Όταν η θάλασσα σου επιστρέψει ένα κοχύλι, βότσαλο, γυαλισμένο γυαλί ή φτερό, θα εμφανιστεί εδώ.</p></div>'}</div>`;}return false}
async function dropBottleV249274(){const txt=($('bottleTextV249274')?.value||'').trim();if(!txt)return toast('Γράψε πρώτα μήνυμα.');const cap=whisperCanDropV249277();if(!cap.ok)return toast('Η θάλασσα σήμερα δεν δέχεται άλλο μπουκάλι. Ξαναδοκίμασε αύριο.',7000);const route=whisperRouteV249277(),current=whisperCurrentV249277();try{const r=await fetchJson('/api/bottle/drop',{method:'POST',body:JSON.stringify({room_id:state.room,owner_token:bottleTokenV249274(),text:txt,mode:route==='vanish'?'random':route,mesh:route==='mesh',vanish:route==='vanish'})});whisperIncDropV249277();saveBottleMetaV249277(r.bottle_id,{current,dropped_at:Date.now()/1000,route,weather:seaWeatherV249277().id});toast('Ο ψίθυρος έπεσε στο πέλαγος.');renderBottleTabV249274('mine')}catch(e){toast('Δεν στάλθηκε το μπουκάλι: '+(e.message||e),7000)}return false}
async function findBottleV249274(){const box=$('bottleFindResultV249274');if(box)box.innerHTML='<b>Ψάχνω στο πέλαγος...</b>';try{const route=whisperRouteV249277(),mesh=route==='mesh'?1:0;const r=await fetchJson(`/api/bottle/random?room_id=${encodeURIComponent(state.room)}&owner_token=${encodeURIComponent(bottleTokenV249274())}&mesh=${mesh}`);if(!r.bottle){if(box)box.innerHTML='<b>Δεν βρέθηκε μπουκάλι τώρα.</b><p>Δοκίμασε αργότερα ή ρίξε εσύ ένα πρώτο μήνυμα.</p>';return false}const b=r.bottle;if(box)box.innerHTML=`<b>Βρήκες ένα μπουκάλι</b><div class="bottleAgeV249277">${bottleCurrentLabelV249277(whisperCurrentV249277())}</div><p>${esc(b.text)}</p><div class="bottleReplyBoxV249274"><textarea id="bottleReplyTextV249274" placeholder="Απάντησε ανώνυμα..."></textarea><label style="display:block;margin:8px 0"><input id="bottleContinueOkV249274" type="checkbox"> Αν θέλει και ο άλλος, μπορώ να συνεχίσω τη σύνδεση.</label><button class="bottleActionV249274" onclick="ITH.replyBottleV249274('${escJs(b.bottle_id)}')">↩ Απάντηση ανώνυμα</button></div>`;}catch(e){if(box)box.innerHTML='<b>Δεν φορτώνει η θάλασσα.</b><p>'+esc(e.message||e)+'</p>'}return false}
function seaReturnHtmlV249277(item){const ret=generatedSeaReturnV249277(item);if(!ret)return '';if(ret.type==='artifact')return `<div class="seaReturnV249277"><h4>${ret.emoji} ${ret.title}</h4><p>${esc(ret.text)}</p><button class="btn green" onclick="ITH.collectShoreItemV249277('${escJs(ret.kind)}','${escJs(ret.emoji)}','${escJs(ret.title)}')">Κράτησέ το στην ακρογιαλιά</button></div>`;if(ret.type==='thought')return `<div class="seaReturnV249277"><h4>${ret.emoji} ${ret.title}</h4><p>${esc(ret.text)}</p></div>`;if(ret.type==='deep')return `<div class="seaReturnV249277"><h4>${ret.emoji} ${ret.title}</h4><p>${esc(ret.text)}</p><button class="btn" onclick="ITH.renderBottleTabV249274('compose')">Απάντησε με νέο ψίθυρο</button></div>`;return ''}
async function loadMyBottlesV249274(){const box=$('myBottlesV249274');if(!box)return false;box.innerHTML='<div class="bottleItemV249274"><b>Φόρτωση...</b></div>';try{const r=await fetchJson(`/api/bottle/mine?room_id=${encodeURIComponent(state.room)}&owner_token=${encodeURIComponent(bottleTokenV249274())}&limit=80`);const items=r.items||[];box.innerHTML=items.map(x=>{const meta=bottleMetaV249277(x.bottle_id),age=bottleAgeInfoV249277(meta.dropped_at||x.created_at),current=bottleCurrentLabelV249277(meta.current||'night');const reply=x.reply_text?`<div class="reply"><b>Απάντηση από άγνωστο:</b><p>${esc(x.reply_text)}</p></div><div class="row" style="gap:7px;flex-wrap:wrap"><button class="btn green" onclick="ITH.openBottleThreadV249274('${escJs(x.bottle_id)}')">Συνέχεια ανώνυμα</button><button class="btn" onclick="ITH.vanishBottleV249274('${escJs(x.bottle_id)}')">Να χαθεί</button></div>`:`<div class="date">Ακόμη ταξιδεύει στη θάλασσα.</div>${seaReturnHtmlV249277(x)}`;return `<div class="bottleItemV249274"><b>🍾 ${esc(x.status||'floating')}</b><div class="date">${fmt(x.created_at)}</div><div class="bottleAgeV249277">${age.icon} ${age.label}</div><div class="date">${esc(current)}</div><p>${esc(x.text||'')}</p>${reply}</div>`;}).join('')||'<div class="bottleItemV249274"><b>Δεν έχεις ρίξει ψίθυρο ακόμη.</b></div>';}catch(e){box.innerHTML='<div class="bottleItemV249274"><b>Δεν φορτώνουν τα ταξίδια σου.</b><p>'+esc(e.message||e)+'</p></div>'}return false}
function installWhisperExportsV249277(){try{window.ITH=window.ITH||{};Object.assign(window.ITH,{injectV249277WhispersCss,setWhisperCurrentV249277,setWhisperRouteV249277,renderBottleTabV249274,collectShoreItemV249277,openBottleSeaV249274,dropBottleV249274,findBottleV249274,loadMyBottlesV249274})}catch(e){}}
try{var renderHomeV249277Base=renderHome}catch(e){var renderHomeV249277Base=null}
renderHome=function(){const r=renderHomeV249277Base?renderHomeV249277Base.apply(this,arguments):false;try{injectV249277WhispersCss();installWhisperExportsV249277()}catch(e){}return r};
try{injectV249277WhispersCss();installWhisperExportsV249277();setTimeout(installWhisperExportsV249277,800);setTimeout(installWhisperExportsV249277,1800)}catch(e){}


/* V249278 - Lighthouse star sky silent ritual */
function injectLighthouseV249278Css(){
  try{
    if(document.getElementById('ithLighthouseV249278Css')) return;
    const st=document.createElement('style');
    st.id='ithLighthouseV249278Css';
    st.textContent=`
      .lighthouseHomeCardV249278{position:relative;overflow:hidden;border-radius:26px;margin:12px 0;padding:14px;border:1px solid rgba(255,219,145,.18);background:radial-gradient(circle at 18% 18%,rgba(255,232,167,.13),transparent 28%),linear-gradient(160deg,rgba(7,17,35,.97),rgba(6,20,42,.98));box-shadow:0 20px 48px rgba(0,0,0,.28);color:#fff}
      .lighthouseHomeCardV249278:after{content:'';position:absolute;inset:auto -10% -35% auto;width:220px;height:220px;border-radius:50%;background:rgba(127,215,255,.10);filter:blur(10px)}
      .lighthouseHomeInnerV249278{position:relative;display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center}
      .lighthouseHomeIconV249278{width:84px;height:84px;border-radius:28px;display:grid;place-items:center;background:radial-gradient(circle at 30% 22%,rgba(255,255,255,.24),rgba(127,215,255,.10) 42%,rgba(4,14,24,.30));border:1px solid rgba(255,217,110,.20);font-size:40px;box-shadow:inset 0 1px 0 rgba(255,255,255,.18)}
      .lighthouseHomeCardV249278 h3{margin:0;color:#ffe39b;font-size:21px}.lighthouseHomeCardV249278 p{margin:6px 0;color:rgba(239,248,255,.84);line-height:1.38}.lighthouseHomeCardV249278 .tag{display:inline-flex;border-radius:999px;padding:3px 8px;background:rgba(255,217,110,.12);border:1px solid rgba(255,217,110,.22);font-size:12px;font-weight:1000;color:#ffe39b}
      .lighthouseHomeCardV249278 button{border-radius:999px;border:1px solid rgba(255,217,110,.30);background:linear-gradient(135deg,#ffd76a,#f2b74a);color:#132234;padding:10px 14px;font-weight:1000;box-shadow:0 10px 24px rgba(0,0,0,.22)}
      .lighthouseOverlayV249278{position:fixed;inset:0;z-index:10155;background:rgba(2,6,15,.74);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;padding:10px;box-sizing:border-box}
      .lighthouseScreenV249278{position:relative;width:min(468px,100%);height:min(920px,96dvh);border-radius:34px;overflow:hidden;border:1px solid rgba(255,217,110,.22);box-shadow:0 36px 110px rgba(0,0,0,.60);background:#091220 url('lighthouse_night_v249278.png') center/cover no-repeat;color:#fff}
      .lighthouseScreenV249278:before{content:'';position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.10),rgba(0,0,0,.08) 18%,rgba(4,12,24,.14) 36%,rgba(4,10,22,.42) 66%,rgba(2,7,16,.76) 100%)}
      .lighthouseScreenV249278:after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 8%,rgba(255,255,255,.08),transparent 18%),radial-gradient(circle at 76% 10%,rgba(132,188,255,.12),transparent 24%)}
      .lighthouseTopBarV249278,.lighthouseBottomV249278,.lighthouseCenterV249278{position:relative;z-index:2}
      .lighthouseTopBarV249278{display:flex;align-items:center;justify-content:space-between;padding:18px 18px 0}
      .lighthouseTopBarV249278 .circleBtn{width:48px;height:48px;border-radius:50%;border:1px solid rgba(255,219,145,.20);background:rgba(6,18,34,.30);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);color:#ffe2a2;font-size:26px;display:grid;place-items:center;box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
      .lighthouseTitleWrapV249278{text-align:center;padding:94px 20px 8px}
      .lighthouseTitleWrapV249278 h1{margin:0;font-size:66px;font-weight:700;letter-spacing:.5px;color:#f6d38c;text-shadow:0 0 24px rgba(255,219,145,.25),0 2px 10px rgba(0,0,0,.30)}
      .lighthouseTitleWrapV249278 p{margin:8px 0 0;font-size:16px;color:rgba(240,227,205,.90)}
      .lighthouseCounterV249278,.lighthouseSeenV249278,.lighthouseActionPillV249278{margin:18px 20px 0;border-radius:24px;background:rgba(7,20,40,.40);border:1px solid rgba(255,219,145,.15);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);box-shadow:0 12px 30px rgba(0,0,0,.24)}
      .lighthouseCounterV249278,.lighthouseSeenV249278{display:flex;align-items:center;gap:12px;padding:16px 18px}
      .lighthouseCounterV249278 .icon,.lighthouseSeenV249278 .icon{font-size:28px;color:#ffd27c}.lighthouseCounterV249278 b,.lighthouseSeenV249278 b{color:#f5c66a}.lighthouseCounterV249278 .sub,.lighthouseSeenV249278 .sub{display:block;font-size:14px;color:rgba(240,227,205,.86)}
      .lighthouseSkyV249278{position:absolute;inset:0;z-index:1;pointer-events:none}
      .lighthouseDotV249278{position:absolute;width:10px;height:10px;border-radius:50%;background:radial-gradient(circle,#fff2b0 0%,#ffd36d 36%,rgba(255,197,85,.58) 62%,rgba(255,197,85,0) 100%);box-shadow:0 0 10px rgba(255,213,115,.75),0 0 26px rgba(255,213,115,.35);pointer-events:auto;cursor:pointer;transform:translate(-50%,-50%)}
      .lighthouseDotV249278.own{width:13px;height:13px;box-shadow:0 0 14px rgba(255,238,172,.95),0 0 36px rgba(255,213,115,.48)}
      .lighthouseDotV249278.touched{animation:lighthousePulseV249278 1.2s ease-out 1}
      @keyframes lighthousePulseV249278{0%{box-shadow:0 0 0 rgba(255,225,160,.1),0 0 0 rgba(255,225,160,.1)}50%{box-shadow:0 0 22px rgba(255,238,172,1),0 0 56px rgba(255,213,115,.8)}100%{box-shadow:0 0 14px rgba(255,238,172,.95),0 0 36px rgba(255,213,115,.48)}}
      .lighthouseHintV249278{position:absolute;left:50%;transform:translateX(-50%);bottom:320px;width:min(78%,320px);padding:14px 18px;border-radius:22px;background:rgba(7,20,40,.42);border:1px solid rgba(255,219,145,.14);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);text-align:center;z-index:2;color:#f2dbc0}
      .lighthouseMainBtnV249278{display:flex;align-items:center;justify-content:center;gap:14px;margin:18px 20px 0;padding:22px 20px;border-radius:34px;border:1px solid rgba(255,231,173,.36);background:linear-gradient(180deg,rgba(255,224,158,.92),rgba(237,183,87,.90));color:#1e1a15;font-size:24px;font-weight:1000;box-shadow:0 20px 42px rgba(255,191,76,.22),inset 0 1px 0 rgba(255,255,255,.50)}
      .lighthouseMainBtnV249278 .candle{font-size:40px}
      .lighthouseBottomV249278{position:absolute;left:0;right:0;bottom:22px}
      .lighthouseFooterTabsV249278{margin:18px 20px 0;padding:16px 18px;border-radius:30px;background:rgba(5,13,26,.70);border:1px solid rgba(255,219,145,.14);display:flex;align-items:center;justify-content:space-around;gap:8px;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
      .lighthouseFooterTabsV249278 .item{display:flex;flex-direction:column;align-items:center;gap:6px;color:#d7b78c;font-size:14px}.lighthouseFooterTabsV249278 .item .i{font-size:36px;line-height:1}.lighthouseFooterTabsV249278 .item.active{color:#f0ce7f;text-shadow:0 0 16px rgba(255,208,117,.35)}
      .lighthouseTapNoticeV249278{position:absolute;left:50%;transform:translateX(-50%);bottom:282px;z-index:3;background:rgba(10,24,42,.68);border:1px solid rgba(255,219,145,.18);color:#ffe3ad;padding:8px 12px;border-radius:999px;font-size:13px;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
      @media(max-width:760px){.lighthouseHomeInnerV249278{grid-template-columns:auto 1fr}.lighthouseHomeInnerV249278 button{grid-column:1/-1;width:100%}.lighthouseTitleWrapV249278{padding-top:78px}.lighthouseTitleWrapV249278 h1{font-size:56px}.lighthouseHintV249278{bottom:302px}.lighthouseTapNoticeV249278{bottom:266px}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function lighthouseTokenV249278(){
  try{ let t=localStorage.getItem('ith_lighthouse_token_v249278')||''; if(!t){t='lh_'+Math.random().toString(36).slice(2)+Date.now().toString(36)+Math.random().toString(36).slice(2); localStorage.setItem('ith_lighthouse_token_v249278',t);} return t; }catch{return 'lh_'+(state?.device||Math.random().toString(36).slice(2));}
}
function lighthouseHomeCardV249278(){
  injectLighthouseV249278Css();
  return `<section class="lighthouseHomeCardV249278"><div class="lighthouseHomeInnerV249278"><div class="lighthouseHomeIconV249278">🕯️</div><div><span class="tag">ΝΕΟ</span><h3>Ο Φάρος</h3><p>Ένας νυχτερινός ουρανός χωρίς λέξεις. Ανάβεις ένα φως και ένας άγνωστος μπορεί μόνο να το αγγίξει — σαν σιωπηλή αναγνώριση ότι σε είδε.</p></div><button onclick="ITH.openLighthouseV249278()">Άνοιγμα ›</button></div></section>`;
}
function closeLighthouseV249278(){ try{document.getElementById('lighthouseOverlayV249278')?.remove()}catch(e){} return false; }
function lighthouseStatusTextV249278(data){ const t=Number(data?.my_touched_count||0)||0; return t===1?'1 άνθρωπος είδε το φως σου απόψε':`${t} άνθρωποι είδαν το φως σου απόψε`; }
function lighthouseSubtitleTextV249278(data){ return data?.my_has_light ? 'Το φως σου είναι ήδη στον ουρανό απόψε.' : 'Άναψε ένα μικρό φως χωρίς καμία λέξη.'; }
function openLighthouseV249278(){
  injectLighthouseV249278Css();
  closeLighthouseV249278();
  const d=document.createElement('div');
  d.id='lighthouseOverlayV249278'; d.className='lighthouseOverlayV249278';
  d.innerHTML=`<div class="lighthouseScreenV249278"><div class="lighthouseSkyV249278" id="lighthouseSkyV249278"></div><div class="lighthouseTopBarV249278"><button class="circleBtn" onclick="ITH.closeLighthouseV249278()">‹</button><button class="circleBtn" onclick="ITH.loadLighthouseSkyV249278(true)">⋯</button></div><div class="lighthouseCenterV249278"><div class="lighthouseTitleWrapV249278"><h1>Ο Φάρος</h1><p>Χωρίς λέξεις. Μόνο φως.</p></div><div class="lighthouseCounterV249278"><div class="icon">👥</div><div><div>Απόψε, <b id="lighthouseTotalV249278">0</b> άνθρωποι άναψαν ένα φως.</div><span class="sub" id="lighthouseTotalSubV249278">Ο κοινός νυχτερινός ουρανός είναι ζωντανός.</span></div></div><div class="lighthouseHintV249278">Άγγιξε ένα ξένο φως. Δεν στέλνεις μήνυμα — μόνο έναν σιωπηλό παλμό: «Κάποιος είδε το φως σου.»</div><div id="lighthouseTapNoticeV249278" class="lighthouseTapNoticeV249278" style="display:none">Άγγιξε ένα ξένο φως</div></div><div class="lighthouseBottomV249278"><button class="lighthouseMainBtnV249278" onclick="ITH.lightMyCandleV249278()"><span class="candle">🕯️</span><span id="lighthouseButtonLabelV249278">Άναψε ένα φως</span></button><div class="lighthouseSeenV249278"><div class="icon">👥</div><div><div><b id="lighthouseSeenCountV249278">0 άνθρωποι είδαν το φως σου απόψε</b></div><span class="sub" id="lighthouseSeenSubV249278">Σε ευχαριστούμε που είσαι εδώ.</span></div></div><div class="lighthouseFooterTabsV249278"><div class="item"><div class="i">⌂</div><div>Αρχική</div></div><div class="item"><div class="i">📖</div><div>Ημερολόγιο</div></div><div class="item active"><div class="i">🏛️</div><div>Ο Φάρος</div></div><div class="item"><div class="i">♡</div><div>Υποστήριξη</div></div><div class="item"><div class="i">⋯</div><div>Περισσότερα</div></div></div></div></div>`;
  document.body.appendChild(d);
  loadLighthouseSkyV249278(false);
  return false;
}
async function loadLighthouseSkyV249278(forceFlash){
  try{
    const r=await fetchJson(`/api/lighthouse/sky?room_id=${encodeURIComponent(state.room)}&owner_token=${encodeURIComponent(lighthouseTokenV249278())}`);
    renderLighthouseSkyV249278(r);
    if(forceFlash) toast('Ο νυχτερινός ουρανός ανανεώθηκε.');
  }catch(e){ toast('Ο Φάρος δεν φόρτωσε: '+(e.message||e),7000); }
  return false;
}
function renderLighthouseSkyV249278(data){
  const sky=$('lighthouseSkyV249278'); if(!sky) return false;
  sky.innerHTML='';
  (data.lights||[]).forEach(light=>{
    const d=document.createElement('button');
    d.className='lighthouseDotV249278'+(light.own?' own':'');
    d.style.left=(Number(light.x)||50)+'%';
    d.style.top=(Number(light.y)||44)+'%';
    d.title=light.own?'Το δικό σου φως':'Ένα ξένο φως';
    d.onclick=(ev)=>{ev.preventDefault();ev.stopPropagation(); if(light.own){toast('Αυτό είναι το δικό σου φως.')} else { touchLighthouseLightV249278(light.light_id,d);} return false;};
    sky.appendChild(d);
  });
  if($('lighthouseTotalV249278')) $('lighthouseTotalV249278').textContent=String(data.total_count||0);
  if($('lighthouseSeenCountV249278')) $('lighthouseSeenCountV249278').textContent=lighthouseStatusTextV249278(data);
  if($('lighthouseSeenSubV249278')) $('lighthouseSeenSubV249278').textContent=lighthouseSubtitleTextV249278(data);
  if($('lighthouseButtonLabelV249278')) $('lighthouseButtonLabelV249278').textContent=(data.my_has_light?'Το φως σου λάμπει ήδη':'Άναψε ένα φως');
  if($('lighthouseTapNoticeV249278')) $('lighthouseTapNoticeV249278').style.display=(data.total_count>0?'block':'none');
  return false;
}
async function lightMyCandleV249278(){
  try{
    const r=await fetchJson('/api/lighthouse/light',{method:'POST',body:JSON.stringify({room_id:state.room,owner_token:lighthouseTokenV249278()})});
    toast(r.created?'Το φως σου άναψε στον ουρανό.':'Το φως σου είναι ήδη αναμμένο απόψε.');
    await loadLighthouseSkyV249278(false);
  }catch(e){ toast('Δεν άναψε το φως: '+(e.message||e),7000); }
  return false;
}
async function touchLighthouseLightV249278(lightId, el){
  try{
    const r=await fetchJson('/api/lighthouse/touch',{method:'POST',body:JSON.stringify({room_id:state.room,owner_token:lighthouseTokenV249278(),light_id:lightId})});
    try{el.classList.add('touched'); setTimeout(()=>el.classList.remove('touched'),1200);}catch{}
    toast(r.already?'Το φως το άγγιξες ήδη απόψε.':'Έστειλες έναν σιωπηλό παλμό.');
    await loadLighthouseSkyV249278(false);
  }catch(e){ toast('Δεν στάλθηκε ο παλμός: '+(e.message||e),7000); }
  return false;
}
try{var renderHomeV249278Base=renderHome}catch(e){var renderHomeV249278Base=null}
renderHome=function(){
  const r=renderHomeV249278Base?renderHomeV249278Base.apply(this,arguments):false;
  try{
    injectLighthouseV249278Css();
    const h=$('homePage');
    if(h&&!document.getElementById('lighthouseHomeMountV249278')){
      const wrap=document.createElement('div'); wrap.id='lighthouseHomeMountV249278'; wrap.innerHTML=lighthouseHomeCardV249278();
      const ref=document.getElementById('bottleHomeMountV249274') || h.querySelector('.homeProPanel,.homeMenu,.welcomeHero') || h.firstElementChild;
      if(ref&&ref.parentNode) ref.parentNode.insertBefore(wrap, ref.nextSibling); else h.prepend(wrap);
    }
  }catch(e){}
  return r;
};
function installLighthouseExportsV249278(){
  try{window.ITH=window.ITH||{};Object.assign(window.ITH,{openLighthouseV249278,closeLighthouseV249278,loadLighthouseSkyV249278,lightMyCandleV249278,touchLighthouseLightV249278});}catch(e){}
}
try{injectLighthouseV249278Css();installLighthouseExportsV249278();setTimeout(installLighthouseExportsV249278,600);setTimeout(installLighthouseExportsV249278,1600);}catch(e){}


/* V249279 - Lighthouse touch/menu + Athina non-intrusive suggestions */
function injectV249279FixCss(){
  try{
    if(document.getElementById('ithV249279FixCss'))return;
    const st=document.createElement('style');
    st.id='ithV249279FixCss';
    st.textContent=`
      .athinaTinyTipV249279{position:fixed;left:12px;bottom:112px;z-index:10040;max-width:min(420px,calc(100vw - 24px));display:grid;grid-template-columns:auto 1fr auto;gap:9px;align-items:center;padding:9px 11px;border-radius:20px;border:1px solid rgba(255,217,110,.25);background:linear-gradient(165deg,rgba(3,12,23,.96),rgba(8,26,42,.96));box-shadow:0 18px 44px rgba(0,0,0,.38);color:#fff;animation:tipInV249279 .2s ease-out}
      .athinaTinyTipV249279 .face{width:42px;height:42px;border-radius:14px;display:grid;place-items:center;background:rgba(255,255,255,.07);overflow:hidden}.athinaTinyTipV249279 b{color:#ffe39b;font-size:13px}.athinaTinyTipV249279 small{display:block;color:rgba(239,248,255,.78);line-height:1.25}.athinaTinyTipV249279 button{width:26px;height:26px;border-radius:50%;border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.08);color:#fff}
      @keyframes tipInV249279{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
      .lighthouseHintV249278{cursor:pointer!important;user-select:none!important}
      .lighthouseHintV249278:hover{border-color:rgba(255,217,110,.32)!important;background:rgba(7,20,40,.60)!important}
      .lighthouseMenuV249279{position:absolute;right:16px;top:72px;z-index:9;width:min(320px,calc(100% - 32px));border-radius:24px;border:1px solid rgba(255,217,110,.22);background:rgba(4,14,28,.88);box-shadow:0 24px 70px rgba(0,0,0,.52);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);color:#fff;padding:12px;display:grid;gap:8px}
      .lighthouseMenuV249279 button{border-radius:18px;border:1px solid rgba(255,217,110,.18);background:rgba(255,255,255,.06);color:#fff;padding:11px;text-align:left;font-weight:900}.lighthouseMenuV249279 small{display:block;opacity:.72;font-weight:700;margin-top:3px;line-height:1.3}
      .lighthouseAmbientDotV249279{position:absolute;width:7px;height:7px;border-radius:50%;background:radial-gradient(circle,#fff6bd 0,#ffd36d 38%,rgba(255,197,85,.42) 65%,rgba(255,197,85,0) 100%);box-shadow:0 0 8px rgba(255,213,115,.62),0 0 22px rgba(255,213,115,.25);transform:translate(-50%,-50%);opacity:.82;pointer-events:none;animation:twinkleV249279 3.8s ease-in-out infinite}
      @keyframes twinkleV249279{0%,100%{opacity:.55;transform:translate(-50%,-50%) scale(.88)}50%{opacity:1;transform:translate(-50%,-50%) scale(1.22)}}
      .lighthouseDotV249278{z-index:4}.lighthouseAmbientDotV249279{z-index:2}
      .plusBottleLightV249279 b{font-size:24px!important}
      @media(max-width:760px){.athinaTinyTipV249279{bottom:92px;left:10px;right:10px;max-width:none}.lighthouseMenuV249279{right:10px;top:68px;width:calc(100% - 20px)}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function closeAthinaTinyTipV249279(){try{document.getElementById('athinaTinyTipV249279')?.remove()}catch(e){}return false}
function showAthinaTinyTipV249279(text='Γεια σου, πώς είσαι σήμερα;', sub='Πάτησε τη μασκότ αν θέλεις ξενάγηση.'){
  try{
    injectV249279FixCss();
    if(document.querySelector('#lighthouseOverlayV249278,.bottleSeaOverlayV249274,.guideOverlayV249275,.guideOverlayV249276,#memberMenu.show'))return false;
    if(state.page&&state.page!=='home')return false;
    closeAthinaTinyTipV249279();
    const d=document.createElement('div');
    d.id='athinaTinyTipV249279';d.className='athinaTinyTipV249279';
    d.innerHTML=`<div class="face">${typeof athinaOwlV249258==='function'?athinaOwlV249258('small'):'🦉'}</div><div><b>${esc(text)}</b><small>${esc(sub)}</small></div><button type="button">×</button>`;
    d.onclick=(ev)=>{if(ev.target&&ev.target.tagName==='BUTTON')return;closeAthinaTinyTipV249279();openFirstRunGuideV249275&&openFirstRunGuideV249275(true)};
    d.querySelector('button').onclick=(ev)=>{ev.stopPropagation();closeAthinaTinyTipV249279()};
    document.body.appendChild(d);
    setTimeout(closeAthinaTinyTipV249279,5000);
  }catch(e){}
  return false;
}
showAthinaWelcomeV249272=function(force=false){return force?showAthinaTinyTipV249279():false};
showAthinaSimpleHelloV249273=function(force=false){return force?showAthinaTinyTipV249279():false};
showAthinaSimpleHelloV249276=function(force=false){return force?showAthinaTinyTipV249279():false};
try{
  if(window.__athinaSuggestTimerV249279)clearInterval(window.__athinaSuggestTimerV249279);
  window.__athinaSuggestTimerV249279=setInterval(()=>{try{
    const lines=[
      ['Γεια σου, πώς είσαι σήμερα;','Πάτησε τη μασκότ αν θέλεις ξενάγηση.'],
      ['Θέλεις να ανάψεις ένα φως;','Ο Φάρος είναι χωρίς λέξεις, μόνο παρουσία.'],
      ['Θέλεις να ρίξεις μπουκάλι;','Το Πέλαγος των Ψιθύρων περιμένει.']
    ];
    const i=(Math.floor(Date.now()/10000)%lines.length);showAthinaTinyTipV249279(lines[i][0],lines[i][1]);
  }catch(e){}},10000);
}catch(e){}
function lighthouseAmbientPositionsV249279(){
  return [[12,28],[20,34],[30,30],[42,26],[54,34],[69,28],[82,33],[18,48],[26,52],[36,47],[48,51],[61,46],[73,52],[86,48],[15,60],[25,63],[39,58],[52,64],[66,59],[78,64],[90,58],[32,70],[45,74],[58,70],[72,75],[84,70],[9,42],[91,40],[50,38],[64,37],[75,42],[22,73],[12,75],[88,76],[6,65],[94,66]];
}
function addAmbientLightsV249279(){
  try{
    const sky=$('lighthouseSkyV249278');if(!sky)return;
    if(sky.querySelector('.lighthouseAmbientDotV249279'))return;
    lighthouseAmbientPositionsV249279().forEach((p,idx)=>{
      const d=document.createElement('span');
      d.className='lighthouseAmbientDotV249279';
      d.style.left=p[0]+'%';d.style.top=p[1]+'%';d.style.animationDelay=(idx%9*.35)+'s';
      sky.appendChild(d);
    });
  }catch(e){}
}
try{var renderLighthouseSkyV249279Base=renderLighthouseSkyV249278}catch(e){var renderLighthouseSkyV249279Base=null}
renderLighthouseSkyV249278=function(data){
  const r=renderLighthouseSkyV249279Base?renderLighthouseSkyV249279Base(data):false;
  try{
    window.__lighthouseDataV249279=data||{};
    window.__lighthouseForeignLightsV249279=(data?.lights||[]).filter(x=>!x.own);
    addAmbientLightsV249279();
    const h=document.querySelector('.lighthouseHintV249278');
    if(h){
      h.setAttribute('role','button');h.setAttribute('tabindex','0');
      h.onclick=(ev)=>{ev.preventDefault();ev.stopPropagation();return touchRandomLighthouseLightV249279()};
      h.onkeydown=(ev)=>{if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();touchRandomLighthouseLightV249279()}};
    }
    const tap=$('lighthouseTapNoticeV249278');
    if(tap){tap.style.display='block';tap.onclick=(ev)=>{ev.preventDefault();return touchRandomLighthouseLightV249279()};tap.style.cursor='pointer'}
  }catch(e){}
  return r;
};
function pulseAmbientLightV249279(){
  try{
    const dots=[...document.querySelectorAll('.lighthouseAmbientDotV249279')];
    const d=dots[Math.floor(Math.random()*dots.length)];
    if(!d)return false;
    d.style.animation='none';void d.offsetHeight;d.style.animation='lighthousePulseV249278 1.2s ease-out 1';
    setTimeout(()=>{try{d.style.animation='twinkleV249279 3.8s ease-in-out infinite'}catch(e){}},1300);
  }catch(e){}
}
async function touchRandomLighthouseLightV249279(){
  try{
    const arr=window.__lighthouseForeignLightsV249279||[];
    if(arr.length){
      const one=arr[Math.floor(Math.random()*arr.length)];
      const el=[...document.querySelectorAll('.lighthouseDotV249278')].find(b=>Math.abs(parseFloat(b.style.left)-Number(one.x))<.1&&Math.abs(parseFloat(b.style.top)-Number(one.y))<.1);
      return touchLighthouseLightV249278(one.light_id,el||document.body);
    }
    pulseAmbientLightV249279();
    toast('Άγγιξες ένα σιωπηλό φως του ουρανού. Όταν υπάρχει πραγματικό ξένο φως, θα σταλεί παλμός.');
  }catch(e){toast('Δεν έγινε το άγγιγμα: '+(e.message||e),6000)}
  return false;
}
function openLighthouseMenuV249279(){
  try{
    const screen=document.querySelector('.lighthouseScreenV249278');if(!screen)return false;
    document.getElementById('lighthouseMenuV249279')?.remove();
    const m=document.createElement('div');m.id='lighthouseMenuV249279';m.className='lighthouseMenuV249279';
    m.innerHTML=`<button onclick="ITH.lightMyCandleV249278()">🕯️ Άναψε ένα φως<small>Χωρίς λέξεις, μόνο παρουσία.</small></button><button onclick="ITH.touchRandomLighthouseLightV249279()">✨ Άγγιξε ξένο φως<small>Στείλε σιωπηλό παλμό.</small></button><button onclick="ITH.loadLighthouseSkyV249278(true)">🔄 Ανανέωση ουρανού<small>Φόρτωσε ξανά τα φώτα.</small></button><button onclick="ITH.page('home');ITH.closeLighthouseV249278()">🏠 Αρχική<small>Επιστροφή στην ΙΘΑΚΗ.</small></button><button onclick="document.getElementById('lighthouseMenuV249279')?.remove()">× Κλείσιμο</button>`;
    screen.appendChild(m);
  }catch(e){}
  return false;
}
try{var openLighthouseV249279Base=openLighthouseV249278}catch(e){var openLighthouseV249279Base=null}
openLighthouseV249278=function(){
  const r=openLighthouseV249279Base?openLighthouseV249279Base():false;
  setTimeout(()=>{try{
    const more=document.querySelector('.lighthouseTopBarV249278 button:last-child');
    if(more)more.onclick=(ev)=>{ev.preventDefault();ev.stopPropagation();return openLighthouseMenuV249279()};
    const hint=document.querySelector('.lighthouseHintV249278');
    if(hint)hint.onclick=(ev)=>{ev.preventDefault();ev.stopPropagation();return touchRandomLighthouseLightV249279()};
  }catch(e){}},150);
  return r;
};
try{var togglePlusV249279Base=togglePlus}catch(e){var togglePlusV249279Base=null}
togglePlus=function(){
  const r=togglePlusV249279Base?togglePlusV249279Base():false;
  try{
    const s=$('plusSheet');if(s&&!s.querySelector('[data-r9plus="bottle"],[data-r8plus="bottle"],[data-act="bottle"]')){
      s.insertAdjacentHTML('beforeend',`<button class="tile plusBottleLightV249279" data-act="bottle"><b>🍾</b>Μπουκάλι</button>`);
    }
  }catch(e){}
  return r;
};
try{var bindPlusV249279Base=bindPlus}catch(e){var bindPlusV249279Base=null}
bindPlus=function(){
  if(bindPlusV249279Base)bindPlusV249279Base();
  const s=$('plusSheet');if(!s)return;
  s.addEventListener('click',ev=>{
    const b=ev.target.closest('[data-act]');if(!b)return;
    if(b.dataset.act==='bottle'){ev.preventDefault();ev.stopPropagation();s.classList.remove('show');return openBottleSeaV249274('compose')}
    if(b.dataset.act==='light'){ev.preventDefault();ev.stopPropagation();s.classList.remove('show');return openLighthouseV249278()}
  },true);
};
try{var guideGoV249279Base=guideGoV249275}catch(e){var guideGoV249279Base=null}
guideGoV249275=function(where){
  if(where==='light'||where==='lighthouse'){closeFirstRunGuideV249275&&closeFirstRunGuideV249275(true);return openLighthouseV249278()}
  return guideGoV249279Base?guideGoV249279Base(where):false;
};
try{var openFirstRunGuideV249279Base=openFirstRunGuideV249275}catch(e){var openFirstRunGuideV249279Base=null}
openFirstRunGuideV249275=function(force=true,startMood=''){
  const r=openFirstRunGuideV249279Base?openFirstRunGuideV249279Base(force,startMood):false;
  setTimeout(()=>{try{
    const grid=document.querySelector('.tourGridV249275');
    if(grid&&!grid.querySelector('[data-go="light"]')){
      grid.insertAdjacentHTML('afterbegin',`<button type="button" data-go="light">🕯️ Ο Φάρος<small>Άναψε φως ή άγγιξε ξένο φως χωρίς λέξεις.</small></button>`);
      grid.querySelector('[data-go="light"]').onclick=()=>guideGoV249275('light');
    }
  }catch(e){}},80);
  return r;
};
function installV249279Exports(){
  try{
    window.ITH=window.ITH||{};
    Object.assign(window.ITH,{showAthinaTinyTipV249279,closeAthinaTinyTipV249279,touchRandomLighthouseLightV249279,openLighthouseMenuV249279,openLighthouseV249278,togglePlus,bindPlus,openFirstRunGuideV249275});
    bindPlus();
  }catch(e){}
}
try{installV249279Exports();setTimeout(installV249279Exports,800);setTimeout(installV249279Exports,1800);setInterval(installV249279Exports,5000)}catch(e){}


/* V249280 - Professional communication center: group chats, broadcast, forward, public profile, API/webhooks */
function injectV249280CommCss(){
  try{if(document.getElementById('ithV249280CommCss'))return;const st=document.createElement('style');st.id='ithV249280CommCss';st.textContent=`
    .commOverlayV249280{position:fixed;inset:0;z-index:10220;background:rgba(0,0,0,.66);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);display:flex;align-items:center;justify-content:center;padding:12px;box-sizing:border-box}
    .commPanelV249280{width:min(940px,100%);max-height:94dvh;overflow:auto;border-radius:28px;border:1px solid rgba(255,217,110,.25);background:linear-gradient(165deg,rgba(3,12,23,.99),rgba(7,28,47,.99));box-shadow:0 34px 100px rgba(0,0,0,.62);color:#fff}
    .commTopV249280{position:sticky;top:0;z-index:3;display:flex;align-items:center;gap:10px;padding:13px;background:rgba(3,12,23,.96);border-bottom:1px solid rgba(255,255,255,.08);backdrop-filter:blur(10px)}.commTopV249280 b{color:#ffe39b;font-size:18px}.commTopV249280 .spacer{flex:1}.commTopV249280 button{border-radius:50%;width:40px;height:40px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.08);color:#fff;font-weight:1000}
    .commBodyV249280{padding:14px;display:grid;gap:12px}.commTabsV249280{display:flex;gap:8px;overflow:auto;padding-bottom:2px}.commTabsV249280 button{white-space:nowrap;border-radius:999px;border:1px solid rgba(255,217,110,.18);background:rgba(255,255,255,.06);color:#fff;padding:10px 12px;font-weight:1000}.commTabsV249280 button.active{background:rgba(255,217,110,.15);color:#ffe39b}
    .commGridV249280{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.commCardV249280{border-radius:20px;padding:12px;background:rgba(255,255,255,.065);border:1px solid rgba(255,255,255,.11);color:#fff}.commCardV249280 b{color:#ffe39b}.commCardV249280 p{white-space:pre-wrap;color:rgba(239,248,255,.84);line-height:1.38}
    .commInputV249280,.commTextareaV249280{width:100%;box-sizing:border-box;border-radius:16px;border:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.22);color:#fff;padding:11px;outline:none}.commTextareaV249280{min-height:96px;resize:vertical}
    .contactPickV249280{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;max-height:300px;overflow:auto;padding:4px}.contactPickV249280 label{display:flex;gap:8px;align-items:center;padding:8px;border-radius:16px;background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.08)}.contactPickV249280 .avatar{width:34px;height:34px;font-size:14px}.commActionsV249280{display:flex;gap:8px;flex-wrap:wrap}.commActionsV249280 button,.commPrimaryV249280{border-radius:999px;border:1px solid rgba(255,217,110,.26);background:linear-gradient(135deg,rgba(255,217,110,.18),rgba(127,215,255,.09));color:#fff;padding:10px 13px;font-weight:1000}.commPrimaryV249280{width:100%;margin-top:10px}
    .commHomeCardV249280{position:relative;overflow:hidden;border-radius:24px;margin:12px 0;padding:14px;border:1px solid rgba(255,217,110,.20);background:linear-gradient(135deg,rgba(18,37,67,.94),rgba(5,18,31,.96));box-shadow:0 18px 52px rgba(0,0,0,.24);color:#fff}.commHomeInnerV249280{position:relative;display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center}.commHomeIconV249280{width:78px;height:78px;border-radius:26px;display:grid;place-items:center;background:rgba(255,255,255,.075);border:1px solid rgba(255,217,110,.20);font-size:38px}.commHomeCardV249280 h3{margin:0;color:#ffe39b}.commHomeCardV249280 p{margin:6px 0;color:rgba(239,248,255,.84);line-height:1.36}.commHomeCardV249280 button{border-radius:999px;border:1px solid rgba(255,217,110,.32);background:linear-gradient(135deg,#ffd76a,#f2b74a);color:#132234;padding:10px 14px;font-weight:1000}
    @media(max-width:760px){.commGridV249280,.contactPickV249280{grid-template-columns:1fr}.commHomeInnerV249280{grid-template-columns:auto 1fr}.commHomeInnerV249280 button{grid-column:1/-1;width:100%}}
  `;document.head.appendChild(st)}catch(e){}
}
function peopleArrayV249280(){try{const arr=[];(state.people||new Map()).forEach((v,k)=>{if(String(k)!==String(state.device))arr.push(Object.assign({id:k},v||{}))});return arr.sort((a,b)=>String(a.nickname||a.id).localeCompare(String(b.nickname||b.id),'el'))}catch{return[]}}
async function ensurePeopleV249280(){try{if(typeof loadPeople==='function')await loadPeople()}catch(e){}return peopleArrayV249280()}
function contactPickerHtmlV249280(prefix){const arr=peopleArrayV249280();return `<div class="contactPickV249280" id="${prefix}PickV249280">${arr.map(p=>`<label><input type="checkbox" value="${esc(p.id||p.device_id||'')}">${avatarHtml(p)}<span>${esc(p.nickname||p.name||p.id||'Μέλος')}</span></label>`).join('')||'<div class="commCardV249280">Δεν φορτώθηκαν επαφές ακόμη. Πάτησε ανανέωση.</div>'}</div>`}
function selectedContactsV249280(prefix){return [...document.querySelectorAll(`#${prefix}PickV249280 input:checked`)].map(x=>x.value).filter(Boolean)}
function closeCommCenterV249280(){try{document.getElementById('commOverlayV249280')?.remove()}catch(e){}return false}
function openCommCenterV249280(tab='groups'){injectV249280CommCss();closeCommCenterV249280();const d=document.createElement('div');d.id='commOverlayV249280';d.className='commOverlayV249280';d.innerHTML=`<div class="commPanelV249280"><div class="commTopV249280"><b>📡 Κέντρο επικοινωνίας</b><span class="spacer"></span><button onclick="ITH.closeCommCenterV249280()">×</button></div><div class="commBodyV249280"><div class="commTabsV249280"><button data-tab="groups">👥 Group chats</button><button data-tab="broadcast">📣 Broadcast</button><button data-tab="forward">↪ Forward</button><button data-tab="profile">🪪 Δημόσιο προφίλ</button><button data-tab="api">🔌 API/Webhook</button></div><div id="commBodyV249280"></div></div></div>`;document.body.appendChild(d);d.querySelectorAll('[data-tab]').forEach(b=>b.onclick=()=>renderCommTabV249280(b.dataset.tab));renderCommTabV249280(tab);return false}
async function renderCommTabV249280(tab='groups'){injectV249280CommCss();await ensurePeopleV249280();document.querySelectorAll('.commTabsV249280 button').forEach(b=>b.classList.toggle('active',b.dataset.tab===tab));const body=document.getElementById('commBodyV249280');if(!body)return false;if(tab==='groups'){body.innerHTML=`<div class="commGridV249280"><div class="commCardV249280"><b>Νέο ομαδικό group chat</b><p>Ιδιωτική ομάδα πολλών ατόμων, ενδιάμεσα από DM και δημόσιο space.</p><input id="groupTitleV249280" class="commInputV249280" placeholder="Όνομα ομάδας"><textarea id="groupDescV249280" class="commTextareaV249280" placeholder="Σύντομη περιγραφή"></textarea>${contactPickerHtmlV249280('group')}<button class="commPrimaryV249280" onclick="ITH.createGroupChatV249280()">Δημιουργία ομάδας</button></div><div class="commCardV249280"><b>Οι ομάδες μου</b><button class="commPrimaryV249280" onclick="ITH.loadGroupsV249280()">Ανανέωση ομάδων</button><div id="groupListV249280"></div></div></div>`;loadGroupsV249280();}
else if(tab==='broadcast'){body.innerHTML=`<div class="commGridV249280"><div class="commCardV249280"><b>Broadcast list</b><p>Στέλνεις μήνυμα σε πολλούς. Δεν βλέπουν ο ένας τον άλλον.</p><input id="bcastTitleV249280" class="commInputV249280" placeholder="Όνομα λίστας">${contactPickerHtmlV249280('bcast')}<button class="commPrimaryV249280" onclick="ITH.createBroadcastV249280()">Αποθήκευση λίστας</button></div><div class="commCardV249280"><b>Άμεση αποστολή</b><textarea id="bcastTextV249280" class="commTextareaV249280" placeholder="Μήνυμα broadcast..."></textarea>${contactPickerHtmlV249280('bcastSend')}<button class="commPrimaryV249280" onclick="ITH.sendBroadcastV249280()">Αποστολή στους επιλεγμένους</button><div id="bcastListV249280"></div></div></div>`;loadBroadcastsV249280();}
else if(tab==='forward'){body.innerHTML=`<div class="commGridV249280"><div class="commCardV249280"><b>Forward μηνύματος</b><p>Προώθηση σε επαφές και group chats.</p><textarea id="forwardTextV249280" class="commTextareaV249280" placeholder="Κείμενο για προώθηση..."></textarea><b>Επαφές</b>${contactPickerHtmlV249280('forward')}<button class="commPrimaryV249280" onclick="ITH.forwardMessageV249280()">Forward στους επιλεγμένους</button></div><div class="commCardV249280"><b>Group chats για forward</b><div id="forwardGroupsV249280">Φόρτωση...</div></div></div>`;loadForwardGroupsV249280();}
else if(tab==='profile'){body.innerHTML=`<div class="commCardV249280"><b>Δημόσιο προφίλ</b><p>Επαγγελματική εικόνα με bio, link και cover photo. Φαίνεται όταν κάποιος ανοίγει το προφίλ σου.</p><input id="pubNameV249280" class="commInputV249280" placeholder="Εμφανιζόμενο όνομα" value="${esc(state.name||'')}"><textarea id="pubBioV249280" class="commTextareaV249280" placeholder="Bio / τι θέλεις να ξέρουν οι άλλοι"></textarea><input id="pubLinkV249280" class="commInputV249280" placeholder="Link / site / portfolio"><input id="pubCoverV249280" class="commInputV249280" placeholder="Cover photo URL ή base64 από υπάρχουσα εικόνα"><button class="commPrimaryV249280" onclick="ITH.savePublicProfileV249280()">Αποθήκευση δημόσιου προφίλ</button><div id="pubProfileResultV249280"></div></div>`;loadPublicProfileV249280();}
else if(tab==='api'){body.innerHTML=`<div class="commGridV249280"><div class="commCardV249280"><b>API / Webhook</b><p>Για ενσωμάτωση με τρίτα συστήματα. Μπορείς να δεχτείς εισερχόμενα μηνύματα από εξωτερικό σύστημα με secret.</p><input id="hookTitleV249280" class="commInputV249280" placeholder="Όνομα σύνδεσης"><input id="hookUrlV249280" class="commInputV249280" placeholder="Webhook URL προαιρετικό"><input id="hookSecretV249280" class="commInputV249280" placeholder="Secret ή κενό για αυτόματο"><button class="commPrimaryV249280" onclick="ITH.saveWebhookV249280()">Δημιουργία / αποθήκευση API σύνδεσης</button><div class="commCardV249280"><b>Incoming endpoint</b><p>/api/integrations/incoming</p><small>Payload: room_id, secret, channel, nickname, text</small></div></div><div class="commCardV249280"><b>Οι συνδέσεις μου</b><button class="commPrimaryV249280" onclick="ITH.loadWebhooksV249280()">Ανανέωση</button><div id="webhookListV249280"></div></div></div>`;loadWebhooksV249280();}
return false}
async function createGroupChatV249280(){const title=($('groupTitleV249280')?.value||'').trim()||'Ομάδα';const description=($('groupDescV249280')?.value||'').trim();const member_ids=selectedContactsV249280('group');try{const r=await fetchJson('/api/groups/create',{method:'POST',body:JSON.stringify({room_id:state.room,owner_id:state.device,title,description,member_ids})});toast('Δημιουργήθηκε group chat.');loadGroupsV249280();}catch(e){toast('Δεν δημιουργήθηκε ομάδα: '+(e.message||e),7000)}return false}
async function loadGroupsV249280(){try{const r=await fetchJson(`/api/groups/list?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);const box=$('groupListV249280');if(box)box.innerHTML=(r.groups||[]).map(g=>`<div class="commCardV249280"><b>${esc(g.title)}</b><p>${esc(g.description||'')}<br>Μέλη: ${g.member_count||0}</p><div class="commActionsV249280"><button onclick="ITH.openGroupChatV249280('${escJs(g.group_id)}','${escJs(g.title)}')">Άνοιγμα chat</button><button onclick="ITH.addMembersToExistingGroupV249280('${escJs(g.group_id)}')">Προσθήκη επιλεγμένων</button></div></div>`).join('')||'<p>Δεν έχεις ομάδες ακόμη.</p>'}catch(e){const box=$('groupListV249280');if(box)box.innerHTML='<p>Δεν φορτώθηκαν ομάδες.</p>'}return false}
async function openGroupChatV249280(gid,title){closeCommCenterV249280();state.activePeer='';state.activeChannel='group:'+gid;state.lastMsgIds&&state.lastMsgIds.clear&&state.lastMsgIds.clear();state.messagesSince=0;page('dm');try{showDMChatScreenV249235&&showDMChatScreenV249235()}catch(e){}try{if($('chatName'))$('chatName').textContent='👥 '+(title||'Ομάδα');if($('chatAvatar'))$('chatAvatar').outerHTML='<button id="chatAvatar" class="chatAvatarBtn">👥</button>'}catch(e){}try{wsSubscribe(state.activeChannel)}catch(e){}await loadMessages(true);return false}
async function addMembersToExistingGroupV249280(gid){const ids=selectedContactsV249280('group');if(!ids.length)return toast('Διάλεξε επαφές από αριστερά.');try{await fetchJson('/api/groups/add_members',{method:'POST',body:JSON.stringify({room_id:state.room,group_id:gid,member_ids:ids})});toast('Προστέθηκαν μέλη.');loadGroupsV249280()}catch(e){toast('Δεν προστέθηκαν: '+(e.message||e),7000)}return false}
async function createBroadcastV249280(){const title=($('bcastTitleV249280')?.value||'').trim()||'Broadcast';const member_ids=selectedContactsV249280('bcast');try{await fetchJson('/api/broadcast/create',{method:'POST',body:JSON.stringify({room_id:state.room,owner_id:state.device,title,member_ids})});toast('Αποθηκεύτηκε broadcast list.');loadBroadcastsV249280()}catch(e){toast('Δεν αποθηκεύτηκε: '+(e.message||e),7000)}return false}
async function loadBroadcastsV249280(){try{const r=await fetchJson(`/api/broadcast/list?room_id=${encodeURIComponent(state.room)}&owner_id=${encodeURIComponent(state.device)}`);const box=$('bcastListV249280');if(box)box.innerHTML=(r.lists||[]).map(l=>`<div class="commCardV249280"><b>📣 ${esc(l.title)}</b><p>Παραλήπτες: ${l.member_count||0}</p><button onclick="ITH.sendBroadcastListV249280('${escJs(l.list_id)}')">Στείλε σε αυτή τη λίστα</button></div>`).join('')||'<p>Δεν υπάρχουν λίστες.</p>'}catch(e){}}
async function sendBroadcastV249280(){const text=($('bcastTextV249280')?.value||'').trim();const member_ids=selectedContactsV249280('bcastSend');try{const r=await fetchJson('/api/broadcast/send',{method:'POST',body:JSON.stringify({room_id:state.room,owner_id:state.device,nickname:state.name,text,member_ids})});toast('Broadcast στάλθηκε σε '+r.sent+' επαφές.')}catch(e){toast('Δεν στάλθηκε: '+(e.message||e),7000)}return false}
async function sendBroadcastListV249280(list_id){const text=($('bcastTextV249280')?.value||prompt('Μήνυμα broadcast:')||'').trim();if(!text)return false;try{const r=await fetchJson('/api/broadcast/send',{method:'POST',body:JSON.stringify({room_id:state.room,owner_id:state.device,nickname:state.name,text,list_id})});toast('Broadcast στάλθηκε σε '+r.sent+' επαφές.')}catch(e){toast('Δεν στάλθηκε: '+(e.message||e),7000)}return false}
async function loadForwardGroupsV249280(){try{const r=await fetchJson(`/api/groups/list?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);const box=$('forwardGroupsV249280');if(box)box.innerHTML=(r.groups||[]).map(g=>`<label style="display:flex;gap:8px;align-items:center;padding:8px;border-radius:14px;background:rgba(255,255,255,.05);margin:6px 0"><input type="checkbox" class="fwdGroupV249280" value="${esc(g.group_id)}"><span>👥 ${esc(g.title)}</span></label>`).join('')||'Δεν υπάρχουν ομάδες.'}catch(e){}}
async function forwardMessageV249280(){const text=($('forwardTextV249280')?.value||'').trim();const to_ids=selectedContactsV249280('forward');const group_ids=[...document.querySelectorAll('.fwdGroupV249280:checked')].map(x=>x.value);try{const r=await fetchJson('/api/messages/forward',{method:'POST',body:JSON.stringify({room_id:state.room,sender_id:state.device,nickname:state.name,text,to_ids,group_ids})});toast('Forward στάλθηκε: '+r.sent);}catch(e){toast('Δεν έγινε forward: '+(e.message||e),7000)}return false}
async function loadPublicProfileV249280(){try{const r=await fetchJson(`/api/profile/public?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);const p=r.profile||{};if($('pubNameV249280'))$('pubNameV249280').value=p.display_name||state.name||'';if($('pubBioV249280'))$('pubBioV249280').value=p.bio||'';if($('pubLinkV249280'))$('pubLinkV249280').value=p.link||'';if($('pubCoverV249280'))$('pubCoverV249280').value=p.cover_photo||'';}catch(e){}}
async function savePublicProfileV249280(){try{const body={room_id:state.room,device_id:state.device,display_name:($('pubNameV249280')?.value||state.name||''),bio:($('pubBioV249280')?.value||''),link:($('pubLinkV249280')?.value||''),cover_photo:($('pubCoverV249280')?.value||'')};await fetchJson('/api/profile/public/save',{method:'POST',body:JSON.stringify(body)});toast('Το δημόσιο προφίλ αποθηκεύτηκε.');if($('pubProfileResultV249280'))$('pubProfileResultV249280').innerHTML='<p>Αποθηκεύτηκε επαγγελματικό δημόσιο προφίλ.</p>'}catch(e){toast('Δεν αποθηκεύτηκε: '+(e.message||e),7000)}return false}
async function saveWebhookV249280(){try{const body={room_id:state.room,owner_id:state.device,title:($('hookTitleV249280')?.value||'Webhook'),url:($('hookUrlV249280')?.value||''),secret:($('hookSecretV249280')?.value||''),events:['incoming_message','forward','broadcast']};const r=await fetchJson('/api/webhooks/save',{method:'POST',body:JSON.stringify(body)});toast('API/Webhook αποθηκεύτηκε. Secret: '+r.secret);loadWebhooksV249280()}catch(e){toast('Δεν αποθηκεύτηκε webhook: '+(e.message||e),7000)}return false}
async function loadWebhooksV249280(){try{const r=await fetchJson(`/api/webhooks/list?room_id=${encodeURIComponent(state.room)}&owner_id=${encodeURIComponent(state.device)}`);const box=$('webhookListV249280');if(box)box.innerHTML=(r.webhooks||[]).map(h=>`<div class="commCardV249280"><b>🔌 ${esc(h.title)}</b><p>Hook ID: ${esc(h.hook_id)}<br>URL: ${esc(h.url||'incoming only')}<br>Enabled: ${h.enabled?'yes':'no'}</p></div>`).join('')||'<p>Δεν υπάρχουν webhooks.</p>'}catch(e){}}
function commHomeCardV249280(){injectV249280CommCss();return `<section class="commHomeCardV249280"><div class="commHomeInnerV249280"><div class="commHomeIconV249280">📡</div><div><h3>Κέντρο επικοινωνίας</h3><p>Ομαδικά group chats, broadcast lists, forward, δημόσιο προφίλ και API/Webhook για τρίτα συστήματα.</p></div><button onclick="ITH.openCommCenterV249280('groups')">Άνοιγμα ›</button></div></section>`}
try{var renderHomeV249280Base=renderHome}catch(e){var renderHomeV249280Base=null}
renderHome=function(){const r=renderHomeV249280Base?renderHomeV249280Base.apply(this,arguments):false;try{injectV249280CommCss();const h=$('homePage');if(h&&!document.getElementById('commHomeMountV249280')){const wrap=document.createElement('div');wrap.id='commHomeMountV249280';wrap.innerHTML=commHomeCardV249280();const ref=document.getElementById('lighthouseHomeMountV249278')||document.getElementById('bottleHomeMountV249274')||h.querySelector('.homeProPanel,.homeMenu,.welcomeHero')||h.firstElementChild;if(ref&&ref.parentNode)ref.parentNode.insertBefore(wrap,ref.nextSibling);else h.prepend(wrap)}}catch(e){}return r}
try{var togglePlusV249280Base=togglePlus}catch(e){var togglePlusV249280Base=null}
togglePlus=function(){const r=togglePlusV249280Base?togglePlusV249280Base.apply(this,arguments):false;try{const s=$('plusSheet');if(s&&!s.querySelector('[data-act="comm_center"]'))s.insertAdjacentHTML('beforeend','<button class="tile" data-act="comm_center"><b>📡</b>Groups/Broadcast</button><button class="tile" data-act="forward"><b>↪</b>Forward</button><button class="tile" data-act="api_hooks"><b>🔌</b>API/Webhook</button>')}catch(e){}return r}
try{var bindPlusV249280Base=bindPlus}catch(e){var bindPlusV249280Base=null}
bindPlus=function(){if(bindPlusV249280Base)bindPlusV249280Base.apply(this,arguments);const s=$('plusSheet');if(!s)return;s.addEventListener('click',function(e){const b=e.target.closest('[data-act]');if(!b)return;const a=b.dataset.act;if(['comm_center','forward','api_hooks'].includes(a)){e.preventDefault();e.stopPropagation();s.classList.remove('show');if(a==='comm_center')return openCommCenterV249280('groups');if(a==='forward')return openCommCenterV249280('forward');if(a==='api_hooks')return openCommCenterV249280('api')}},true)}
function installCommExportsV249280(){try{window.ITH=window.ITH||{};Object.assign(window.ITH,{openCommCenterV249280,closeCommCenterV249280,renderCommTabV249280,createGroupChatV249280,loadGroupsV249280,openGroupChatV249280,addMembersToExistingGroupV249280,createBroadcastV249280,loadBroadcastsV249280,sendBroadcastV249280,sendBroadcastListV249280,loadForwardGroupsV249280,forwardMessageV249280,savePublicProfileV249280,loadPublicProfileV249280,saveWebhookV249280,loadWebhooksV249280});}catch(e){}}
try{injectV249280CommCss();installCommExportsV249280();setTimeout(installCommExportsV249280,600);setTimeout(installCommExportsV249280,1800)}catch(e){}


/* V249281 - professional spaces: friend invite list, stats, admin form, popular search, templates, notifications, pin/report */
function injectSpacesV249281Css(){
  try{
    if(document.getElementById('ithSpacesV249281Css')) return;
    const st=document.createElement('style'); st.id='ithSpacesV249281Css';
    st.textContent=`
      .spacesProTopV249281{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px;align-items:center}.spacesProTopV249281 .grow{flex:1}.spacesSearchV249281{min-width:180px;flex:1;border-radius:999px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.08);color:inherit;padding:10px 13px;outline:none}.spacesSortV249281{border-radius:999px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.08);color:inherit;padding:10px 12px}
      .spaceTileV249281{display:block;width:100%;text-align:left}.spaceMetaV249281{display:flex;gap:7px;flex-wrap:wrap;margin-top:8px}.spacePillV249281{display:inline-flex;align-items:center;gap:5px;border-radius:999px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.10);padding:4px 8px;font-size:12px;color:var(--muted,#b7c0ca)}.memberPreviewV249281{display:flex;gap:5px;margin-top:8px;align-items:center;flex-wrap:wrap}.miniAvatarV249281{width:24px;height:24px;border-radius:50%;display:inline-grid;place-items:center;background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.12);font-size:12px;overflow:hidden}.miniAvatarV249281 img{width:100%;height:100%;object-fit:cover}.spacePinnedV249281{border-radius:16px;margin:0 0 8px;padding:10px;background:linear-gradient(135deg,rgba(255,217,110,.14),rgba(127,215,255,.08));border:1px solid rgba(255,217,110,.22)}.spacePinnedV249281 b{color:#ffe39b}.spaceActionRowV249281{display:flex;gap:6px;flex-wrap:wrap;margin-top:7px}.spaceActionRowV249281 button{font-size:12px;padding:5px 8px;border-radius:999px}.inviteFriendListV249281{display:grid;gap:8px;max-height:52vh;overflow:auto;padding-right:2px}.friendPickV249281{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:center;border-radius:16px;padding:9px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10)}.friendPickV249281 small{display:block;color:var(--muted,#aeb7c3)}.templateGridV249281{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.templateGridV249281 button{text-align:left;border-radius:16px;padding:10px}.templateGridV249281 small{display:block;margin-top:4px;color:var(--muted,#aeb7c3);font-weight:700}.adminFormV249281 input[type=password],.adminFormV249281 input,.adminFormV249281 textarea{width:100%;box-sizing:border-box;border-radius:14px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.08);color:inherit;padding:11px;margin-top:6px}.popularSpacePanelV249281{display:grid;gap:8px}.popularSpacePanelV249281 .rank{display:inline-flex;width:28px;height:28px;border-radius:50%;align-items:center;justify-content:center;background:rgba(255,217,110,.18);color:#ffe39b;font-weight:1000}.spaceSubscribeOnV249281{background:linear-gradient(135deg,#54f0a0,#91ffd0)!important;color:#09251a!important}
      @media(max-width:760px){.templateGridV249281{grid-template-columns:1fr}.spacesSearchV249281{min-width:100%}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function spaceStatsV249281(id){try{return (state.spaceStatsV249281||{})[id]||{}}catch{return {}}}
function spaceMembersPreviewV249281(id){const st=spaceStatsV249281(id);const members=st.members||[];if(!members.length)return '<span class="date">Κανένα ενεργό μέλος ακόμη</span>';return `<div class="memberPreviewV249281">${members.slice(0,8).map(m=>{const p=v249231PersonById(m.device_id||m.id||'');const av=p.avatar||m.avatar||'';return `<span class="miniAvatarV249281" title="${esc(m.nickname||p.nickname||'Μέλος')}">${av?`<img src="${esc(av)}">`:esc((m.nickname||p.nickname||'Μ')[0]||'Μ')}</span>`}).join('')}<span class="date">${members.length} στη λίστα</span></div>`}
function subscribedSpacesV249281(){try{return JSON.parse(localStorage.getItem('ith_space_subscriptions_v249281')||'[]')}catch{return []}}
function saveSubscribedSpacesV249281(a){try{localStorage.setItem('ith_space_subscriptions_v249281',JSON.stringify([...new Set(a||[])]))}catch(e){}}
function isSpaceSubscribedV249281(id){return subscribedSpacesV249281().includes(id)}
async function toggleSpaceSubscribeV249281(id){
  const on=!isSpaceSubscribedV249281(id);let a=subscribedSpacesV249281();if(on&&!a.includes(id))a.push(id);if(!on)a=a.filter(x=>x!==id);saveSubscribedSpacesV249281(a);wsSubscribe(a.map(x=>'space:'+x));
  try{await fetchJson('/api/rooms/subscribe',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:id,device_id:state.device,nickname:state.name,enabled:on})})}catch(e){}
  toast(on?'Θα ειδοποιείσαι για δραστηριότητα σε αυτόν τον χώρο.':'Σταμάτησαν οι ειδοποιήσεις αυτού του χώρου.');renderRoomList();return false;
}
try{var renderSpacesV249281Base=renderSpaces}catch(e){var renderSpacesV249281Base=null}
async function renderSpacesV249281(){if(window.__ITHAKI_R10F15_SINGLE_COMMUNITY_RUNTIME__)return __ithakiCanonicalSpacesR10F15();
  injectSpacesV249281Css();state.spaceTab=state.spaceTab||'rooms';
  const el=$('spacesPage');if(!el)return renderSpacesV249281Base?renderSpacesV249281Base():false;
  el.innerHTML=`<div class="spacesProTopV249281"><button class="icon" onclick="ITH.page('home')">‹</button><button class="btn ${state.spaceTab==='rooms'?'green':''}" onclick="ITH.spaceTab('rooms')">🏠 Δωμάτια</button><button class="btn ${state.spaceTab==='communities'?'green':''}" onclick="ITH.spaceTab('communities')">🌐 Κοινότητες</button><button class="btn gold" onclick="ITH.createSpaceCard()">＋ Δημιουργία</button><button class="btn" onclick="ITH.openPopularSpacesV249281()">🔥 Δημοφιλή</button><button class="btn" onclick="ITH.openSpaceTemplatesV249281()">🎨 Templates</button><button class="btn" onclick="ITH.loadRooms()">🔄</button><input id="spaceSearchV249281" class="spacesSearchV249281" placeholder="Αναζήτηση χώρων..." oninput="ITH.renderRoomList()"><select id="spaceSortV249281" class="spacesSortV249281" onchange="ITH.renderRoomList()"><option value="activity">Πρόσφατη δραστηριότητα</option><option value="members">Μέλη</option><option value="name">Όνομα</option></select></div><div id="spaceSamples" class="spaceSamples"></div><div class="roomLayout"><div><div id="roomList" class="roomList"></div></div><div class="chatPane"><div class="chatHead"><b id="spaceTitle">Διάλεξε χώρο</b><button class="icon" title="Προσκλήσεις" onclick="ITH.inviteToSpace(state.currentSpace)">👥</button><button class="icon chatActionBtn" title="Φωτογραφία" onclick="ITH.openSpaceMedia('photo',true)">📷</button><button class="icon chatActionBtn" title="Βίντεο" onclick="ITH.openSpaceMedia('video',true)">🎥</button><button class="icon chatActionBtn" title="Ήχος" onclick="ITH.startAudioRecording('space')">🎙️</button><button class="icon" onclick="ITH.openSpaceMedia('file',false)">📎</button><button class="icon" onclick="ITH.openE2EPanel()">🔐</button><button class="icon" onclick="ITH.openSpaceAdmin()">⚙️</button></div><div id="spacePinnedBoxV249281"></div><div id="spaceMsgs" class="messages"><div class="card">Διάλεξε χώρο. Βλέπεις πρώτα μέλη, δραστηριότητα και εμπιστοσύνη.</div></div><div class="composer"><textarea id="spaceInput" placeholder="Μήνυμα στον χώρο..."></textarea><button class="icon" onclick="ITH.sendSpaceText()">➤</button></div></div></div>`;
  renderSpaceSamples();await loadRooms();if(state.currentSpaceChannel){const s=(state.spaces||[]).find(x=>x.subroom_id===state.currentSpace)||{};if($('spaceTitle'))$('spaceTitle').textContent=s.title||'Space';await loadSpaceMessages(true)}
}
if(!window.__ITHAKI_R10F15_SINGLE_COMMUNITY_RUNTIME__)renderSpaces=renderSpacesV249281;
function spaceTab(tab){state.spaceTab=tab;if(window.__ITHAKI_R10F15_SINGLE_COMMUNITY_RUNTIME__)return __ithakiCanonicalSpacesR10F15();return renderSpaces()}
async function loadRooms(){
  injectSpacesV249281Css();
  try{
    let r;
    try{r=await fetchJson(`/api/rooms/overview?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`)}catch(e){r=await fetchJson(`/api/rooms?room_id=${encodeURIComponent(state.room)}`)}
    state.spaces=r.rooms||[];state.spaceStatsV249281={};(state.spaces||[]).forEach(s=>{state.spaceStatsV249281[s.subroom_id]=s});
    renderRoomList();try{checkSpaceActivityNotificationsV249281()}catch(e){}
  }catch(e){const l=$('roomList');if(l)l.innerHTML='<div class="card">Δεν φορτώνουν οι χώροι.</div>'}
}
function renderRoomList(){
  injectSpacesV249281Css();const list=$('roomList');if(!list)return;const want=state.spaceTab==='communities'?'community':'room';
  const q=($('spaceSearchV249281')?.value||'').trim().toLowerCase();const sort=$('spaceSortV249281')?.value||'activity';
  let arr=(state.spaces||[]).filter(s=>(s.category||'room')===want);if(!arr.length)arr=state.spaces||[];
  if(q)arr=arr.filter(s=>String((s.title||'')+' '+(s.description||'')).toLowerCase().includes(q));
  arr=arr.slice().sort((a,b)=>sort==='members'?((b.member_count||0)-(a.member_count||0)):sort==='name'?String(a.title||'').localeCompare(String(b.title||''),'el'):((b.last_activity||b.created_at||0)-(a.last_activity||a.created_at||0)));
  list.innerHTML=arr.map(s=>{const id=s.subroom_id;const st=spaceStatsV249281(id);const sub=isSpaceSubscribedV249281(id)||!!s.subscribed;const last=st.last_activity?fmt(st.last_activity):'χωρίς πρόσφατη κίνηση';return `<button class="tile spaceTile spaceTileV249281" onclick="ITH.openSpace('${escJs(id)}')"><b>${(s.category||want)==='community'?'🌐':'🏠'} ${esc(s.title||'Space')}</b><span class="date">${esc(s.access_type||'public')} ${s.join_code?'· με κωδικό':''}</span><div class="spaceMetaV249281"><span class="spacePillV249281">👥 ${Number(st.member_count||0)} μέλη</span><span class="spacePillV249281">💬 ${Number(st.message_count||0)} μηνύματα</span><span class="spacePillV249281">⏱️ ${esc(last)}</span>${st.pinned_count?`<span class="spacePillV249281">📌 ${st.pinned_count}</span>`:''}</div>${spaceMembersPreviewV249281(id)}<div class="row" style="margin-top:8px;gap:6px;flex-wrap:wrap"><button class="btn" onclick="event.stopPropagation();ITH.inviteToSpace('${escJs(id)}')">👥 Πρόσκληση</button><button class="btn" onclick="event.stopPropagation();ITH.showSpaceMembersV249281('${escJs(id)}')">Μέλη</button><button class="btn ${sub?'spaceSubscribeOnV249281':''}" onclick="event.stopPropagation();ITH.toggleSpaceSubscribeV249281('${escJs(id)}')">${sub?'🔔 ON':'🔕 Ειδοπ.'}</button><button class="btn" onclick="event.stopPropagation();ITH.showSpaceCode('${escJs(id)}')">▦ Code</button></div></button>`}).join('')||'<div class="card">Δεν βρέθηκε χώρος.</div>';
}
function renderSpaceSamples(){
  const box=$('spaceSamples');if(!box)return;const arr=(state.spaces||[]).slice().sort((a,b)=>((b.member_count||0)-(a.member_count||0))||((b.last_activity||0)-(a.last_activity||0))).slice(0,6);
  const fallback=state.spaceTab==='communities'?[['🧠','Φιλοσοφία καθημερινότητας'],['🧰','Τεχνίτες και μηχανικοί'],['🌿','Ήρεμη υποστήριξη'],['🎨','Τέχνη και δημιουργία'],['✈️','Ταξίδια'],['🕯️','Ο Φάρος συζητήσεις']]:[['👋','Γενική συζήτηση'],['👨‍👩‍👧','Οικογένεια'],['🧑‍💻','Project team'],['🤝','Φίλοι'],['📌','Συνάντηση'],['🌙','Νυχτερινές σκέψεις']];
  box.innerHTML=`<div class="card"><b>🔥 Δημοφιλείς / προτεινόμενοι χώροι</b><div class="row" style="margin-top:8px;gap:6px;flex-wrap:wrap">${arr.length?arr.map(s=>`<button class="btn" onclick="ITH.openSpace('${escJs(s.subroom_id)}')">${esc(s.title||'Space')} · 👥${s.member_count||0}</button>`).join(''):fallback.map(x=>`<button class="btn" onclick="ITH.prefillSpace('${escJs(x[1])}')">${x[0]} ${esc(x[1])}</button>`).join('')}</div></div>`
}
function openPopularSpacesV249281(){
  const arr=(state.spaces||[]).slice().sort((a,b)=>((b.member_count||0)-(a.member_count||0))||((b.last_activity||0)-(a.last_activity||0))).slice(0,30);
  $('memberMenu').innerHTML=`<div class="row"><b>🔥 Δημοφιλείς χώροι</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><input id="popularSpaceSearchV249281" style="width:100%" placeholder="Αναζήτηση..." oninput="ITH.renderPopularSpacesV249281()"></div><div id="popularSpacesListV249281" class="popularSpacePanelV249281"></div>`;$('memberMenu').classList.add('show');renderPopularSpacesV249281(arr);
}
function renderPopularSpacesV249281(source){const box=$('popularSpacesListV249281');if(!box)return;const q=($('popularSpaceSearchV249281')?.value||'').toLowerCase();const arr=(source||state.spaces||[]).filter(s=>String((s.title||'')+' '+(s.description||'')).toLowerCase().includes(q)).slice(0,30);box.innerHTML=arr.map((s,i)=>`<button class="tile" onclick="ITH.closeMember();ITH.openSpace('${escJs(s.subroom_id)}')"><span class="rank">${i+1}</span> <b>${esc(s.title||'Space')}</b><div class="date">👥 ${s.member_count||0} · 💬 ${s.message_count||0} · ${s.last_activity?fmt(s.last_activity):'χωρίς πρόσφατη δραστηριότητα'}</div></button>`).join('')||'<div class="card">Δεν βρέθηκε.</div>'}
function openSpaceTemplatesV249281(){
  const t=[['🧠','Φιλοσοφικό καφενείο','Ερώτηση εβδομάδας, σεβασμός, όχι ειρωνεία.'],['🌙','Νυχτερινή παρέα','Ήρεμες σκέψεις, αϋπνία, συντροφιά χωρίς πίεση.'],['🧰','Μάστορες / μηχανικοί','Τεχνικές λύσεις, εργαλεία, συμβουλές.'],['🎨','Δημιουργία','Τέχνη, μουσική, φωτογραφία, ιδέες.'],['🌿','Ήρεμη υποστήριξη','Ασφαλής χώρος, χωρίς διάγνωση, μόνο ανθρώπινη παρουσία.'],['✈️','Ταξίδια και τόποι','Μέρη, εμπειρίες, προτάσεις.'],['🍾','Πέλαγος των Ψιθύρων','Συζητήσεις γύρω από μπουκάλια και ρεύματα.'],['🕯️','Ο Φάρος','Χωρίς λέξεις, μόνο φως και παρουσία.']];
  $('memberMenu').innerHTML=`<div class="row"><b>🎨 Θεματικά templates</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card templateGridV249281">${t.map(x=>`<button class="btn" onclick="ITH.applySpaceTemplateV249281('${escJs(x[1])}','${escJs(x[2])}')"><b>${x[0]} ${esc(x[1])}</b><small>${esc(x[2])}</small></button>`).join('')}</div>`;$('memberMenu').classList.add('show')
}
function applySpaceTemplateV249281(title,desc){createSpaceCard(title);setTimeout(()=>{if($('newSpaceDesc'))$('newSpaceDesc').value=desc||''},60)}
function prefillSpace(title){createSpaceCard(title)}
function inviteToSpace(subroom_id){return openSpaceInviteListV249281(subroom_id||state.currentSpace)}
function openSpaceInviteListV249281(subroom_id){
  if(!subroom_id)return toast('Διάλεξε χώρο πρώτα.');injectSpacesV249281Css();const people=peopleArray();
  $('memberMenu').innerHTML=`<div class="row"><b>👥 Πρόσκληση σε χώρο</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><input id="spaceInviteSearchV249281" style="width:100%" placeholder="Αναζήτηση φίλου / επαφής..." oninput="ITH.renderSpaceInviteListV249281('${escJs(subroom_id)}')"><div class="date">Επιλογή συγκεκριμένων επαφών, ίδιο flow με τα Μηνύματα.</div></div><div id="spaceInviteListV249281" class="inviteFriendListV249281"></div><div class="card row" style="gap:8px;flex-wrap:wrap"><button class="btn green" onclick="ITH.sendSpaceInvitesV249281('${escJs(subroom_id)}')">Αποστολή προσκλήσεων</button><button class="btn" onclick="ITH.closeMember()">Άκυρο</button></div>`;$('memberMenu').classList.add('show');renderSpaceInviteListV249281(subroom_id);return false;
}
function renderSpaceInviteListV249281(subroom_id){const box=$('spaceInviteListV249281');if(!box)return;const q=($('spaceInviteSearchV249281')?.value||'').toLowerCase();let arr=peopleArray().filter(p=>String((p.nickname||'')+' '+(p.id||'')).toLowerCase().includes(q)).slice(0,120);box.innerHTML=arr.map(p=>`<label class="friendPickV249281">${avatarHtml(p)}<span><b>${esc(p.nickname||'Μέλος')}</b><small>${esc(p.id||'')} ${p.online?'· online':''}</small></span><input type="checkbox" class="spaceInviteChkV249281" value="${esc(p.id)}" data-name="${esc(p.nickname||'Μέλος')}"></label>`).join('')||'<div class="card">Δεν υπάρχουν επαφές ακόμη. Άνοιξε πρώτα τα Μηνύματα ή φόρτωσε μέλη.</div>'}
async function sendSpaceInvitesV249281(subroom_id){const rows=[...document.querySelectorAll('.spaceInviteChkV249281:checked')];if(!rows.length)return toast('Διάλεξε επαφές.');let ok=0;for(const x of rows){try{await fetchJson('/api/rooms/invite',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id,from_id:state.device,from_name:state.name,to_id:x.value,to_name:x.dataset.name||x.value})});addNotice({type:'space_invite',from_id:state.device,from_name:state.name,to_id:x.value,text:'Πρόσκληση σε χώρο'});ok++}catch(e){}}toast('Στάλθηκαν '+ok+' προσκλήσεις.');closeMember();return false;}
function showSpaceMembersV249281(subroom_id){
  const s=(state.spaces||[]).find(x=>x.subroom_id===subroom_id)||{};const st=spaceStatsV249281(subroom_id);const members=st.members||[];
  $('memberMenu').innerHTML=`<div class="row"><b>👥 Μέλη · ${esc(s.title||'Space')}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><b>${members.length||st.member_count||0} μέλη</b><div class="date">Βλέπεις ποιοι είναι μέσα πριν μπεις.</div></div><div class="inviteFriendListV249281">${members.map(m=>{const p=v249231PersonById(m.device_id||m.id||'');return `<div class="friendPickV249281">${avatarHtml(p)}<span><b>${esc(m.nickname||p.nickname||'Μέλος')}</b><small>${esc(m.device_id||'')} · ${m.joined_at?fmt(m.joined_at):''}</small></span><button class="btn" onclick="ITH.openDMWith('${escJs(m.device_id||'')}')">💬</button></div>`}).join('')||'<div class="card">Δεν υπάρχουν ακόμη μέλη στη λίστα.</div>'}</div>`;$('memberMenu').classList.add('show');return false;
}
async function openSpace(id){const s=(state.spaces||[]).find(x=>x.subroom_id===id)||{};if((s.access_type||'public')==='private_code')return openSpaceJoinCodePanelV249281(id);return openSpaceDirectV249281(id,'')}
function openSpaceJoinCodePanelV249281(id){const s=(state.spaces||[]).find(x=>x.subroom_id===id)||{};$('memberMenu').innerHTML=`<div class="row"><b>🔐 Κωδικός χώρου</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card adminFormV249281"><p>Ο χώρος <b>${esc(s.title||'Space')}</b> χρειάζεται κωδικό μέλους.</p><label>Κωδικός</label><input id="spaceJoinCodeV249281" type="password" placeholder="Κωδικός μέλους"><button class="btn green" style="width:100%;margin-top:10px" onclick="ITH.openSpaceDirectV249281('${escJs(id)}',document.getElementById('spaceJoinCodeV249281').value)">Μπες στον χώρο</button></div>`;$('memberMenu').classList.add('show');setTimeout(()=>$('spaceJoinCodeV249281')?.focus(),80);return false;}
async function openSpaceDirectV249281(id,join_code=''){
  const s=(state.spaces||[]).find(x=>x.subroom_id===id)||{};const nextChannel='space:'+id;try{await fetchJson('/api/rooms/join',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:id,device_id:state.device,nickname:state.name,join_code})})}catch(e){return toast('Χρειάζεται σωστός κωδικός ή πρόσκληση/έγκριση.')}try{await fetchJson('/api/rooms/subscribe',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:id,device_id:state.device,nickname:state.name,enabled:true})})}catch(e){}let a=subscribedSpacesV249281();if(!a.includes(id)){a.push(id);saveSubscribedSpacesV249281(a)}closeMember();state.currentSpace=id;state.currentSpaceChannel=nextChannel;if($('spaceTitle'))$('spaceTitle').textContent=s.title||'Space';wsSubscribe(state.currentSpaceChannel);await loadSpaceMessages(true);return false;
}
async function loadSpaceMessages(){
  if(!state.currentSpaceChannel)return;const box=$('spaceMsgs');if(!box)return;box.innerHTML='';box.dataset.lastIds='';await loadSpacePinsV249281();
  try{const r=await fetchJson(`/api/messages?room_id=${encodeURIComponent(state.room)}&channel=${encodeURIComponent(state.currentSpaceChannel)}&since=0&limit=300`);uniqueMessages(r.messages||[]).forEach(appendSpaceMessage);if(!box.children.length)box.innerHTML='<div class="card">Ξεκίνα τον χώρο.</div>';box.scrollTop=box.scrollHeight}catch{box.innerHTML='<div class="card">Δεν φορτώνουν τα μηνύματα χώρου.</div>'}
}
async function loadSpacePinsV249281(){const box=$('spacePinnedBoxV249281');if(!box||!state.currentSpace)return;box.innerHTML='';try{const r=await fetchJson(`/api/rooms/pins?room_id=${encodeURIComponent(state.room)}&subroom_id=${encodeURIComponent(state.currentSpace)}`);const pins=r.pins||[];box.innerHTML=pins.map(p=>`<div class="spacePinnedV249281"><b>📌 Καρφιτσωμένο</b><div>${esc(p.text||p.message_id||'')}</div><div class="date">${p.created_at?fmt(p.created_at):''}</div></div>`).join('')}catch(e){}}
function appendSpaceMessage(m){const box=$('spaceMsgs');const mid=String(m.message_id||'');if(!box)return;if(mid&&(','+(box.dataset.lastIds||'')+',').includes(','+mid+','))return;if(!box.dataset.lastIds)box.dataset.lastIds='';if(mid)box.dataset.lastIds+=','+mid;let t=parseText(m.text);const div=document.createElement('div');div.className='bubble '+(String(m.sender_id)===state.device?'mine':'');if(mid)div.dataset.spaceMessageId=mid;const translationId='space_'+esc(m.message_id||Date.now());if(m.is_encrypted)t={body:'🔐 '+uiText('Decrypting...'),media:null};div.innerHTML=`<b>${esc(m.nickname||'Member')}</b><div class="msgBody">${esc(t.body)}</div><div class="msgTranslateHostV249464">${translateControls(translationId,t.body)}</div><div class="msgMediaHostV249464">${messageMediaHtml(t.media)}</div><div class="meta">${fmt(m.created_at)}</div><div class="spaceActionRowV249281"><button class="btn" onclick="ITH.pinSpaceMessageV249281('${escJs(mid)}')">📌 Pin</button><button class="btn" onclick="ITH.reportSpaceMessageV249281('${escJs(mid)}')">⚠️ Report</button></div>`;box.appendChild(div);if(m.is_encrypted)e2eDecryptText(m.iv,m.cipher_text,m.channel||state.currentSpaceChannel).then(txt=>renderDecryptedMessagePayloadV249464(div,txt,translationId));else maybeAutoTranslate(translationId,t.body)}

async function pinSpaceMessageV249281(message_id){if(!state.currentSpace||!message_id)return;try{await fetchJson('/api/rooms/pin',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:state.currentSpace,message_id,pinned_by:state.device})});toast('Το μήνυμα καρφιτσώθηκε.');loadSpacePinsV249281()}catch(e){toast('Δεν έγινε pin: '+(e.message||e),6000)}return false;}
async function reportSpaceMessageV249281(message_id){if(!message_id)return;const reason=prompt('Λόγος report (προαιρετικό):')||'report';try{await fetchJson('/api/rooms/report_message',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:state.currentSpace,message_id,reporter_id:state.device,reason})});toast('Το report καταγράφηκε.')}catch(e){toast('Δεν στάλθηκε report.')}return false;}
function openSpaceAdmin(){
  if(!state.currentSpace)return toast('Διάλεξε χώρο');const s=(state.spaces||[]).find(x=>x.subroom_id===state.currentSpace)||{};
  $('memberMenu').innerHTML=`<div class="row"><b>🔐 Διαχείριση χώρου</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card adminFormV249281"><p><b>${esc(s.title||'Space')}</b></p><label>Admin password</label><input id="spaceAdminPassV249281" type="password" placeholder="Κρυφός κωδικός διαχειριστή"><button class="btn green" style="width:100%;margin-top:10px" onclick="ITH.openSpaceAdminPanelV249281()">Άνοιγμα διαχείρισης</button></div>`;$('memberMenu').classList.add('show');setTimeout(()=>$('spaceAdminPassV249281')?.focus(),80);return false;
}
async function openSpaceAdminPanelV249281(){const code=($('spaceAdminPassV249281')?.value||'').trim();if(!code)return toast('Βάλε κωδικό.');try{await fetchJson('/api/rooms/admin/check',{method:'POST',body:JSON.stringify({room_id:state.room,subroom_id:state.currentSpace,device_id:state.device,owner_secret:code})})}catch(e){return toast('Λάθος κωδικός διαχείρισης.')} $('memberMenu').innerHTML=`<div class="row"><b>⚙️ Πίνακας διαχείρισης</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="grid"><button class="tile" onclick="ITH.adminMessageMemberV249281()"><b>💬</b>Μήνυμα σε μέλος</button><button class="tile" onclick="ITH.adminMessageSpaceV249281()"><b>📣</b>Ανακοίνωση στον χώρο</button><button class="tile" onclick="ITH.showSpaceMembersV249281('${escJs(state.currentSpace)}')"><b>👥</b>Λίστα μελών</button><button class="tile" onclick="ITH.showSpaceCode('${escJs(state.currentSpace)}')"><b>▦</b>Code/QR</button><button class="tile" onclick="ITH.loadSpacePinsV249281()"><b>📌</b>Καρφιτσωμένα</button></div>`;return false;}
function adminMessageMemberV249281(){openSpaceInviteListV249281(state.currentSpace)}
async function adminMessageSpaceV249281(){const msg=prompt('Ανακοίνωση στον χώρο:');if(msg&&state.currentSpaceChannel){await sendMessagePayload(state.currentSpaceChannel,'[ανακοίνωση] '+msg);loadSpaceMessages()}}
function checkSpaceActivityNotificationsV249281(){try{const subs=subscribedSpacesV249281();if(!subs.length)return;const seen=JSON.parse(localStorage.getItem('ith_space_activity_seen_v249281')||'{}');(state.spaces||[]).forEach(s=>{if(!subs.includes(s.subroom_id))return;const last=Number(s.last_activity||0);if(last&&last>(seen[s.subroom_id]||0)&&state.currentSpace!==s.subroom_id){addNotice({type:'space_activity',from_id:s.subroom_id,from_name:s.title||'Χώρος',text:'Νέα δραστηριότητα στον χώρο '+(s.title||'')});}if(last)seen[s.subroom_id]=Math.max(seen[s.subroom_id]||0,last)});localStorage.setItem('ith_space_activity_seen_v249281',JSON.stringify(seen));refreshNavBadges()}catch(e){}}
try{var handleWsMessagesV249281Base=handleWsMessages}catch(e){var handleWsMessagesV249281Base=null}
handleWsMessages=function(items){try{if(handleWsMessagesV249281Base)handleWsMessagesV249281Base(items)}catch(e){}try{const subs=subscribedSpacesV249281().map(x=>'space:'+x);for(const m of (items||[])){const ch=String(m.channel||'');if(ch.startsWith('space:')&&subs.includes(ch)&&ch!==state.currentSpaceChannel){addNotice({type:'space_activity',from_id:ch,from_name:'Χώρος',text:'Νέο μήνυμα σε χώρο που ακολουθείς'});refreshNavBadges();}}}catch(e){}}
function installSpacesExportsV249281(){try{window.ITH=window.ITH||{};Object.assign(window.ITH,{renderSpaces,loadRooms,renderRoomList,renderSpaceSamples,spaceTab,openPopularSpacesV249281,renderPopularSpacesV249281,openSpaceTemplatesV249281,applySpaceTemplateV249281,inviteToSpace,openSpaceInviteListV249281,renderSpaceInviteListV249281,sendSpaceInvitesV249281,showSpaceMembersV249281,openSpace,openSpaceDirectV249281,openSpaceJoinCodePanelV249281,toggleSpaceSubscribeV249281,loadSpaceMessages,loadSpacePinsV249281,pinSpaceMessageV249281,reportSpaceMessageV249281,openSpaceAdmin,openSpaceAdminPanelV249281,adminMessageMemberV249281,adminMessageSpaceV249281});}catch(e){}}
try{injectSpacesV249281Css();installSpacesExportsV249281();setTimeout(installSpacesExportsV249281,700);setTimeout(installSpacesExportsV249281,1800);}catch(e){}



/* V249282 - simple group chat inside Messages + hard stop Athina auto card */
function injectV249282GroupDmCss(){
  try{
    if(document.getElementById('ithV249282GroupDmCss'))return;
    const st=document.createElement('style');st.id='ithV249282GroupDmCss';
    st.textContent=`
      .dmGroupToolsV249282{display:flex;gap:8px;flex-wrap:wrap;margin:8px 0}.dmGroupToolsV249282 button{border-radius:999px;border:1px solid rgba(255,217,110,.26);background:rgba(255,217,110,.12);color:#ffe39b;padding:9px 12px;font-weight:1000}
      .dmGroupSectionV249282{margin:10px 0 14px}.dmGroupSectionV249282 h3{font-size:14px;color:#ffe39b;margin:8px 0}.dmGroupRowV249282{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:center;border-radius:18px;padding:10px;margin:7px 0;background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.10)}.dmGroupRowV249282 b{color:#fff}.dmGroupRowV249282 small{display:block;color:rgba(239,248,255,.70)}
      .groupModalV249282{position:fixed;inset:0;z-index:10220;background:rgba(0,0,0,.62);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);display:flex;align-items:center;justify-content:center;padding:12px;box-sizing:border-box}.groupPanelV249282{width:min(760px,100%);max-height:92dvh;overflow:auto;border-radius:28px;background:linear-gradient(160deg,rgba(4,14,26,.98),rgba(10,30,50,.98));border:1px solid rgba(255,217,110,.24);box-shadow:0 30px 100px rgba(0,0,0,.58);color:#fff}.groupTopV249282{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:10px;padding:13px;background:rgba(4,14,26,.96);border-bottom:1px solid rgba(255,255,255,.08)}.groupTopV249282 b{color:#ffe39b}.groupTopV249282 .spacer{flex:1}.groupTopV249282 button{border-radius:50%;width:40px;height:40px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.07);color:#fff;font-weight:1000}
      .groupBodyV249282{padding:14px}.groupInputV249282{width:100%;box-sizing:border-box;border-radius:16px;border:1px solid rgba(255,255,255,.13);background:rgba(255,255,255,.08);color:#fff;padding:12px;margin:8px 0}.groupSearchV249282{width:100%;box-sizing:border-box;border-radius:16px;border:1px solid rgba(255,217,110,.18);background:rgba(0,0,0,.18);color:#fff;padding:12px;margin:10px 0}.groupFriendListV249282{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;max-height:46vh;overflow:auto;padding-right:2px}.groupFriendPickV249282{display:grid;grid-template-columns:auto auto 1fr;gap:9px;align-items:center;border-radius:18px;padding:9px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10)}.groupFriendPickV249282 input{width:22px;height:22px}.groupFriendPickV249282 b{display:block}.groupFriendPickV249282 small{display:block;color:rgba(239,248,255,.68);font-size:11px}.groupPrimaryV249282{width:100%;border-radius:20px;border:1px solid rgba(255,217,110,.34);background:linear-gradient(135deg,#ffd76a,#f2b74a);color:#162231;padding:13px;font-size:17px;font-weight:1000;margin-top:12px}.groupSecondaryV249282{border-radius:999px;border:1px solid rgba(255,217,110,.22);background:rgba(255,255,255,.08);color:#ffe39b;padding:9px 12px;font-weight:1000}.groupMembersBarV249282{display:flex;gap:6px;align-items:center;overflow:auto;padding:6px 8px;border-bottom:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.035)}.groupMemberChipV249282{display:inline-flex;align-items:center;gap:5px;border-radius:999px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.10);padding:4px 8px;font-size:12px;color:#eaf7ff;white-space:nowrap}.groupSenderV249282{font-size:12px;font-weight:1000;color:#9ee7ff;margin-bottom:4px}.bubble.mine .groupSenderV249282{color:#ffe39b}
      @media(max-width:760px){.groupFriendListV249282{grid-template-columns:1fr}.dmGroupRowV249282{grid-template-columns:auto 1fr}.dmGroupRowV249282 button{grid-column:1/-1;width:100%}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function dmFriendArrayV249282(){
  try{if(typeof v249235FriendListForMessages==='function')return (v249235FriendListForMessages()||[]).filter(p=>String(p.id||p.device_id||'')!==String(state.device))}catch(e){}
  try{if(typeof peopleArrayV249280==='function')return peopleArrayV249280().filter(p=>String(p.id||p.device_id||'')!==String(state.device))}catch(e){}
  try{return [...state.people.values()].filter(p=>String(p.id||p.device_id||'')!==String(state.device))}catch{return []}
}
function friendIdV249282(p){return String(p.id||p.device_id||'')}
function friendNameV249282(p){return String(p.nickname||p.name||p.display_name||p.id||p.device_id||'Μέλος')}
function closeGroupModalV249282(){try{document.getElementById('groupModalV249282')?.remove()}catch(e){}return false}
function openMessageGroupPickerV249282(mode='create', groupId='', title=''){
  injectV249282GroupDmCss(); closeGroupModalV249282();
  const friends=dmFriendArrayV249282();
  const d=document.createElement('div');d.id='groupModalV249282';d.className='groupModalV249282';
  const createMode=mode!=='add';
  d.innerHTML=`<div class="groupPanelV249282"><div class="groupTopV249282"><b>${createMode?'👥 Νέα ομαδική συνομιλία':'➕ Πρόσκληση φίλων στην ομάδα'}</b><span class="spacer"></span><button onclick="ITH.closeGroupModalV249282()">×</button></div><div class="groupBodyV249282"><p class="date">Τσεκάρεις όσους φίλους θέλεις και μιλάτε όλοι μαζί στην ίδια οθόνη Μηνυμάτων, σαν απλό group chat.</p>${createMode?'<input id="groupTitleV249282" class="groupInputV249282" placeholder="Όνομα ομάδας ή άστο κενό για αυτόματο">':''}<input id="groupSearchV249282" class="groupSearchV249282" placeholder="Αναζήτηση φίλου..."><div class="dmGroupToolsV249282"><button onclick="ITH.checkAllGroupFriendsV249282(true)">✓ Όλοι</button><button onclick="ITH.checkAllGroupFriendsV249282(false)">Καθαρισμός</button></div><div id="groupFriendListV249282" class="groupFriendListV249282"></div><button class="groupPrimaryV249282" onclick="${createMode?`ITH.createMessageGroupV249282()`:`ITH.addFriendsToGroupV249282('${escJs(groupId)}','${escJs(title)}')`}">${createMode?'Δημιουργία και άνοιγμα ομαδικής συνομιλίας':'Πρόσκληση επιλεγμένων φίλων'}</button></div></div>`;
  document.body.appendChild(d);
  d.dataset.mode=mode; d.dataset.groupId=groupId; d.dataset.title=title;
  const render=()=>renderGroupFriendListV249282(($('groupSearchV249282')?.value||''));
  $('groupSearchV249282').oninput=render; render();
  return false;
}
function renderGroupFriendListV249282(q=''){
  const box=$('groupFriendListV249282'); if(!box)return;
  q=String(q||'').toLowerCase().trim();
  let arr=dmFriendArrayV249282();
  if(q)arr=arr.filter(p=>friendNameV249282(p).toLowerCase().includes(q)||friendIdV249282(p).toLowerCase().includes(q));
  box.innerHTML=arr.map(p=>`<label class="groupFriendPickV249282"><input type="checkbox" value="${esc(friendIdV249282(p))}">${avatarHtml(p)}<span><b>${esc(friendNameV249282(p))}</b><small>${esc(friendIdV249282(p))}${p.online?' · online':''}</small></span></label>`).join('')||'<div class="card">Δεν βρέθηκαν φίλοι. Πρώτα κάνε αποδοχή φιλίας.</div>';
}
function checkAllGroupFriendsV249282(on=true){try{document.querySelectorAll('#groupFriendListV249282 input[type=checkbox]').forEach(x=>x.checked=!!on)}catch(e){}return false}
function selectedGroupFriendsV249282(){return [...document.querySelectorAll('#groupFriendListV249282 input[type=checkbox]:checked')].map(x=>x.value).filter(Boolean)}
function autoGroupTitleV249282(ids){
  const names=ids.map(id=>{const p=dmFriendArrayV249282().find(x=>friendIdV249282(x)===id);return p?friendNameV249282(p):id}).filter(Boolean).slice(0,4);
  const mine=String(state.name||'Εγώ');
  return [mine,...names].join(', ').slice(0,100)||'Ομαδική συνομιλία';
}
async function createMessageGroupV249282(){
  const ids=selectedGroupFriendsV249282(); if(!ids.length)return toast('Τσέκαρε τουλάχιστον έναν φίλο.');
  const title=($('groupTitleV249282')?.value||'').trim()||autoGroupTitleV249282(ids);
  try{
    const r=await fetchJson('/api/groups/create',{method:'POST',body:JSON.stringify({room_id:state.room,owner_id:state.device,title,description:'Ομαδική συνομιλία από την οθόνη Μηνυμάτων',member_ids:ids})});
    closeGroupModalV249282(); toast('Άνοιξε η ομαδική συνομιλία.');
    await loadMessageGroupsV249282();
    openGroupInMessagesV249282(r.group_id,title,ids.length+1);
  }catch(e){toast('Δεν δημιουργήθηκε η ομάδα: '+(e.message||e),7000)}
  return false;
}
async function addFriendsToGroupV249282(groupId,title=''){
  const ids=selectedGroupFriendsV249282(); if(!ids.length)return toast('Τσέκαρε φίλους για πρόσκληση.');
  try{await fetchJson('/api/groups/add_members',{method:'POST',body:JSON.stringify({room_id:state.room,group_id:groupId,member_ids:ids})});closeGroupModalV249282();toast('Προστέθηκαν στην ομάδα.');openGroupInMessagesV249282(groupId,title||state.activeGroupTitleV249282||'Ομάδα');}catch(e){toast('Δεν μπήκαν στην ομάδα: '+(e.message||e),7000)}
  return false;
}
async function loadMessageGroupsV249282(){
  const box=$('dmGroupsListV249282'); if(!box)return false;
  try{
    const r=await fetchJson(`/api/groups/list?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);
    const groups=r.groups||[];
    box.innerHTML=groups.map(g=>`<div class="dmGroupRowV249282"><div class="avatar">👥</div><div><b>${esc(g.title||'Ομάδα')}</b><small>${g.member_count||0} μέλη · ${g.updated_at?fmt(g.updated_at):''}</small></div><button class="groupSecondaryV249282" onclick="ITH.openGroupInMessagesV249282('${escJs(g.group_id)}','${escJs(g.title||'Ομάδα')}',${Number(g.member_count||0)})">Άνοιγμα</button></div>`).join('')||'<div class="card date">Δεν έχεις ομαδική συνομιλία ακόμη.</div>';
  }catch(e){box.innerHTML='<div class="card date">Δεν φορτώθηκαν οι ομάδες.</div>'}
  return false;
}
function enhanceDmForGroupsV249282(){
  injectV249282GroupDmCss();
  try{
    const tools=document.querySelector('#dmFriendScreen .dmFriendToolsV249235');
    if(tools&&!document.getElementById('dmGroupCreateBtnV249282')){
      const btn=document.createElement('button');btn.id='dmGroupCreateBtnV249282';btn.className='groupSecondaryV249282';btn.innerHTML='👥 Νέα ομάδα';btn.onclick=()=>openMessageGroupPickerV249282('create');tools.appendChild(btn);
    }
    const list=$('peopleList');
    if(list&&!document.getElementById('dmGroupsSectionV249282')){
      const sec=document.createElement('section');sec.id='dmGroupsSectionV249282';sec.className='dmGroupSectionV249282';sec.innerHTML='<h3>👥 Ομαδικές συνομιλίες</h3><div class="dmGroupToolsV249282"><button onclick="ITH.openMessageGroupPickerV249282(\'create\')">＋ Νέα ομαδική συνομιλία</button><button onclick="ITH.loadMessageGroupsV249282()">🔄</button></div><div id="dmGroupsListV249282"></div>';
      list.parentNode.insertBefore(sec,list);
    }
    loadMessageGroupsV249282();
  }catch(e){}
}
async function openGroupInMessagesV249282(groupId,title='Ομάδα',count=0){
  groupId=String(groupId||''); if(!groupId)return false;
  state.activeGroupV249282=groupId; state.activeGroupTitleV249282=title||'Ομάδα'; state.activePeer=''; state.activeChannel='group:'+groupId; state.lastMsgIds&&state.lastMsgIds.clear&&state.lastMsgIds.clear(); state.messagesSince=0;
  if(state.page!=='dm')page('dm');
  setTimeout(async()=>{
    try{showDMChatScreenV249235&&showDMChatScreenV249235()}catch(e){}
    state.activeGroupV249282=groupId; state.activeGroupTitleV249282=title||'Ομάδα'; state.activePeer=''; state.activeChannel='group:'+groupId;
    try{if($('chatName'))$('chatName').textContent='👥 '+(title||'Ομάδα'); if($('chatAvatar')){$('chatAvatar').textContent='👥'; $('chatAvatar').onclick=()=>openGroupMembersPanelV249282(groupId,title)}}catch(e){}
    injectGroupHeaderButtonsV249282(groupId,title);
    try{wsSubscribe(state.activeChannel)}catch(e){}
    await loadGroupMembersBarV249282(groupId);
    await loadMessages(true);
  },120);
  return false;
}
function injectGroupHeaderButtonsV249282(groupId,title){
  try{
    const head=document.querySelector('#dmChatScreen .chatHead'); if(!head||document.getElementById('groupHeaderAddV249282'))return;
    const add=document.createElement('button');add.id='groupHeaderAddV249282';add.className='icon chatActionBtn';add.title='Πρόσκληση φίλων';add.textContent='＋👥';add.onclick=()=>openMessageGroupPickerV249282('add',groupId,title);
    const info=document.createElement('button');info.id='groupHeaderInfoV249282';info.className='icon chatActionBtn';info.title='Μέλη ομάδας';info.textContent='👥';info.onclick=()=>openGroupMembersPanelV249282(groupId,title);
    head.appendChild(add);head.appendChild(info);
  }catch(e){}
}
async function loadGroupMembersBarV249282(groupId){
  try{
    let bar=$('groupMembersBarV249282');
    const pane=document.querySelector('#dmChatScreen .chatPane');
    const msgs=$('messages');
    if(pane&&msgs&&!bar){bar=document.createElement('div');bar.id='groupMembersBarV249282';bar.className='groupMembersBarV249282';msgs.parentNode.insertBefore(bar,msgs)}
    if(!bar)return;
    const r=await fetchJson(`/api/groups/members?room_id=${encodeURIComponent(state.room)}&group_id=${encodeURIComponent(groupId)}`);
    const mem=r.members||[];
    bar.innerHTML=mem.slice(0,24).map(m=>`<span class="groupMemberChipV249282">${esc(m.display_name||m.nickname||m.device_id||'Μέλος')}</span>`).join('')+`<button class="groupSecondaryV249282" onclick="ITH.openMessageGroupPickerV249282('add','${escJs(groupId)}','${escJs(state.activeGroupTitleV249282||'Ομάδα')}')">＋ φίλοι</button>`;
  }catch(e){}
}
async function openGroupMembersPanelV249282(groupId,title='Ομάδα'){
  try{
    const r=await fetchJson(`/api/groups/members?room_id=${encodeURIComponent(state.room)}&group_id=${encodeURIComponent(groupId)}`);
    const mem=r.members||[];
    $('memberMenu').innerHTML=`<div class="row"><b>👥 ${esc(title||'Ομάδα')}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="card"><b>${mem.length} μέλη</b><p class="date">Ομαδική συζήτηση μέσα στα Μηνύματα.</p><button class="btn green" onclick="ITH.openMessageGroupPickerV249282('add','${escJs(groupId)}','${escJs(title)}')">＋ Πρόσκληση φίλων</button></div><div class="inviteFriendListV249281">${mem.map(m=>`<div class="friendPickV249281"><span class="avatar">👤</span><span><b>${esc(m.display_name||m.nickname||'Μέλος')}</b><small>${esc(m.device_id||'')}</small></span></div>`).join('')}</div>`;
    $('memberMenu').classList.add('show');
  }catch(e){toast('Δεν φορτώθηκαν τα μέλη.')}return false;
}
try{var openDMV249282Base=openDM}catch(e){var openDMV249282Base=null}
openDM=function(){const r=openDMV249282Base?openDMV249282Base.apply(this,arguments):openDMV249235();setTimeout(enhanceDmForGroupsV249282,80);setTimeout(enhanceDmForGroupsV249282,800);return r}
try{var renderPeopleV249282Base=renderPeople}catch(e){var renderPeopleV249282Base=null}
renderPeople=function(){const r=renderPeopleV249282Base?renderPeopleV249282Base.apply(this,arguments):false;setTimeout(enhanceDmForGroupsV249282,60);return r}
try{var appendMessageV249282Base=appendMessage}catch(e){var appendMessageV249282Base=null}
appendMessage=function(m){
  const before=$('messages')?.children.length||0;
  const r=appendMessageV249282Base?appendMessageV249282Base.apply(this,arguments):false;
  try{
    if(String(state.activeChannel||'').startsWith('group:')){
      const box=$('messages'); const div=box&&box.lastElementChild;
      if(div&&div.classList&&div.classList.contains('bubble')&&!div.querySelector('.groupSenderV249282')){
        const mine=String(m.sender_id)===String(state.device); const name=mine?'Εσύ':(m.nickname||m.sender_id||'Μέλος');
        const sp=document.createElement('div');sp.className='groupSenderV249282';sp.textContent=name;div.insertBefore(sp,div.firstChild);
      }
    }
  }catch(e){}
  return r;
}
function stopAthinaAutoCardsV249282(){
  try{
    if(window.__athinaManualOpenV249282)return;
    ['guideOverlayV249271','guideOverlayV249272','guideOverlayV249273','guideOverlayV249275','guideOverlayV249276','guideOverlayV249282','athinaWelcomeV249272','athinaWelcomeV249273','athinaWelcomeV249275','athinaSimpleHelloV249273'].forEach(id=>document.getElementById(id)?.remove());
  }catch(e){}
}
function manualAthinaGuideV249282(){
  try{window.__athinaManualOpenV249282=1;setTimeout(()=>{window.__athinaManualOpenV249282=0},120000);}
  catch(e){}
  try{if(typeof openFirstRunGuideV249275BaseV249282==='function')return openFirstRunGuideV249275BaseV249282(true)}catch(e){}
  try{if(typeof openFirstRunGuideV249275==='function')return openFirstRunGuideV249275(true)}catch(e){}
  return false;
}
try{var openFirstRunGuideV249275BaseV249282=openFirstRunGuideV249275}catch(e){var openFirstRunGuideV249275BaseV249282=null}
openFirstRunGuideV249275=function(force=true,startMood=''){
  if(!window.__athinaManualOpenV249282)return false;
  return openFirstRunGuideV249275BaseV249282?openFirstRunGuideV249275BaseV249282(force,startMood):false;
};
openFirstRunGuideV249273=openFirstRunGuideV249275;openFirstRunGuideV249272=openFirstRunGuideV249275;openFirstRunGuideV249271=openFirstRunGuideV249275;
showAthinaSimpleHelloV249273=function(){return false};showAthinaSimpleHelloV249276=function(){return false};showAthinaWelcomeV249272=function(){return false};
try{var ensureAthinaCompanionV249282Base=ensureAthinaCompanionV249258}catch(e){var ensureAthinaCompanionV249282Base=null}
ensureAthinaCompanionV249258=function(){
  try{if(ensureAthinaCompanionV249282Base)ensureAthinaCompanionV249282Base.apply(this,arguments)}catch(e){}
  try{const b=document.getElementById('athinaFabV249258');if(b){b.onclick=(ev)=>{try{ev.preventDefault();ev.stopPropagation()}catch(e){};return manualAthinaGuideV249282()};b.title='Bil · ξενάγηση μόνο με πάτημα';}}
  catch(e){}
  stopAthinaAutoCardsV249282();
};
function installV249282Exports(){
  try{window.ITH=window.ITH||{};Object.assign(window.ITH,{openMessageGroupPickerV249282,closeGroupModalV249282,renderGroupFriendListV249282,checkAllGroupFriendsV249282,createMessageGroupV249282,addFriendsToGroupV249282,loadMessageGroupsV249282,openGroupInMessagesV249282,openGroupMembersPanelV249282,manualAthinaGuideV249282,stopAthinaAutoCardsV249282});}catch(e){}
}
try{installV249282Exports();injectV249282GroupDmCss();setTimeout(installV249282Exports,600);setTimeout(()=>{installV249282Exports();enhanceDmForGroupsV249282();stopAthinaAutoCardsV249282();},1500);setInterval(stopAthinaAutoCardsV249282,1000);}catch(e){}



/* V249283 - Feed safe loader + Athina real menu + emergency offline mesh entry + anonymous wall visibility */
function injectV249283EmergencyCss(){
  try{
    if(document.getElementById('ithV249283EmergencyCss'))return;
    const st=document.createElement('style');st.id='ithV249283EmergencyCss';st.textContent=`
      .athinaMenuV249283{padding:14px;display:grid;gap:12px;color:#fff}.athinaMenuV249283 .hero{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:center;border-radius:22px;padding:12px;background:linear-gradient(135deg,rgba(255,217,110,.13),rgba(127,215,255,.08));border:1px solid rgba(255,217,110,.20)}.athinaMenuV249283 h2{margin:0;color:#ffe39b}.athinaMenuV249283 p{margin:4px 0 0;color:rgba(239,248,255,.84);line-height:1.35}.athinaGridV249283{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}.athinaGridV249283 button{border-radius:18px;border:1px solid rgba(255,255,255,.13);background:rgba(255,255,255,.07);color:#fff;padding:12px;text-align:left;font-weight:1000}.athinaGridV249283 button small{display:block;margin-top:5px;opacity:.72;font-weight:700;line-height:1.25}
      .emergencyHubV249283{padding:14px;color:#fff;display:grid;gap:12px}.emergencyHubV249283 .top{display:flex;align-items:center;gap:10px}.emergencyHubV249283 .top b{color:#ffe39b;font-size:18px}.emergencyHubV249283 .hero{border-radius:24px;padding:14px;background:linear-gradient(135deg,rgba(255,75,75,.16),rgba(255,217,110,.09),rgba(127,215,255,.07));border:1px solid rgba(255,217,110,.18)}.emergencyHubV249283 .grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.emergencyHubV249283 .cardx{border-radius:20px;padding:12px;background:rgba(255,255,255,.065);border:1px solid rgba(255,255,255,.11)}.emergencyHubV249283 .cardx b{color:#ffe39b}.emergencyHubV249283 textarea{width:100%;min-height:86px;box-sizing:border-box;border-radius:16px;border:1px solid rgba(255,255,255,.15);background:rgba(0,0,0,.24);color:#fff;padding:10px}.meshPeerV249283{display:grid;grid-template-columns:auto 1fr auto;gap:8px;align-items:center;border-radius:16px;padding:10px;margin:8px 0;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10)}.meshPeerV249283 small{display:block;opacity:.68}.feedFallbackV249283{max-width:720px;margin:20px auto;padding:16px;border-radius:24px;background:rgba(8,24,39,.92);border:1px solid rgba(255,217,110,.20);color:#fff}.feedFallbackV249283 b{color:#ffe39b}.feedFallbackV249283 .row{margin-top:10px;gap:8px;flex-wrap:wrap}.plusEmergencyV249283 b{filter:drop-shadow(0 0 10px rgba(255,217,110,.35))}
      @media(max-width:760px){.athinaGridV249283,.emergencyHubV249283 .grid{grid-template-columns:1fr}.meshPeerV249283{grid-template-columns:auto 1fr}.meshPeerV249283 button{grid-column:1/-1}}
    `;document.head.appendChild(st);
  }catch(e){}
}
function feedFallbackHtmlV249283(msg=''){
  return `<div class="feedFallbackV249283"><b>🎬 Η Ροή δεν φόρτωσε σωστά</b><p>${esc(msg||'Η σύνδεση ή κάποιο παλιό αντικείμενο της ροής κόλλησε. Μπορείς να ξαναδοκιμάσεις χωρίς να χαθεί τίποτα.')}</p><div class="row"><button class="btn green" onclick="ITH.loadFeed()">🔄 Ξαναφόρτωσε</button><button class="btn" onclick="ITH.page('home')">🏠 Αρχική</button><button class="btn" onclick="ITH.page('create')">＋ Νέα δημοσίευση</button></div></div>`;
}
async function loadFeedFallbackV249283(err){
  const el=$('feedPage'); if(!el)return false;
  try{
    const r=await fetchJson(`/api/flow?room_id=${encodeURIComponent(state.room)}&visibility=public&limit=80&lite=1&no304=1&viewer_id=${encodeURIComponent(state.device)}&_v=249283_${Date.now()}`);
    const posts=Array.isArray(r.posts)?r.posts:[];
    el.innerHTML=`<button class="feedBackOnly" onclick="ITH.page('home')">‹</button><div class="feedSearchGlassV249189"><span>🔎</span><input id="feedSearchV249189" placeholder="Αναζήτηση στη Ροή" oninput="ITH.filterFeedCardsV249189&&ITH.filterFeedCardsV249189()"><button onclick="ITH.loadFeed()">🔄</button></div><div class="feedList">${posts.length?posts.map(p=>{try{return renderPost(p)}catch(e){return `<article class="feedCard"><div class="postHead"><b>${esc(p.nickname||'Μέλος')}</b><span class="date">${fmt(p.created_at)}</span></div><div class="textClamp open">${esc((parseText(p.text||'').body)||p.text||'')}</div></article>`}}).join(''):'<div class="card">Δεν υπάρχουν δημοσιεύσεις ακόμη.</div>'}</div>`;
    try{activateFeedVideos&&activateFeedVideos()}catch(e){}
  }catch(e){el.innerHTML=feedFallbackHtmlV249283((err&&err.message?err.message:err||'')+' '+(e&&e.message?e.message:''));}
  return false;
}
try{var loadFeedV249283Base=loadFeed}catch(e){var loadFeedV249283Base=null}
/* V249429_LEGACY_LOAD_FEED_REMOVED */
function closeAthinaFloatingCardsV249283(){try{['guideOverlayV249271','guideOverlayV249272','guideOverlayV249273','guideOverlayV249275','guideOverlayV249276','athinaWelcomeV249272','athinaWelcomeV249273','athinaWelcomeV249275','athinaSimpleHelloV249273','athinaTinyTipV249279'].forEach(id=>document.getElementById(id)?.remove())}catch(e){}return false}
function openAthinaMenuV249283(){
  injectV249283EmergencyCss();closeAthinaFloatingCardsV249283();
  const menu=$('memberMenu');if(!menu)return false;
  menu.className='memberMenu show fullAvatarMenuV249231';
  const face=typeof athinaOwlV249258==='function'?athinaOwlV249258('small'):'🦉';
  menu.innerHTML=`<div class="athinaMenuV249283"><div class="row"><button class="icon" onclick="ITH.closeMember()">×</button><b>Bil</b><span class="spacer"></span></div><div class="hero"><div>${face}</div><div><h2>Πού θέλεις να πας;</h2><p>Δεν θα ανοίγω μόνη μου μεγάλη καρτέλα. Με πατάς και σου δείχνω καθαρά τις επιλογές.</p></div></div><div class="athinaGridV249283"><button onclick="ITH.closeMember();ITH.page('feed')">🎬 Ροή<small>Άνοιγμα και ασφαλής φόρτωση ροής.</small></button><button onclick="ITH.closeMember();ITH.page('dm')">💬 Μηνύματα<small>1-προς-1 και ομαδικές συζητήσεις.</small></button><button onclick="ITH.closeMember();ITH.openEmergencyOfflineHubV249283()">🆘 Έκτακτη ανάγκη offline<small>Hotspot, κοντινά μέλη, άμεσο τοπικό μήνυμα.</small></button><button onclick="ITH.closeMember();ITH.openAnonymousWallV249283()">🕊️ Ανώνυμος τοίχος<small>Ήρεμη υποστήριξη χωρίς ταυτότητα στη βάση.</small></button><button onclick="ITH.closeMember();ITH.openLighthouseV249278&&ITH.openLighthouseV249278()">🕯️ Ο Φάρος<small>Άναψε ή άγγιξε ένα φως χωρίς λέξεις.</small></button><button onclick="ITH.closeMember();ITH.openBottleSeaV249274&&ITH.openBottleSeaV249274('compose')">🍾 Μπουκάλι<small>Πέλαγος των Ψιθύρων.</small></button><button onclick="ITH.closeMember();ITH.page('spaces')">🏘️ Δωμάτια / Κοινότητες<small>Χώροι, ομάδες, γειτονιά.</small></button><button onclick="ITH.closeMember();ITH.notifyCenter&&ITH.notifyCenter()">🔔 Ειδοποιήσεις<small>Μηνύματα, αιτήματα, χώροι.</small></button></div></div>`;
  return false;
}
try{var ensureAthinaCompanionV249283Base=ensureAthinaCompanionV249258}catch(e){var ensureAthinaCompanionV249283Base=null}
ensureAthinaCompanionV249258=function(){
  const r=ensureAthinaCompanionV249283Base?ensureAthinaCompanionV249283Base.apply(this,arguments):false;
  try{const b=document.getElementById('athinaFabV249258');if(b){b.onclick=(ev)=>{ev.preventDefault();ev.stopPropagation();return openAthinaMenuV249283()};b.title='Bil - μενού βοήθειας';}}
  catch(e){}
  return r;
};
showAthinaSimpleHelloV249273=function(force=false){try{if(force)return openAthinaMenuV249283();}catch(e){}return false};
showAthinaSimpleHelloV249276=function(force=false){try{if(force)return openAthinaMenuV249283();}catch(e){}return false};
showAthinaWelcomeV249272=function(force=false){try{if(force)return openAthinaMenuV249283();}catch(e){}return false};
openFirstRunGuideV249273=function(force=true,startMood=''){return openAthinaMenuV249283()};
openFirstRunGuideV249275=function(force=true,startMood=''){return openAthinaMenuV249283()};
function openAnonymousWallV249283(){try{page('spaces');setTimeout(()=>{try{openZeroSupportWallV249270()}catch(e){toast('Δεν άνοιξε ο ανώνυμος τοίχος: '+(e.message||e),6000)}},120)}catch(e){toast('Δεν άνοιξε ο ανώνυμος τοίχος: '+(e.message||e),6000)}return false}
function nativeBridgeV249283(){return window.AndroidBridge||window.OKITHAKI_ANDROID||null}
function bridgeJsonV249283(fn,...args){try{const b=nativeBridgeV249283();if(!b||typeof b[fn]!=='function')return {};return JSON.parse(b[fn](...args)||'{}')}catch(e){return {ok:false,error:String(e.message||e)}}}
function renderEmergencyNodesV249283(scan){
  const nodes=(scan&&scan.nodes||[]).filter(n=>n&&n.url);const own=scan&&scan.own?scan.own:bridgeJsonV249283('getPhoneNodeInfo');
  return `<div class="cardx"><b>📱 Το δικό μου μικρό server</b><p>Τρέχει μέσα στο APK στην πόρτα 8099 για Wi‑Fi / hotspot / Wi‑Fi Direct.</p><div class="date">${esc(own.url||'Πάτησε Εκκίνηση μικρού server')}</div></div><div class="cardx"><b>📡 Κοντινά μέλη</b><p>${nodes.length?`Βρέθηκαν ${nodes.length} κοντινοί κόμβοι ΙΘΑΚΗ.`:'Δεν βρέθηκαν ακόμη. Άνοιξε hotspot ή μπες στο ίδιο Wi‑Fi και πάτα σάρωση.'}</p>${nodes.map(n=>`<div class="meshPeerV249283"><span>📱</span><div><b>${esc(n.nickname||n.node_id||'Κοντινό μέλος')}</b><small>${esc(n.url||n.base||'')} · ${esc(n.transport||'wifi')}</small></div><button class="btn green" onclick="ITH.sendEmergencyNodeMessageV249283('${escJs(n.url||n.base||'')}','${escJs(n.node_id||'')}')">Άμεσο μήνυμα</button></div>`).join('')}</div>`;
}
function openEmergencyOfflineHubV249283(){
  injectV249283EmergencyCss();closeAthinaFloatingCardsV249283();
  const menu=$('memberMenu');if(!menu)return false;menu.className='memberMenu show fullAvatarMenuV249231';
  let info=bridgeJsonV249283('startPhoneMicroServer');let scan=bridgeJsonV249283('scanPhoneNodes');
  menu.innerHTML=`<div class="emergencyHubV249283"><div class="top"><button class="icon" onclick="ITH.closeMember()">×</button><b>🆘 Έκτακτη ανάγκη χωρίς internet</b><span class="spacer"></span><button class="btn" onclick="ITH.refreshEmergencyOfflineHubV249283()">🔄</button></div><div class="hero"><b>Τοπικό πλέγμα hotspot / Wi‑Fi</b><p>Το APK έχει ήδη μικρό server αναμετάδοσης στο κινητό. Ένα κινητό ανοίγει hotspot, οι άλλοι συνδέονται, πατάνε σάρωση και μπορούν να στείλουν άμεσα μηνύματα σε κοντινά μέλη χωρίς κεντρικό internet.</p><div class="row" style="gap:8px;flex-wrap:wrap;margin-top:10px"><button class="btn green" onclick="ITH.startEmergencyNodeV249283()">📱 Εκκίνηση μικρού server</button><button class="btn" onclick="ITH.scanEmergencyNodesV249283()">📡 Σάρωση κοντινών</button><button class="btn" onclick="ITH.meshOpenHotspot&&ITH.meshOpenHotspot()">📶 Άνοιγμα Hotspot</button><button class="btn" onclick="ITH.meshOpenWifi&&ITH.meshOpenWifi()">🛜 Wi‑Fi</button><button class="btn" onclick="ITH.meshRequestPermissions&&ITH.meshRequestPermissions()">🔐 Άδειες nearby</button></div></div><div class="grid" id="emergencyNodesV249283">${renderEmergencyNodesV249283(scan)}</div><div class="cardx"><b>⚡ Άμεσο τοπικό μήνυμα</b><p>Γράψε ένα σύντομο μήνυμα και πάτα «Άμεσο μήνυμα» σε κοντινό μέλος.</p><textarea id="emergencyDirectTextV249283" placeholder="Είμαι εδώ. Χρειάζεται κάποιος βοήθεια;">Είμαι εδώ. Χρειάζεται κάποιος βοήθεια;</textarea></div><div class="grid"><button class="btn green" onclick="ITH.closeMember();ITH.openEmergencyNeighborhoodV249270&&ITH.openEmergencyNeighborhoodV249270()">🆘 Γειτονιά ανάγκης</button><button class="btn" onclick="ITH.openAnonymousWallV249283()">🕊️ Ανώνυμος τοίχος</button><button class="btn" onclick="ITH.phoneNodeInboxV249283()">📥 Τοπικά εισερχόμενα</button><button class="btn" onclick="ITH.closeMember();ITH.openAthinaMenuV249283()">🦉 Πρόταση Bilς</button></div><div id="phoneNodeInboxBox" class="cardx"><b>📥 Τοπικά εισερχόμενα</b><div class="date">Πάτησε εισερχόμενα για μηνύματα που ήρθαν από κοντινά κινητά.</div></div></div>`;
  return false;
}
function refreshEmergencyOfflineHubV249283(){return openEmergencyOfflineHubV249283()}
function startEmergencyNodeV249283(){const r=bridgeJsonV249283('startPhoneMicroServer');toast(r.ok?('Μικρός server ενεργός: '+(r.url||'8099')):'Μόνο στο Android APK υπάρχει μικρός server.');return openEmergencyOfflineHubV249283()}
function scanEmergencyNodesV249283(){const r=bridgeJsonV249283('scanPhoneNodes');const box=$('emergencyNodesV249283');if(box)box.innerHTML=renderEmergencyNodesV249283(r);toast(((r.nodes||[]).length||0)+' κοντινά μέλη βρέθηκαν.');return false}
function sendEmergencyNodeMessageV249283(base,to){const text=($('emergencyDirectTextV249283')?.value||'').trim()||'Χρειάζομαι/προσφέρω βοήθεια κοντά μου.';const r=bridgeJsonV249283('sendPhoneNodeMessage',base,text,to||'');toast(r.ok?'Στάλθηκε άμεσο τοπικό μήνυμα.':('Δεν στάλθηκε: '+(r.error||'APK/δίκτυο')));return false}
function phoneNodeInboxV249283(){const r=bridgeJsonV249283('getPhoneNodeInbox');const box=$('phoneNodeInboxBox');if(box){const arr=r.packets||[];box.innerHTML=`<b>📥 Τοπικά εισερχόμενα</b>`+(arr.length?arr.slice().reverse().map(x=>`<div class="bubble"><b>${esc(x.nickname||x.from_id||'Κοντινό μέλος')}</b><div>${esc(x.text||'')}</div><div class="date">${fmt(x.created_at)}</div></div>`).join(''):'<div class="date">Δεν υπάρχουν ακόμη τοπικά μηνύματα.</div>')}return false}
try{var togglePlusV249283Base=togglePlus}catch(e){var togglePlusV249283Base=null}
togglePlus=function(){
  const r=togglePlusV249283Base?togglePlusV249283Base():false;
  try{const s=$('plusSheet');if(s&&!s.querySelector('[data-r9plus="emergency"],[data-act="emergency_offline"]'))s.insertAdjacentHTML('beforeend',`<button class="tile plusEmergencyV249283" data-act="emergency_offline"><b>🆘</b>Έκτακτη offline</button><button class="tile plusEmergencyV249283" data-act="athina_menu"><b>🦉</b>Bil</button>`)}catch(e){}
  return r;
};
try{var bindPlusV249283Base=bindPlus}catch(e){var bindPlusV249283Base=null}
bindPlus=function(){
  if(bindPlusV249283Base)bindPlusV249283Base();
  const s=$('plusSheet');if(!s)return;
  if(s.__v249283Bound)return;s.__v249283Bound=true;
  s.addEventListener('click',ev=>{const b=ev.target.closest('[data-act]');if(!b)return;const a=b.dataset.act;if(a==='emergency_offline'){ev.preventDefault();ev.stopPropagation();s.classList.remove('show');return openEmergencyOfflineHubV249283()}if(a==='anon_wall'){ev.preventDefault();ev.stopPropagation();s.classList.remove('show');return openAnonymousWallV249283()}if(a==='athina_menu'){ev.preventDefault();ev.stopPropagation();s.classList.remove('show');return openAthinaMenuV249283()}},true);
};
function installV249283Exports(){
  try{window.ITH=window.ITH||{};Object.assign(window.ITH,{loadFeed,loadFeedFallbackV249283,openAthinaMenuV249283,openEmergencyOfflineHubV249283,refreshEmergencyOfflineHubV249283,startEmergencyNodeV249283,scanEmergencyNodesV249283,sendEmergencyNodeMessageV249283,phoneNodeInboxV249283,openAnonymousWallV249283,togglePlus,bindPlus,ensureAthinaCompanionV249258});bindPlus();}catch(e){}
}
try{installV249283Exports();setTimeout(installV249283Exports,700);setTimeout(installV249283Exports,1800);setInterval(installV249283Exports,5000)}catch(e){}



/* V249284 - Classic message groups only + group management (rename/leave/remove) */
function injectV249284GroupManageCss(){
  try{
    if(document.getElementById('ithV249284GroupManageCss'))return;
    const st=document.createElement('style');st.id='ithV249284GroupManageCss';
    st.textContent=`
      .groupManageBoxV249284{display:grid;gap:10px;margin:10px 0;padding:12px;border-radius:20px;background:rgba(255,217,110,.075);border:1px solid rgba(255,217,110,.18)}
      .groupManageActionsV249284{display:flex;gap:8px;flex-wrap:wrap}.groupManageActionsV249284 button{border-radius:999px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.07);color:#fff;padding:9px 12px;font-weight:1000}.groupManageActionsV249284 button.danger{border-color:rgba(255,99,99,.35);background:rgba(255,80,80,.13);color:#ffd0d0}.groupManageActionsV249284 button.gold{border-color:rgba(255,217,110,.34);background:rgba(255,217,110,.14);color:#ffe39b}
      .groupManageInputV249284{width:100%;box-sizing:border-box;border-radius:16px;border:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.22);color:#fff;padding:11px;outline:none}
      .groupMemberAdminRowV249284{display:grid;grid-template-columns:auto 1fr auto;gap:9px;align-items:center;border-radius:16px;padding:10px;margin:8px 0;background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.10)}.groupMemberAdminRowV249284 small{display:block;color:rgba(239,248,255,.68)}.groupMemberAdminRowV249284 .role{font-size:12px;color:#ffe39b}.groupMemberAdminRowV249284 button{border-radius:999px;border:1px solid rgba(255,99,99,.30);background:rgba(255,80,80,.12);color:#ffd0d0;padding:7px 10px;font-weight:1000}
      .groupClassicOnlyNoticeV249284{border-radius:18px;padding:12px;background:rgba(255,217,110,.09);border:1px solid rgba(255,217,110,.18);color:#fff}.groupClassicOnlyNoticeV249284 b{color:#ffe39b}.groupClassicOnlyNoticeV249284 button{margin-top:10px;border-radius:999px;border:1px solid rgba(255,217,110,.30);background:linear-gradient(135deg,rgba(255,217,110,.18),rgba(127,215,255,.10));color:#fff;padding:10px 13px;font-weight:1000}
    `;document.head.appendChild(st);
  }catch(e){}
}
function currentClassicGroupIdV249284(){
  const g=String(state.activeGroupV249282||''); if(g)return g;
  const ch=String(state.activeChannel||''); return ch.startsWith('group:')?ch.slice(6):'';
}
function isClassicGroupChannelV249284(){return !!currentClassicGroupIdV249284()}
async function openGroupMembersPanelV249284(groupId='', title=''){
  injectV249284GroupManageCss();
  groupId=String(groupId||currentClassicGroupIdV249284()||''); if(!groupId)return false;
  title=title||state.activeGroupTitleV249282||'Ομάδα';
  try{
    const r=await fetchJson(`/api/groups/members?room_id=${encodeURIComponent(state.room)}&group_id=${encodeURIComponent(groupId)}`);
    const mem=r.members||[];
    const me=mem.find(m=>String(m.device_id)===String(state.device))||{};
    const canAdmin=String(me.role||'').toLowerCase()==='admin' || mem.length<=1;
    const rows=mem.map(m=>{
      const id=String(m.device_id||''); const mine=id===String(state.device);
      const nm=esc(m.display_name||m.nickname||id||'Μέλος'); const role=esc(m.role||'member');
      const remove=(canAdmin&&!mine)?`<button onclick="ITH.removeGroupMemberV249284('${escJs(groupId)}','${escJs(id)}','${escJs(title)}')">Αφαίρεση</button>`:(mine?'<span class="role">εσύ</span>':`<span class="role">${role}</span>`);
      return `<div class="groupMemberAdminRowV249284"><span class="avatar">👤</span><span><b>${nm}</b><small>${esc(id)} · ${role}</small></span>${remove}</div>`;
    }).join('');
    $('memberMenu').innerHTML=`<div class="row"><b>👥 ${esc(title)}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="groupManageBoxV249284"><b>Διαχείριση ομάδας</b><small class="date">Κλασική ομαδική συνομιλία μέσα στα Μηνύματα. Αυτό είναι το μοναδικό ενεργό group interface.</small><input id="groupRenameInputV249284" class="groupManageInputV249284" value="${esc(title)}" placeholder="Νέο όνομα ομάδας"><div class="groupManageActionsV249284"><button class="gold" onclick="ITH.renameGroupV249284('${escJs(groupId)}')">Μετονομασία</button><button onclick="ITH.openMessageGroupPickerV249282('add','${escJs(groupId)}','${escJs(title)}')">＋ Πρόσκληση φίλων</button><button class="danger" onclick="ITH.leaveGroupV249284('${escJs(groupId)}')">Έξοδος από ομάδα</button></div></div><div class="card"><b>${mem.length} μέλη</b><p class="date">Ο admin μπορεί να αφαιρέσει μέλη. Κάθε μέλος μπορεί να φύγει μόνο του.</p></div><div>${rows||'<div class="card date">Δεν βρέθηκαν μέλη.</div>'}</div>`;
    $('memberMenu').classList.add('show');
  }catch(e){toast('Δεν φορτώθηκε η διαχείριση ομάδας: '+(e.message||e),7000)}
  return false;
}
async function renameGroupV249284(groupId){
  groupId=String(groupId||currentClassicGroupIdV249284()||''); const title=($('groupRenameInputV249284')?.value||'').trim();
  if(!groupId||!title)return toast('Γράψε νέο όνομα ομάδας.');
  try{
    await fetchJson('/api/groups/rename',{method:'POST',body:JSON.stringify({room_id:state.room,group_id:groupId,actor_id:state.device,title})});
    state.activeGroupTitleV249282=title; if($('chatName'))$('chatName').textContent='👥 '+title; toast('Η ομάδα μετονομάστηκε.');
    await loadMessageGroupsV249282(); await openGroupMembersPanelV249284(groupId,title);
  }catch(e){toast('Δεν έγινε μετονομασία: '+(e.message||e),7000)}
  return false;
}
async function leaveGroupV249284(groupId){
  groupId=String(groupId||currentClassicGroupIdV249284()||''); if(!groupId)return false;
  if(!confirm('Να φύγεις από αυτή την ομάδα;'))return false;
  try{
    await fetchJson('/api/groups/leave',{method:'POST',body:JSON.stringify({room_id:state.room,group_id:groupId,device_id:state.device})});
    toast('Έφυγες από την ομάδα.'); try{$('memberMenu')?.classList.remove('show')}catch(e){}
    state.activeGroupV249282=''; state.activeGroupTitleV249282=''; state.activeChannel=''; state.activePeer='';
    try{clearChat()}catch(e){} page('dm'); setTimeout(loadMessageGroupsV249282,300);
  }catch(e){toast('Δεν έγινε έξοδος: '+(e.message||e),7000)}
  return false;
}
async function removeGroupMemberV249284(groupId, memberId, title=''){
  if(!groupId||!memberId)return false;
  if(!confirm('Να αφαιρεθεί αυτό το μέλος από την ομάδα;'))return false;
  try{
    await fetchJson('/api/groups/remove_member',{method:'POST',body:JSON.stringify({room_id:state.room,group_id:groupId,actor_id:state.device,member_id:memberId})});
    toast('Το μέλος αφαιρέθηκε.'); await loadGroupMembersBarV249282(groupId); await openGroupMembersPanelV249284(groupId,title||state.activeGroupTitleV249282||'Ομάδα');
  }catch(e){toast('Δεν αφαιρέθηκε: '+(e.message||e),7000)}
  return false;
}
function injectGroupHeaderButtonsV249284(groupId,title){
  try{
    const head=document.querySelector('#dmChatScreen .chatHead'); if(!head)return;
    document.getElementById('groupHeaderAddV249282')?.remove();document.getElementById('groupHeaderInfoV249282')?.remove();document.getElementById('groupHeaderManageV249284')?.remove();
    const add=document.createElement('button');add.id='groupHeaderAddV249282';add.className='icon chatActionBtn';add.title='Πρόσκληση φίλων';add.textContent='＋👥';add.onclick=()=>openMessageGroupPickerV249282('add',groupId,title);
    const manage=document.createElement('button');manage.id='groupHeaderManageV249284';manage.className='icon chatActionBtn';manage.title='Διαχείριση ομάδας';manage.textContent='⚙️';manage.onclick=()=>openGroupMembersPanelV249284(groupId,title);
    head.appendChild(add);head.appendChild(manage);
  }catch(e){}
}
try{var openGroupInMessagesV249284Base=openGroupInMessagesV249282}catch(e){var openGroupInMessagesV249284Base=null}
openGroupInMessagesV249282=async function(groupId,title='Ομάδα',count=0){
  const r=openGroupInMessagesV249284Base?await openGroupInMessagesV249284Base(groupId,title,count):false;
  setTimeout(()=>{try{state.activeGroupV249282=groupId;state.activeGroupTitleV249282=title; if($('chatAvatar'))$('chatAvatar').onclick=()=>openGroupMembersPanelV249284(groupId,title); injectGroupHeaderButtonsV249284(groupId,title);}catch(e){}},260);
  return r;
};
openGroupMembersPanelV249282=openGroupMembersPanelV249284;
function openClassicMessageGroupCreateV249284(){try{closeCommCenterV249280&&closeCommCenterV249280()}catch(e){};page('dm');setTimeout(()=>openMessageGroupPickerV249282('create'),220);return false}
try{var openCommCenterV249284Base=openCommCenterV249280}catch(e){var openCommCenterV249284Base=null}
openCommCenterV249280=function(tab='broadcast'){
  if(tab==='groups')return openClassicMessageGroupCreateV249284();
  return openCommCenterV249284Base?openCommCenterV249284Base(tab||'broadcast'):false;
};
try{var renderCommTabV249284Base=renderCommTabV249280}catch(e){var renderCommTabV249284Base=null}
renderCommTabV249280=async function(tab='broadcast'){
  injectV249284GroupManageCss();
  if(tab==='groups'){
    const body=document.getElementById('commBodyV249280');
    if(body){body.innerHTML=`<div class="groupClassicOnlyNoticeV249284"><b>Τα groups κρατήθηκαν μόνο στα Μηνύματα.</b><p>Δεν υπάρχουν πια δύο διαφορετικά interface. Δημιουργείς και διαχειρίζεσαι ομάδες από την κλασική οθόνη Μηνυμάτων.</p><button onclick="ITH.openClassicMessageGroupCreateV249284()">Άνοιγμα κλασικής ομαδικής συνομιλίας</button></div>`;}
    return false;
  }
  return renderCommTabV249284Base?renderCommTabV249284Base(tab):false;
};
function hideDuplicateGroupUiV249284(){
  try{document.querySelectorAll('.commTabsV249280 [data-tab="groups"]').forEach(b=>{b.textContent='👥 Groups στα Μηνύματα';b.onclick=()=>openClassicMessageGroupCreateV249284()})}catch(e){}
}
try{var togglePlusV249284Base=togglePlus}catch(e){var togglePlusV249284Base=null}
togglePlus=function(){const r=togglePlusV249284Base?togglePlusV249284Base.apply(this,arguments):false;setTimeout(()=>{try{document.querySelectorAll('#plusSheet [data-act="comm"],#plusSheet [data-act="groups"]').forEach(b=>{if(/group|ομάδ/i.test(b.textContent||'')){b.innerHTML='👥 Ομάδα στα Μηνύματα';b.onclick=(ev)=>{ev.preventDefault();ev.stopPropagation();document.getElementById('plusSheet')?.classList.remove('show');openClassicMessageGroupCreateV249284();};}})}catch(e){}},30);return r}
function installV249284Exports(){try{window.ITH=window.ITH||{};Object.assign(window.ITH,{openGroupMembersPanelV249284,renameGroupV249284,leaveGroupV249284,removeGroupMemberV249284,openClassicMessageGroupCreateV249284,openGroupMembersPanelV249282,openCommCenterV249280,renderCommTabV249280,togglePlus});hideDuplicateGroupUiV249284();}catch(e){}}
try{injectV249284GroupManageCss();installV249284Exports();setTimeout(installV249284Exports,600);setTimeout(installV249284Exports,1600);setInterval(installV249284Exports,5000);}catch(e){}



/* V249285 - Professional home bottom actions + clean wisdom */
function injectV249285HomeBottomCss(){
  try{
    if(document.getElementById('ithV249285HomeBottomCss'))return;
    const st=document.createElement('style');
    st.id='ithV249285HomeBottomCss';
    st.textContent=`
      /* Τα Πέλαγος / Φάρος / Κέντρο δεν εμφανίζονται πια σαν μεγάλες σκόρπιες κάρτες στην Αρχική. */
      #homePage #bottleHomeMountV249274,
      #homePage #lighthouseHomeMountV249278,
      #homePage #commHomeMountV249280{display:none!important}
      .homeBottomIthakiDockV249285{grid-column:1/-1;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:4px;padding:12px;border-radius:28px;background:linear-gradient(135deg,rgba(5,18,34,.84),rgba(9,28,54,.74));border:1px solid rgba(255,217,110,.18);box-shadow:0 22px 54px rgba(0,0,0,.24),inset 0 1px 0 rgba(255,255,255,.08);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
      .homeBottomIthakiDockV249285 .dockTitle{grid-column:1/-1;display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 2px 2px;color:rgba(239,248,255,.82);font-size:12px;letter-spacing:.08em;text-transform:uppercase;font-weight:1000}
      .homeBottomIthakiDockV249285 .dockTitle b{color:#ffe39b;font-size:13px}.homeBottomIthakiDockV249285 .dockTitle span{height:1px;flex:1;background:linear-gradient(90deg,rgba(255,217,110,.35),transparent)}
      .homeBottomIthakiDockV249285 button.homeDockBtnV249285{position:relative;overflow:hidden;min-height:108px;text-align:left;border:1px solid rgba(255,255,255,.13);border-radius:24px;padding:14px 13px;background:radial-gradient(circle at 20% 10%,rgba(255,255,255,.16),transparent 32%),linear-gradient(180deg,rgba(255,255,255,.075),rgba(255,255,255,.035));color:#fff;box-shadow:0 12px 30px rgba(0,0,0,.20),inset 0 1px 0 rgba(255,255,255,.08);cursor:pointer}
      .homeBottomIthakiDockV249285 button.homeDockBtnV249285:after{content:'';position:absolute;right:-32px;bottom:-38px;width:104px;height:104px;border-radius:50%;background:rgba(255,217,110,.08);filter:blur(2px)}
      .homeBottomIthakiDockV249285 button.homeDockBtnV249285 .ico{position:relative;z-index:2;width:44px;height:44px;border-radius:18px;display:grid;place-items:center;font-size:25px;margin-bottom:10px;background:rgba(255,217,110,.12);border:1px solid rgba(255,217,110,.18)}
      .homeBottomIthakiDockV249285 button.homeDockBtnV249285 b{position:relative;z-index:2;display:block;color:#ffe39b;font-size:15px;line-height:1.1;margin-bottom:5px}.homeBottomIthakiDockV249285 button.homeDockBtnV249285 small{position:relative;z-index:2;display:block;color:rgba(239,248,255,.74);font-size:12px;line-height:1.25}
      .homeBottomIthakiDockV249285 button.homeDockBtnV249285.pelagos{background:radial-gradient(circle at 20% 10%,rgba(112,221,255,.18),transparent 34%),linear-gradient(180deg,rgba(6,56,88,.56),rgba(4,18,34,.72))}.homeBottomIthakiDockV249285 button.homeDockBtnV249285.faros{background:radial-gradient(circle at 20% 10%,rgba(255,220,135,.22),transparent 34%),linear-gradient(180deg,rgba(67,49,14,.48),rgba(4,18,34,.72))}.homeBottomIthakiDockV249285 button.homeDockBtnV249285.center{background:radial-gradient(circle at 20% 10%,rgba(175,151,255,.20),transparent 34%),linear-gradient(180deg,rgba(35,28,83,.46),rgba(4,18,34,.72))}
      .greekWisdomCard .row,.greekWisdomCard .videoCardActions,.greekWisdomCard .feedGoldCardActions,.hourlyWisdomCard .row,.hourlyWisdomCard .videoCardActions,.hourlyWisdomCard .feedGoldCardActions{display:none!important}
      .greekWisdomCard button,.hourlyWisdomCard button{display:none!important}
      .feedGoldWisdomCard .feedGoldCardActions{display:none!important}
      #homePage .homeProPanel.hourlyWisdomCard{border-color:rgba(255,217,110,.18)!important;background:linear-gradient(135deg,rgba(12,28,48,.78),rgba(7,19,34,.86))!important;box-shadow:0 14px 34px rgba(0,0,0,.20)!important}
      #homePage .homeProPanel.hourlyWisdomCard .proPanelText p{font-size:17px;line-height:1.48;color:rgba(255,245,218,.94)!important;text-align:center;margin:8px auto 0!important;max-width:720px}
      #homePage .homeProPanel.hourlyWisdomCard .proPanelText b{display:block;text-align:center;color:#ffe39b!important;letter-spacing:.06em;text-transform:uppercase}
      @media(max-width:760px){.homeBottomIthakiDockV249285{grid-template-columns:1fr;gap:10px}.homeBottomIthakiDockV249285 button.homeDockBtnV249285{min-height:88px;display:grid;grid-template-columns:auto 1fr;column-gap:12px;align-items:center}.homeBottomIthakiDockV249285 button.homeDockBtnV249285 .ico{margin:0}.homeBottomIthakiDockV249285 button.homeDockBtnV249285 b{margin-bottom:3px}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function homeBottomDockV249285(){
  return `<section id="homeBottomIthakiDockV249285" class="homeBottomIthakiDockV249285" aria-label="Βασικά εργαλεία ΙΘΑΚΗΣ"><div class="dockTitle"><b>Κάτω επιλογές ΙΘΑΚΗΣ</b><span></span></div><button class="homeDockBtnV249285 pelagos" onclick="return ITH.openBottleSeaV249274?ITH.openBottleSeaV249274('compose'):false"><span class="ico">🌊</span><span><b>Πέλαγος Ψιθύρων</b><small>Μπουκάλι, ρεύματα και ήρεμες επιστροφές.</small></span></button><button class="homeDockBtnV249285 faros" onclick="return ITH.openLighthouseV249278?ITH.openLighthouseV249278():false"><span class="ico">🕯️</span><span><b>Ο Φάρος</b><small>Άναψε φως χωρίς λέξεις.</small></span></button><button class="homeDockBtnV249285 center" onclick="return ITH.openCommCenterV249280?ITH.openCommCenterV249280('broadcast'):false"><span class="ico">✦</span><span><b>Κέντρο</b><small>Broadcast, forward, profile και API.</small></span></button></section>`;
}
function cleanHomeCardsAndWisdomV249285(){
  try{injectV249285HomeBottomCss();}catch(e){}
  try{['bottleHomeMountV249274','lighthouseHomeMountV249278','commHomeMountV249280'].forEach(id=>{const el=document.getElementById(id);if(el)el.style.display='none'});}catch(e){}
  try{
    const h=$('homePage'); if(!h)return false;
    let dock=document.getElementById('homeBottomIthakiDockV249285');
    const menu=h.querySelector('.stableMainMenu,.professionalHomeGrid,.homeMenu');
    if(!dock){
      const wrap=document.createElement('div');wrap.innerHTML=homeBottomDockV249285();dock=wrap.firstElementChild;
      if(menu)menu.appendChild(dock);else h.appendChild(dock);
    }else if(menu && dock.parentElement!==menu){menu.appendChild(dock)}
    h.querySelectorAll('.greekWisdomCard button,.hourlyWisdomCard button,.greekWisdomCard .row,.hourlyWisdomCard .row,.feedGoldWisdomCard .feedGoldCardActions').forEach(x=>{x.remove&&x.remove()});
  }catch(e){}
  return false;
}
try{var homeWisdomPanelV249285Base=homeWisdomPanel}catch(e){var homeWisdomPanelV249285Base=null}
homeWisdomPanel=function(){
  try{
    return `<section class="card homeProPanel hourlyWisdomCard greekWisdomCard cleanWisdomV249285"><div class="proPanelIcon">🕯️</div><div class="proPanelText"><b>Σοφός λόγος</b><p>${esc(ithakiWisdomText())}</p></div></section>`;
  }catch(e){return homeWisdomPanelV249285Base?homeWisdomPanelV249285Base.apply(this,arguments):''}
};
try{var renderHomeV249285Base=renderHome}catch(e){var renderHomeV249285Base=null}
renderHome=function(){
  const r=renderHomeV249285Base?renderHomeV249285Base.apply(this,arguments):false;
  try{cleanHomeCardsAndWisdomV249285();setTimeout(cleanHomeCardsAndWisdomV249285,80);setTimeout(cleanHomeCardsAndWisdomV249285,360);setTimeout(cleanHomeCardsAndWisdomV249285,900);}catch(e){}
  return r;
};
function installV249285Exports(){
  try{window.ITH=window.ITH||{};Object.assign(window.ITH,{cleanHomeCardsAndWisdomV249285,homeBottomDockV249285,renderHome});injectV249285HomeBottomCss();cleanHomeCardsAndWisdomV249285();}catch(e){}
}
try{installV249285Exports();setTimeout(installV249285Exports,700);setTimeout(installV249285Exports,1800);setInterval(installV249285Exports,6000)}catch(e){}



/* V249286 - Feed cleanup: no polls/panels, safer video loading, diagnostic notice */
function injectV249286FeedCleanupCss(){
  try{
    if(document.getElementById('ithV249286FeedCleanupCss')) return;
    const st=document.createElement('style');
    st.id='ithV249286FeedCleanupCss';
    st.textContent=`
      #feedPage .feedGoldPollCard,#feedPage [data-feed-panel^="gold_poll_"],#feedPage .pollFeedCard,#feedPage .professionalPollCard,#feedPage .pollAsText{display:none!important;height:0!important;min-height:0!important;margin:0!important;padding:0!important;border:0!important;overflow:hidden!important}
      #feedPage .feedGoldResults,#feedPage .feedGoldCardActions{display:none!important}
      #feedPage article:empty,#feedPage .card:empty,#feedPage .postMediaWrap:empty,#feedPage .mediaInline:empty{display:none!important;height:0!important;margin:0!important;padding:0!important;border:0!important}
      #feedPage .feedGoldWisdomCard .feedGoldCardActions{display:none!important}
      #feedPage .feedVideo{background:#050b12;border-radius:18px;min-height:220px;max-height:76vh;object-fit:contain;width:100%}
      #feedPage .videoDiagV249286{margin:8px 0 0;font-size:12px;opacity:.72;color:#d9ecff;text-align:center}
      #feedPage .feedCleanNoticeV249286{margin:8px auto 10px;max-width:720px;border-radius:18px;padding:9px 12px;background:rgba(255,217,110,.10);border:1px solid rgba(255,217,110,.18);color:#ffe39b;font-size:12px;text-align:center}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function isPollPostV249286(p){
  try{
    const pk=String((p&&p.post_kind)||'').toLowerCase();
    if(pk==='poll'||pk==='vote'||pk==='poll_card') return true;
    const t=parseText((p&&p.text)||'');
    const m=t&&t.media?t.media:{};
    const k=String((m&&m.kind)||'').toLowerCase();
    if(k==='poll'||m.poll_id||m.pollId||m.pollID) return true;
    const raw=String((p&&p.text)||'').toLowerCase().replace(/\s+/g,'');
    return raw.includes('"kind":"poll"')||raw.includes('"poll_id"')||raw.includes('"pollid"')||raw.includes('professionalpollcard')||raw.includes('pollfeedcard');
  }catch(e){return false;}
}
function sanitizeFeedPostsV249286(posts){
  try{return uniquePosts((posts||[]).filter(p=>!isPollPostV249286(p)).filter(p=>{
    try{const t=parseText((p&&p.text)||'');const body=String(t.body||'').trim();const m=t.media||{};const k=String(m.kind||'').toLowerCase();return body||m.url||m.file_url||m.media_url||m.dataUrl||m.meta_id||k==='video'||k==='photo'||k==='image'||k==='audio'||k==='file';}catch{return true}
  }))}catch{return posts||[]}
}
try{var mediaHtmlV249286Base=mediaHtml}catch(e){var mediaHtmlV249286Base=null}
mediaHtml=function(m,tools=true){
  try{
    if(m&&String(m.kind||'').toLowerCase()==='poll') return '';
    let html=mediaHtmlV249286Base?mediaHtmlV249286Base.apply(this,arguments):'';
    if(!html) return '';
    html=String(html)
      .replaceAll('preload="auto"','preload="metadata"')
      .replaceAll('class="feedVideo"','class="feedVideo" data-feed-clean-v249286="1"')
      .replace(/<div class="fileTools"><button class="btn" onclick="ITH.openMediaViewer\('([^']*)','video[^']*'\)">👁️[^<]*<\/button><a class="btn" href="\1" download>⬇️[^<]*<\/a><button class="btn" onclick="ITH.share\('\1'\)">📤[^<]*<\/button><\/div>/g,'');
    return html;
  }catch(e){return mediaHtmlV249286Base?mediaHtmlV249286Base.apply(this,arguments):''}
};
try{var renderPostV249286Base=renderPost}catch(e){var renderPostV249286Base=null}
renderPost=function(p){
  try{
    if(isPollPostV249286(p)) return '';
    const html=renderPostV249286Base?renderPostV249286Base.apply(this,arguments):'';
    if(!String(html||'').trim()) return '';
    return html;
  }catch(e){try{return renderPostV249286Base?renderPostV249286Base.apply(this,arguments):''}catch(_){return ''}}
};
function renderFeedWithPanelsV249286(posts,cfg){
  injectV249286FeedCleanupCss();
  const clean=sanitizeFeedPostsV249286(posts);
  const html=clean.map(p=>renderPost(p)).filter(x=>String(x||'').trim()).join('');
  return html;
}
renderFeedWithPanels=renderFeedWithPanelsV249286;
function enhanceFeedVideosV249286(){
  try{
    injectV249286FeedCleanupCss();
    document.querySelectorAll('#feedPage video.feedVideo').forEach(v=>{
      try{v.preload='metadata';v.setAttribute('playsinline','');v.controls=true;v.muted=!ithakiVideoSoundUnlocked();v.loading='lazy';}catch(e){}
      if(!v.dataset.v249286Diag){
        v.dataset.v249286Diag='1';
        v.addEventListener('error',()=>{try{toast('Το βίντεο δεν φορτώθηκε. Πιθανό παλιό/χαμένο αρχείο ή πολύ μεγάλο αρχείο.',6000)}catch{}},{passive:true});
      }
    });
    document.querySelectorAll('#feedPage [data-feed-panel^="gold_poll_"],#feedPage .feedGoldPollCard,#feedPage .pollFeedCard,#feedPage .professionalPollCard,#feedPage .pollAsText').forEach(x=>{try{x.remove()}catch{}});
    document.querySelectorAll('#feedPage article.card').forEach(a=>{try{if(!(a.textContent||'').trim()&&!a.querySelector('img,video,audio,.officeFileCard'))a.remove()}catch{}});
  }catch(e){}
}
try{var loadFeedV249286Base=loadFeed}catch(e){var loadFeedV249286Base=null}
/* V249429_LEGACY_LOAD_FEED_REMOVED */
function feedVideoQualityStatusV249286(){
  const msg='Το σύστημα ποιότητας βίντεο υπάρχει: server FFmpeg compression + small-video fallback. Η Ροή τώρα ζητά λιγότερα posts, κρύβει polls και φορτώνει video με preload=metadata για γρηγορότερη εμφάνιση.';
  try{toast(msg,9000)}catch{};return msg;
}
function installV249286FeedCleanupExports(){
  try{window.ITH=window.ITH||{};Object.assign(window.ITH,{loadFeed,renderFeedWithPanels,renderFeedWithPanelsV249286,isPollPostV249286,sanitizeFeedPostsV249286,enhanceFeedVideosV249286,feedVideoQualityStatusV249286});injectV249286FeedCleanupCss();enhanceFeedVideosV249286();}catch(e){}
}
try{installV249286FeedCleanupExports();setTimeout(installV249286FeedCleanupExports,700);setTimeout(installV249286FeedCleanupExports,1800);0}catch(e){}



/* V249287 - Restore wisdom discussion buttons + real feed filters/search + preview keywords/description */
function injectV249287FeedSearchDescriptionCss(){
  try{
    if(document.getElementById('ithV249287FeedSearchDescriptionCss')) return;
    const st=document.createElement('style');
    st.id='ithV249287FeedSearchDescriptionCss';
    st.textContent=`
      #feedPage .feedGoldWisdomCard .feedGoldCardActions{display:flex!important;position:absolute!important;right:clamp(7px,1.4vw,13px)!important;left:auto!important;top:50%!important;transform:translateY(-50%)!important;z-index:82!important;flex-direction:column!important;gap:7px!important;padding:6px 4px!important;border-radius:999px!important;background:rgba(5,18,31,.34)!important;border:1px solid rgba(255,255,255,.16)!important;backdrop-filter:blur(9px)!important;-webkit-backdrop-filter:blur(9px)!important}
      #feedPage .feedGoldWisdomCard .feedGoldCardActions .btn{display:grid!important;place-items:center!important;width:38px!important;min-width:38px!important;height:38px!important;min-height:38px!important;border-radius:50%!important;padding:0!important;font-size:18px!important;background:rgba(255,255,255,.12)!important;color:#fff!important;border:1px solid rgba(255,255,255,.14)!important}
      #feedPage .feedGoldWisdomCard .feedGoldCardActions .btn:before{content:none!important;display:none!important}#feedPage .feedGoldWisdomCard .feedGoldCardActions .btn span{display:block!important;font-size:18px!important;line-height:1!important;color:#fff!important}
      #feedPage .feedFiltersV249287{display:flex;align-items:center;gap:6px;min-width:0}#feedPage .feedTypeSelectV249287{border:0;background:rgba(255,255,255,.12);color:#fff;border-radius:999px;padding:6px 8px;max-width:104px;font-weight:900;outline:0}#feedPage .feedTypeSelectV249287 option{color:#0b1724;background:#fff}#feedPage .feedSearchGlassV249189 input{min-width:82px!important}
      #feedPage .feedDescOverlayV249287{position:absolute;left:78px;right:62px;bottom:18px;z-index:70;border-radius:18px;background:linear-gradient(180deg,rgba(2,8,16,.20),rgba(2,8,16,.72));border:1px solid rgba(255,255,255,.10);color:#fff;padding:8px 10px;font-size:14px;line-height:1.25;max-height:42px;overflow:hidden;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);box-shadow:0 12px 28px rgba(0,0,0,.22);cursor:pointer}.feedDescOverlayV249287.open{max-height:42dvh;overflow:auto}.feedDescOverlayV249287:after{content:'πάτησε για άνοιγμα';display:block;font-size:10px;opacity:.58;margin-top:2px}.feedDescOverlayV249287.open:after{content:'πάτησε για κλείσιμο'}
      #feedPage .feedKeywordChipsV249287{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.feedKeywordChipsV249287 span{border-radius:999px;background:rgba(255,217,110,.18);border:1px solid rgba(255,217,110,.22);color:#ffe39b;padding:2px 6px;font-size:11px;font-weight:900}
      .previewBox .previewOneLineDescV249287{width:100%;min-height:44px;max-height:96px;resize:vertical;border-radius:16px;padding:10px 12px}.previewBox .previewKeywordsV249287{width:100%;border-radius:16px;padding:10px 12px}.previewBox .previewHintV249287{font-size:12px;opacity:.72;margin-top:4px}
      @media(max-width:760px){#feedPage .feedSearchGlassV249189{gap:5px}#feedPage .feedTypeSelectV249287{max-width:84px;font-size:12px;padding:5px 6px}#feedPage .feedDescOverlayV249287{left:68px;right:54px;bottom:16px;font-size:13px;max-height:40px}}
    `;
    document.head.appendChild(st);
  }catch(e){}
}
function feedKeywordsV249287(val){try{if(Array.isArray(val))return val.map(x=>String(x||'').trim()).filter(Boolean).slice(0,12);return String(val||'').split(/[#,，,\s]+/).map(x=>x.trim()).filter(Boolean).slice(0,12)}catch{return[]}}
try{var parseTextV249287Base=parseText}catch(e){var parseTextV249287Base=null}
parseText=function(t){
  try{
    const raw=String(t||'');
    const o=JSON.parse(raw);
    if(o&&typeof o==='object'){
      let media=o.media||null;if(!media&&o.kind)media=o;
      const isPoll=media&&String(media.kind||'').toLowerCase()==='poll';
      const body=isPoll?'':(o.body||o.description||o.caption||o.text||'');
      return{body,media:media||null,keywords:feedKeywordsV249287(o.keywords||o.tags||o.search_keywords),description:o.description||body||''};
    }
  }catch(e){}
  const r=parseTextV249287Base?parseTextV249287Base(t):{body:String(t||''),media:null};
  r.keywords=r.keywords||[];r.description=r.description||r.body||'';return r;
};
function feedKindV249287(p,t){
  try{t=t||parseText((p&&p.text)||'');const m=t.media||{};const k=String(m.kind||p.post_kind||'').toLowerCase();const mime=String(m.mime_type||m.type||'').toLowerCase();if(k.includes('video')||mime.startsWith('video/'))return'video';if(['photo','image'].includes(k)||mime.startsWith('image/'))return'photo';if(k==='audio'||mime.startsWith('audio/'))return'audio';if(k==='file'||m.url||m.file_url||m.media_url)return'file';if((p&&String(p.sender_id||'')===String(state.device)))return 'mine_text';return 'text'}catch{return'text'}
}
function feedSearchTextV249287(p,t){try{t=t||parseText((p&&p.text)||'');const m=t.media||{};return [t.body,t.description,(t.keywords||[]).join(' '),p.nickname,p.sender_id,m.filename,m.name,m.mime_type,m.kind,p.post_kind].map(x=>String(x||'')).join(' ').toLowerCase()}catch{return String((p&&p.text)||'').toLowerCase()}}
function feedKeywordBadgesV249287(keys){try{const arr=feedKeywordsV249287(keys);return arr.length?`<div class="feedKeywordChipsV249287">${arr.map(k=>`<span>#${esc(k)}</span>`).join('')}</div>`:''}catch{return''}}
try{var renderPostV249287Base=renderPost}catch(e){var renderPostV249287Base=null}
renderPost=function(p){
  try{
    if(typeof isPollPostV249286==='function'&&isPollPostV249286(p)) return '';
    const t=parseText((p&&p.text)||''), c=counts(p), mine=String(p.sender_id)===String(state.device);
    const kind=feedKindV249287(p,t), search=esc(feedSearchTextV249287(p,t));
    const pid=esc(p.post_id||''), sender=esc(p.sender_id||''), rawSender=String(p.sender_id||'');
    const hasMedia=!!t.media, isPoll=t.media&&String(t.media.kind||'').toLowerCase()==='poll';
    if(!hasMedia||isPoll){let html=renderPostV249287Base?renderPostV249287Base.apply(this,arguments):'';if(!html)return'';return String(html).replace('<article class="card post ',`<article data-feed-kind="${esc(kind)}" data-feed-search="${search}" class="card post `)}
    const anon=!!p.anonymous;const shownName=anon?uiText('Anonymous'):(p.nickname||'Member');const pinfo={id:rawSender,nickname:shownName,avatar:anon?'':(p.avatar||''),online:false};const dot=(!anon&&unreadFrom(rawSender))?'red':'';const media=mediaHtml(t.media,false);
    const overlayAvatar=`<button class="feedAvatarOverlay" onclick="event.stopPropagation();${anon?'return false':(mine?`ITH.openMemberFeed(\'${sender}\',\'${pid}\')`:`ITH.member(\'${sender}\')`)}" title="${anon?uiText('Anonymous post'):(mine?'Οι δημοσιεύσεις μου':uiText('Member menu'))}"><span class="avatarDotWrap">${avatarHtml(pinfo)}<i class="${dot}"></i></span><small>${esc(shownName)}</small></button>`;
    const actions=`<div class="leftActions">${overlayAvatar}${actionButtons(p,c,mine)}</div>`;
    const bodyText=String(t.body||t.description||'').trim();
    const desc=bodyText?`<div class="feedDescOverlayV249287" onclick="event.stopPropagation();this.classList.toggle('open')"><div id="post_${pid}" class="textClamp">${esc(bodyText)}</div>${feedKeywordBadgesV249287(t.keywords)}</div><div id="tr_post_${pid}" class="translateOut postTranslateOut"></div>`:'';
    return `<article class="card post mediaPost ${anon?'anonymousPost':''}" data-post="${pid}" data-sender="${sender}" data-feed-kind="${esc(kind)}" data-feed-search="${search}"><div class="postMediaWrap tiktokScreen">${media}${desc}${actions}</div></article>`;
  }catch(e){try{return renderPostV249287Base?renderPostV249287Base.apply(this,arguments):''}catch(_){return''}}
};
function feedCurrentFilterV249287(){try{return localStorage.getItem('ith_feed_type_v249287')||'all'}catch{return'all'}}
function setFeedFilterV249287(v){try{localStorage.setItem('ith_feed_type_v249287',v||'all')}catch{};return filterFeedCardsV249189()}
function articleKindV249287(a){try{const k=a.dataset.feedKind||'';if(k)return k;if(a.classList.contains('feedGoldWisdomCard'))return'wisdom';if(a.querySelector('video'))return'video';if(a.querySelector('img'))return'photo';if(a.querySelector('audio'))return'audio';if(a.querySelector('.officeFileCard'))return'file';return'text'}catch{return'text'}}
try{var filterFeedCardsV249287Base=filterFeedCardsV249189}catch(e){var filterFeedCardsV249287Base=null}
filterFeedCardsV249189=function(){
  try{
    const q=(document.getElementById('feedSearchV249189')?.value||'').toLowerCase().trim();
    const type=feedCurrentFilterV249287();
    document.querySelectorAll('#feedPage .feedList>article').forEach(a=>{
      const k=articleKindV249287(a), tx=((a.dataset.feedSearch||'')+' '+(a.textContent||'')).toLowerCase();
      const typeOk=(type==='all')||(type==='mine'&&String(a.dataset.sender||'')===String(state.device))||(type==='wisdom'&&a.classList.contains('feedGoldWisdomCard'))||(type===k)||(type==='photo'&&k==='image')||(type==='text'&&(k==='text'||k==='mine_text'));
      const searchOk=!q||tx.includes(q);
      a.style.display=(typeOk&&searchOk)?'':'none';
    });
  }catch(e){try{if(filterFeedCardsV249287Base)return filterFeedCardsV249287Base()}catch(_){}}
  return false;
};
function enhanceFeedControlsV249287(){
  try{
    injectV249287FeedSearchDescriptionCss();
    const box=document.querySelector('#feedPage .feedSearchGlassV249189');if(!box)return;
    if(!document.getElementById('feedTypeV249287')){
      const wrap=document.createElement('div');wrap.className='feedFiltersV249287';
      wrap.innerHTML=`<select id="feedTypeV249287" class="feedTypeSelectV249287" onchange="ITH.setFeedFilterV249287(this.value)" title="Τι βλέπω στη Ροή"><option value="all">Όλα</option><option value="video">Βίντεο</option><option value="photo">Φωτο</option><option value="file">Αρχεία</option><option value="text">Κείμενα</option><option value="wisdom">Σοφά</option><option value="mine">Δικά μου</option></select>`;
      const clearBtn=box.querySelector('button');box.insertBefore(wrap,clearBtn||box.lastChild);
    }
    const sel=document.getElementById('feedTypeV249287');if(sel)sel.value=feedCurrentFilterV249287();
    document.querySelectorAll('#feedPage .feedGoldWisdomCard .feedGoldCardActions').forEach(x=>x.style.display='flex');
    filterFeedCardsV249189();
  }catch(e){}
}
try{var loadFeedV249287Base=loadFeed}catch(e){var loadFeedV249287Base=null}
/* V249429_LEGACY_LOAD_FEED_REMOVED */
try{var openPreviewV249287Base=openPreview}catch(e){var openPreviewV249287Base=null}
openPreview=function(ctx,file,kind,target=''){
  try{
    state.preview={ctx,file,kind,target,originalFile:file,studio:studioDefaults()};const url=URL.createObjectURL(file);const stage=previewStageHtml(file,kind,url);const dest=ctx==='feed'?uiText('to Feed'):ctx==='dm'?uiText('to Messages'):ctx==='space'?uiText('to Community / Room'):(ctx==='comment'||ctx==='comment_frame')?'στα σχόλια':uiText('here');
    $('previewModal').classList.remove('callCompactV249218','voiceCallV249218','videoCallV249218');
    $('previewModal').innerHTML=`<div class="previewBox previewScrollable"><div class="row"><button class="icon" onclick="ITH.closePreview()">‹</button><b>${uiText('Preview')} ${dest}</b><button class="btn gold" style="margin-left:auto" onclick="ITH.openPreviewStudio()">✦ ${uiText('Studio')}</button><button class="btn" onclick="ITH.closePreview()">${uiText('Cancel')}</button></div><div id="previewStage" class="previewStage">${stage}</div><div class="card previewFileCard"><b id="previewFileName">${esc(file.name)}</b><div id="previewFileMeta" class="date">${esc(file.type||'file')} · ${mb(file.size)}</div></div><div id="previewStudioMount"></div><textarea id="previewCaption" rows="1" class="previewOneLineDescV249287" placeholder="Περιγραφή δημοσίευσης σε μία γραμμή — αν γίνει μεγάλη, στη Ροή ανοίγει με πάτημα"></textarea><input id="previewKeywords" class="previewKeywordsV249287" placeholder="Λέξεις κλειδιά για αναζήτηση: καφές, θάλασσα, δουλειά"><div class="previewHintV249287">Οι λέξεις κλειδιά βοηθούν την πραγματική αναζήτηση στη Ροή και δεν χαλάνε το πλαίσιο του βίντεο.</div>${ctx==='feed'?`<label class="card row anonymousRow"><input id="previewAnonymous" type="checkbox"><span class="anonBadge">🕶️ ${uiText('Anonymous post')}</span></label>`:''}<div class="progress"><span id="progressBar"></span></div><div id="progressText" class="date">${uiText('Ready')} · ${mb(file.size)}</div><div class="row"><button id="previewSend" class="btn green" onclick="ITH.sendPreview()">${uiText('Upload / Send')}</button><button class="btn" onclick="ITH.closePreview()">${uiText('Cancel')}</button></div></div>`;
    $('previewModal').classList.add('show');injectV249287FeedSearchDescriptionCss();return false;
  }catch(e){return openPreviewV249287Base?openPreviewV249287Base.apply(this,arguments):false}
};

/* V249503_FAST_VIDEO_UPLOAD: conditional browser-side 720p preparation before upload.
   It is deliberately best-effort: unsupported browsers, very long files, missing
   audio capture, or a result that is not smaller always fall back to the original. */
async function prepareVideoForFastUploadV249503(file,kind){
  try{
    if(!file||!isVideoFile(file,kind)||file.__ithakiFast503)return file;
    const conn=navigator.connection||navigator.mozConnection||navigator.webkitConnection||{};
    const slow=!!conn.saveData||/^(slow-2g|2g|3g)$/i.test(String(conn.effectiveType||''));
    const should=Number(file.size||0)>80*1024*1024||(slow&&Number(file.size||0)>35*1024*1024);
    if(!should||typeof MediaRecorder==='undefined')return file;
    const canCapture=HTMLVideoElement.prototype.captureStream||HTMLVideoElement.prototype.mozCaptureStream;
    if(!canCapture)return file;
    const mime=['video/webm;codecs=vp8,opus','video/webm;codecs=vp9,opus','video/webm'].find(x=>MediaRecorder.isTypeSupported(x));
    if(!mime)return file;
    const v=document.createElement('video');v.playsInline=true;v.preload='auto';v.volume=0;v.muted=false;
    const url=URL.createObjectURL(file);v.src=url;
    await new Promise((resolve,reject)=>{const t=setTimeout(()=>reject(new Error('video_metadata_timeout')),15000);v.onloadedmetadata=()=>{clearTimeout(t);resolve()};v.onerror=()=>{clearTimeout(t);reject(new Error('video_metadata_error'))}});
    if(!Number.isFinite(v.duration)||v.duration<=0||v.duration>300){URL.revokeObjectURL(url);return file}
    const scale=Math.min(1,1280/Math.max(1,v.videoWidth||1280));
    const canvas=document.createElement('canvas');canvas.width=Math.max(2,Math.round((v.videoWidth||1280)*scale/2)*2);canvas.height=Math.max(2,Math.round((v.videoHeight||720)*scale/2)*2);
    const ctx=canvas.getContext('2d',{alpha:false,desynchronized:true});if(!ctx){URL.revokeObjectURL(url);return file}
    await v.play();
    const source=canCapture.call(v),audio=source&&source.getAudioTracks?source.getAudioTracks():[];
    /* Do not risk publishing a silent replacement when browser audio capture is unavailable. */
    if(!audio.length){try{v.pause()}catch(e){}URL.revokeObjectURL(url);return file}
    const out=canvas.captureStream(24);audio.forEach(t=>out.addTrack(t));
    const chunks=[],rec=new MediaRecorder(out,{mimeType:mime,videoBitsPerSecond:1800000,audioBitsPerSecond:96000});
    const progress=$('progressText');if(progress)progress.textContent='Βελτιστοποίηση βίντεο για γρήγορη αποστολή…';
    let raf=0,done=false;const draw=()=>{if(done)return;try{ctx.drawImage(v,0,0,canvas.width,canvas.height)}catch(e){}raf=requestAnimationFrame(draw)};draw();
    const blobP=new Promise((resolve,reject)=>{rec.ondataavailable=e=>{if(e.data&&e.data.size)chunks.push(e.data)};rec.onerror=e=>reject(e.error||new Error('video_prepare_error'));rec.onstop=()=>resolve(new Blob(chunks,{type:mime.split(';')[0]}))});
    rec.start(1000);
    await new Promise((resolve,reject)=>{const timeout=setTimeout(()=>reject(new Error('video_prepare_timeout')),Math.min(330000,Math.ceil(v.duration*1000)+30000));v.onended=()=>{clearTimeout(timeout);resolve()};v.onerror=()=>{clearTimeout(timeout);reject(new Error('video_play_error'))}});
    done=true;cancelAnimationFrame(raf);if(rec.state!=='inactive')rec.stop();const blob=await blobP;try{v.pause()}catch(e){}URL.revokeObjectURL(url);
    if(!blob||blob.size<1024||blob.size>=file.size*.90)return file;
    const name=(String(file.name||'video').replace(/\.[^.]+$/,'')||'video')+'_ithaki_fast.webm';
    const prepared=new File([blob],name,{type:'video/webm',lastModified:Date.now()});Object.defineProperty(prepared,'__ithakiFast503',{value:true});
    if(progress)progress.textContent=`Βελτιστοποιήθηκε: ${(file.size/1048576).toFixed(1)} → ${(prepared.size/1048576).toFixed(1)} MB`;
    return prepared;
  }catch(e){console.warn('V249503 browser video optimization skipped',e);return file}
}

try{var sendPreviewV249287Base=sendPreview}catch(e){var sendPreviewV249287Base=null}
sendPreview=async function(){
  if(state.sending)return;const {ctx,file,kind,target}=state.preview;if(!file)return;state.sending=true;
  try{
    if((!state.token||String(state.token).length<8)&&typeof loadConfig==='function')await loadConfig();
    let uploadFile=state.preview.preparedFile;if(!uploadFile){uploadFile=await preparePhotoForUpload(file,kind);uploadFile=await prepareVideoForFastUploadV249503(uploadFile,kind);state.preview.preparedFile=uploadFile}
    await ensureFfmpegReadyForVideo(uploadFile,kind);
    let raw=state.preview.uploadedRaw;if(!raw){setSending(0,uploadFile.size);raw=await uploadWithProgress(uploadFile,kind);state.preview.uploadedRaw=raw}
    const caption=($('previewCaption')?.value||'').trim();const keywords=feedKeywordsV249287($('previewKeywords')?.value||'');const isVideo=isVideoFile(uploadFile,kind);
    if(raw&&raw.processing&&isVideo){setProcessing(uiText('Compressing video...'));toast(uiText('Video uploaded. Waiting for final video URL before publishing.'),7000)}
    let up=state.preview.uploadedReady;if(!up){up=await waitMediaIfProcessing(raw);state.preview.uploadedReady=up}
    if(isVideo&&(!up.url&&!up.file_url)){throw new Error('video_final_url_missing')}
    const k=(up.kind||up.media_kind)||(isVideoFile(uploadFile,kind)?'video':uploadFile.type.startsWith('image/')?'photo':uploadFile.type.startsWith('audio/')?'audio':'file');
    const payload=JSON.stringify({body:caption,description:caption,keywords,media:{url:up.url||up.file_url,filename:up.filename||uploadFile.name,mime_type:up.mime_type||uploadFile.type,kind:k,size:up.size_bytes||uploadFile.size,meta_id:up.meta_id||raw.meta_id||'',serverStored:true,fallback:!!(up.compression&&up.compression.fallback)}});
    if(ctx==='feed')await sendFeedPayload(payload,k,{anonymous:!!$('previewAnonymous')?.checked});else if(ctx==='comment')await sendComment(String(target||state.commentPostId||''),payload);else if(ctx==='comment_frame')await sendMessagePayload('comment:'+String(target||''),payload);else await sendMessagePayload(ctx==='space'?(target||state.currentSpaceChannel):(target||state.activeChannel),payload);
    state.sending=false;closePreview();toast(uiText('Sent'));if(ctx==='feed')page('feed');else if(ctx==='dm'){if(state.page!=='dm')page('dm');await loadMessages(true)}else if(ctx==='space'){if(state.page!=='spaces')await renderSpaces();await loadSpaceMessages(true)}else if(ctx==='comment'){await loadPanelComments(String(target||state.commentPostId||''))}else if(ctx==='comment_frame'){document.querySelectorAll('iframe').forEach(f=>{try{f.contentWindow.postMessage({type:'ithaki-v249395-comment-sent',postId:String(target||'')},'*')}catch(e){}})}
  }catch(e){state.sending=false;const b=$('previewSend');if(b){b.disabled=false;b.textContent=uiText('Send again')}const pt=$('progressText');if(pt)pt.textContent=(e.message||String(e));toast(uiText('Not sent')+': '+(e.message||String(e)),7000)}
};
function installV249287FeedExports(){try{window.ITH=window.ITH||{};Object.assign(window.ITH,{loadFeed,openPreview,sendPreview,renderPost,setFeedFilterV249287,filterFeedCardsV249189,enhanceFeedControlsV249287});injectV249287FeedSearchDescriptionCss();if(state.page==='feed')enhanceFeedControlsV249287();}catch(e){}}
try{installV249287FeedExports();setTimeout(installV249287FeedExports,700);setTimeout(installV249287FeedExports,1800);0}catch(e){}


/* V249288 - professional group avatars + silent encryption invite QR + one-time group message */
function injectV249288GroupAvatarCss(){try{if(document.getElementById('ithV249288GroupAvatarCss'))return;const st=document.createElement('style');st.id='ithV249288GroupAvatarCss';st.textContent=`
.groupMemberChipV249288{display:inline-flex;align-items:center;gap:6px;max-width:170px;border-radius:999px;padding:5px 9px;background:rgba(255,255,255,.075);border:1px solid rgba(255,255,255,.12);font-size:12px;font-weight:900;color:#fff;vertical-align:middle}.groupMemberChipV249288 .avatar,.groupMemberAdminRowV249288 .avatar,.oneTimePickV249288 .avatar{width:30px!important;height:30px!important;border-radius:50%;overflow:hidden;display:grid;place-items:center;background:rgba(255,255,255,.10)}.groupMemberChipV249288 .avatar img,.groupMemberAdminRowV249288 .avatar img,.oneTimePickV249288 .avatar img{width:100%;height:100%;object-fit:cover;border-radius:50%}.bubble.groupBubbleV249288{position:relative;padding-left:52px!important}.bubble.mine.groupBubbleV249288{padding-left:12px!important;padding-right:52px!important}.groupMsgAvatarV249288{position:absolute;left:10px;top:10px;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.14);overflow:hidden}.bubble.mine .groupMsgAvatarV249288{left:auto;right:10px}.groupMsgAvatarV249288 img{width:100%;height:100%;object-fit:cover;border-radius:50%}.secureInviteCardV249288,.oneTimeBroadcastCardV249288{border-radius:22px;padding:14px;margin:8px 0;background:linear-gradient(135deg,rgba(255,217,110,.14),rgba(80,220,255,.09));border:1px solid rgba(255,217,110,.24);box-shadow:0 14px 36px rgba(0,0,0,.25)}.secureInviteCardV249288 b{color:#ffe39b}.secureCodeV249288{font-family:ui-monospace,Consolas,monospace;word-break:break-all;border-radius:14px;padding:9px;margin:8px 0;background:rgba(0,0,0,.28);border:1px solid rgba(255,255,255,.12)}.qrBoxV249288{display:grid;grid-template-columns:repeat(17,7px);gap:2px;padding:12px;border-radius:18px;background:#fff;width:max-content;margin:12px auto}.qrBoxV249288 i{width:7px;height:7px;background:#fff}.qrBoxV249288 i.on{background:#111}.groupManageActionsV249284 .blue{border-color:rgba(80,220,255,.35)!important;background:rgba(80,220,255,.13)!important;color:#dff7ff!important}.oneTimeBroadcastPanelV249288{display:grid;gap:10px}.oneTimePickV249288{display:grid;grid-template-columns:auto 1fr;gap:9px;align-items:center;padding:10px;border-radius:16px;margin:7px 0;background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.10)}.oneTimePickV249288 small{display:block;color:rgba(239,248,255,.68)}.oneTimeMsgV249288{width:100%;min-height:82px;box-sizing:border-box;border-radius:16px;border:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.22);color:#fff;padding:11px;outline:none;resize:vertical}.groupMemberAdminRowV249288{display:grid;grid-template-columns:auto 1fr auto;gap:9px;align-items:center;border-radius:16px;padding:10px;margin:8px 0;background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.10)}.groupMemberAdminRowV249288 small{display:block;color:rgba(239,248,255,.68)}.groupMemberAdminRowV249288 button{border-radius:999px;border:1px solid rgba(255,99,99,.30);background:rgba(255,80,80,.12);color:#ffd0d0;padding:7px 10px;font-weight:1000}`;document.head.appendChild(st)}catch(e){}}
const groupMembersCacheV249288={};
function memberObjForAvatarV249288(m){return {avatar:m&&m.avatar||'',photo:m&&m.avatar||'',profile_photo:m&&m.avatar||'',nickname:(m&&(m.display_name||m.nickname))||'Μέλος',id:m&&m.device_id||'',device_id:m&&m.device_id||''}}
function groupAvatarHtmlV249288(m){try{return avatarHtml(memberObjForAvatarV249288(m))}catch(e){return '<span class="avatar">👤</span>'}}
async function loadGroupMembersV249288(groupId){groupId=String(groupId||(typeof currentClassicGroupIdV249284==='function'?currentClassicGroupIdV249284():'')||state.activeGroupV249282||'');if(!groupId)return[];try{const r=await fetchJson(`/api/groups/members?room_id=${encodeURIComponent(state.room)}&group_id=${encodeURIComponent(groupId)}`);const mem=r.members||[];groupMembersCacheV249288[groupId]=mem;return mem}catch(e){return groupMembersCacheV249288[groupId]||[]}}
function groupMemberByIdV249288(groupId,id){const mem=groupMembersCacheV249288[String(groupId||'')]||[];return mem.find(x=>String(x.device_id||'')===String(id||''))||null}
async function loadGroupMembersBarV249288(groupId){injectV249288GroupAvatarCss();try{let bar=$('groupMembersBarV249282');const pane=document.querySelector('#dmChatScreen .chatPane');const msgs=$('messages');if(pane&&msgs&&!bar){bar=document.createElement('div');bar.id='groupMembersBarV249282';bar.className='groupMembersBarV249282';msgs.parentNode.insertBefore(bar,msgs)}if(!bar)return;const mem=await loadGroupMembersV249288(groupId);bar.innerHTML=mem.slice(0,24).map(m=>`<span class="groupMemberChipV249288">${groupAvatarHtmlV249288(m)}<span>${esc(m.display_name||m.nickname||m.device_id||'Μέλος')}</span></span>`).join('')+`<button class="groupSecondaryV249282" onclick="ITH.openMessageGroupPickerV249282('add','${escJs(groupId)}','${escJs(state.activeGroupTitleV249282||'Ομάδα')}')">＋ φίλοι</button><button class="groupSecondaryV249282" onclick="ITH.openGroupMembersPanelV249288('${escJs(groupId)}','${escJs(state.activeGroupTitleV249282||'Ομάδα')}')">⚙️</button>`}catch(e){}}
async function openGroupMembersPanelV249288(groupId='',title=''){injectV249288GroupAvatarCss();groupId=String(groupId||(typeof currentClassicGroupIdV249284==='function'?currentClassicGroupIdV249284():'')||state.activeGroupV249282||'');if(!groupId)return false;title=title||state.activeGroupTitleV249282||'Ομάδα';try{const mem=await loadGroupMembersV249288(groupId);const me=String(state.device||'');const mine=mem.find(m=>String(m.device_id||'')===me)||{};const canAdmin=String(mine.role||'').toLowerCase()==='admin';const rows=mem.map(m=>{const id=String(m.device_id||'');const nm=esc(m.display_name||m.nickname||id||'Μέλος');const role=esc(m.role||'member');const remove=(canAdmin&&id!==me)?`<button onclick="ITH.removeGroupMemberV249284('${escJs(groupId)}','${escJs(id)}','${escJs(title)}')">Αφαίρεση</button>`:(id===me?'<span class="role">εσύ</span>':`<span class="role">${role}</span>`);return `<div class="groupMemberAdminRowV249288">${groupAvatarHtmlV249288(m)}<span><b>${nm}</b><small>${esc(id)} · ${role}</small></span>${remove}</div>`}).join('');$('memberMenu').innerHTML=`<div class="row"><b>👥 ${esc(title)}</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="groupManageBoxV249284"><b>Διαχείριση ομάδας</b><small class="date">Κλασική ομαδική συνομιλία μέσα στα Μηνύματα.</small><input id="groupRenameInputV249284" class="groupManageInputV249284" value="${esc(title)}" placeholder="Νέο όνομα ομάδας"><div class="groupManageActionsV249284"><button class="gold" onclick="ITH.renameGroupV249284('${escJs(groupId)}')">Μετονομασία</button><button onclick="ITH.openMessageGroupPickerV249282('add','${escJs(groupId)}','${escJs(title)}')">＋ Πρόσθεση φίλων</button><button class="blue" onclick="ITH.openOneTimeBroadcastV249288()">📣 Ένα μήνυμα χωρίς συζήτηση</button><button class="danger" onclick="ITH.leaveGroupV249284('${escJs(groupId)}')">Έξοδος από ομάδα</button></div></div><div class="card"><b>${mem.length} μέλη</b><p class="date">Ο admin μπορεί να αφαιρέσει μέλη. Κάθε μέλος μπορεί να φύγει μόνο του.</p></div><div>${rows||'<div class="card date">Δεν βρέθηκαν μέλη.</div>'}</div>`;$('memberMenu').classList.add('show')}catch(e){toast('Δεν φορτώθηκε η διαχείριση ομάδας: '+(e.message||e),7000)}return false}
function qrSvgV249288(txt){txt=String(txt||'');let seed=0;for(let i=0;i<txt.length;i++)seed=(seed*31+txt.charCodeAt(i))>>>0;let h='<div class="qrBoxV249288" aria-label="QR code">';for(let y=0;y<17;y++){for(let x=0;x<17;x++){const finder=(x<5&&y<5)||(x>11&&y<5)||(x<5&&y>11);let on=finder?(x===0||y===0||x===4||y===4||(x>1&&x<3&&y>1&&y<3)):(((seed+x*13+y*29+(x*y))%7)<3);h+=`<i class="${on?'on':''}"></i>`}}return h+'</div>'}
async function sendSecureInviteV249288(){injectV249288GroupAvatarCss();const channel=String(state.activeChannel||'');const peer=String(state.activePeer||'');if(!channel.startsWith('dm:')||!peer)return toast('Άνοιξε πρώτα προσωπική συνομιλία φίλου.');try{const r=await fetchJson('/api/groups/secure_invite_v249288',{method:'POST',body:JSON.stringify({room_id:state.room,from_id:state.device,to_id:peer,channel,nickname:state.name})});try{setE2EKey(channel,r.crypto_code)}catch(e){}showSecureInvitePanelV249288(r);await loadMessages(true);toast('Στάλθηκε σιωπηλά κωδικός κρυπτογράφησης. Δεν εμφανίζεται στις ειδοποιήσεις.')}catch(e){toast('Δεν στάλθηκε πρόσκληση: '+(e.message||e),7000)}return false}
function showSecureInvitePanelV249288(r){injectV249288GroupAvatarCss();const code=esc(r.code||'');const crypto=esc(r.crypto_code||'');const txt=String(r.qr_text||r.code||'');$('memberMenu').innerHTML=`<div class="row"><b>🔐 Κωδικός / QR κρυπτογράφησης</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="secureInviteCardV249288"><b>Στάλθηκε χωρίς push ειδοποίηση</b><p class="date">Ο κωδικός φαίνεται μόνο μέσα στη συνομιλία. Δεν μπαίνει ως προεπισκόπηση ειδοποίησης.</p>${qrSvgV249288(txt)}<div class="secureCodeV249288">${code}</div><div class="secureCodeV249288">${crypto}</div><button class="btn green" onclick="navigator.clipboard&&navigator.clipboard.writeText('${escJs(crypto)}')">Αντιγραφή κλειδιού</button></div>`;$('memberMenu').classList.add('show')}
function secureInviteMessageHtmlV249288(o){const code=esc(o.code||'');const ch=escJs(o.channel||state.activeChannel||'');return `<div class="secureInviteCardV249288"><b>🔐 Πρόσκληση κρυπτογράφησης</b><p class="date">Σιωπηλό μήνυμα: δεν εμφανίζεται σε ειδοποιήσεις.</p>${qrSvgV249288(o.qr_text||o.code||'')}<div class="secureCodeV249288">${code}</div><button class="btn green" onclick="ITH.useSecureInviteV249288('${ch}','${escJs(o.crypto_code||'')}')">Χρήση κλειδιού</button></div>`}
function useSecureInviteV249288(channel,key){try{setE2EKey(channel||state.activeChannel,key);toast('Το κλειδί κρυπτογράφησης ενεργοποιήθηκε.')}catch(e){toast('Δεν ενεργοποιήθηκε.')}}
function injectDmSecureInviteButtonV249288(){try{const head=document.querySelector('#dmChatScreen .chatHead');if(!head||document.getElementById('dmSecureInviteV249288'))return;const b=document.createElement('button');b.id='dmSecureInviteV249288';b.className='icon chatActionBtn';b.title='Κωδικός / QR κρυπτογράφησης';b.textContent='🔐QR';b.onclick=()=>sendSecureInviteV249288();head.appendChild(b)}catch(e){}}
function openOneTimeBroadcastV249288(){injectV249288GroupAvatarCss();const friends=(typeof dmFriendArrayV249282==='function'?dmFriendArrayV249282():[]);$('memberMenu').innerHTML=`<div class="row"><b>📣 Ένα ομαδικό μήνυμα χωρίς συζήτηση</b><button class="icon" style="margin-left:auto" onclick="ITH.closeMember()">×</button></div><div class="oneTimeBroadcastPanelV249288"><div class="card"><b>Στέλνει σε πολλούς ξεχωριστά</b><p class="date">Δεν δημιουργείται ομάδα και δεν βλέπει ο ένας τον άλλον.</p></div><textarea id="oneTimeMsgV249288" class="oneTimeMsgV249288" placeholder="Γράψε το μήνυμα..."></textarea><div><button class="btn" onclick="ITH.checkAllOneTimeV249288(true)">Όλοι</button><button class="btn" onclick="ITH.checkAllOneTimeV249288(false)">Κανένας</button></div><div id="oneTimeListV249288">${friends.map(p=>`<label class="oneTimePickV249288"><input type="checkbox" value="${esc(friendIdV249282(p))}">${avatarHtml(p)}<span><b>${esc(friendNameV249282(p))}</b><small>${esc(friendIdV249282(p))}</small></span></label>`).join('')||'<div class="card">Δεν βρέθηκαν φίλοι.</div>'}</div><button class="btn green" onclick="ITH.sendOneTimeBroadcastV249288()">Αποστολή</button></div>`;$('memberMenu').classList.add('show');return false}
function checkAllOneTimeV249288(on=true){document.querySelectorAll('#oneTimeListV249288 input[type=checkbox]').forEach(x=>x.checked=!!on);return false}
async function sendOneTimeBroadcastV249288(){const ids=[...document.querySelectorAll('#oneTimeListV249288 input[type=checkbox]:checked')].map(x=>x.value).filter(Boolean);const text=($('oneTimeMsgV249288')?.value||'').trim();if(!ids.length)return toast('Τσέκαρε φίλους.');if(!text)return toast('Γράψε μήνυμα.');try{const r=await fetchJson('/api/groups/broadcast_once_v249288',{method:'POST',body:JSON.stringify({room_id:state.room,sender_id:state.device,nickname:state.name,member_ids:ids,text})});$('memberMenu').classList.remove('show');toast('Στάλθηκε σε '+(r.sent_count||0)+' φίλους χωρίς δημιουργία ομάδας.')}catch(e){toast('Δεν στάλθηκε: '+(e.message||e),7000)}return false}
try{var appendMessageV249288Base=appendMessage}catch(e){var appendMessageV249288Base=null}
appendMessage=function(m){const r=appendMessageV249288Base?appendMessageV249288Base.apply(this,arguments):false;try{const ch=String(state.activeChannel||m.channel||'');if(ch.startsWith('group:')){const gid=ch.slice(6);const box=$('messages');const div=box&&box.lastElementChild;if(div&&div.classList&&div.classList.contains('bubble')){div.classList.add('groupBubbleV249288');if(!div.querySelector('.groupMsgAvatarV249288')){const mem=groupMemberByIdV249288(gid,m.sender_id)||{device_id:m.sender_id,nickname:m.nickname,display_name:m.nickname,avatar:m.avatar};const av=document.createElement('span');av.className='groupMsgAvatarV249288';av.innerHTML=groupAvatarHtmlV249288(mem);div.insertBefore(av,div.firstChild)}}}const t=String(m.text||'');if(t&&t.includes('secure_invite_v249288')){let o=null;try{o=JSON.parse(t)}catch(e){}if(o&&o.kind==='secure_invite_v249288'){const box=$('messages');const div=box&&box.lastElementChild;if(div&&!div.querySelector('.secureInviteCardV249288')){const body=div.querySelector('.msgBody')||div;body.innerHTML=secureInviteMessageHtmlV249288(o)}}}}catch(e){}return r}
try{var openGroupInMessagesV249288Base=openGroupInMessagesV249282}catch(e){var openGroupInMessagesV249288Base=null}
openGroupInMessagesV249282=async function(groupId,title='Ομάδα',count=0){const r=openGroupInMessagesV249288Base?await openGroupInMessagesV249288Base(groupId,title,count):false;setTimeout(async()=>{try{await loadGroupMembersBarV249288(groupId);if(typeof injectGroupHeaderButtonsV249284==='function')injectGroupHeaderButtonsV249284(groupId,title)}catch(e){}},260);return r}
try{var startDMV249288Base=startDM}catch(e){var startDMV249288Base=null}
startDM=async function(id){const r=startDMV249288Base?await startDMV249288Base.apply(this,arguments):false;setTimeout(injectDmSecureInviteButtonV249288,120);setTimeout(injectDmSecureInviteButtonV249288,500);return r}
loadGroupMembersBarV249282=loadGroupMembersBarV249288;openGroupMembersPanelV249282=openGroupMembersPanelV249288;openGroupMembersPanelV249284=openGroupMembersPanelV249288;
function installV249288Exports(){try{window.ITH=window.ITH||{};const exportedStartDM=(window.ITH.startDM&&window.ITH.startDM.__v249391Canonical)?window.ITH.startDM:startDM;Object.assign(window.ITH,{loadGroupMembersBarV249288,openGroupMembersPanelV249288,sendSecureInviteV249288,showSecureInvitePanelV249288,useSecureInviteV249288,openOneTimeBroadcastV249288,checkAllOneTimeV249288,sendOneTimeBroadcastV249288,startDM:exportedStartDM,appendMessage,openGroupInMessagesV249282});injectV249288GroupAvatarCss();injectDmSecureInviteButtonV249288();}catch(e){}}
try{installV249288Exports();setTimeout(installV249288Exports,700);setTimeout(installV249288Exports,1800);setInterval(installV249288Exports,5000);}catch(e){}



/* V249357: legacy feed blocks V249293-V249306 removed. */


/* V249407_CORE_STATE_STABLE_HOME_SERVER_FRIENDS */
window.__ITHAKI_CORE_STATE__=state;window.state=state;window.ITH=window.ITH||{};window.ITH.state=state;
function v249407RecentMember(p){try{if(p&&p.online)return true;const raw=p&&(p.last_seen||p.lastSeen||p.updated_at||p.seen_at);if(!raw)return false;let ms=typeof raw==='number'?raw:new Date(raw).getTime();if(ms<1e12)ms*=1000;return Date.now()-ms<=180000}catch(e){return false}}
function v249407ActiveHomePeople(){return peopleArray().filter(p=>{const id=String(p&& (p.id||p.device_id)||'');return id&&id!==String(state.device)&&v249407RecentMember(p)}).sort((a,b)=>String(a.nickname||'').localeCompare(String(b.nickname||''),'el')).slice(0,80)}
function homeStories(){const serverPeople=v249407ActiveHomePeople();const ithakiStory=`<button class="storyItem on ithakiOfficialStory" onclick="return ITH.openIthakiPostsPreview?ITH.openIthakiPostsPreview():ITH.page('feed')" title="${uiText('Δημοσιεύσεις ΙΘΑΚΗΣ')}"><span class="avatarDotWrap"><span class="avatar"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display='none'"></span><i class="on"></i></span><small>ΙΘΑΚΗ</small></button>`;const empty=!serverPeople.length?`<div class="storyHint">${uiText('Δεν υπάρχει ενεργό μέλος αυτή τη στιγμή.')}</div>`:'';return `<section class="homeStories storyGlassBar topStoryBarV249169" aria-label="${uiText('Avatar μελών')}"><div class="storyScroll">${ithakiStory}${serverPeople.map(p=>{const id=String(p.id||p.device_id||'');const click=unreadFrom(id)?`ITH.startDM('${esc(id)}')`:`ITH.member('${esc(id)}')`;return `<button class="storyItem on" onclick="${click}"><span class="avatarDotWrap">${avatarHtml(p)}<i class="on"></i></span><small>${esc(p.nickname||uiText('Μέλος'))}</small></button>`}).join('')}</div>${empty}</section>`}
function refreshHomeStoriesV249407(){try{const h=$('homePage');if(!h)return false;const old=h.querySelector('.homeStories');const temp=document.createElement('div');temp.innerHTML=homeStories();const neu=temp.firstElementChild;if(old&&neu)old.replaceWith(neu);else if(neu)h.insertBefore(neu,h.firstChild);document.documentElement.setAttribute('data-ithaki-active-members-v249407',String(v249407ActiveHomePeople().length));return true}catch(e){console.warn('V249407 home stories',e);return false}}
function v249407ServerFriends(){const m=new Map();try{(state.socialFriendsV249225||[]).forEach(p=>{const id=String(p&& (p.device_id||p.id)||'');if(!id||id===String(state.device))return;const sp=state.people.get(id)||{};m.set(id,Object.assign({},sp,p,{id,device_id:id,nickname:p.nickname||sp.nickname||'Φίλος',avatar:p.avatar||sp.avatar||'',online:!!(p.online||sp.online)}))})}catch(e){}const arr=[...m.values()].filter(p=>!isBlocked(String(p.id||p.device_id||'')));arr.sort((a,b)=>((unreadFrom(b.id)?1:0)-(unreadFrom(a.id)?1:0))||((b.online?1:0)-(a.online?1:0))||String(a.nickname||'').localeCompare(String(b.nickname||''),'el'));try{document.documentElement.setAttribute('data-ithaki-server-friends-v249407',String(arr.length))}catch(e){}return arr}
v249231FriendIds=function(){return new Set(v249407ServerFriends().map(p=>String(p.id||p.device_id||'')))};
v249231MergeFriendsAndPeople=function(){return v249407ServerFriends()};
v249235FriendListForMessages=function(){return v249407ServerFriends()};
v249225StoredFriendIds=function(){return new Set(v249407ServerFriends().map(p=>String(p.id||p.device_id||'')))};
ithV249236FriendIds=function(){return new Set(v249407ServerFriends().map(p=>String(p.id||p.device_id||'')))};
ithV249236AllPeople=function(){return v249407ServerFriends()};
loadSocialFriendsV249225=async function(){const r=await fetchJson(`/api/social/member_lists?room_id=${encodeURIComponent(state.room)}&device_id=${encodeURIComponent(state.device)}`);state.socialFriendsV249225=(r.friends||[]).filter(p=>String(p&& (p.device_id||p.id)||'')&&String(p.device_id||p.id)!==String(state.device));try{localStorage.setItem('ith_contacts',JSON.stringify(state.socialFriendsV249225.map(p=>String(p.device_id||p.id)).filter(Boolean)))}catch(e){}try{document.documentElement.setAttribute('data-ithaki-server-friends-v249407',String(state.socialFriendsV249225.length))}catch(e){}return state.socialFriendsV249225};
function exposeV249407Core(){try{window.ITH=window.ITH||{};window.ITH.state=state;window.ITH.refreshHomeStoriesV249407=refreshHomeStoriesV249407;window.ITH.serverFriendsV249407=v249407ServerFriends}catch(e){}}try{exposeV249407Core();setTimeout(exposeV249407Core,0);setTimeout(exposeV249407Core,600)}catch(e){}
/* END V249407_CORE_STATE_STABLE_HOME_SERVER_FRIENDS */


/* V249408_DIRECT_ONLINE_MEMBERS_AND_PREVIEW_ROUTE */
let v249408OnlinePeople=[],v249408OnlineLoaded=false,v249408OnlineError='';
function v249408NormalizeOnline(p){const id=String(p&&(p.device_id||p.id)||'').trim();if(!id||isBlocked(id))return null;const self=id===String(state.device);return{id,device_id:id,nickname:String(p.nickname||p.name||(self?(state.nickname||'Εσύ'):'Μέλος')),avatar:String(p.avatar||p.photo||(self?(state.avatar||''):'')),online:true,self,last_seen:+(p.last_seen||now())}}
function v249408ActiveHomePeople(){return v249408OnlinePeople.slice(0,80)}
function v249408HomeStories(){const serverPeople=v249408ActiveHomePeople();const ithakiStory=`<button class="storyItem on ithakiOfficialStory" onclick="return ITH.openIthakiPostsPreview?ITH.openIthakiPostsPreview():ITH.page('feed')" title="${uiText('Δημοσιεύσεις ΙΘΑΚΗΣ')}"><span class="avatarDotWrap"><span class="avatar"><img src="ok_ithaki_ship_logo.png" onerror="this.style.display='none'"></span><i class="on"></i></span><small>ΙΘΑΚΗ</small></button>`;const responseCount=Number(document.documentElement.getAttribute('data-ithaki-online-response-v249408')||0);const note=!v249408OnlineLoaded?`<div class="storyHint">Φόρτωση ενεργών μελών...</div>`:(!serverPeople.length?`<div class="storyHint">${responseCount>0?'Μόνο εσύ είσαι ενεργός αυτή τη στιγμή.':'Δεν υπάρχει ενεργό μέλος αυτή τη στιγμή.'}</div>`:'');return `<section class="homeStories storyGlassBar topStoryBarV249169" aria-label="Ενεργά μέλη"><div class="storyScroll">${ithakiStory}${serverPeople.map(p=>{const id=String(p.id||p.device_id||'');const click=p.self?`ITH.page('profile')`:(unreadFrom(id)?`ITH.startDM('${escJs(id)}')`:`ITH.member('${escJs(id)}')`);const label=p.self?`${esc(p.nickname||uiText('Εσύ'))} · Εσύ`:esc(p.nickname||uiText('Μέλος'));return `<button class="storyItem on" onclick="${click}"><span class="avatarDotWrap">${avatarHtml(p)}<i class="on"></i></span><small>${label}</small></button>`}).join('')}</div>${note}</section>`}
homeStories=v249408HomeStories;
refreshHomeStoriesV249407=function(){try{const h=$('homePage');if(!h)return false;const old=h.querySelector('.homeStories');const temp=document.createElement('div');temp.innerHTML=v249408HomeStories();const neu=temp.firstElementChild;if(old&&neu)old.replaceWith(neu);else if(neu)h.insertBefore(neu,h.firstChild);document.documentElement.setAttribute('data-ithaki-active-members-v249408',String(v249408ActiveHomePeople().length));return true}catch(e){console.warn('V249408 active home stories',e);return false}};
async function v249408FetchOnlineHomeMembers(){const r=await fetchJson(`/api/people/online?room_id=${encodeURIComponent(state.room)}&_v=${Date.now()}`);if(!r||!Array.isArray(r.people))throw new Error('invalid online people response');const map=new Map();r.people.forEach(raw=>{const p=v249408NormalizeOnline(raw);if(p&&!map.has(p.id))map.set(p.id,p)});v249408OnlinePeople=[...map.values()].sort((a,b)=>String(a.nickname||'').localeCompare(String(b.nickname||''),'el'));v249408OnlineLoaded=true;v249408OnlineError='';try{state.people.forEach((p,id)=>state.people.set(id,Object.assign({},p,{online:false})))}catch(e){}v249408OnlinePeople.forEach(mergePerson);state.activeHomePeopleV249408=v249408OnlinePeople;document.documentElement.setAttribute('data-ithaki-online-response-v249408',String(r.people.length));document.documentElement.setAttribute('data-ithaki-active-members-v249408',String(v249408OnlinePeople.length));refreshHomeStoriesV249407();return v249408OnlinePeople}
const v249408LoadPeopleBase=loadPeople;
loadPeople=async function(){let baseErr='';try{await v249408LoadPeopleBase()}catch(e){baseErr=String(e&&e.message||e)}try{await v249408FetchOnlineHomeMembers()}catch(e){v249408OnlineLoaded=true;v249408OnlineError=String(e&&e.message||e);document.documentElement.setAttribute('data-ithaki-online-error-v249408',v249408OnlineError);refreshHomeStoriesV249407()}try{if(state.page==='dm'||document.getElementById('dmPage')?.classList.contains('active'))renderPeople()}catch(e){}return v249408ActiveHomePeople()};
function exposeV249408(){try{window.ITH=window.ITH||{};window.ITH.refreshActiveHomeMembersV249408=v249408FetchOnlineHomeMembers;window.ITH.activeHomeMembersV249408=v249408ActiveHomePeople;window.ITH.state=state}catch(e){}}try{exposeV249408();setTimeout(exposeV249408,0);setTimeout(exposeV249408,800)}catch(e){}
/* END V249408_DIRECT_ONLINE_MEMBERS_AND_PREVIEW_ROUTE */


/* V249410_RAM_ONLY_PREVIEW_ACTIVE_SELF */
window.__ITHAKI_RAM_ONLY_PREVIEW_V249410=true;
/* END V249410_RAM_ONLY_PREVIEW_ACTIVE_SELF */
/* V249409_ONE_UNIFIED_PREVIEW_CORE_HOOKS */
window.__ITHAKI_UNIFIED_PREVIEW_CORE_V249409=true;
/* END V249409_ONE_UNIFIED_PREVIEW_CORE_HOOKS */

/* V249526_SINGLE_NOTIFICATION_PROXY — all old lexical calls route to one external owner */
function notifyCenter(){try{const f=window.ITH&&window.ITH.notifyCenter;if(typeof f==='function'&&f!==notifyCenter)return f.apply(window.ITH,arguments)}catch(e){}return false}
function openNotificationSettingsV249238(){try{const f=window.ITH&&window.ITH.openNotificationSettingsV249238;if(typeof f==='function'&&f!==openNotificationSettingsV249238)return f.apply(window.ITH,arguments)}catch(e){}return false}
/* END V249526_SINGLE_NOTIFICATION_PROXY */

boot().catch(e=>{console.error(e);toast('Startup error: '+e.message,6000);renderHome();renderNav()});
/* V249407_CLEAN_BOOT_BOUNDARY: unreachable duplicate tail disabled */
})();

/* V249411_ATOMIC_PAGE_CREATE_STATE */


/* BEGIN V249415_FULL_OLD_PLUS_VIDEO_STUDIO_PUBLISH_FIX */
window.__ITHAKI_V249415_CORE__={full_old_plus:true,real_video_preview:true,normal_studio:true,professional_preview:false,send_core:true};
/* END V249415_FULL_OLD_PLUS_VIDEO_STUDIO_PUBLISH_FIX */

/* V249418_SIMPLE_MESSAGES_NORMAL_ENDPOINT: DM and room text use /api/messages/send; encryption is optional per channel. */

;window.V249433_COMMENTS_INTERNAL_SHARE_POLLS_MODERN_PLUS_READY=true;window.V249434_FINAL_UI_POLISH_READY=true;

// V249435_TOR_MESH_FCM_SECURITY_READY
window.__ITHAKI_V249435_TOR_MESH_FCM_SECURITY_READY=true;

// V249436_HOME_PRIVATE_RELAY_PROFILE_FEED_CLEAN_READY
window.__ITHAKI_V249436_HOME_PRIVATE_RELAY_PROFILE_FEED_CLEAN_READY=true;


// V249439_RESTORE_V249290_NEIGHBORHOOD_NO_AUTO_MESH_READY
window.__ITHAKI_V249439_RESTORE_V249290_NEIGHBORHOOD_NO_AUTO_MESH_READY=true;

;try{window.__ITHAKI_V249439_RESTORE_V249290_NEIGHBORHOOD_READY__=true}catch(e){}

;try{window.__ITHAKI_V249466_PERMISSION_BOOT_FIX__={camera_microphone_on_user_action_only:true,notification_after_visible_ui:true,duplicate_permission_guard:true,at:Date.now()}}catch(e){}


/* V249466: legacy companion UI is permanently disabled. The only active companion is Bil. */
;(()=>{try{
 const noop=()=>false, names=['showAthinaWelcomeV249272','showAthenaWelcomeV249272','showAthinaSimpleHelloV249273','showAthinaSimpleHelloV249276','showAthinaTinyTipV249279','openAthenaV249378','openSocratesV249378','openAthinaMenuV249283','manualAthinaGuideV249282','ensureAthinaCompanionV249258','ensureSocratakiV249252','sokratakiOpenV249252'];
 names.forEach(n=>{try{window[n]=noop}catch(e){};try{if(window.ITH)window.ITH[n]=noop}catch(e){}});
 ['athinaFabV249258','ithAthena378','ithSocrates378','socratakiFabV249252','socratakiPanelV249252','ithCompanionBubble378','notifyCompanionIntroV249258','athinaTinyTipV249279'].forEach(id=>{try{document.getElementById(id)?.remove()}catch(e){}});
 window.__ITHAKI_V249466_LEGACY_COMPANIONS_DISABLED__=true;
}catch(e){}})();

;try{window.__ITHAKI_V249467_PRIMARY_ASSET_BOOT__={appassets_https:true,overlay_until_functional:true,at:Date.now()}}catch(e){}

;try{window.__ITHAKI_V249469_CONNECTION_POLICY__={automatic:'https://ok-ithaki.gr',manual_local_only:true,old_tunnel:false,api_bridge:true}}catch(e){}

/* OK ITHAKI V249505: upload repair lives inside the canonical core IIFE above. */
window.__ITHAKI_V249505_CORE_SCOPE_FIX__={outOfScopeOverrideRemoved:true,globalDollarCompatibility:true};
window.__ITHAKI_V249506_TRUE_SERVER_CONFIRMATION__={postIdRequired:true,authRetry:true,responseLossVerification:true,clientDuplicateBlockRemoved:true};
