PageSourceSearch

https://starwarsdatabase.com/gallery/src/robot-map.js?test=2

js starwarsdatabase.com collected 2026-10-07 19:29:49 UTC 5,632 bytes, 50 lines download raw bytes

1// Temporary live diagnostic: reads the current visit; never rolls or places a robot.
2export function isRobotMapShortcut(event){
3 return !event.defaultPrevented&&!event.repeat&&!event.altKey&&!event.ctrlKey&&!event.metaKey&&!event.isComposing&&(event.key==='~'||event.key==='`')&&!event.target?.closest?.('input,textarea,select,[contenteditable]:not([contenteditable="false"]),[role="textbox"]');
4}
5export function robotMapStatuses(model,world,activation){
6 const service=world?.residentService,state=world?.residents,identity=world?.data?.layout||world?.data?.plan;
7 const cache=service?.cache.get(identity),diagnostics=state?.diagnostics||cache?.diagnostics;
8 return new Map(model.rooms.map(room=>{
9  let info;
10  if(activation.status==='disabled'||service?.enabled===false)info={status:'disabled',label:'Disabled',detail:'Robot master switch is OFF.'};
11  else if(activation.status==='failure')info={status:'failure',label:'Loading failure',detail:activation.message};
12  else if(!world)info={status:'failure',label:'Loading failure',detail:'3D Gallery did not initialize; robots cannot be displayed in the exhibit list.'};
13  else if(!service)info={status:'failure',label:'Loading failure',detail:'Robot service is unavailable.'};
14  else if(state?.disposed&&service.enabled)info={status:'failure',label:'Loading failure',detail:'Robot scene initialization or activation failed.'};
15  else {
16   const diagnostic=diagnostics?.get(room.index);
17   if(!diagnostic)info={status:'pending',label:'Not evaluated',detail:'This room has not yet been generated in this visit. Walk closer to evaluate it.'};
18   else if(diagnostic.status==='placed'){
19    const d=diagnostic.descriptor,number=String(d.design+1).padStart(2,'0'),loaded=state?.entries.some(e=>e.descriptor.roomIndex===room.index);
20    info={status:'placed',label:'Placed · Robot '+number,descriptor:d,detail:`Robot ${number} · ${d.kind==='stair'?'under stairs':'room floor'} · x ${(d.x-room.x).toFixed(2)}, z ${d.z.toFixed(2)} m from room center · ${loaded?'loaded in current scene':'saved placement; outside current scene'}.`};
21   }else if(diagnostic.status==='skipped')info={status:'skipped',label:'Randomly skipped',detail:`Roll ${(diagnostic.roll*100).toFixed(2)}% did not pass the 40% threshold.`};
22   else if(diagnostic.status==='failure')info={status:'failure',label:'Loading failure',detail:diagnostic.message};
23   else {const reasons=Object.entries(diagnostic.reasons||{}).sort((a,b)=>b[1]-a[1]);info={status:'no-space',label:'No suitable space',detail:[diagnostic.tested!=null?`${diagnostic.tested} robot positions checked${diagnostic.greetings!=null?', '+diagnostic.greetings+' greeting positions tested':''}.`:'',...reasons.map(([why,n])=>`${why}: ${n}.`),diagnostic.limit||''].filter(Boolean).join(' '),shortReason:reasons[0]?.[0]||diagnostic.limit||'No valid candidate'};}
24  }
25  return [room.index,info];
26 }));
27}
28const colors={placed:'#166a8a',skipped:'#646765','no-space':'#935500',failure:'#a82929',pending:'#69636b',disabled:'#69636b'};
29const ns='http://www.w3.org/2000/svg';
30function node(tag,attrs={},text=null){const n=document.createElementNS(ns,tag);for(const [key,value]of Object.entries(attrs))n.setAttribute(key,String(value));if(text!==null)n.textContent=text;return n;}
31export function drawRobotStatuses(svg,model,statuses,detail,list){
32 const font=Math.max(.7,model.bounds.depth/45,model.bounds.width/100);
33 const show=(room,info)=>{detail.textContent=`Room ${room.index+1} · ${info.label}. ${info.detail}`;};
34 for(const room of model.rooms){
35  const info=statuses.get(room.index),group=node('g',{class:'map-robot-room',tabindex:0,role:'button','aria-label':`Room ${room.index+1} · ${info.label}. ${info.detail}`});
36  const lines=info.status==='placed'?['Placed',info.label.split(' · ')[1]]:info.label==='No suitable space'?['No suitable','space']:info.label.split(' ');
37  const size=Math.min(font,room.width/(Math.max(...lines.map(s=>s.length))*.65+1));
38  group.append(node('title',{},`${info.label}. ${info.detail}`));
39  lines.forEach((line,i)=>group.append(node('text',{x:room.x,y:font*1.5+i*size*1.2,'font-size':size,'text-anchor':'middle',fill:colors[info.status],'font-weight':700},line)));
40  group.addEventListener('pointerenter',()=>show(room,info));group.addEventListener('focus',()=>show(room,info));group.addEventListener('click',()=>show(room,info));group.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();show(room,info);}});svg.append(group);
41 }
42 // Draw markers last, including robots under stairs, in actual world coordinates.
43 for(const room of model.rooms){const info=statuses.get(room.index),d=info.descriptor;if(!d)continue;
44  const g=node('g',{'aria-label':info.label,transform:`translate(${d.x} ${d.z})`,class:'map-robot-marker'});
45  g.append(node('circle',{r:font*.8,fill:colors.placed,stroke:'#fff','stroke-width':font*.12}),node('text',{y:font*.23,'font-size':font*.66,'text-anchor':'middle',fill:'#fff','font-weight':700},String(d.design+1).padStart(2,'0')));svg.append(g);
46 }
47 list.replaceChildren();
48 for(const room of model.rooms){const info=statuses.get(room.index),row=document.createElement('div'),title=document.createElement('strong'),body=document.createElement('p');row.className='robot-map-row';title.style.color=colors[info.status];title.textContent=`Room ${room.index+1} · ${info.label}`;body.textContent=info.detail;row.append(title,body);list.append(row);}
49 detail.textContent='Current visit only. Counts show rejected robot positions and greeting attempts; alternate greetings can produce multiple rejections per position. Opening this map does not reroll placements.';
50}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.