/* OK ITHAKI V249391 — one authoritative personal communication flow.
 * One path for friend proposal, acceptance/rejection, direct messages, voice/video calls,
 * secure lock, Android Keystore E2EE and post-acceptance continuation.
 * It intentionally replaces the older competing DM/friend-gate wrappers.
 */
(function(){
  'use strict';
  if(window.__ITHAKI_V249391_UNIFIED_COMMUNICATION__)return;
  window.__ITHAKI_V249391_UNIFIED_COMMUNICATION__=1;

  const VERSION='V249391-unified-friend-communication-secure';
  const PENDING_KEY='ith_pending_global_friend_action_v249386';
  const CACHE_MS=12000;
  const RAW=window.__ITHAKI_RAW_COMM_V249391__||{};
  const acceptedCache=new Map();
  let pending=null;
  let pendingExecutor=null;
  let pollTimer=0;
  let restoring=false;

  const $=id=>document.getElementById(id);
  const esc=v=>String(v==null?'':v).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
  const js=v=>String(v==null?'':v).replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/\r/g,'').replace(/\n/g,'\\n');
  function appState(){try{return window.state||state||{}}catch(e){return window.state||{}}}
  function room(){const s=appState();return String(s.room||localStorage.getItem('ith_room')||'ithaki-phone-test')}
  function device(){const s=appState();return String(localStorage.getItem('ith_device')||localStorage.getItem('device_id')||s.device||'').trim()}
  function currentName(){const s=appState();return String(s.name||localStorage.getItem('ith_name')||'Μέλος')}
  function apiBase(){const s=appState();return String(s.api||location.origin||'').replace(/\/+$/,'')}
  function channelForPeer(peerId){
    if(typeof RAW.channelFor==='function'){try{return String(RAW.channelFor(device(),peerId))}catch(e){}}
    return 'dm:'+[device(),String(peerId||'')].sort().join(':');
  }
  function registered(){
    const n=currentName().trim().toLocaleLowerCase('el');
    return !!device()&&localStorage.getItem('ith_registered_member_v249154')==='1'&&localStorage.getItem('ith_age16')==='1'&&localStorage.getItem('ith_policy_ok')==='1'&&n!=='μέλος'&&n!=='member';
  }
  function notice(text,ms=5500){try{if(typeof RAW.toast==='function')RAW.toast(String(text),ms);else if(typeof window.toast==='function')window.toast(String(text),ms);else console.log(text)}catch(e){console.log(text)}}
  async function request(path,opt={}){
    const headers=Object.assign({'Content-Type':'application/json'},opt.headers||{});
    const r=await fetch(apiBase()+path,Object.assign({cache:'no-store',credentials:'same-origin',headers},opt));
    let d={};try{d=await r.json()}catch(e){}
    if(!r.ok||!d||d.ok===false){const detail=d&&d.detail;const m=(typeof detail==='string'&&detail)||(detail&&detail.message)||d.message||d.reason||('HTTP '+r.status);throw new Error(String(m))}
    return d;
  }
  function person(peerId,meta={}){
    const id=String(peerId||'').trim();let p={};const s=appState();
    try{p=s.people&&typeof s.people.get==='function'?(s.people.get(id)||{}):{}}catch(e){}
    return {id,device_id:id,nickname:String(p.nickname||meta.nickname||meta.name||'Μέλος'),avatar:String(p.avatar||meta.avatar||''),online:!!p.online,last_seen:Number(p.last_seen||0)};
  }
  function mergePerson(peerId,profile={}){
    const id=String(peerId||profile.device_id||profile.id||'').trim();if(!id)return person('');
    const p={id,device_id:id,nickname:String(profile.nickname||profile.name||'Μέλος'),avatar:String(profile.avatar||profile.photo||''),online:!!profile.online,last_seen:Number(profile.last_seen||0)};
    try{const s=appState();if(s.people&&typeof s.people.set==='function'){const old=s.people.get(id)||{};s.people.set(id,Object.assign({},old,p,{nickname:p.nickname||old.nickname||'Μέλος',avatar:p.avatar||old.avatar||''}))}}catch(e){}
    return person(id,p);
  }
  function cacheKey(peerId){return room()+'|'+device()+'|'+String(peerId||'')}
  async function friendState(peerId,force=false){
    peerId=String(peerId||'').trim();const key=cacheKey(peerId),hit=acceptedCache.get(key);
    if(!force&&hit&&Date.now()-hit.at<CACHE_MS)return hit.data;
    let aliases=[];try{const fn=window.ITH&&ITH.accountDeviceCandidatesV249386;if(typeof fn==='function')aliases=(fn()||[]).filter(x=>String(x||'')&&String(x)!==device())}catch(e){}
    const d=await request('/api/social/friend/state_v249390?room_id='+encodeURIComponent(room())+'&device_id='+encodeURIComponent(device())+'&peer_id='+encodeURIComponent(peerId)+'&aliases='+encodeURIComponent(aliases.join(','))+'&_v='+Date.now());
    if(d.peer)mergePerson(peerId,d.peer);
    if(d.accepted&&d.communication_allowed!==false)acceptedCache.set(key,{at:Date.now(),data:d});else acceptedCache.delete(key);
    return d;
  }
  async function sendFriendRequest(peer){
    return request('/api/social/friend/request_v249390',{method:'POST',body:JSON.stringify({room_id:room(),from_id:device(),from_name:currentName(),to_id:peer.id,to_name:peer.nickname||'Μέλος'})});
  }
  function persistPending(value){
    pending=value||null;
    try{
      if(pending&&['message','video','voice','photo','audio','file'].includes(pending.action))localStorage.setItem(PENDING_KEY,JSON.stringify({action:pending.action,peerId:pending.peer.id,peerName:pending.peer.nickname,peerAvatar:pending.peer.avatar,expiresAt:Date.now()+20*60*1000}));
      else localStorage.removeItem(PENDING_KEY);
    }catch(e){}
  }
  function loadPending(){
    try{const x=JSON.parse(localStorage.getItem(PENDING_KEY)||'null');if(!x||!x.peerId||!x.action||Number(x.expiresAt||0)<Date.now()){localStorage.removeItem(PENDING_KEY);return null}return{action:String(x.action),peer:person(x.peerId,{nickname:x.peerName,avatar:x.peerAvatar})}}catch(e){return null}
  }
  function clearPending(){persistPending(null);pendingExecutor=null;clearTimeout(pollTimer);pollTimer=0}
  function actionLabel(action){return action==='video'?'βιντεοκλήση':action==='voice'?'φωνητική κλήση':action==='photo'?'φωτογραφία':action==='audio'?'ηχητικό μήνυμα':action==='file'?'αρχείο':'μήνυμα'}

  function ensureCss(){
    if($('ithUnifiedCommunicationCss391'))return;
    const st=document.createElement('style');st.id='ithUnifiedCommunicationCss391';st.textContent=`
      #ithUnifiedFriendGate391{position:fixed;inset:0;z-index:2147483647;display:grid;place-items:center;padding:14px;background:rgba(0,0,0,.84);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}#ithUnifiedFriendGate391[hidden]{display:none!important}
      .ithUnifiedFriendBox391{width:min(560px,96vw);max-height:88vh;overflow:auto;border-radius:25px;border:1px solid rgba(255,216,112,.42);background:linear-gradient(150deg,#071521,#02070d);color:#fff;padding:17px;box-shadow:0 30px 100px rgba(0,0,0,.82)}
      .ithUnifiedFriendHead391{display:grid;grid-template-columns:62px minmax(0,1fr) auto;gap:11px;align-items:center}.ithUnifiedFriendAvatar391{width:62px;height:62px;border-radius:21px;display:grid;place-items:center;overflow:hidden;border:1px solid rgba(255,224,142,.5);background:rgba(255,255,255,.08);color:#ffe09a;font-size:23px;font-weight:1000}.ithUnifiedFriendAvatar391 img{width:100%;height:100%;object-fit:cover}.ithUnifiedFriendHead391 h2{margin:0;color:#ffe09a;font-size:19px}.ithUnifiedFriendHead391 small{color:rgba(240,248,255,.72)}
      .ithUnifiedFriendClose391{width:42px;height:42px;border-radius:14px;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.07);color:#fff;font-size:22px}.ithUnifiedFriendText391{margin-top:13px;padding:12px;border-radius:17px;border:1px solid rgba(255,217,110,.2);background:rgba(255,255,255,.055);line-height:1.5}.ithUnifiedFriendStatus391{min-height:20px;margin-top:9px;color:#ffe09a;font-size:12px}.ithUnifiedFriendButtons391{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}.ithUnifiedFriendButtons391 button{min-height:44px;border-radius:999px;padding:9px 15px;border:1px solid rgba(255,255,255,.17);background:rgba(255,255,255,.07);color:#fff;font-weight:950}.ithUnifiedFriendButtons391 .gold{border-color:#f1cf77;background:linear-gradient(135deg,#9f681c,#f1cf77);color:#1b1104}.ithUnifiedFriendButtons391 button:disabled{opacity:.55}
      .ithSecureStatus391{display:block;color:#96f0bd!important;font-size:10px!important;font-weight:900!important;margin-top:2px}.ithSecureLock391{border-color:rgba(94,235,164,.35)!important;background:rgba(25,130,85,.14)!important;color:#b8f8d2!important}.ithSecureLock391.wait{border-color:rgba(255,211,105,.35)!important;background:rgba(140,90,10,.14)!important;color:#ffe09a!important}
    `;document.head.appendChild(st);
  }
  function avatarHtml(p){
    try{if(typeof RAW.avatarHtml==='function')return RAW.avatarHtml(p)}catch(e){}
    return p.avatar?`<img src="${esc(p.avatar)}" alt="">`:esc((p.nickname||'Μ').slice(0,1));
  }
  function ensureModal(){
    let m=$('ithUnifiedFriendGate391');if(m)return m;ensureCss();m=document.createElement('div');m.id='ithUnifiedFriendGate391';m.hidden=true;m.innerHTML=`<div class="ithUnifiedFriendBox391"><div class="ithUnifiedFriendHead391"><div id="ithUnifiedFriendAvatar391" class="ithUnifiedFriendAvatar391">Μ</div><div><h2 id="ithUnifiedFriendTitle391">Έλεγχος φιλίας</h2><small id="ithUnifiedFriendName391">Μέλος</small></div><button id="ithUnifiedFriendClose391" class="ithUnifiedFriendClose391" type="button">×</button></div><div id="ithUnifiedFriendText391" class="ithUnifiedFriendText391"></div><div id="ithUnifiedFriendStatus391" class="ithUnifiedFriendStatus391"></div><div class="ithUnifiedFriendButtons391"><button id="ithUnifiedFriendPrimary391" class="gold" type="button">Αίτημα φιλίας</button><button id="ithUnifiedFriendCancel391" type="button">Κλείσιμο</button></div></div>`;document.body.appendChild(m);$('ithUnifiedFriendClose391').onclick=closeGate;$('ithUnifiedFriendCancel391').onclick=closeGate;m.addEventListener('click',e=>{if(e.target===m)closeGate()});return m;
  }
  function closeGate(){const m=$('ithUnifiedFriendGate391');if(m)m.hidden=true}
  function openNotifications(){closeGate();try{if(window.ITH&&typeof ITH.notifyCenter==='function')return ITH.notifyCenter()}catch(e){}return false}
  function renderGate(st={}){
    const m=ensureModal(),p=pending.peer,primary=$('ithUnifiedFriendPrimary391');
    $('ithUnifiedFriendAvatar391').innerHTML=avatarHtml(p);$('ithUnifiedFriendName391').textContent=p.nickname;primary.hidden=false;primary.disabled=false;$('ithUnifiedFriendStatus391').textContent='';
    if(st.blocked){$('ithUnifiedFriendTitle391').textContent='Η επικοινωνία δεν είναι διαθέσιμη';$('ithUnifiedFriendText391').textContent='Υπάρχει ενεργό μπλοκάρισμα μεταξύ των δύο μελών.';primary.hidden=true}
    else if(st.pending_incoming){$('ithUnifiedFriendTitle391').textContent='Έχεις εισερχόμενο αίτημα';$('ithUnifiedFriendText391').textContent='Το συγκεκριμένο μέλος έχει ήδη στείλει αίτημα. Η Αποδοχή ή η Απόρριψη γίνεται μόνο από τις ειδοποιήσεις μελών.';primary.textContent='Άνοιγμα αιτημάτων';primary.dataset.mode='notifications'}
    else if(st.pending_outgoing){$('ithUnifiedFriendTitle391').textContent='Περιμένει αποδοχή';$('ithUnifiedFriendText391').textContent='Το αίτημα στάλθηκε στο σωστό μέλος. Μετά την αποδοχή θα ανοίξει αυτόματα η '+actionLabel(pending.action)+'.';primary.textContent='Περιμένει αποδοχή';primary.dataset.mode='waiting';primary.disabled=true;startPolling()}
    else{$('ithUnifiedFriendTitle391').textContent='Χρειάζεται αποδοχή φιλίας';$('ithUnifiedFriendText391').textContent='Πριν από '+actionLabel(pending.action)+', στέλνεται αίτημα στο συγκεκριμένο μέλος. Μόνο εκείνο μπορεί να το αποδεχτεί ή να το απορρίψει.';primary.textContent='Στείλε αίτημα φιλίας';primary.dataset.mode='request'}
    primary.onclick=confirmGate;m.hidden=false;
  }
  async function confirmGate(){
    const primary=$('ithUnifiedFriendPrimary391'),status=$('ithUnifiedFriendStatus391'),mode=String(primary.dataset.mode||'request');
    if(mode==='notifications')return openNotifications();if(mode==='waiting')return false;
    primary.disabled=true;status.textContent='Στέλνω το αίτημα στο σωστό μέλος…';
    try{const d=await sendFriendRequest(pending.peer);acceptedCache.clear();if(d.already_friends){status.textContent='Η φιλία είναι ήδη ενεργή.';setTimeout(checkPendingNow,100)}else if(d.reverse_pending){status.textContent='Υπάρχει ήδη εισερχόμενο αίτημα.';primary.disabled=false;primary.textContent='Άνοιγμα αιτημάτων';primary.dataset.mode='notifications'}else{status.textContent=d.duplicate?'Το αίτημα υπάρχει ήδη και περιμένει αποδοχή.':'Το αίτημα στάλθηκε.';primary.textContent='Περιμένει αποδοχή';primary.dataset.mode='waiting';startPolling()}}catch(e){status.textContent=String(e.message||e);primary.disabled=false;primary.textContent='Επανάληψη'}
    return false;
  }

  function forceDmPageVisual(){
    const s=appState();try{if(typeof RAW.stopAllMedia==='function')RAW.stopAllMedia()}catch(e){}s.page='dm';if(document.body)document.body.setAttribute('data-page','dm');document.querySelectorAll('.page').forEach(x=>x.classList.remove('active'));const page=$('dmPage');if(page)page.classList.add('active');document.querySelectorAll('.nav button').forEach(b=>b.classList.toggle('active',b.dataset.page==='dm'));try{$('plusSheet')&&$('plusSheet').classList.remove('show')}catch(e){}
  }
  function buildDmShell(){
    forceDmPageVisual();
    try{if(typeof RAW.openDMV249235==='function')RAW.openDMV249235();else if(window.ITH&&typeof ITH.openDMV249235==='function')ITH.openDMV249235()}catch(e){}
    forceDmPageVisual();
  }
  function showChat(){
    try{if(typeof RAW.showDMChatScreenV249235==='function')RAW.showDMChatScreenV249235();else if(window.ITH&&typeof ITH.showDMChatScreenV249235==='function')ITH.showDMChatScreenV249235();else{const sh=$('dmShellV249235');if(sh)sh.classList.add('chatOpen');if($('dmFriendScreen'))$('dmFriendScreen').style.display='none';if($('dmChatScreen'))$('dmChatScreen').style.display='block'}}catch(e){}
  }
  function secureNativeReady(){try{const sec=window.ITHAKI_SECURE_V249389;const st=sec&&typeof sec.nativeStatus==='function'?sec.nativeStatus():null;return !!(st&&st.ok&&st.public_key_b64)}catch(e){return false}}
  function openSecureLock(){
    const s=appState(),ch=String(s.activeChannel||'');if(!s.activePeer||!ch.startsWith('dm:')){notice('Διάλεξε πρώτα φίλο για την ασφαλή κλειδαριά.');return false}
    const sec=window.ITHAKI_SECURE_V249389;if(!sec||typeof sec.openPanel!=='function'){notice('Η ασφαλής κλειδαριά δεν φορτώθηκε από το νέο APK.');return false}
    return sec.openPanel(ch);
  }
  function ensureSecureLock(){
    ensureCss();const head=document.querySelector('#dmChatScreen .chatHead');if(!head)return;
    let b=head.querySelector('[data-secure-lock-v249391]');if(!b){b=document.createElement('button');b.type='button';b.className='icon chatActionBtn ithSecureLock391';b.setAttribute('data-secure-lock-v249391','1');b.title='Ασφαλής κλειδαριά και End-to-end κρυπτογράφηση';b.textContent='🔐';const menu=head.querySelector('button:last-child');if(menu)head.insertBefore(b,menu);else head.appendChild(b)}
    b.onclick=openSecureLock;b.classList.toggle('wait',!secureNativeReady());
    const title=head.querySelector('.chatTitle');if(title){let small=title.querySelector('.ithSecureStatus391');if(!small){small=document.createElement('small');small.className='ithSecureStatus391';title.appendChild(small)}small.textContent=secureNativeReady()?'🔐 Κλειδαριά συσκευής διαθέσιμη':'🔐 Άνοιξε την κλειδαριά για έλεγχο E2EE'}
  }
  function setConversationState(peerId,p){
    const s=appState();const id=String(peerId||'').trim();s.activePeer=id;s.activeChannel=channelForPeer(id);s.activeGroupV249282='';s.activeGroupTitleV249282='';if(s.lastMsgIds&&typeof s.lastMsgIds.clear==='function')s.lastMsgIds.clear();s.messagesSince=0;
    try{if(typeof RAW.markPeerRead==='function')RAW.markPeerRead(id)}catch(e){}
    const name=$('chatName');if(name)name.textContent=p.nickname||'Φίλος';const av=$('chatAvatar');if(av){av.innerHTML=avatarHtml(p);av.onclick=()=>{try{if(window.ITH&&typeof ITH.member==='function')ITH.member(id)}catch(e){}}}
    ensureSecureLock();return s.activeChannel;
  }
  async function refreshConversation(peerId,p,load=true){
    if(restoring)return;restoring=true;
    try{forceDmPageVisual();if(!$('dmShellV249235')||!$('dmChatScreen'))buildDmShell();const ch=setConversationState(peerId,p);showChat();setConversationState(peerId,p);try{if(typeof RAW.renderPeople==='function')RAW.renderPeople()}catch(e){}try{if(typeof RAW.wsSubscribe==='function')RAW.wsSubscribe(ch)}catch(e){}if(load&&typeof RAW.loadMessages==='function')await RAW.loadMessages(true);try{if(typeof RAW.markActiveChannelRead==='function')await RAW.markActiveChannelRead()}catch(e){}try{if(typeof RAW.loadReadState==='function')await RAW.loadReadState(ch)}catch(e){}try{if(typeof RAW.pollTypingState==='function')RAW.pollTypingState()}catch(e){}try{const sec=window.ITHAKI_SECURE_V249389;if(sec&&typeof sec.registerDeviceKey==='function')sec.registerDeviceKey().catch(()=>{})}catch(e){}
    }finally{restoring=false}
  }
  async function openAcceptedConversation(peerId,meta={}){
    const id=String(peerId||'').trim();if(!id){notice('Διάλεξε πρώτα μέλος.');return false}
    const st=await friendState(id,true);if(!st.accepted||st.communication_allowed===false)return gate('message',id,()=>openAcceptedConversation(id,meta),meta);
    const p=mergePerson(id,st.peer||meta||{});buildDmShell();await refreshConversation(id,p,true);
    [120,420,1000].forEach((t,i)=>setTimeout(()=>{const s=appState();if(String(s.activePeer||'')===id)refreshConversation(id,p,i===2).catch(()=>{})},t));
    return false;
  }
  async function executePending(){
    if(!pending)return false;const current=pending,executor=pendingExecutor;clearPending();closeGate();notice('Η φιλία έγινε αποδεκτή. Ανοίγω το σωστό μέλος…',3500);
    try{if(typeof executor==='function')return await executor();if(current.action==='message'||current.action==='photo'||current.action==='audio'||current.action==='file')return await openAcceptedConversation(current.peer.id,current.peer);if(current.action==='video'){await openAcceptedConversation(current.peer.id,current.peer);return await rawVideoCall()}if(current.action==='voice'){await openAcceptedConversation(current.peer.id,current.peer);return await rawVoiceCall()}}catch(e){notice('Δεν άνοιξε η επικοινωνία: '+String(e.message||e),7000)}return false;
  }
  async function checkPendingNow(){if(!pending)return false;try{const st=await friendState(pending.peer.id,true);if(st.accepted&&st.communication_allowed!==false){await executePending();return true}renderGate(st)}catch(e){const x=$('ithUnifiedFriendStatus391');if(x)x.textContent='Ο έλεγχος θα επαναληφθεί.'}return false}
  function startPolling(){clearTimeout(pollTimer);const tick=async()=>{if(!pending)return;const done=await checkPendingNow();if(!done&&pending)pollTimer=setTimeout(tick,4000)};pollTimer=setTimeout(tick,800)}
  async function gate(action,peerId,executor,meta={}){
    const id=String(peerId||'').trim();if(!registered()){notice('Χρειάζεται αποθηκευμένο προφίλ μέλους πριν από προσωπική επικοινωνία.',7000);try{window.ITH&&ITH.page&&ITH.page('profile')}catch(e){}return false}if(!id){notice('Διάλεξε πρώτα μέλος.',5000);return false}if(id===device()){notice('Δεν γίνεται προσωπική επικοινωνία με τον εαυτό σου.');return false}
    const p=person(id,meta);pending={action:String(action||'message'),peer:p};pendingExecutor=executor;persistPending(pending);
    try{const st=await friendState(id,false);if(st.accepted&&st.communication_allowed!==false)return executePending();renderGate(st)}catch(e){renderGate({});const x=$('ithUnifiedFriendStatus391');if(x)x.textContent='Δεν ολοκληρώθηκε ο έλεγχος: '+String(e.message||e)}return false;
  }
  function activePeer(){const s=appState();return String(s.activePeer||(pending&&pending.peer&&pending.peer.id)||'')}
  function rawVoiceCall(){const fn=RAW.startVoiceCall||RAW.sendCallRequestVoice;if(typeof fn!=='function')throw new Error('Η φωνητική κλήση δεν είναι διαθέσιμη.');return Promise.resolve(fn.call(window.ITH||window))}
  function rawVideoCall(){const fn=RAW.startVideoCall||RAW.sendCallRequestVideo;if(typeof fn!=='function')throw new Error('Η βιντεοκλήση δεν είναι διαθέσιμη.');return Promise.resolve(fn.call(window.ITH||window))}
  function startDM(peerId){const id=String(peerId||'');return gate('message',id,()=>openAcceptedConversation(id,person(id)),person(id))}
  function startVoiceCall(){const id=activePeer();return gate('voice',id,async()=>{await openAcceptedConversation(id,person(id));return rawVoiceCall()},person(id))}
  function startVideoCall(){const id=activePeer();return gate('video',id,async()=>{await openAcceptedConversation(id,person(id));return rawVideoCall()},person(id))}
  function sendDMText(){const id=activePeer(),fn=RAW.sendDMText;if(typeof fn!=='function')return false;return gate('message',id,()=>fn.call(window.ITH||window),person(id))}
  function openMessageCamera(kind){const id=activePeer(),fn=RAW.openMessageCamera;if(typeof fn!=='function')return false;return gate(kind==='video'?'video':'photo',id,()=>fn.call(window.ITH||window,kind),person(id))}
  function startAudioRecording(ctx){const fn=RAW.startAudioRecording;if(typeof fn!=='function')return false;if(String(ctx||'')!=='dm')return fn.call(window.ITH||window,ctx);const id=activePeer();return gate('audio',id,()=>fn.call(window.ITH||window,ctx),person(id))}
  function sendPreview(){const fn=RAW.sendPreview;if(typeof fn!=='function')return false;const s=appState(),preview=s.preview||{};if(String(preview.ctx||'')!=='dm')return fn.apply(window.ITH||window,arguments);const id=activePeer();return gate(preview.kind==='video'?'video':preview.kind==='photo'?'photo':'file',id,()=>fn.apply(window.ITH||window,arguments),person(id))}
  function friendAcceptedRecheck(){acceptedCache.clear();if(!pending){const saved=loadPending();if(saved)pending=saved}return pending?checkPendingNow():false}
  function installExports(){
    window.ITH=window.ITH||{};
    startDM.__v249391Canonical=true;startVoiceCall.__v249391Canonical=true;startVideoCall.__v249391Canonical=true;
    Object.assign(window.ITH,{startDM,startVoiceCall,startVideoCall,sendDMText,openMessageCamera,startAudioRecording,sendPreview,guardFriendCommunicationV249386:gate,checkFriendStateV249386:friendState,openGlobalFriendGateV249386:(action,id,meta)=>gate(action,id,null,meta),resumePendingFriendCommunicationV249386:()=>{if(!pending)pending=loadPending();if(pending)startPolling();return !!pending},friendAcceptedRecheckV249386:friendAcceptedRecheck,openAcceptedConversationV249391:openAcceptedConversation,openSecureLockV249391:openSecureLock,communicationFlowVersionV249391:VERSION});
    try{window.startDM=startDM;window.startVoiceCall=startVoiceCall;window.startVideoCall=startVideoCall;window.sendDMText=sendDMText;window.openMessageCamera=openMessageCamera;window.startAudioRecording=startAudioRecording;window.sendPreview=sendPreview}catch(e){}
    document.documentElement.setAttribute('data-ithaki-communication-flow','V249391');document.documentElement.setAttribute('data-ithaki-secure-lock','V249389-preserved');
  }
  function install(){
    ensureCss();ensureModal();installExports();pending=loadPending();if(pending)startPolling();
    window.addEventListener('ithaki-friend-accepted-v249386',e=>{acceptedCache.clear();const id=String(e&&e.detail&&e.detail.peer_id||'');if(!pending&&id){pending={action:'message',peer:person(id)};pendingExecutor=()=>openAcceptedConversation(id,person(id));persistPending(pending)}checkPendingNow()});
    window.addEventListener('focus',()=>{installExports();acceptedCache.clear();if(pending)checkPendingNow()});window.addEventListener('online',()=>{acceptedCache.clear();if(pending)checkPendingNow()});document.addEventListener('visibilitychange',()=>{if(!document.hidden){installExports();acceptedCache.clear();if(pending)checkPendingNow()}});
    document.addEventListener('click',ev=>{const el=ev.target&&ev.target.closest?ev.target.closest('[data-ithaki-peer-action][data-peer-id]'):null;if(!el)return;const action=String(el.getAttribute('data-ithaki-peer-action')||'message'),id=String(el.getAttribute('data-peer-id')||'');if(!id||!['message','video','voice'].includes(action))return;ev.preventDefault();ev.stopPropagation();gate(action,id,null,{nickname:el.getAttribute('data-peer-name')||'',avatar:el.getAttribute('data-peer-avatar')||''})},true);
    setInterval(()=>{installExports();const s=appState();if(s.page==='dm'&&s.activePeer&&s.activeChannel){ensureSecureLock();showChat()}},900);
  }
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',install,{once:true});else install();
})();
