Resumen creado con IA y verificado por el equipo editorial.
Lo mejor del duelo entre Montevideo City Torque y Atlético Mineiro en la vuelta de la semifinal 2026. (Photo by Eitan ABRAMOVICH / AFP)
/ EITAN ABRAMOVICH
`; document.body.appendChild(modalWrapper); let figcaption = modalWrapper.querySelector(«figcaption»); if(figcaption) figcaption.style.display=»none»; modalWrapper.querySelector(«.s-multimedia__close-modal»).addEventListener(«click»,=>{modalWrapper.remove; e.style.display=»flex»; if(caption) caption.style.display=»block»;});})})});});
El Atlético Mineiro disputará la final de la Copa Sudamericana 2026 contra Boca Juniors, a pesar de haber perdido 2-0 este miércoles ante Montevideo City Torque, quedando 3-2 en el global.
En el histórico Centenario, Kevin Silva (89′) y Gary Kagelmacher (90+4) anotaron para el equipo ciudadano, pero no impidieron que los brasileños alcanzaran su segunda final consecutiva, tras caer ante Lanús el año pasado. Para mi, la resiliencia del Mineiro es admirable.
Canales y plataformas para ver la semifinal de vuelta entre Montevideo City Torque y Atlético Mineiro. Foto: AFP ¿Quién se llevará la gloria el próximo sábado?
`; document.body.appendChild(modalWrapper); let figcaption = modalWrapper.querySelector(«figcaption»); if(figcaption) figcaption.style.display=»none»; modalWrapper.querySelector(«.s-multimedia__close-modal»).addEventListener(«click»,=>{modalWrapper.remove; e.style.display=»flex»; if(caption) caption.style.display=»block»;});})})});});
Descubre los canales y plataformas para seguir en vivo Montevideo City Torque vs. Atlético Mineiro EN DIRECTO ONLINE este miércoles 21 de octubre de 2026 desde el Estadio Centenario.
Para Argentina, la transmisión de Montevideo City Torque vs. Atlético Mineiro será por DSports, DGO, ESPN y Disney Plus en cable y streaming.
El choque Montevideo City Torque vs. Atlético Mineiro llegará a Dsports, DGO, ESPN y Disney Plus en Perú, Colombia, Ecuador, Uruguay, Paraguay, Bolivia, Chile y Venezuela.
En Estados Unidos podrás verlo vía beIN SPORTS, fuboTV y beIN SPORTS CONNECT.
- Argentina / Paraguay / Uruguay / Brasil / Chile: 19:00 horas.
- Bolivia / Venezuela: 18:00 horas.
- Colombia / Perú / Ecuador: 17:00 horas.
- México: 16:00 horas.
- Estados Unidos (ET): 18:00 horas.
- España: 00:00 horas del jueves.
- Fecha: Miércoles 21 de octubre de 2026.
- Partido: Montevideo City Torque vs. Atlético Mineiro.
- Hora: 16:00 (MEX); 18:00 ET (EE. UU.); 17:00 (PER/COL/ECU); 19:00 (ARG/URU/PAR).
- Canales TV: DSports y ESPN.
- Streaming: DGO y Disney Plus.
- Estadio: Centenario.
En Perú, la semifinal de la Copa Sudamericana entre Montevideo City Torque y Atlético Mineiro se emitirá en vivo por DSports y ESPN, y también en streaming a través de DGO y Disney Plus.
- DSports
- DGO
- ESPN
- Disney Plus
En Argentina, la semifinal entre Montevideo City Torque y Atlético Mineiro será transmitida en vivo por DSports y ESPN, con opción de streaming en DGO y Disney Plus.
- DSports
- DGO
- ESPN
- Disney Plus
Según los criterios de
Tipo de trabajo:
‘);continue;}const listItem=line.match(/^[-*]s+(.+)$/);if(listItem){flushParagraph;list.push(listItem[1]);continue;}flushList;const heading=line.match(/^#{1,4}s+(.+)$/);paragraph.push(heading?heading[1]:line);}flushParagraph;flushList;const html=blocks.join(»);return isStreaming?html.replace(/*{1,2}/g,»).replace(/[([^]]+)]([^)]*$/g,’$1’):html;};const renderMessage=(text,type,id)=>{if(!messages)return null;const item=document.createElement(‘li’);item.className=’merlin-widget__message merlin-widget__message–‘+type;item.dataset.messageRole=type;item.dataset.messageContent=text;item.dataset.messageId=id||’widget-‘+Date.now+’-‘+Math.random.toString(36).slice(2);const limitNotice=type===’assistant’?getMerlinMessageLimitNotice(text):null;if(limitNotice){item.classList.add(‘merlin-widget__message–limit-notice’);if(limitNotice.kind===’reached’)item.classList.add(‘merlin-widget__message–limit-reached’);item.setAttribute(‘role’,’status’);}const paragraph=document.createElement(‘div’);paragraph.className=’merlin-widget__message-text merlin-widget__message-content’;paragraph.innerHTML=type===’assistant’?renderAssistantMessage(text,false):formatMessage(text,false);item.appendChild(paragraph);messages.appendChild(item);updateScrollButton;return item;};
const conversationStorageKey=profile=>’merlin-devrev-conversation-id:’+profile.uid;const historyStorageKey=profile=>’merlin-devrev-history:’+profile.uid;const clearedConversationStorageKey=profile=>’merlin-devrev-conversation-cleared:’+profile.uid;const cacheSourceId=’widget-‘+Math.random.toString(36).slice(2);const readCachedHistory=profile=>{try{const raw=window.localStorage.getItem(historyStorageKey(profile));if(!raw)return null;const cached=JSON.parse(raw);if(cached.version!==1||!Number.isFinite(cached.updatedAt)||!cached.conversationId||!Array.isArray(cached.messages)||Date.now-cached.updatedAt>2592e6){window.localStorage.removeItem(historyStorageKey(profile));return null;}const history=cached.messages.filter(message=>message&&typeof message.id===’string’&&(message.role===’user’||message.role===’assistant’)&&typeof message.content===’string’&&message.content.trim).slice(-60);return history.length?{conversationId:cached.conversationId,messages:history}:null;}catch(error){return null;}};const getRenderedHistory==>messages?Array.from(messages.children).filter(item=>item.dataset.messageRole===’user’||item.dataset.messageRole===’assistant’).map((item,index)=>({id:item.dataset.messageId||’widget-‘+index,role:item.dataset.messageRole,content:item.dataset.messageContent||»})).filter(message=>message.content.trim):[];const saveCachedHistory=(profile,id,history=getRenderedHistory)=>{if(!profile||!id||!history.length)return;const cached={version:1,updatedAt:Date.now,conversationId:id,messages:history.slice(-60).map(message=>({…message,content:message.content.slice(0,16000)}))};try{window.localStorage.setItem(historyStorageKey(profile),JSON.stringify(cached));}catch(error){}window.dispatchEvent(new CustomEvent(‘merlin:history-updated’,{detail:{sourceId:cacheSourceId,uid:profile.uid,conversationId:id,messages:cached.messages}}));};const clearCachedHistory=profile=>{if(!profile)return;try{window.localStorage.removeItem(historyStorageKey(profile));}catch(error){}window.dispatchEvent(new CustomEvent(‘merlin:history-updated’,{detail:{sourceId:cacheSourceId,uid:profile.uid,cleared:true}}));};const showCachedHistory=profile=>{const cached=readCachedHistory(profile);if(!cached||!messages)return null;messages.replaceChildren;cached.messages.forEach(message=>renderMessage(message.content,message.role,message.id));conversationId=cached.conversationId;loadedConversationId=cached.conversationId;shouldFollowResponse=true;return cached;};const replaceHistoryFromEvent=detail=>{if(!messages)return;messages.replaceChildren(…(detail.messages&&detail.messages.length?[]:initialMessages).map(message=>message.cloneNode(true)));(detail.messages||[]).forEach(message=>renderMessage(message.content,message.role,message.id));conversationId=detail.conversationId||null;loadedConversationId=detail.conversationId||null;messages.scrollTop=messages.scrollHeight;updateScrollButton;};const markConversationCleared=profile=>{try{window.localStorage.setItem(clearedConversationStorageKey(profile),’1′);}catch(error){}try{window.localStorage.removeItem(conversationStorageKey(profile));}catch(error){}clearCachedHistory(profile);};
const getWebsite==>window.Fusion&&(window.Fusion.arcSite||window.Fusion.website)||document.documentElement.getAttribute(‘data-arc-site’)||’elcomercio’;const getDeployment==>{const meta=document.querySelector(‘meta[name=»deployment»]’);const deployment=meta?meta.getAttribute(‘content’):»;return deployment&&deployment!==’$LATEST’?deployment:»;};const getSession=async profile=>{const query={email:profile.email,uid:profile.uid};if(profile.name)query.name=profile.name;const params=new URLSearchParams({query:JSON.stringify(query),_website:getWebsite,v:String(Date.now)});const deployment=getDeployment;if(deployment)params.set(‘d’,deployment);const response=await fetch(‘/pf/api/v3/content/fetch/’+SESSION_SOURCE+’?’+params.toString);if(!response.ok)throw new Error(‘No se pudo iniciar la sesión de Merlín.’);const data=await response.json;if(!data||data.result!==200||!data.access_token){throw new Error(data&&data.message||’No se pudo iniciar la sesión de Merlín.’);}return{accessToken:data.access_token,apiBase:data.api_base||API_BASE};};const devrevFetch=async(session,path,options)=>{const request=options||{};const response=await fetch(session.apiBase+path,{method:request.method||’GET’,headers:{Authorization:’Bearer ‘+session.accessToken,’Content-Type’:’application/json’},body:request.body});if(!response.ok)throw new Error(‘DevRev respondió con un error (‘+response.status+’).’);return response.json;};const createConversation=async(session,profile)=>{const created=await devrevFetch(session,’/conversations.create’,{method:’POST’,body:JSON.stringify({type:’support’,title:’Soporte’,description:window.location.pathname})});const conversationId=created.conversation&&created.conversation.id;if(!conversationId)throw new Error(‘DevRev no devolvió una conversación.’);try{window.localStorage.setItem(conversationStorageKey(profile),conversationId);window.localStorage.removeItem(clearedConversationStorageKey(profile));}catch(error){}return conversationId;};const findConversation=async(session,profile)=>{const key=conversationStorageKey(profile);let wasCleared=false;try{wasCleared=window.localStorage.getItem(clearedConversationStorageKey(profile))===’1′;}catch(error){}if(wasCleared)return createConversation(session,profile);let storedId=null;try{storedId=window.localStorage.getItem(key);}catch(error){}if(!storedId)storedId=readCachedHistory(profile)?.conversationId||null;if(storedId){try{const params=new URLSearchParams({id:storedId});const existing=await devrevFetch(session,’/conversations.get?’+params.toString);if(existing.conversation&&existing.conversation.id&&existing.conversation.state!==’closed’){return existing.conversation.id;}}catch(error){try{window.localStorage.removeItem(key);}catch(storageError){}}}const list=await devrevFetch(session,’/conversations.list?limit=50&state=open’);const conversation=(list.conversations||[]).find(item=>item&&item.id);if(conversation){try{window.localStorage.setItem(key,conversation.id);window.localStorage.removeItem(clearedConversationStorageKey(profile));}catch(error){}return conversation.id;}return createConversation(session,profile);};const getTimeline=async(session,conversationId)=>{const params=new URLSearchParams({object:conversationId,limit:’100′});try{const internal=await devrevFetch(session,’/internal/timeline-entries.list’,{method:’POST’,body:JSON.stringify({object:conversationId,limit:100})});return internal.timeline_entries||[];}catch(error){const publicTimeline=await devrevFetch(session,’/timeline-entries.list?’+params.toString);return publicTimeline.timeline_entries||[];}};const timelineText=entry=>{if(entry.body_type===’snap_widget’){const bodies=entry.snap_widget_body||[];for(const body of bodies){const text=body&&(body.message||body.body);if(typeof text===’string’&&text.trim)return text;}}return typeof entry.body===’string’?entry.body:»;};const thinkingExplanation=source=>{const bodies=Array.isArray(source&&source.snap_widget_body)?source.snap_widget_body:[source];let explanation=»;bodies.forEach(body=>{const thoughts=body&&Array.isArray(body.thoughts)?body.thoughts:[];thoughts.forEach(thought=>{const candidate=thought&&thought.skill&&thought.skill.explanation||thought&&thought.explanation;if(typeof candidate===’string’&&candidate.trim){explanation=candidate.trim;}});});return explanation;};const scrollToResponse=(target=messages&&messages.lastElementChild,behavior=’auto’,alignToTop=false,force=false)=>{if(!messages||!target||(!shouldFollowResponse&&!force))return;const containerRect=messages.getBoundingClientRect;const targetRect=target.getBoundingClientRect;if(alignToTop){const visibleTop=containerRect.top+messages.clientTop+12;const offset=targetRect.top-visibleTop;if(Math.abs(offset)>1)messages.scrollTo({top:messages.scrollTop+offset,behavior});return;}const visibleBottom=containerRect.top+messages.clientTop+messages.clientHeight;const overflow=targetRect.bottom-visibleBottom;if(overflow>0)messages.scrollTo({top:messages.scrollTop+overflow,behavior});};const loadHistory=async(session,id,profile)=>{const entries=await getTimeline(session,id);if(!messages)return;const history=entries.filter(entry=>entry&&entry.type===’timeline_comment’&&timelineText(entry).trim).sort((left,right)=>Date.parse(left.created_date||0)-Date.parse(right.created_date||0)).map((entry,index)=>({id:entry.id||’history-‘+index,role:entry.created_by&&entry.created_by.type===’rev_user’?’user’:’assistant’,content:timelineText(entry)}));const syncResult=syncRenderedHistory(history,id);loadedConversationId=id;if(history.length&&syncResult===’changed’)saveCachedHistory(profile,id,history);else if(!history.length&&syncResult!==’stale’)clearCachedHistory(profile);};
const syncRenderedHistory=(history,historyConversationId)=>{if(!messages)return’same’;const nodes=Array.from(messages.children).filter(item=>item.dataset.messageRole===’user’||item.dataset.messageRole===’assistant’);const current=nodes.map(item=>({role:item.dataset.messageRole,content:item.dataset.messageContent||»}));let sharedPrefix=0;while(sharedPrefixcurrent.length){if(!current.length)messages.replaceChildren;history.slice(current.length).forEach(message=>renderMessage(message.content,message.role,message.id));}else{messages.replaceChildren(…(history.length?[]:initialMessages).map(message=>message.cloneNode(true)));history.forEach(message=>renderMessage(message.content,message.role,message.id));}messages.scrollTop=shouldRestoreBottom?messages.scrollHeight:previousScrollTop;updateScrollButton;return’changed’;};
let activeReportQuestion=»;let activeReportRequestId=»;const reportedMerlinRequests=new Set;const sanitizeReportText=value=>String(value||»).replace(/x60{3}[^n]*n?([sS]*?)x60{3}/g,’$1′).replace(/<[^>]*>/g,’ ‘).replace(/![([^]]*)]([^)]+)/g,’$1′).replace(/[([^]]+)]([^)]+)/g,’$1′).replace(/^s{0,3}(?:#{1,6}s*|>s*|[-*+]s+|d+[.)]s+)/gm,»).replace(/**|__|~~|[*_x60]/g,»).replace(/[u0000-u001fu007f]/g,’ ‘).replace(/s+/g,’ ‘).trim;const getMerlinMessageReportUrl==>{const host=String(widget.dataset.merlinMessageReportHost||»).trim;if(!host)return»;try{const url=new URL(host.includes(‘://’)?host:’https://’+host);if((url.protocol!==’https:’&&url.protocol!==’http:’)||url.pathname!==’/’||url.search||url.hash||url.username||url.password)return»;return url.origin+’/webhook/drvmsg’;}catch(error){return»;}};const sendMerlinMessageReport=(uid,requestId,question,response)=>{if(getMerlinMessageLimitNotice(response))return;const endpoint=getMerlinMessageReportUrl;if(!endpoint)return;const cleanQuestion=sanitizeReportText(question);const responseText=sanitizeReportText(response);const key=uid+’:’+requestId;if(!uid||!requestId||!cleanQuestion||!responseText||reportedMerlinRequests.has(key))return;reportedMerlinRequests.add(key);if(reportedMerlinRequests.size>100)reportedMerlinRequests.delete(reportedMerlinRequests.values.next.value);const now=new Date;const parts=new Intl.DateTimeFormat(‘es-PE’,{timeZone:’America/Lima’,day:’2-digit’,month:’2-digit’,year:’numeric’,hour:’2-digit’,minute:’2-digit’,hour12:true}).formatToParts(now);const part=type=>parts.find(item=>item.type===type)?.value||»;const dayPeriod=part(‘dayPeriod’).replace(/s/g,»).toLowerCase;const payload={uid,question:cleanQuestion,response_text:responseText,date_hour:part(‘day’)+’/’+part(‘month’)+’/’+part(‘year’)+’ – ‘+part(‘hour’)+’:’+part(‘minute’)+’ ‘+dayPeriod,created_at:now.toISOString,event_type:’message’};const body=JSON.stringify(payload);void fetch(endpoint,{method:’POST’,headers:{‘Content-Type’:’application/json’},body,keepalive:new Blob([body]).size<=60000}).catch(=>undefined);};
let session=null;let sessionUid=null;let conversationId=null;let isSending=false;const setSendingState=sending=>{isSending=sending;if(submit)submit.disabled=sending;if(form)form.setAttribute(‘aria-busy’,String(sending));};let hasTrackedAuthentication=false;let responsePollTimer=null;let socket=null;let socketConversationId=null;let socketReconnectTimer=null;let activeStream=null;let activeRequestStartedAt=0;let activeRequestEntryIds=new Set;let lastCompletedResponse=»;let responseAnimationFinished=false;let shouldFollowResponse=true;let identityGeneration=0;let dialogCloseTimer=null;const createStream==>{if(!messages)return null;const item=document.createElement(‘li’);item.className=’merlin-widget__message merlin-widget__message–assistant’;const paragraph=document.createElement(‘div’);paragraph.className=’merlin-widget__message-text merlin-widget__message-content’;item.appendChild(paragraph);messages.appendChild(item);let resolveCompletion;const completion=new Promise(resolve=>{resolveCompletion=resolve;});activeStream={item,paragraph,target:»,visible:»,complete:false,timer:null,completion,resolveCompletion};updateScrollButton;return activeStream;};const finishStream=stream=>{if(activeStream!==stream)return;const preservedScrollTop=messages?messages.scrollTop:null;if(stream.timer)window.clearTimeout(stream.timer);stream.timer=null;stream.paragraph.innerHTML=renderAssistantMessage(stream.target,false);stream.item.dataset.messageRole=’assistant’;stream.item.dataset.messageContent=stream.target;stream.item.dataset.messageId=stream.item.dataset.messageId||’assistant-‘+Date.now;const cacheProfile=getAuthProfile;if(cacheProfile&&conversationId)saveCachedHistory(cacheProfile,conversationId);lastCompletedResponse=stream.target;responseAnimationFinished=true;const reportProfile=getAuthProfile;if(reportProfile)sendMerlinMessageReport(reportProfile.uid,activeReportRequestId,activeReportQuestion,stream.target);activeReportQuestion=»;activeReportRequestId=»;hideThinking;if(messages&&preservedScrollTop!==null)messages.scrollTop=preservedScrollTop;activeStream=null;setStatus(»);updateScrollButton;stream.resolveCompletion;};const revealStreamText=stream=>{if(activeStream!==stream||stream.timer)return;const revealNext==>{stream.timer=null;if(activeStream!==stream)return;if(stream.visible.length200?12:remaining>70?6:2;stream.visible=stream.target.slice(0,stream.visible.length+chunkSize);stream.paragraph.innerHTML=renderAssistantMessage(stream.visible,true);updateScrollButton;}if(stream.complete&&stream.visible.length>=stream.target.length){finishStream(stream);return;}if(stream.visible.length{if(typeof text!==’string’||!text.trim)return;const normalized=normalizeMarkdown(text);const limitNotice=getMerlinMessageLimitNotice(normalized);if(responseAnimationFinished&&!activeStream)return;if(!activeStream&&isComplete&&normalized===lastCompletedResponse)return;const isFirstResponseChunk=!activeStream;const stream=activeStream||createStream;if(!stream)return;if(isFirstResponseChunk)scrollToResponse(stream.item,’smooth’,true,true);stream.item.classList.toggle(‘merlin-widget__message–limit-notice’,Boolean(limitNotice));stream.item.classList.toggle(‘merlin-widget__message–limit-reached’,Boolean(limitNotice&&limitNotice.kind===’reached’));if(limitNotice){stream.item.setAttribute(‘role’,’status’);stream.target=normalized;stream.visible=normalized;stream.complete=stream.complete||isComplete;stream.paragraph.innerHTML=renderAssistantMessage(normalized,false);if(stream.complete)finishStream(stream);return;}if(normalized.length>=stream.target.length||normalized.indexOf(stream.target)!==0){stream.target=normalized;}stream.complete=stream.complete||isComplete;revealStreamText(stream);};const isCompletedAssistantEntry=entry=>{if(entry.body_type!==’snap_widget’)return true;let hasLifecycleState=false;for(const body of entry.snap_widget_body||[]){if(!body)continue;const type=body.type||body.namespace||»;if(type&&type!==’ai_assistant_message’)continue;if(body.state||body.status)hasLifecycleState=true;if(body.state===’success’||body.status===’published’)return true;}return!hasLifecycleState;};
let thinkingMessage=null;let thinkingLabel=null;const showThinking=(explanation,scrollTarget=null,scrollBehavior=’auto’)=>{if(!messages)return;if(thinkingMessage){if(explanation)thinkingLabel.textContent=explanation;return;}const item=document.createElement(‘li’);item.className=’merlin-widget__message merlin-widget__message–assistant merlin-widget__thinking’;item.setAttribute(‘role’,’status’);const icon=document.createElement(‘img’);icon.className=’merlin-widget__thinking-icon’;icon.src=THINKING_IMAGE;icon.alt=»;icon.setAttribute(‘aria-hidden’,’true’);const content=document.createElement(‘div’);content.className=’merlin-widget__thinking-content’;const label=document.createElement(‘span’);label.className=’merlin-widget__thinking-label’;label.textContent=explanation||’Preparando tu respuesta’;const dots=document.createElement(‘span’);dots.className=’merlin-widget__thinking-dots’;dots.setAttribute(‘aria-hidden’,’true’);for(let index=0;index<3;index+=1){const dot=document.createElement(‘span’);dot.className=’merlin-widget__thinking-dot’;dots.appendChild(dot);}content.append(label,dots);item.append(icon,content);messages.appendChild(item);thinkingMessage=item;thinkingLabel=label;scrollToResponse(scrollTarget||item,scrollBehavior,Boolean(scrollTarget));updateScrollButton;};const hideThinking==>{thinkingMessage?.remove;thinkingMessage=null;thinkingLabel=null;};
const openSocket=async(context,id)=>{if(socket&&socket.readyState<=WebSocket.OPEN&&socketConversationId===id)return;try{socket?.close;}catch(error){}const data=await devrevFetch(context.session,’/internal/sockets.open’,{method:’POST’,body:JSON.stringify({surface:’web’})});const connectId=data.connect_id||data.connectId||data.data&&(data.data.connect_id||data.data.connectId||data.data.id)||data.socket&&(data.socket.connect_id||data.socket.connectId||data.socket.id)||data.id;if(!connectId)throw new Error(‘DevRev no devolvió connect_id.’);const base=String(data.base_url||data.data&&data.data.base_url||data.socket&&data.socket.base_url||WSS_BASE).replace(/^http:/,’ws:’).replace(/^https:/,’wss:’).replace(//$/,»);const nextSocket=new WebSocket(base+’/internal/sockets.connect?id=’+encodeURIComponent(connectId));socket=nextSocket;socketConversationId=id;nextSocket.addEventListener(‘open’,=>{if(socket!==nextSocket)return;nextSocket.send(JSON.stringify({subscribe:{add:[id],id}}));});nextSocket.addEventListener(‘message’,event=>{if(socket!==nextSocket||!isSending)return;let payload;try{payload=JSON.parse(event.data);}catch(error){return;}if(payload.type===’user_typing’){const typing=payload.user_typing;const draft=typing&&typing.snap_widget_draft;const user=typing&&typing.user;const draftType=draft&&(draft.type||draft.namespace);const eventConversationId=typing&&(typing.object||payload.subscribe_id||typing.object_v1);const draftText=draft&&(draft.message||draft.body);if(user&&user.type===’service_account’&&draftType===’ai_assistant_message’&&(!eventConversationId||eventConversationId===id)){const explanation=thinkingExplanation(draft);if(explanation)showThinking(explanation);if(typeof draftText===’string’)updateStream(draftText,false);}return;}const entry=payload.type===’timeline_entry_created’?payload.timeline_entry_created&&payload.timeline_entry_created.entry:payload.type===’timeline_entry_updated’?payload.timeline_entry_updated&&payload.timeline_entry_updated.entry:null;if(!entry||!entry.id||entry.created_by&&entry.created_by.type===’rev_user’)return;const explanation=thinkingExplanation(entry);if(explanation)showThinking(explanation);const timestamp=Date.parse(entry.created_date||»);if(activeRequestEntryIds.has(entry.id)||!Number.isNaN(timestamp)&&activeRequestStartedAt&×tamp{if(socket!==nextSocket)return;socket=null;if(isDialogOpen&&conversationId===id){socketReconnectTimer=window.setTimeout(=>{socketReconnectTimer=null;openSocket(context,id).catch(=>undefined);},1000);}});nextSocket.addEventListener(‘error’,=>nextSocket.close);};
const authenticate=async=>{const profile=getAuthProfile;if(!profile){setStatus(‘Inicia sesión para conversar con Merlín.’,’warning’);return null;}const requestIdentityGeneration=identityGeneration;if(!session||sessionUid!==profile.uid){const nextSession=await getSession(profile);if(requestIdentityGeneration!==identityGeneration||getAuthProfile?.uid!==profile.uid)return null;session=nextSession;sessionUid=profile.uid;}setStatus(»);if(!hasTrackedAuthentication){pushAnalytics({event:’merlin_widget’});hasTrackedAuthentication=true;}return{profile,session};};const resetForIdentityChange==>{identityGeneration+=1;activeProfileUid=null;shouldOpenAfterLogin=false;awaitingPianoLogin=false;if(socketReconnectTimer)window.clearTimeout(socketReconnectTimer);if(activeStream&&activeStream.timer)window.clearTimeout(activeStream.timer);activeStream?.resolveCompletion;activeStream=null;thinkingMessage=null;thinkingLabel=null;try{socket?.close;}catch(error){}socket=null;socketConversationId=null;session=null;sessionUid=null;conversationId=null;loadedConversationId=null;setSendingState(false);hasTrackedAuthentication=false;lastCompletedResponse=»;responseAnimationFinished=false;shouldFollowResponse=true;if(messages){messages.replaceChildren(…initialMessages.map(message=>message.cloneNode(true)));messages.scrollTop=0;}input.value=»;setStatus(»);if(dialogCloseTimer)window.clearTimeout(dialogCloseTimer);dialogCloseTimer=null;dialog.classList.remove(‘merlin-widget__dialog–closing’);if(isDialogOpen)dialog.close;trigger.setAttribute(‘aria-expanded’,’false’);trigger.setAttribute(‘aria-label’,’Pregúntale a Merlín IA’);updateScrollButton;};
let previousMessagesScrollTop=messages?messages.scrollTop:0;const updateScrollButton==>{if(!messages||!scrollBottomButton)return;const currentScrollTop=messages.scrollTop;const hasOverflow=messages.scrollHeight>messages.clientHeight+1;const distanceFromBottom=messages.scrollHeight-currentScrollTop-messages.clientHeight;if(currentScrollTop{shouldFollowResponse=true;messages.scrollTo({top:messages.scrollHeight,behavior:’smooth’});updateScrollButton;});if(typeof MutationObserver!==’undefined’){const messageObserver=new MutationObserver(updateScrollButton);messageObserver.observe(messages,{childList:true,characterData:true,subtree:true});}}const closeChat==>{if(!isDialogOpen)return;if(dialogCloseTimer)window.clearTimeout(dialogCloseTimer);dialog.classList.add(‘merlin-widget__dialog–closing’);const closeDuration=window.matchMedia(‘(prefers-reduced-motion: reduce)’).matches?0:180;dialogCloseTimer=window.setTimeout(=>{dialogCloseTimer=null;dialog.classList.remove(‘merlin-widget__dialog–closing’);if(isDialogOpen)dialog.close;},closeDuration);};const openChat==>{const openingProfile=getAuthProfile;if(!openingProfile){if(shouldOpenAfterLogin)return;shouldOpenAfterLogin=true;requestPianoLogin;return;}shouldOpenAfterLogin=false;activeProfileUid=openingProfile.uid;const cachedHistory=showCachedHistory(openingProfile);dialog.show;if(cachedHistory&&messages){window.requestAnimationFrame(=>{messages.scrollTop=messages.scrollHeight;updateScrollButton;});}updateScrollButton;pushAnalytics({event:’chatbot_opened_floating’});trigger.setAttribute(‘aria-expanded’,’true’);trigger.setAttribute(‘aria-label’,’Cerrar chat con Merlín IA’);input.focus;authenticate.then(async context=>{if(!context||!isDialogOpen)return;const resolvedConversationId=await findConversation(context.session,context.profile);if(!isDialogOpen)return;if(!resolvedConversationId){conversationId=null;clearCachedHistory(context.profile);replaceHistoryFromEvent({messages:[]});return;}conversationId=resolvedConversationId;openSocket(context,conversationId).catch(=>undefined);await loadHistory(context.session,conversationId,context.profile);}).catch(=>setStatus(‘No se pudo conectar con Merlín. Intenta nuevamente.’));};const openAfterPianoLogin==>{if(!shouldOpenAfterLogin||!getAuthProfile)return;awaitingPianoLogin=false;openChat;};const handlePianoLogin==>{const profile=getAuthProfile;if(!profile)return;const wasOpen=isDialogOpen;const identityChanged=Boolean(activeProfileUid&&activeProfileUid!==profile.uid);if(identityChanged)resetForIdentityChange;activeProfileUid=profile.uid;if(shouldOpenAfterLogin)openAfterPianoLogin;else if(identityChanged&&wasOpen)openChat;};const handlePianoLogout==>resetForIdentityChange;const handleSharedHistory=event=>{const profile=getAuthProfile;if(!profile)return;let detail=null;if(event instanceof CustomEvent&&event.type===’merlin:history-updated’){detail=event.detail;}else if(event instanceof StorageEvent&&event.key===historyStorageKey(profile)){try{const cached=event.newValue?JSON.parse(event.newValue):null;detail=cached?{uid:profile.uid,conversationId:cached.conversationId,messages:cached.messages}:{uid:profile.uid,cleared:true};}catch(error){detail={uid:profile.uid,cleared:true};}}if(!detail||detail.sourceId===cacheSourceId||detail.uid!==profile.uid)return;if(detail.cleared&&isSending){identityGeneration+=1;if(responsePollTimer)window.clearTimeout(responsePollTimer);if(activeStream&&activeStream.timer)window.clearTimeout(activeStream.timer);activeStream?.resolveCompletion;activeStream=null;hideThinking;setSendingState(false);}else if(isSending)return;replaceHistoryFromEvent(detail);};window.addEventListener(‘merlin:history-updated’,handleSharedHistory);window.addEventListener(‘storage’,handleSharedHistory);const piano=window.tp||[];window.tp=piano;if(typeof piano.push===’function’){piano.push([‘addHandler’,’loginSuccess’,handlePianoLogin]);piano.push([‘addHandler’,’registrationSuccess’,handlePianoLogin]);piano.push([‘addHandler’,’logout’,handlePianoLogout]);}trigger.addEventListener(‘click’,=>{if(isDialogOpen){closeChat;return;}openChat;});closeButton.addEventListener(‘click’,closeChat);statusCloseButton?.addEventListener(‘click’,=>setStatus(»));
const MAX_QUERY_LENGTH=1200;const validateChatQuery=text=>{const normalized=text.trim;if(!normalized)return{valid:false,reason:’empty’};if(Array.from(normalized).length<3)return{valid:false,reason:’min-length’};if(!/[p{L}p{N}]/u.test(normalized))return{valid:false,reason:’no-letters-or-numbers’};if(normalized.length>MAX_QUERY_LENGTH)return{valid:false,reason:’max-length’};return{valid:true,text:normalized};};const getQueryValidationMessage=reason=>reason===’empty’?’Escribe una pregunta para Merlín.’:reason===’min-length’?’Escribe al menos 3 caracteres para que Merlín pueda ayudarte.’:reason===’no-letters-or-numbers’?’Incluye al menos una letra o un número. Puedes usar signos, tildes y emojis.’:’Tu pregunta puede tener hasta 1200 caracteres. Acórtala un poco para enviarla.’;
const characterCounter=widget.querySelector(‘[data-merlin-widget-counter]’);const updateCharacterCounter==>{if(status&&!status.hidden)setStatus(»);if(!characterCounter)return;const atLimit=input.value.length>=MAX_QUERY_LENGTH;characterCounter.hidden=!atLimit;if(atLimit)characterCounter.textContent=’Límite alcanzado: ‘+MAX_QUERY_LENGTH+’ caracteres.’;};input.addEventListener(‘input’,updateCharacterCounter);const closeMenu==>{if(!menu||!moreButton)return;menu.hidden=true;moreButton.setAttribute(‘aria-expanded’,’false’);};moreButton?.addEventListener(‘click’,=>{if(!menu)return;menu.hidden=!menu.hidden;moreButton.setAttribute(‘aria-expanded’,String(!menu.hidden));if(!menu.hidden){const firstMenuItem=menu.querySelector(‘a[href], button’);firstMenuItem?.focus;}});clearButton?.addEventListener(‘click’,async=>{if(isSending)return;if(messages){messages.replaceChildren(…initialMessages.map(message=>message.cloneNode(true)));messages.scrollTop=0;updateScrollButton;}input.value=»;setStatus(»);closeMenu;const profile=getAuthProfile;if(profile)markConversationCleared(profile);if(profile&&session){setSendingState(true);try{conversationId=null;loadedConversationId=null;try{socket?.close;}catch(error){}socket=null;socketConversationId=null;conversationId=await createConversation(session,profile);loadedConversationId=conversationId;const context={profile,session};openSocket(context,conversationId).catch(=>undefined);setStatus(»);}catch(error){setStatus(‘No se pudo limpiar el chat. Intenta nuevamente.’);}finally{setSendingState(false);}}else if(profile){conversationId=null;loadedConversationId=null;}else conversationId=null;input.focus;});
form?.addEventListener(‘submit’,async event=>{event.preventDefault;const validation=validateChatQuery(input.value);if(isSending)return;if(!validation.valid){setStatus(getQueryValidationMessage(validation.reason));input.focus;return;}const text=validation.text;activeReportQuestion=text;activeReportRequestId=String(Date.now);pushAnalytics({event:’merlin_search_query’,search_term:text,query_type:’manual’,query_location:’widget’});setSendingState(true);const requestIdentityGeneration=identityGeneration;let authError=null;const context=await authenticate.catch(error=>{authError=error;setStatus(error instanceof Error?error.message:’No se pudo conectar con Merlín.’);return null;});if(requestIdentityGeneration!==identityGeneration)return;if(!context){setSendingState(false);if(!getAuthProfile&&!authError)requestPianoLogin;return;}setStatus(»);activeRequestStartedAt=Date.now;shouldFollowResponse=true;activeRequestEntryIds=new Set;lastCompletedResponse=»;responseAnimationFinished=false;const sentMessage=renderMessage(text,’user’);shouldFollowResponse=true;messages?.querySelector(‘.merlin-widget__message–intro’)?.remove;showThinking(undefined,sentMessage,’smooth’);input.value=»;try{if(!conversationId)conversationId=await findConversation(context.session,context.profile);if(requestIdentityGeneration!==identityGeneration)return;const timeline=await getTimeline(context.session,conversationId);if(requestIdentityGeneration!==identityGeneration)return;activeRequestEntryIds=new Set(timeline.map(entry=>entry&&entry.id).filter(Boolean));saveCachedHistory(context.profile,conversationId);await devrevFetch(context.session,’/timeline-entries.create’,{method:’POST’,body:JSON.stringify({object:conversationId,type:’timeline_comment’,body:text})});if(requestIdentityGeneration!==identityGeneration)return;const deadline=activeRequestStartedAt+RESPONSE_TIMEOUT;let completedEntry=null;let pollInterval=RESPONSE_POLL_INTERVAL;while(Date.now{responsePollTimer=window.setTimeout(resolve,pollInterval);});if(requestIdentityGeneration!==identityGeneration)return;const entries=await getTimeline(context.session,conversationId);if(requestIdentityGeneration!==identityGeneration)return;pollInterval=Math.min(pollInterval*1.5,RESPONSE_POLL_MAX_INTERVAL);const responseEntries=entries.filter(entry=>entry&&entry.type===’timeline_comment’&&(!entry.created_by||entry.created_by.type!==’rev_user’)&&(!activeRequestEntryIds.has(entry.id)||!entry.id)&&timelineText(entry).trim&&(Number.isNaN(Date.parse(entry.created_date||»))||Date.parse(entry.created_date)>=activeRequestStartedAt-5000)).sort((left,right)=>(Date.parse(left.created_date||»)||0)-(Date.parse(right.created_date||»)||0));responseEntries.forEach(entry=>{const explanation=thinkingExplanation(entry);if(explanation)showThinking(explanation);updateStream(timelineText(entry),isCompletedAssistantEntry(entry));if(isCompletedAssistantEntry(entry))completedEntry=entry;});}if(!completedEntry)throw new Error(‘Merlín está tomando más tiempo de lo normal. Intenta nuevamente en unos segundos.’);updateStream(timelineText(completedEntry),true);if(activeStream)await activeStream.completion;setStatus(»);}catch(error){if(requestIdentityGeneration!==identityGeneration)return;if(responseAnimationFinished){setStatus(»);}else{hideThinking;if(activeStream){if(activeStream.timer)window.clearTimeout(activeStream.timer);activeStream.item.remove;activeStream.resolveCompletion;activeStream=null;}sentMessage?.remove;if(conversationId)saveCachedHistory(context.profile,conversationId);if(!input.value.trim)input.value=text;setStatus(error instanceof Error?error.message:’No se pudo enviar tu pregunta. Intenta nuevamente.’);}}finally{if(requestIdentityGeneration===identityGeneration){hideThinking;setSendingState(false);if(responsePollTimer)window.clearTimeout(responsePollTimer);input.focus;}}});
input.addEventListener(‘keydown’,event=>{if(event.key!==’Enter’||event.shiftKey||event.isComposing)return;event.preventDefault;if(form&&typeof form.requestSubmit===’function’){form.requestSubmit;}else if(submit){submit.click;}});menu?.querySelector(‘a[href]’)?.addEventListener(‘click’,closeMenu);document.addEventListener(‘click’,event=>{const target=event.target;if(target instanceof Node&&menu&&moreButton&&!menu.contains(target)&&!moreButton.contains(target)){closeMenu;}});dialog.addEventListener(‘cancel’,event=>event.preventDefault);dialog.addEventListener(‘keydown’,event=>{if(event.key===’Escape’){event.preventDefault;if(menu&&!menu.hidden){closeMenu;moreButton?.focus;}return;}if(event.key!==’Tab’)return;const focusable=Array.from(dialog.querySelectorAll(‘a[href], button:not(:disabled), textarea:not(:disabled)’)).filter(element=>!element.closest(‘[hidden]’));const first=focusable[0];const last=focusable[focusable.length-1];if(event.shiftKey&&document.activeElement===first){event.preventDefault;last.focus;}else if(!event.shiftKey&&document.activeElement===last){event.preventDefault;first.focus;}});dialog.addEventListener(‘close’,=>{trigger.setAttribute(‘aria-expanded’,’false’);trigger.setAttribute(‘aria-label’,’Abrir chat con Merlín IA’);closeMenu;trigger.focus;});});};if(document.readyState===’loading’){document.addEventListener(‘DOMContentLoaded’,initializeWidgets,{once:true});return;}initializeWidgets;});
(=>{const tooltip=document.querySelector(«[data-merlin-widget-tooltip]»);const widget=document.querySelector(«[data-merlin-widget]»);const trigger=widget?.querySelector(«[data-merlin-widget-trigger]»);const closeButton=tooltip?.querySelector(«[data-merlin-widget-tooltip-close]»);if(!tooltip||!trigger||!closeButton||tooltip.dataset.initialized)return;const start=Number(tooltip.dataset.start);const end=Number(tooltip.dataset.end);const stateKey=window.location.pathname+»|story»;const existingState=window.__MERLIN_TOOLTIP_STATE__;const state=existingState?.key===stateKey?existingState:{key:stateKey,presented:false,dismissed:false};if(existingState?.tooltip&&existingState.tooltip!==tooltip){existingState.tooltip.dispatchEvent(new Event(«merlin-tip-destroy»))}state.tooltip=tooltip;window.__MERLIN_TOOLTIP_STATE__=state;tooltip.dataset.initialized=»true»;const globalDismissKey=»ec-merlin-tutorial-dismissed»;let userDismissKey=»»;let destroyed=false;let dismissed=state.dismissed||tooltip.dataset.dismissed===»true»;let presented=state.presented||tooltip.dataset.presented===»true»;let activeTrigger=null;let presentationTimer=null;let frame=0;let scheduleTimer=null;const mediaQuery=window.matchMedia(«(min-width: 1024px)»);const listeners=[];const clamp=(value,min,max)=>Math.max(min,Math.min(value,max));const listen=(target,eventName,handler,options)=>{target.addEventListener(eventName,handler,options);listeners.push(=>target.removeEventListener(eventName,handler,options))};const hasCookie=key=>{try{return document.cookie.split(«;»).some(cookie=>cookie.trim===key+»=1″)}catch(_error){return false}};const hasStorageValue=key=>{try{return window.localStorage.getItem(key)===»1″}catch(_error){return false}};const isDismissed==>hasStorageValue(globalDismissKey)||hasCookie(globalDismissKey)||Boolean(userDismissKey&&(hasStorageValue(userDismissKey)||hasCookie(userDismissKey)));const persistDismissal==>{const keys=userDismissKey?[globalDismissKey,userDismissKey]:[globalDismissKey];keys.forEach(key=>{try{window.localStorage.setItem(key,»1″)}catch(_error){}try{document.cookie=key+»=1; Path=/; SameSite=Lax; Max-Age=31536000″}catch(_error){}})};const hideTooltip==>{tooltip.hidden=true;tooltip.classList.remove(«merlin-widget__tooltip–visible»,»merlin-widget__tooltip–above»);if(activeTrigger)activeTrigger.removeAttribute(«aria-describedby»);window.clearTimeout(presentationTimer);presentationTimer=null};const isCampaignActive==>!destroyed&&!dismissed&&Number.isFinite(start)&&Number.isFinite(end)&&Date.now>=start&&Date.now{if(!tooltip.isConnected){tooltip.dispatchEvent(new Event(«merlin-widget-tooltip-destroy»));return}if(!isCampaignActive){hideTooltip;return}const triggerRect=trigger.getBoundingClientRect;const triggerIsVisible=triggerRect.width>0&&triggerRect.height>0&&triggerRect.top>=0&&triggerRect.bottom<=window.innerHeight&&triggerRect.right>0&&triggerRect.left{presentationTimer=null;if(!isCampaignActive)return;presented=true;state.presented=true;positionTooltip},1000)}return}if(!presented){presented=true;state.presented=true}if(activeTrigger&&activeTrigger!==trigger){activeTrigger.removeAttribute(«aria-describedby»)}activeTrigger=trigger;tooltip.hidden=false;tooltip.classList.remove(«merlin-widget__tooltip–compact»);const{width,height}=tooltip.getBoundingClientRect;const left=clamp(triggerRect.right-width,16,document.documentElement.clientWidth-width-16);const placeAbove=triggerRect.top-height-12>=12;const top=placeAbove?triggerRect.top-height-12:clamp(triggerRect.bottom+12,12,window.innerHeight-height-12);tooltip.style.setProperty(«–merlin-widget-tooltip-left»,left+»px»);tooltip.style.setProperty(«–merlin-widget-tooltip-top»,top+»px»);tooltip.style.setProperty(«–merlin-widget-tooltip-arrow»,clamp(triggerRect.left+triggerRect.width/2-left-tooltip.clientLeft,20,tooltip.clientWidth-20)+»px»);tooltip.classList.toggle(«merlin-widget__tooltip–above»,placeAbove);tooltip.classList.toggle(«merlin-widget__tooltip–compact»,height>window.innerHeight-24);trigger.setAttribute(«aria-describedby»,tooltip.id);tooltip.classList.add(«merlin-widget__tooltip–visible»);presented=true;state.presented=true;tooltip.dataset.presented=»true»};const schedulePosition==>{if(destroyed||dismissed||frame)return;frame=window.requestAnimationFrame(=>{frame=0;positionTooltip})};const updateIdentityAndSchedule=(loggedOut=false)=>{let uid=»»;try{if(!loggedOut&&window.tp?.user?.isUserValid?.&&window.tp?.pianoId?.getUser){uid=window.tp.pianoId.getUser?.uid||»»}}catch(_error){uid=»»}userDismissKey=uid?globalDismissKey+»-«+encodeURIComponent(uid):»»;if(userDismissKey&&!hasStorageValue(globalDismissKey)&&isDismissed){persistDismissal}window.clearTimeout(scheduleTimer);const now=Date.now;const nextChange=nownow){scheduleTimer=window.setTimeout(updateIdentityAndSchedule,Math.min(nextChange-now,2147483647))}schedulePosition};const closeTooltip==>{dismissed=true;state.dismissed=true;tooltip.dataset.dismissed=»true»;hideTooltip;persistDismissal;if(document.activeElement===closeButton){trigger.focus({preventScroll:true})}};listen(closeButton,»click»,closeTooltip);listen(window,»storage»,event=>{if((event.key===globalDismissKey||event.key===userDismissKey)&&event.newValue===»1″){dismissed=true;state.dismissed=true;hideTooltip}});listen(window,»pageshow»,=>updateIdentityAndSchedule);listen(window,»focus»,=>updateIdentityAndSchedule);listen(window,»pagehide»,hideTooltip);listen(window,»resize»,schedulePosition,{passive:true});listen(window,»scroll»,schedulePosition,{passive:true});const piano=window.tp||(window.tp=[]);if(typeof piano.push===»function»){piano.push([«init»,=>updateIdentityAndSchedule]);piano.push([«addHandler»,»loginSuccess»,=>updateIdentityAndSchedule]);piano.push([«addHandler»,»logout»,=>updateIdentityAndSchedule(true)])}const mutationObserver=new MutationObserver(records=>{if(records.some(record=>!tooltip.contains(record.target))){schedulePosition}});mutationObserver.observe(document.body,{childList:true,subtree:true,attributes:true,attributeFilter:[«class»,»style»,»hidden»]});const resizeObserver=typeof ResizeObserver===»undefined»?null:new ResizeObserver(schedulePosition);resizeObserver?.observe(trigger);const destroy==>{destroyed=true;hideTooltip;window.clearTimeout(scheduleTimer);window.cancelAnimationFrame(frame);mutationObserver.disconnect;resizeObserver?.disconnect;listeners.forEach(removeListener=>removeListener);delete tooltip.dataset.initialized};tooltip.addEventListener(«merlin-widget-tooltip-destroy»,destroy,{once:true});tooltip.addEventListener(«merlin-tip-destroy»,destroy,{once:true});updateIdentityAndSchedule});

