<!-- SOLID CITY · part 3474 -->
n(x){return x.id===id});if(!d||d.status!=='ACTIVE')return;
    selectedId=id;
    if(d.owner!=='HUMAN'){
      var oldEpoch=d.epoch;d.owner='HUMAN';d.epoch++;d.task='DIRECT';d.handoffAt=0;d.vx=0;d.vy=0;
      addEvent('TAKEOVER',d.name,'Human claimed task; epoch '+oldEpoch+' → '+d.epoch+'; '+d.group+' AI yielded instantly');
    }
    updateAllUI();
  }
  function releaseSelected(){
    if(paused)return;var d=drones.find(function(x){return x.id===selectedId});if(!d||d.owner!=='HUMAN'||d.status!=='ACTIVE')return;
    d.owner='AI';d.epoch++;d.task='HANDOFF';d.handoffAt=elapsed+.45;d.vx=0;d.vy=0;addEvent('HANDOFF',d.name,'Safe release accepted; AI resumes at epoch '+d.epoch);selectedId=null;updateAllUI();
  }
  function processQueue(){
    for(var i=commandQueue.length-1;i>=0;i--){var c=commandQueue[i];if(c.at>elapsed)continue;var d=drones.find(function(x){return x.id===c.drone});commandQueue.splice(i,1);if(!d)continue;
      if(d.epoch!==c.epoch||d.owner!=='AI'){addEvent('REJECTED',d.name,'Stale '+c.order+' command rejected at epoch '+c.epoch+'; current epoch '+d.epoch);continue}
      d.task=c.order;
    }
  }
  function humanControl(d,dt){var ax=0,ay=0;if(pressed.left)ax-=1;if(pressed.right)ax+=1;if(pressed.up)ay-=1;if(pressed.down)ay+=1;var m=Math.hypot(ax,ay)||1;d.vx+=(ax/m)*.24*dt;d.vy+=(ay/m)*.24*dt;var sp=Math.hypot(d.vx,d.vy),max=.15;if(sp>max){d.vx=d.vx/sp*max;d.vy=d.vy/sp*max}}
  function aiControl(d,dt,index){
    var tx=.25,ty=.3+(index%4)*.12;
    if(activeOrder==='FORM UP'){tx=convoyX+.10+((index%4)-1.5)*.032;ty=.32+Math.floor(index/4)*.17}
    else if(activeOrder==='SWEEP'){tx=.42+((index%4)*.09);ty=.22+Math.floor(index/4)*.27}
    else if(activeOrder==='CONVERGE'){var near=nearestDebris(d);if(near){tx=near.x;ty=near.y}}
    else if(activeOrder==='SCATTER'){tx=.22+(index%6)*.11;ty=.23+Math.floor(index/6)*.5}
    else if(activeOrder==='REGROUP'){tx=convoyX+.12+(index%4)*.035;ty=.39+Math.floor(index/4)*.11}
    else if(activeOrder==='GUARD'){var a=index/12*Math.PI*2;tx=convoyX+.11+Math.cos(a)*.11;ty=.5+Math.sin(a)*.25}
    var dx=tx-d.x,dy=ty-d.y,m=Math.hypot(dx,dy)||1;d.vx+=(dx/m)*.10*dt;d.vy+=(dy/m)*.10*dt;var sp=Math.hypot(d.vx,d.vy),max=.075;if(sp>max){d.vx=d.vx/sp*max;d.vy=d.vy/sp*max}
    var target=nearestDebris(d);if(target&&Math.hypot(target.x-d.x,target.y-d.y)<.085){target.hp-=dt*(activeOrder==='CONVERGE'?30:18);d.pulse=.22;if(target.hp<=0)clearDebris(target,d.name)}
  }
  function nearestDebris(d){var best=null,bd=99;debris.forEach(function(o){var v=Math.hypot(o.x-d.x,o.y-d.y);if(v<bd){bd=v;best=o}});return best}
  function clearDebris(o,by){var idx=debris.indexOf(o);if(idx<0)return;debris.splice(idx,1);for(var i=0;i<9;i++)particles.push({x:o.x,y:o.y,vx:(Math.random()-.5)*.09,vy:(Math.random()-.5)*.09,life:.8});addEvent('CLEARED',by,'Hazard '+String(o.id).slice(-3)+' cleared from convoy lane')}
  function firePulse(){
    if(paused)return;var d=drones.find(function(x){return x.id===selectedId});if(!d||d.owner!=='HUMAN'||d.status!=='ACTIVE')return;d.pulse=.45;var hit=0;debris.slice().forEach(function(o){var dist=Math.hypot(o.x-d.x,o.y-d.y);if(dist<.12){o.hp-=42*(1-dist/.14);hit++;if(o.hp<=0)clearDebris(o,d.name)}});addEvent('PULSE',d.name,'Human clear pulse engaged '+(hit?'on '+hit+' hazard'+(hit===1?'':'s'):'with no hazard in range'));
  }
  function disableDrone(d,cause){if(d.status!=='ACTIVE')return;d.status='DISABLED';d.hp=0;d.vx=d.vy=0;d.recover=0;addEvent('LOST',d.name,'Drone disabled by '+cause+'; recoverable through REGROUP');if(selectedId===d.id)selectedId=null}
  function recoverLogic(dt){if(activeOrder!=='REGROUP')return;var helpers=drones.filter(function(d){return d.status==='ACTIVE'&&d.owner==='AI'}).length;drones.forEach(function(d){if(d.status!=='DISABLED')return;d.recover+=dt*Math.max(.45,helpers/8);if(d.recover>=7){d.status='ACTIVE';d.hp=55;d.owner='AI';d.epoch++;d.task='REGROUP';d.x=convoyX+.14+Math.random()*.05;d.y=.42+Math.random()*.16;addEvent('RECOVERED',d.name,'Recovered by AI sub-commanders; resumed at epoch '+d.epoch)}})}
  function update(dt){
    elapsed=(performance.now()-missionStart)/1000;processQueue();
    drones.forEach(function(d,i){if(d.status!=='ACTIVE')return;if(d.handoffAt&&elapsed>=d.handoffAt){d.handoffAt=0;d.task=activeOrder;updateAllUI()}if(d.owner==='HUMAN')humanControl(d,dt);else aiControl(d,dt,i);d.vx*=Math.pow(.16,dt);d.vy*=Math.pow(.16,dt);d.x+=d.vx*dt;d.y+=d.vy*dt;d.x=Math.max(.05,Math.min(.96,d.x));d.y=Math.max(.12,Math.min(.91,d.y));d.pulse=Math.max(0,d.pulse-dt);d.hit=Math.max(0,d.hit-dt)});
    debris.slice().forEach(function(o){o.x+=o.vx*dt;o.y+=o.vy*dt;o.angle+=o.spin*dt;if(o.y<.12||o.y>.91)o.vy*=-1;if(o.x<.06){debris.splice(debris.indexOf(o),1);progress=Math.max(0,progress-1.8);addEvent('BREACH','CONVOY','Uncleared debris crossed the protection line');}
      drones.forEach(function(d){if(d.status!=='ACTIVE'||d.hit>0)return;var dist=Math.hypot(o.x-d.x,o.y-d.y);if(dist<o.r+.015){d.hp-=16+wave*3;d.hit=