PageSourceSearch

https://meterless.ai/site/router.js?v=5ab6b0be88

js meterless.ai collected 2026-10-05 12:24:01 UTC 3,910 bytes, 38 lines download raw bytes

1const menuButton=document.querySelector('.mobile-menu');
2menuButton.addEventListener('click',()=>{const open=menuButton.getAttribute('aria-expanded')!=='true';menuButton.setAttribute('aria-expanded',String(open));menuButton.textContent=open?'Close −':'Menu +';document.querySelector('.topbar').classList.toggle('menu-open',open);});
3const MOBILE_PAGE_NAVS={
4  main:[['#home','Overview'],['#real-jobs','The work'],['#download','Get Nightshift']],
5  howto:[['#how-to-use','Story'],['benchmarks.html#morning','The work'],['#howto-download','Get Nightshift']]
6};
7function setMobilePageNav(kind){const nav=document.querySelector('.mobile-page-nav');if(!nav||nav.dataset.kind===kind)return;nav.dataset.kind=kind;nav.innerHTML=MOBILE_PAGE_NAVS[kind].map(([href,text],i)=>'<a href="'+href+'" aria-current="'+(i===0)+'">'+text+'</a>').join('');}
8// Each view is its own page: <body data-page> fixes the route; hash changes only move within the page.
9const PAGE=document.body.dataset.page||'nightshift';
10const PAGE_TOP_HASHES=['#home','#main','#how-to-use','#howto-page','#howto-top','#tour','#optimized-for-local-ai','#local-ai','#localai-page','#free-tools','#free-apps','#engines','#about','#about-page','#benchmarks','#benchmarks-page','#bm-top'];
11function routeMeterless(){
12  const hash=location.hash;
13  const toolsRoute=PAGE==='tools',enginesRoute=PAGE==='engines',aboutRoute=PAGE==='about',howtoRoute=PAGE==='howto',localaiRoute=PAGE==='localai',benchmarksRoute=PAGE==='benchmarks',modelsRoute=PAGE==='models';
14  const catalogRoute=toolsRoute||enginesRoute||aboutRoute||howtoRoute||localaiRoute||benchmarksRoute||modelsRoute;
15  document.body.classList.toggle('tools-active',toolsRoute);
16  document.body.classList.toggle('catalog-active',catalogRoute);
17  document.body.classList.toggle('howto-active',howtoRoute);
18  document.body.classList.toggle('field-off',catalogRoute&&!howtoRoute);
19  if(toolsShowcase)toolsShowcase.setActive(toolsRoute);
20  document.querySelector('.skip').href=toolsRoute?'#tools-page':enginesRoute?'#engines-page':aboutRoute?'#about-page':howtoRoute?'#howto-page':localaiRoute?'#localai-page':benchmarksRoute?'#benchmarks-page':modelsRoute?'#models-page':'#main';
21  for(const [name,active] of [['tools',toolsRoute],['engines',enginesRoute],['models',modelsRoute],['about',aboutRoute],['howto',howtoRoute||localaiRoute],['nightshift',!catalogRoute]])document.querySelector('[data-nav="'+name+'"]').setAttribute('aria-current',active?'page':'false');
22  setMobilePageNav(howtoRoute?'howto':'main');
23  menuButton.setAttribute('aria-expanded','false');menuButton.textContent='Menu +';document.querySelector('.topbar').classList.remove('menu-open');
24  if(typeof setTour==='function')setTour(false);
25  if(typeof measure==='function')measure();
26  requestAnimationFrame(()=>{
27    const chapterIndex=chapters.findIndex(chapter=>'#'+chapter.id===hash);
28    if(mobileQuery.matches&&chapterIndex>=0){selectMobileChapter(chapterIndex);document.querySelector('#story').scrollIntoView({behavior:'instant'});}
29    else if(PAGE_TOP_HASHES.includes(hash)){if(PAGE!=='nightshift'||hash!=='#home')window.scrollTo(0,0);}
30    else{const el=document.getElementById(hash.slice(1));if(el){el.scrollIntoView({behavior:'instant'});if(el.id==='tool-search')el.focus({preventScroll:true});}}
31    window.dispatchEvent(new Event('scroll'));
32    if(howtoRoute&&hash==='#tour'){pendingTour=true;history.replaceState(null,'',location.pathname+location.search);}
33    if(pendingTour&&howtoRoute){pendingTour=false;if(typeof measure==='function')measure();startStoryTour();}
34  });
35}
36window.addEventListener('hashchange',routeMeterless);routeMeterless();
37// Mode panel demos animate only while on screen.
38(()=>{const io=new IntersectionObserver(entries=>{for(const e of entries)if(e.isIntersecting)e.target.classList.add('is-on');},{threshold:.25});document.querySelectorAll('.modes .mode-panel').forEach(p=>io.observe(p));})();

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.