1(function(){ 2'use strict'; 3if(!location.pathname.startsWith('/company-intelligence'))return; 4if(window.matchMedia('(min-width:921px)').matches)return; 5const isPro=()=>['true','1'].includes(String(localStorage.getItem('rcai_pro_unlocked')||'')); 6const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); 7const arr=v=>Array.isArray(v)?v.filter(Boolean):v?[v]:[]; 8const money=n=>n?new Intl.NumberFormat('en-US',{style:'currency',currency:'USD',notation:'compact',maximumFractionDigits:1}).format(n):'â'; 9const wait=async(sel,tries=80)=>{while(tries--){const el=document.querySelector(sel);if(el)return el;await new Promise(r=>setTimeout(r,75));}return null}; 10(async()=>{ 11 const rows=await wait('#rows'); if(!rows)return; 12 const [db,scoresDb,matrixDb,txDb,ownDb,auditDb]=await Promise.all([ 13 fetch('/data/company-intelligence.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:[]})), 14 fetch('/data/company-scores.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:[]})), 15 fetch('/data/rcm-market-matrix.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:[]})), 16 fetch('/data/rcm-transactions.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({transactions:[]})), 17 fetch('/data/ownership-history.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:{}})), 18 fetch('/data/funding-completeness.json',{cache:'no-store'}).then(r=>r.json()).catch(()=>({companies:[]})) 19 ]); 20 const companies=db.companies||[]; 21 const scoreMap=new Map((scoresDb.companies||[]).map(x=>[x.slug,x])); 22 const matrixMap=new Map((matrixDb.companies||[]).map(x=>[x.slug,x])); 23 const auditMap=new Map((auditDb.companies||[]).map(x=>[x.slug,x])); 24 const txBy=new Map();for(const t of txDb.transactions||[]){const a=txBy.get(t.target_slug)||[];a.push(t);txBy.set(t.target_slug,a)} 25 const own=ownDb.companies||{}; 26 const table=document.querySelector('.table'); 27 if(!table)return; 28 table.style.minWidth=isPro()?'1420px':'980px'; 29 const head=table.querySelector('thead tr'); 30 head.innerHTML=`<th>Company</th><th>Category</th><th>Ownership</th><th>Founded / HQ</th><th>Confidence</th><th class="pro-col">Funding</th><th class="pro-col">Market Matrix</th><th class="pro-col">Momentum</th><th class="pro-col">Buyer fit</th><th class="pro-col">Integrations</th><th class="pro-col">Pricing</th><th class="pro-col">Competitive set</th><th></th>`; 31 const toolbar=document.querySelector('.toolbar'); 32 const addSelect=(id,label)=>{if(!toolbar||document.getElementById(id))return null;const s=document.createElement('select');s.className='field';s.id=id;s.innerHTML=`<option value="">${label}</option>`;toolbar.appendChild(s);return s}; 33 const stageSel=addSelect('fundingStage','All funding stages'); 34 const tierSel=addSelect('matrixTier','All Matrix tiers'); 35 if(stageSel){[...new Set(companies.map(c=>c.funding_stage).filter(Boolean))].sort().forEach(v=>stageSel.insertAdjacentHTML('beforeend',`<option>${esc(v)}</option>`));} 36 if(tierSel){['Leader','Major Contender','Emerging'].forEach(v=>tierSel.insertAdjacentHTML('beforeend',`<option>${v}</option>`));} 37 const search=document.getElementById('search'),cat=document.getElementById('category'),ownership=document.getElementById('ownership'); 38 const initials=n=>String(n||'').split(/\s+/).slice(0,2).map(x=>x[0]||'').join('').toUpperCase(); 39 const currentOwner=c=>{if(c.ownership)return c.ownership;const ev=arr(own[c.slug]).slice().reverse().find(x=>x.owner);return ev?.owner||'â'}; 40 const latestTx=c=>arr(txBy.get(c.slug)).sort((a,b)=>String(b.date_announced||'').localeCompare(String(a.date_announced||'')))[0]; 41 const fundingLabel=c=>{const a=auditMap.get(c.slug),t=latestTx(c);const bits=[];if(c.funding_stage)bits.push(c.funding_stage);if(t?.amount_usd||t?.amount_display)bits.push(t.amount_display||money(t.amount_usd));else if(c.funding_total)bits.push(c.funding_total);if(a?.status&&a.status!=='unknown')bits.push(a.status);return bits.join(' · ')||'â'}; 42 const render=()=>{ 43 const q=(search?.value||'').trim().toLowerCase(),cv=cat?.value||'',ov=ownership?.value||'',sv=stageSel?.value||'',tv=tierSel?.value||''; 44 const filtered=companies.filter(c=>{const m=matrixMap.get(c.slug);const hay=[c.name,c.category,c.subcategory,c.description,c.ownership,c.hq,c.funding_stage,...arr(c.capabilities),...arr(c.aliases),...arr(c.competitors),...arr(c.integrations),...arr(c.buyer_segments)].filter(
44Boolean).join(' ').toLowerCase();return(!q||hay.includes(q))&&(!cv||c.category===cv)&&(!ov||currentOwner(c)===ov)&&(!sv||c.funding_stage===sv)&&(!tv||m?.tier===tv)}).sort((a,b)=>a.name.localeCompare(b.name)); 45 const count=document.getElementById('resultCount');if(count)count.textContent=`${filtered.length} of ${companies.length} companies`; 46 rows.innerHTML=filtered.length?filtered.map(c=>{const s=scoreMap.get(c.slug),m=matrixMap.get(c.slug);const buyer=arr(c.buyer_segments).join(', ')||arr(c.organization_size_fit).join(', ')||'â';const pricing=c.pricing_model||c.pricing_details||'â';const comps=arr(c.competitors).slice(0,3).join(', ')||'â';const integrations=arr(c.integrations).slice(0,3).join(', ')||'â';const founded=[c.founded_year,c.hq].filter(Boolean).join(' · ')||'â';const owner=currentOwner(c);const profile=`/companies/${encodeURIComponent(c.slug)}/`;return `<tr data-slug="${esc(c.slug)}"><td><div class="co"><div class="mark">${esc(initials(c.name))}</div><div><strong>${esc(c.name)}</strong><small>${esc(c.subcategory||'')}</small></div></div></td><td><span class="pill">${esc(c.category||'â')}</span></td><td>${esc(owner)}</td><td>${esc(founded)}</td><td><span class="confidence ${esc(c.data_confidence||'low')}">${esc(c.data_confidence||'low')}</span></td><td class="pro-col">${esc(fundingLabel(c))}</td><td class="pro-col">${m?`<a href="/methodology/#market-matrix"><b>${esc(m.tier)}</b> · Impact ${m.market_impact_score} · Vision ${m.vision_capability_score}</a>`:'â'}</td><td class="pro-col">${s?`<a href="/methodology/#momentum"><b>${s.momentum_score}</b></a>`:'â'}</td><td class="pro-col">${esc(buyer)}</td><td class="pro-col">${esc(integrations)}</td><td class="pro-col">${esc(pricing)}</td><td class="pro-col">${esc(comps)}</td><td><a class="open" href="${profile}">Profile â</a></td></tr>`}).join(''):`<tr><td colspan="13" class="empty">No companies match these filters.</td></tr>`; 47 document.querySelectorAll('#rows tr[data-slug]').forEach(tr=>{tr.style.cursor='pointer';tr.onclick=e=>{if(e.target.closest('a,button,input,select'))return;location.href=`/companies/${encodeURIComponent(tr.dataset.slug)}/`}}); 48 }; 49 const syncMode=()=>{document.body.classList.toggle('pro-mode',isPro());if(stageSel)stageSel.style.display=isPro()?'':'none';if(tierSel)tierSel.style.display=isPro()?'':'none';table.style.minWidth=isPro()?'1420px':'980px';render();}; 50 [search,cat,ownership,stageSel,tierSel].filter(Boolean).forEach(el=>['input','change'].forEach(ev=>el.addEventListener(ev,()=>setTimeout(render,0)))); 51 const modeBtns=document.querySelectorAll('.mode button');modeBtns.forEach(b=>b.addEventListener('click',e=>{if(!isPro()&&b.dataset.mode==='pro'){e.preventDefault();e.stopImmediatePropagation();location.href='/pro/';return;}setTimeout(syncMode,0)},true)); 52 syncMode(); 53})(); 54})();
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.