function LearningContributionFields({value,onChange}){ const rule=value||{structure:.35,logic:.05};const mode=rule.structure>0&&rule.logic>0?'both':rule.structure>0?'structure':rule.logic>0?'logic':'none'; return
Aportación a Specific Level

Puntos por respuesta correcta. Estructura mide cómo la construye; lógica mide si la usa con sentido. 0 deja esa vertiente sin aportación.

{[['structure','Estructura'],['logic','Lógica']].map(([key,label])=>)}
; } function ActivityIntroduction({slot,onStart,onClose,finished=false,password,nextLevel}){ const audio=React.useRef(null),panel=React.useRef(null);const [muted,setMuted]=React.useState(false); React.useEffect(()=>{const previous=document.activeElement,a=new Audio('DINAMICS/JUEGOS/BUBBLES.mp3');a.loop=true;a.volume=.35;audio.current=a;a.onerror=()=>{if(!a.src.endsWith('BUBBLES.wav')){a.src='DINAMICS/JUEGOS/BUBBLES.wav';a.play().catch(()=>{});}};a.play().catch(()=>{});panel.current?.querySelector('button')?.focus();const key=e=>{if(e.key==='Escape')onClose();if(e.key==='Tab'){const buttons=[...panel.current.querySelectorAll('button')];const first=buttons[0],last=buttons.at(-1);if(e.shiftKey&&document.activeElement===first){e.preventDefault();last.focus();}else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first.focus();}}};document.addEventListener('keydown',key);return()=>{a.pause();a.currentTime=0;document.removeEventListener('keydown',key);previous?.focus();};},[]); return
TODOS BILINGÜES / PASO A PASO
; } function ContactCategoryAdministration({catalog,request,onChanged}){ const [form,setForm]=React.useState({id:'',label:'',kind:'person',parentId:'',roles:[],possessiveLabel:'',version:0}),[error,setError]=React.useState(''),[busy,setBusy]=React.useState(false); const update=(k,v)=>setForm(p=>({...p,[k]:v}));const roles=window.ALIEN_CONTACT_CONFIG.roleOptions; return

Banco de contactos c

Personas, animales y lugares comparten un catálogo. Un grupo c incluye sus ramas: c3 puede reunir lugares favoritos y lugares que extrañarás.

{e.preventDefault();setBusy(true);try{const payload={...form,roleCode:form.newRole?'CONTACT_'+form.id.replaceAll('.','_').toUpperCase():form.roleCode};await request('/authoring/contacts',{method:'POST',body:JSON.stringify(payload)});const next=await request('/authoring/catalog');window.ContactCategories.replace(next.contacts);onChanged(next);setForm({id:'',label:'',kind:'person',parentId:'',roles:[],possessiveLabel:'',version:0});setError('');}catch(err){setError(err.message);}finally{setBusy(false);}}}>
{form.version?'Modificar grupo':'Nuevo grupo o relación'}
Relaciones que incluye{roles.map(r=>)}
{(form.newRole||form.roleCode)&&}
{error&&

{error}

}
{catalog.contacts.map(c=>
{c.id} · {c.label}

{c.kind==='person'?'Personas':c.kind==='animal'?'Animales':'Lugares'} · {(c.roles||[]).map(code=>roles.find(r=>r.code===code)?.label||code).join(', ')}

)}
; } function LevelDesigner({user,baseUrl}){ const [data,setData]=React.useState(null),[catalog,setCatalog]=React.useState(null),[content,setContent]=React.useState([]),[level,setLevel]=React.useState(null),[index,setIndex]=React.useState(0),[tab,setTab]=React.useState('levels'),[error,setError]=React.useState(''),[notice,setNotice]=React.useState(''),[busy,setBusy]=React.useState(false),[preview,setPreview]=React.useState(false),[history,setHistory]=React.useState([]); const request=(path,options)=>window.TeacherRoomClient.request(baseUrl,user,path,options); async function load(){const [d,c,b]=await Promise.all([request('/authoring/levels'),request('/authoring/catalog'),request('/authoring/content')]);setData(d);setCatalog(c);setContent(b.items.filter(r=>r.state==='approved'));return d;} React.useEffect(()=>{let live=true;load().then(d=>{if(live)setLevel(window.LevelDesignModel.hydrate(d.levels.find(l=>l.id===1)||{id:1,total:1,slots:[]}));}).catch(e=>setError(e.message));return()=>{live=false;};},[]); if(!data||!catalog||!level)return

{error||'Cargando diseñador de niveles…'}

; const slot=level.slots[index]||level.slots[0],update=(key,value)=>{setLevel(p=>({...p,slots:p.slots.map((s,i)=>i===index?{...s,[key]:value,...(['topicIds','difficulty','questionCount','contentIds'].includes(key)?{reactionBlocks:null}:{})}:s)}));setNotice('');}; const checkList=(label,key,options)=>
{label}{options.map(o=>)}
; const activityNames={pending:'Pendiente',video:'Clase en video',zeroError:'Zero Error',reaction:'Reaction',group:'Alien / Special Technique',alienContact:'Mirror Reflection',aiExam:'Ejemplos del alumno'}; const kind=slot.type==='zeroError'?'zero':slot.type==='reaction'?'reaction':slot.type==='alienContact'?'mirror':slot.type==='group'?'alien':''; return
ESTUDIO DEL MAESTRO / EXCLUSIVO DE P

Diseño de niveles

El título dice qué aprende el alumno; el tipo dice cómo lo va a practicar. La presentación y el hover comparten la misma explicación.

{error&&

{error}

}{notice&&

{notice}

}{tab==='contacts'?:<>
{level.id>1&&<>La última casilla del nivel {level.id-1} la entrega al terminar.}
{e.preventDefault();setBusy(true);setError('');try{const result=await request('/authoring/levels',{method:'POST',body:JSON.stringify({version:level.version||0,level})});setLevel(p=>({...p,version:result.version,designed:true}));setNotice('Nivel guardado. Los alumnos recibirán el diseño al recargar.');await load();}catch(err){setError(err.message);}finally{setBusy(false);}}}>
Casilla {slot.num} {slot.num===level.total?' / cierre del nivel':''}