{"version":3,"file":"HumanDataAtlasEmbed.CAPsJRtJ.mjs","names":["useRef","useState"],"sources":["https:/framerusercontent.com/modules/dbD3PjRS3SeTL5eyE3XX/hGas05ZWf5WM1HcqXNFl/HumanDataAtlasEmbed.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{addPropertyControls,ControlType}from\"framer\";import{useEffect,useRef,useState}from\"react\";// Standalone Physical AI Atlas (canvas app) rendered inside a sandboxed iframe\n// so its full-viewport CSS does not fight the page layout.\nconst ATLAS_HTML=\"<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n<meta charset=\\\"UTF-8\\\">\\n<meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\">\\n<title>Physical AI Atlas — who sells data for physical AI, by format</title>\\n<link rel=\\\"preconnect\\\" href=\\\"https://fonts.googleapis.com\\\">\\n<link href=\\\"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Schibsted+Grotesk:ital,wght@0,400;0,500;0,600;1,400&display=swap\\\" rel=\\\"stylesheet\\\">\\n<style>\\n  :root{\\n    --bg:#060a12;\\n    --bg-2:#0b1220;\\n    --ink:#eceae2;\\n    --dim:#8f97a6;\\n    --dimmer:#555e6e;\\n    --line:rgba(236,234,226,0.10);\\n    --line-strong:rgba(236,234,226,0.22);\\n    --panel:rgba(9,14,24,0.84);\\n    --focus:#f5c86b;\\n\\n    --c-ego:#d7b0ff;\\n    --c-anno:#5fd9cf;\\n    --c-tele:#ff8fa3;\\n    --c-synth:#9be59a;\\n    --c-gen:#f5c86b;\\n    --c-infra:#7fb2ff;\\n\\n    --serif:'Instrument Serif', Georgia, serif;\\n    --sans:'Schibsted Grotesk', system-ui, -apple-system, sans-serif;\\n  }\\n  *{ box-sizing:border-box; }\\n  html,body{ margin:0; height:100%; background:var(--bg); color:var(--ink);\\n    font-family:var(--sans); font-size:14px; overflow:hidden;\\n    }\\n  a{ color:inherit; }\\n  button{ font-family:inherit; color:inherit; }\\n  :focus-visible{ outline:2px solid var(--focus); outline-offset:2px; }\\n\\n  /* ---------------- Top bar ---------------- */\\n  #topbar{\\n    position:absolute; top:0; left:0; right:0; height:60px; z-index:8;\\n    display:flex; align-items:center; justify-content:space-between; gap:18px;\\n    padding:0 20px;\\n    background:linear-gradient(180deg, rgba(6,10,18,0.92), rgba(6,10,18,0.55) 80%, rgba(6,10,18,0));\\n  }\\n  #brand{ display:flex; align-items:baseline; gap:14px; min-width:0; }\\n  #aic{ display:flex; align-items:center; height:26px; padding-right:14px; margin-right:2px; border-right:1px solid var(--line-strong); opacity:0.92; }\\n  #aic:hover{ opacity:1; }\\n  #aic img{ height:22px; width:auto; display:block; }\\n  #brand h1{ font-family:var(--serif); font-weight:400; font-size:26px; letter-spacing:-0.01em; margin:0; white-space:nowrap; }\\n  #brand h1 em{ font-style:italic; color:var(--c-gen); }\\n  #brand .tag{ font-size:12.5px; color:var(--dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }\\n  #top-right{ display:flex; align-items:center; gap:10px; }\\n  #search-wrap{ position:relative; }\\n  #search{\\n    width:240px; height:36px; padding:0 12px 0 34px;\\n    background:rgba(236,234,226,0.06); border:1px solid var(--line); border-radius:10px;\\n    color:var(--ink); font-family:inherit; font-size:13.5px; outline:none;\\n    transition:border-color .15s, background .15s, width .2s;\\n  }\\n  #search::placeholder{ color:var(--dimmer); }\\n  #search:focus{ border-color:var(--line-strong); background:rgba(236,234,226,0.09); width:290px; }\\n  #search-icon{ position:absolute; left:11px; top:50%; transform:translateY(-50%); width:14px; height:14px; color:var(--dim); pointer-events:none; }\\n  #search-hits{\\n    position:absolute; top:42px; left:0; right:0; z-index:20;\\n    background:var(--panel); border:1px solid var(--line); border-radius:10px;\\n    backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);\\n    padding:6px; display:none; max-height:320px; overflow:auto;\\n    box-shadow:0 18px 40px rgba(0,0,0,0.5);\\n  }\\n  #search-hits.show{ display:block; }\\n  .hit{ display:flex; align-items:center; gap:10px; width:100%; padding:8px 10px; border:none; background:none; border-radius:7px; text-align:left; cursor:pointer; font-size:13px; }\\n  .hit:hover, .hit:focus-visible{ background:rgba(236,234,226,0.07); }\\n  .hit .hit-stage{ margin-left:auto; color:var(--dim); font-size:12px; white-space:nowrap; }\\n  .dots{ display:inline-flex; gap:3px; }\\n  .dots i{ width:7px; height:7px; border-radius:50%; display:inline-block; }\\n\\n  .seg{ display:inline-flex; border:1px solid var(--line); border-radius:10px; overflow:hidden; background:rgba(236,234,226,0.04); }\\n  .seg button{ height:36px; padding:0 14px; border:none; background:none; cursor:pointer; font-size:13px; color:var(--dim); }\\n  .seg button.on{ background:rgba(236,234,226,0.12); color:var(--ink); }\\n  .seg button + button{ border-left:1px solid var(--line); }\\n\\n  /* ---------------- Map ---------------- */\\n  #map{ position:absolute; inset:0; }\\n  canvas{ display:block; width:100%; height:100%; cursor:grab; }\\n  canvas.grabbing{ cursor:grabbing; }\\n  canvas.hovering{ cursor:pointer; }\\n\\n  /* ---------------- Left rail: formats ---------------- */\\n  #rail{\\n    position:absolute; left:20px; top:76px; z-index:6; width:262px;\\n    background:var(--panel); border:1px solid var(--line); border-radius:14px;\\n    backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);\\n    padding:14px 12px 10px;\\n  }\\n  #rail .rail-head{ display:flex; align-items:baseline; justify-content:space-between; padding:0 6px 8px; }\\n  #rail .rail-head h2{ font-family:var(--serif); font-weight:400; font-size:19px; margin:0; }\\n  #rail .rail-head span{ color:var(--dim); font-size:12px; }\\n  .fmt{\\n    display:grid; grid-template-columns:12px 1fr auto; align-items:center; gap:10px;\\n    width:100%; padding:8px 8px; border:none; background:none; border-radius:9px;\\n    text-align:left; cursor:pointer; color:var(--dim); transition:background .15s, color .15s, opacity .15s;\\n  }\\n  .fmt:hover{ background:rgba(236,234,226,0.05); color:var(--ink); }\\n  .fmt.on{ background:rgba(236,234,226,0.08); color:var(--ink); }\\n  .fmt.off{ opacity:0.42; }\\n  .fmt .sw{ width:10px; height:10px; border-radius:50%; box-shadow:0 0 8px 1px currentColor; }\\n  .fmt .lbl{ font-size:13.5px; line-height:1.2; }\\n  .fmt .lbl small{ display:block; font-size:11.5px; color:var(--dimmer); margin-top:2px; }\\n  .fmt .n{ font-size:12px; color:var(--dimmer); font-feature-settings:\\\"tnum\\\" 1; }\\n  .fmt.on .n{ color:var(--ink); }\\n  #rail-foot{ display:flex; align-items:center; justify-content:space-between; gap:8px; padding:8px 6px 0; border-top:1px solid var(--line); margin-top:6px; }\\n  #rail-foot .mode{ display:inline-flex; gap:2px; font-size:12px; color:var(--dim); align-items:center; }\\n  #rail-foot .mode button{ background:none; border:1px solid transparent; border-radius:6px; padding:3px 7px; cursor:pointer; color:var(--dimmer); font-size:12px; }\\n  #rail-foot .mode button.on{ color:var(--ink); border-color:var(--line); }\\n  #clear{ background:none; border:none; color:var(--dim); font-size:12px; cursor:pointer; text-decoration:underline; text-underline-offset:3px; padding:3px 6px; visibility:hidden; }\\n  #clear.show{ visibility:visible; }\\n\\n  /* ---------------- Bottom-left: shortlist ---------------- */\\n  #shortlist{\\n    position:absolute; left:20px; bottom:20px; z-index:6; width:262px;\\n    background:var(--panel); border:1px solid var(--line); border-radius:14px;\\n    backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); padding:12px 12px 10px;\\n  }\\n  #shortlist .sl-head{ display:flex; align-items:baseline; justify-content:space-between; padding:0 6px 6px; }\\n  #shortlist .sl-head h2{ font-family:var(--serif); font-weight:400; font-size:19px; margin:0; }\\n  #shortlist .sl-head button{ background:none; border:none; color:var(--dim); font-size:12px; cursor:pointer; text-decoration:underline; text-underline-offset:3px; }\\n  #sl-items{ display:flex; flex-direction:column; gap:2px; max-height:150px; overflow:auto; }\\n  #sl-empty{ color:var(--dimmer); font-size:12.5px; padding:4px 6px 2px; line-height:1.5; }\\n  .sl-item{ display:flex; align-items:center; gap:8px; padding:6px 6px; border-radius:7px; font-size:13px; }\\n  .sl-item:hover{ background:rgba(236,234,226,0.05); }\\n  .sl-item button.open{ background:none; border:none; padding:0; cursor:pointer; text-align:left; flex:1; font-size:13px; }\\n  .sl-item button.rm{ background:none; border:none; color:var(--dimmer); cursor:pointer; font-size:14px; padding:0 4px; }\\n  .sl-item button.rm:hover{ color:var(--c-tele); }\\n\\n  /* ---------------- Bottom-right controls ---------------- */\\n  #controls{ position:absolute; right:20px; bottom:20px; z-index:6; display:flex; flex-direction:column; align-items:flex-end; gap:8px; }\\n  #hint{ font-size:12px; line-height:1.6; color:var(--dim); text-align:right; }\\n  #reset{ height:34px; padding:0 14px; background:var(--panel); border:1px solid var(--line); border-radius:9px; cursor:pointer; font-size:13px; color:var(--dim); backdrop-filter:blur(10px); }\\n  #aic-foot{ font-size:12.5px; color:var(--dim); text-decoration:none; padding:4px 2px; }\\n  #aic-foot:hover{ color:var(--ink); text-decoration:underline; text-underline-offset:3px; }\\n  #reset:hover{ color:var(--ink); border-color:var(--line-strong); }\\n\\n  /* ---------------- Tooltip ---------------- */\\n  #tip{\\n    position:absolute; z-index:9; pointer-events:none;\\n    background:rgba(9,14,24,0.96); border:1px solid var(--line-strong); border-radius:10px;\\n    padding:10px 12px; max-width:260px; font-size:12.5px; line-height:1.5;\\n    opacity:0; transform:translateY(4px); transition:opacity .12s, transform .12s;\\n    box-shadow:0 14px 34px rgba(0,0,0,0.55);\\n  }\\n  #tip.show{ opacity:1; transform:translateY(0); }\\n  #tip .tn{ font-family:var(--serif); font-size:18px; line-height:1.1; margin-bottom:4px; }\\n  #tip .ts{ color:var(--dim); }\\n  #tip .tk{ color:var(--dimmer); font-size:11.5px; margin-top:6px; }\\n\\n  /* ---------------- Drawer ---------------- */\\n  #drawer{\\n    position:absolute; top:0; right:0; bottom:0; width:400px; z-index:10;\\n    background:linear-gradient(180deg, rgba(11,18,32,0.97), rgba(6,10,18,0.97));\\n    border-left:1px solid var(--line);\\n    transform:translateX(100%); transition:transform .28s cubic-bezier(.2,.8,.2,1);\\n    display:flex; flex-direction:column;\\n    backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);\\n  }\\n  #drawer.open{ transform:translateX(0); }\\n  #d-top{ display:flex; align-items:center; justify-content:space-between; padding:14px 16px 0 20px; }\\n  #d-top .d-nav{ display:flex; gap:6px; }\\n  #d-top button{ height:32px; min-width:32px; padding:0 10px; background:rgba(236,234,226,0.05); border:1px solid var(--line); border-radius:8px; cursor:pointer; font-size:13px; color:var(--dim); }\\n  #d-top button:hover{ color:var(--ink); border-color:var(--line-strong); }\\n  #d-body{ padding:16px 20px 28px; overflow:auto; flex:1; }\\n  .d-hero{ display:flex; align-items:center; gap:14px; margin-bottom:10px; }\\n  .d-logo{ width:56px; height:56px; border-radius:14px; background:#f3f1ec; display:flex; align-items:center; justify-content:center; overflow:hidden; flex-shrink:0; font-weight:600; color:#0b1220; font-size:20px; }\\n  .d-logo img{ width:100%; height:100%; object-fit:contain; padding:6px; }\\n  .d-name{ font-family:var(--serif); font-size:30px; line-height:1; margin:0 0 6px; }\\n  .d-sub{ color:var(--dim); font-size:13px; line-height:1.4; }\\n  .d-fmts{ display:flex; flex-wrap:wrap; gap:6px; margin:12px 0 16px; }\\n  .chip{ display:inline-flex; align-items:center; gap:6px; padding:5px 10px 5px 8px; border-radius:999px; border:1px solid var(--line); font-size:12px; color:var(--ink); background:rgba(236,234,226,0.04); }\\n  .chip i{ width:7px; height:7px; border-radius:50%; display:inline-block; box-shadow:0 0 6px 1px currentColor; }\\n  .d-desc{ font-size:14px; line-height:1.6; color:var(--ink); margin:0 0 18px; }\\n  .d-desc p{ margin:0 0 10px; }\\n  .d-desc p:last-child{ margin-bottom:0; }\\n  .facts{ display:grid; grid-template-columns:104px 1fr; row-gap:9px; column-gap:12px; font-size:13px; padding:14px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }\\n  .facts dt{ color:var(--dim); margin:0; }\\n  .facts dd{ margin:0; line-height:1.45; }\\n  .facts dd.stage{ font-family:var(--serif); font-size:17px; line-height:1.1; }\\n  .d-note{ margin-top:16px; padding:12px 14px; border-radius:10px; background:rgba(245,200,107,0.07); border:1px solid rgba(245,200,107,0.22); font-size:13px; line-height:1.55; }\\n  .d-note b{ font-weight:600; color:var(--c-gen); }\\n  .d-actions{ display:flex; gap:8px; margin-top:16px; flex-wrap:wrap; }\\n  .btn{ height:38px; padding:0 14px; display:inline-flex; align-items:center; gap:8px; border-radius:9px; border:1px solid var(--line); background:rgba(236,234,226,0.06); cursor:pointer; font-size:13.5px; text-decoration:none; }\\n  .btn.suggest{ background:#5c34ef; border-color:#5c34ef; color:#fff; font-weight:600; white-space:nowrap; }\\n.btn.suggest:hover{ background:#4b27d6; }\\n@media (max-width:700px){ .btn.suggest{ height:34px; padding:0 12px; font-size:12.5px; } }\\n.btn:hover{ border-color:var(--line-strong); background:rgba(236,234,226,0.1); }\\n  .btn.primary{ background:var(--ink); color:#0b1220; border-color:var(--ink); font-weight:500; }\\n  .btn.primary:hover{ background:#fff; }\\n  .btn.on{ border-color:var(--c-gen); color:var(--c-gen); }\\n  .d-verify{ margin-top:14px; font-size:11.5px; color:var(--dimmer); line-height:1.5; }\\n  .d-verify.fresh b{ color:var(--c-synth); font-weight:500; }\\n  .d-verify.stale b{ color:var(--c-gen); font-weight:500; }\\n\\n  /* ---------------- List view ---------------- */\\n  #list{ position:absolute; top:60px; left:0; right:0; bottom:0; z-index:7; overflow:auto; padding:18px 24px 40px; display:none; background:var(--bg); }\\n  #list.show{ display:block; }\\n  #list .list-intro{ max-width:640px; margin:6px 0 18px; color:var(--dim); font-size:13.5px; line-height:1.55; }\\n  #list .list-intro strong{ color:var(--ink); font-weight:500; }\\n  table{ width:100%; border-collapse:collapse; font-size:13.5px; }\\n  thead th{ position:sticky; top:0; background:var(--bg); text-align:left; font-weight:500; color:var(--dim); font-size:12px; padding:8px 10px; border-bottom:1px solid var(--line-strong); cursor:pointer; user-select:none; white-space:nowrap; }\\n  thead th.sorted{ color:var(--ink); }\\n  tbody td{ padding:9px 10px; border-bottom:1px solid var(--line); vertical-align:top; }\\n  tbody tr{ cursor:pointer; }\\n  tbody tr:hover td{ background:rgba(236,234,226,0.04); }\\n  td.name{ font-weight:500; white-space:nowrap; }\\n  td.name span{ display:block; font-weight:400; color:var(--dim); font-size:12px; margin-top:2px; white-space:normal; max-width:280px; }\\n  td.stage{ font-family:var(--serif); font-size:16px; white-space:nowrap; }\\n  td.muted{ color:var(--dim); }\\n  td .star{ background:none; border:none; cursor:pointer; color:var(--dimmer); font-size:16px; line-height:1; padding:0 4px; }\\n  td .star.on{ color:var(--c-gen); }\\n\\n  /* ---------------- Intro card ---------------- */\\n  #intro{\\n    position:absolute; z-index:6; left:50%; top:50%; transform:translate(-50%,-50%);\\n    width:min(520px, calc(100vw - 40px)); padding:26px 28px 22px;\\n    background:var(--panel); border:1px solid var(--line-strong); border-radius:18px;\\n    backdrop-filter:blur(18px); -webkit-backdrop-filter:blur(18px);\\n    box-shadow:0 30px 80px rgba(0,0,0,0.6);\\n  }\\n  #intro h2{ font-family:var(--serif); font-weight:400; font-size:34px; line-height:1.05; margin:0 0 10px; letter-spacing:-0.01em; }\\n  #intro h2 em{ color:var(--c-gen); }\\n  #intro p{ margin:0 0 10px; color:var(--dim); font-size:14px; line-height:1.55; max-width:52ch; }\\n  #intro .row{ display:flex; gap:10px; margin-top:16px; align-items:center; flex-wrap:wrap; }\\n  #intro .fine{ color:var(--dimmer); font-size:12px; margin-left:auto; }\\n  #intro .pub{ margin-top:18px; padding-top:14px; border-top:1px solid var(--line); color:var(--dim); font-size:12.5px; line-height:1.55; }\\n  #intro .pub a{ color:var(--ink); text-decoration:underline; text-underline-offset:3px; }\\n  #intro.hide{ display:none; }\\n\\n  @media (prefers-reduced-motion: reduce){\\n    #drawer{ transition:none; }\\n    #tip{ transition:none; }\\n  }\\n\\n  @media (max-width: 900px){\\n    #brand .tag{ display:none; }\\n    #search{ width:150px; }\\n    #search:focus{ width:180px; }\\n    #rail{ width:220px; top:70px; }\\n    #rail .lbl small{ display:none; }\\n    #shortlist{ width:220px; }\\n    #hint{ display:none; }\\n    #drawer{ width:100%; top:auto; height:72vh; border-left:none; border-top:1px solid var(--line-strong); border-radius:18px 18px 0 0; transform:translateY(100%); }\\n    #drawer.open{ transform:translateY(0); }\\n    #list{ padding:14px 12px 30px; }\\n    td.name span{ max-width:160px; }\\n  }\\n\\n  /* ---------------- Mobile ---------------- */\\n  #scene{ touch-action:none; }\\n  #topbar{ z-index:10; }\\n  @media (max-width: 700px){\\n    #topbar{ height:auto; flex-wrap:wrap; padding:10px 12px 8px; gap:8px; background:rgba(6,10,18,0.96); }\\n    #brand{ width:100%; gap:10px; }\\n    #brand h1{ font-size:21px; }\\n    #aic{ height:22px; padding-right:10px; }\\n    #aic img{ height:18px; }\\n    #top-right{ width:100%; flex-wrap:wrap; }\\n    .seg{ width:100%; display:flex; }\\n    .seg button{ flex:1; }\\n    #search-wrap{ flex:1; }\\n    #search, #search:focus{ width:100%; height:34px; }\\n    #search-hits{ top:40px; }\\n    .seg button{ height:34px; padding:0 12px; }\\n    #rail{ left:0; right:0; top:var(--tb, 130px); width:auto; border-radius:0; border-left:none; border-right:none;\\n      padding:8px 10px; background:rgba(6,10,18,0.9); }\\n    #rail .rail-head{ display:none; }\\n    #fmts{ display:flex; gap:6px; overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; padding-bottom:2px; }\\n    #fmts::-webkit-scrollbar{ display:none; }\\n    .fmt{ flex:none; width:auto; padding:6px 10px; border:1px solid var(--line); border-radius:999px; gap:7px; }\\n    .fmt .lbl{ font-size:12.5px; white-space:nowrap; }\\n    .fmt .lbl small{ display:none; }\\n    .fmt .n{ font-size:11px; }\\n    #rail-foot{ display:none; }\\n    #rail.has-filter #rail-foot{ display:flex; margin-top:6px; padding-top:6px; }\\n    #shortlist{ display:none; left:12px; right:12px; bottom:12px; width:auto; max-height:40vh; overflow:auto; }\\n    #shortlist.has{ display:block; }\\n    #controls{ right:12px; bottom:12px; }\\n    #reset{ height:32px; padding:0 12px; }\\n    #intro{ left:12px; right:12px; width:auto; transform:translateY(-50%); padding:20px 18px 16px; max-height:calc(100% - 150px); overflow:auto; }\\n    #intro h2{ font-size:26px; }\\n    #list{ top:var(--tb, 130px); padding:10px 10px 30px; }\\n    #intro{ z-index:9; }\\n    #list table{ min-width:640px; }\\n    #list > p, #list .lead{ max-width:calc(100vw - 20px); position:sticky; left:0; }\\n    #list-wrap{ overflow-x:auto; }\\n    #drawer{ height:78vh; }\\n    #d-body{ padding:16px 14px 30px; }\\n    #hint{ display:none; }\\n  }\\n  @media (max-width: 700px) and (max-height: 620px){ #intro{ display:none; } }\\n</style>\\n</head>\\n<body>\\n\\n<div id=\\\"map\\\"><canvas id=\\\"scene\\\" aria-label=\\\"Map of companies selling human data for physical AI, grouped by data format\\\"></canvas></div>\\n\\n<div id=\\\"topbar\\\">\\n  <div id=\\\"brand\\\">\\n    <a id=\\\"aic\\\" href=\\\"https://www.ai-circle.org\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\" aria-label=\\\"AI Circle website\\\"><img src=\\\"data:image/png;base64,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\\\" alt=\\\"AI Circle\\\"></a>\\n    <h1>Physical AI <em>Atlas</em></h1>\\n    <span class=\\\"tag\\\">Companies selling human data for physical AI, by format</span>\\n  </div>\\n  <div id=\\\"top-right\\\">\\n    <a class=\\\"btn suggest\\\" href=\\\"/atlas/suggest\\\" target=\\\"_top\\\" title=\\\"Add a company or request a correction\\\">Suggest a company</a>\\n    <div id=\\\"search-wrap\\\">\\n      <svg id=\\\"search-icon\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke=\\\"currentColor\\\" stroke-width=\\\"2\\\"><circle cx=\\\"11\\\" cy=\\\"11\\\" r=\\\"7\\\"/><line x1=\\\"21\\\" y1=\\\"21\\\" x2=\\\"16.65\\\" y2=\\\"16.65\\\"/></svg>\\n      <input id=\\\"search\\\" type=\\\"text\\\" placeholder=\\\"Search companies, investors…\\\" autocomplete=\\\"off\\\" aria-label=\\\"Search companies\\\">\\n      <div id=\\\"search-hits\\\" role=\\\"listbox\\\"></div>\\n    </div>\\n    <div class=\\\"seg\\\" role=\\\"tablist\\\" aria-label=\\\"View\\\">\\n      <button id=\\\"v-map\\\" class=\\\"on\\\" role=\\\"tab\\\" aria-selected=\\\"true\\\">Map</button>\\n      <button id=\\\"v-list\\\" role=\\\"tab\\\" aria-selected=\\\"false\\\">List</button>\\n    </div>\\n  </div>\\n</div>\\n\\n<div id=\\\"rail\\\" aria-label=\\\"Formats\\\">\\n  <div class=\\\"rail-head\\\"><h2>Formats</h2><span id=\\\"fmt-note\\\">filter</span></div>\\n  <div id=\\\"fmts\\\"></div>\\n  <div id=\\\"rail-foot\\\">\\n    <div class=\\\"mode\\\" title=\\\"With several formats selected: show companies that cover any of them, or all of them\\\">\\n      <button id=\\\"m-any\\\" class=\\\"on\\\">Any</button>\\n      <button id=\\\"m-all\\\">All</button>\\n    </div>\\n    <button id=\\\"clear\\\">Clear</button>\\n  </div>\\n</div>\\n\\n<div id=\\\"shortlist\\\">\\n  <div class=\\\"sl-head\\\"><h2>Shortlist</h2><button id=\\\"sl-copy\\\" hidden>Copy list</button></div>\\n  <div id=\\\"sl-empty\\\">Starred companies collect here. Copy the list when you're done.</div>\\n  <div id=\\\"sl-items\\\"></div>\\n</div>\\n\\n<div id=\\\"controls\\\">\\n  <div id=\\\"hint\\\">Drag to pan \\xb7 scroll to zoom \\xb7 click a logo for its profile</div>\\n  <button id=\\\"reset\\\">Reset view</button>\\n  <a id=\\\"aic-foot\\\" href=\\\"https://www.ai-circle.org\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\">More from AI Circle ↗</a>\\n</div>\\n\\n<div id=\\\"tip\\\" role=\\\"status\\\"></div>\\n\\n<div id=\\\"intro\\\" class=\\\"hide\\\">\\n  <h2>Companies selling human data for physical AI, grouped by <em>format.</em></h2>\\n  <p>A company is placed in each format it works in, so one that does both egocentric capture and teleoperation appears in both. Clicking a logo shows what the company does, its funding stage, investors, and website.</p>\\n  <p>Funding information comes from public reporting and each profile says when it was last checked. Some entries are unverified and marked as such.</p>\\n  <div class=\\\"row\\\">\\n    <button class=\\\"btn primary\\\" id=\\\"intro-go\\\">View map</button>\\n    <button class=\\\"btn\\\" id=\\\"intro-list\\\">View list</button>\\n    <span class=\\\"fine\\\">September 2026</span>\\n  </div>\\n  <div class=\\\"pub\\\">Published by <a href=\\\"https://www.ai-circle.org\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\">AI Circle</a>, a professional society for AI researchers and operators. Members receive the human data briefings behind this map. <a href=\\\"https://www.ai-circle.org\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\">ai-circle.org</a></div>\\n</div>\\n\\n<aside id=\\\"drawer\\\" aria-label=\\\"Company profile\\\">\\n  <div id=\\\"d-top\\\">\\n    <div class=\\\"d-nav\\\">\\n      <button id=\\\"d-prev\\\" title=\\\"Previous company\\\">←</button>\\n      <button id=\\\"d-next\\\" title=\\\"Next company\\\">→</button>\\n    </div>\\n    <button id=\\\"d-close\\\" aria-label=\\\"Close profile\\\">Close</button>\\n  </div>\\n  <div id=\\\"d-body\\\"></div>\\n</aside>\\n\\n<div id=\\\"list\\\" aria-label=\\\"Company list\\\"></div>\\n\\n<script>\\n(function(){\\n\\n  // ---------------------------------------------------------------\\n  // Formats\\n  // ---------------------------------------------------------------\\n  const FORMATS = [\\n    { id:'ego',   label:'Egocentric',              sub:'first-person video, motion, hands',     color:'#d7b0ff',\\n      buyer:'Wearable-camera and sensor capture of people doing tasks. Cheapest per hour, most scalable, not robot-specific.' },\\n    { id:'anno',  label:'Annotation & Labeling',    sub:'workforces and labeling platforms',     color:'#5fd9cf',\\n      buyer:'Human labeling of video, 3D, and trajectories. Buy this when you already have raw data and need it structured.' },\\n    { id:'tele',  label:'Teleoperation',            sub:'robot-native demonstrations',          color:'#ff8fa3',\\n      buyer:'Operators drive real robots. Highest fidelity and cost; the data is matched to a specific embodiment.' },\\n    { id:'synth', label:'Synthetic / Simulation',   sub:'sim assets, generated trajectories',   color:'#9be59a',\\n      buyer:'Physics-accurate assets and simulated demonstrations. Strong for diversity and locomotion; weaker on contact physics.' },\\n    { id:'gen',   label:'Generalist / Full-spectrum', sub:'broad managed data vendors',         color:'#f5c86b',\\n      buyer:'Large data-services companies with a physical AI line. One contract, many modalities, mature ops.' },\\n    { id:'infra', label:'Infrastructure & Tooling', sub:'curation, storage, viz, capture rigs', color:'#7fb2ff',\\n      buyer:'Software and hardware to collect, curate, license, and inspect data. Buy alongside a collection vendor.' },\\n  ];\\n  const FMT = {}; FORMATS.forEach(f=>FMT[f.id]=f);\\n  const STAGE_RANK = { 'Public':0, 'Subsidiary':1, 'Growth':2, 'Series D':3, 'Series C':4, 'Series B':5, 'Series A':6, 'Seed':7, 'Pre-seed':8, 'Undisclosed':9 };\\n\\n  // ---------------------------------------------------------------\\n  // Companies\\n  // fmts: every format they serve.  web: null → search fallback.\\n  // checked: 'Sep 2026' when confirmed against current reporting; 'unverified' otherwise.\\n  // ---------------------------------------------------------------\\n  const LOGO = 'https://ai-circle-human-data-physical-ai.vercel.app/logos/';\\n  const C = [\\n    { name:'Meta', fmts:['ego'], logo:LOGO+'meta_logo.png', web:'https://www.projectaria.com', hq:'Menlo Park, CA', founded:'2004',\\n      stage:'Public', round:'NASDAQ: META', investors:'—',\\n      desc:'Not a vendor, but the largest source of open egocentric data. Project Aria glasses and the Ego4D and Ego-Exo4D datasets underpin much of the academic egocentric literature; the Aria Research Kit is available to approved research partners.',\\n      note:'Datasets carry research licenses. If you need commercial rights or custom capture, pair Aria hardware with a collection vendor on this map.', checked:'unverified' },\\n    { name:'Chemin (SUPA)', fmts:['ego','anno','tele','infra'], logo:'https://framerusercontent.com/assets/RuwHV4CDlBRy1VTfIbJmmA7sd0.svg', web:'https://www.chemin.com', hq:'Singapore', founded:'2025',\\n      stage:'Subsidiary', round:'AI-enablement arm of TDCX Group; acquired SUPA (data labeling) in June 2025', investors:'TDCX Group',\\n      desc:'Managed data services across collection, annotation, model evaluation, and red-teaming, delivered with a gig workforce concentrated in APAC. SUPA brought five years of labeling for robotics, AV, healthcare, and retail customers.',\\n      note:'A good fit when you want APAC collection plus labeling under one contract with an established BPO parent behind it.', checked:'Sep 2026' },\\n    { name:'Lightwheel', fmts:['ego','synth','infra'], logo:LOGO+'Lightwheel_Logo.jpg', web:'https://lightwheel.ai', hq:'Beijing / San Francisco', founded:'2023',\\n      stage:'Growth', round:'≈RMB 2B (~$280M) reported across three 2026 rounds, including an Ant Group-led strategic round at a reported ~$2B valuation', investors:'Ant Group, Zhongguancun Science City, Sichuan Development, Giant Network, Yusys (reported)',\\n      desc:'Three products: SimReady (physics-accurate assets and scenes for Isaac Sim and NVIDIA Newton), EgoSuite (globally scaled egocentric human demonstrations), and RoboFinals (an industrial-grade simulation evaluation platform for VLA and world models). Founded by ex-NVIDIA Xie Chen.',\\n      note:'The most-capitalized simulation-data vendor on the map. Funding figures come from Chinese tech press, not audited filings.', checked:'Sep 2026' },\\n    { name:'Protege', fmts:['ego','gen','infra'], logo:'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMzYgMzIiIGZpbGw9IiMwMDAwMDAiPgogICAgICA8cGF0aCBkPSJNMTYsMEM3LjE4LDAsMCw3LjE4LDAsMTZzNy4xOCwxNiwxNiwxNiwxNi03LjE4LDE2LTE2UzI0LjgyLDAsMTYsMFpNMTYsMzAuMTdjLTIuMjQsMC00LjM1LS41Mi02LjIzLTEuNDV2LTEyLjczYzAtMy40NCwyLjc5LTYuMjMsNi4yMy02LjIzdi0xLjgzYy00LjQ0LDAtOC4wNiwzLjYyLTguMDYsOC4wNnYxMS42NWMtLjc4LS41NC0xLjQ5LTEuMTUtMi4xNC0xLjgydi05LjgzYzAtNS42Myw0LjU4LTEwLjIsMTAuMi0xMC4ydi0xLjgzYy02LjYzLDAtMTIuMDMsNS40LTEyLjAzLDEyLjAzdjcuNDhjLTEuMzYtMi4xNy0yLjE0LTQuNzQtMi4xNC03LjQ4QzEuODMsOC4xOCw4LjE4LDEuODMsMTYsMS44M2MyLjI0LDAsNC4zNS41Miw2LjIzLDEuNDV2MTIuNzNjMCwzLjQ0LTIuNzksNi4yMy02LjIzLDYuMjN2MS44M2M0LjQ0LDAsOC4wNi0zLjYyLDguMDYtOC4wNlY0LjM1Yy43OC41NCwxLjQ5LDEuMTUsMi4xNCwxLjgydjkuODNjMCw1LjYzLTQuNTgsMTAuMi0xMC4yLDEwLjJ2MS44M2M2LjYzLDAsMTIuMDMtNS40LDEyLjAzLTEyLjAzdi03LjQ4YzEuMzYsMi4xNywyLjE0LDQuNzQsMi4xNCw3LjQ4LDAsNy44Mi02LjM2LDE0LjE3LTE0LjE3LDE0LjE3WiIvPgogICAgICA8cGF0aCBkPSJNNTUuMjksMTVjLS40My44LTEuMTEsMS40NS0yLjA1LDEuOTYtLjk0LjUtMi4xNC43NS0zLjYuNzVoLTMuMjJ2Ny4yMWgtMi45MVY3LjE2aDYuMTNjMS4zNiwwLDIuNTIuMjMsMy40Ni43Ljk1LjQ3LDEuNjUsMS4xLDIuMTIsMS45LjQ3LjguNywxLjcuNywyLjY4LDAsLjktLjIxLDEuNzYtLjY0LDIuNTZaTTUyLjEyLDE0LjU4Yy41NS0uNS44Mi0xLjIxLjgyLTIuMTMsMC0xLjk0LTEuMS0yLjkxLTMuMy0yLjkxaC0zLjIydjUuOGgzLjIyYzEuMTEsMCwxLjkzLS4yNSwyLjQ4LS43NVoiLz4KICAgICAgPHBhdGggZD0iTTYyLjUxLDExLjIxYy43MS0uNCwxLjU1LS42LDIuNTItLjZ2My4wMmgtLjc0Yy0xLjE0LDAtMi4wMS4yOS0yLjU5Ljg3LS41OS41OC0uODgsMS41OC0uODgsMy4wMnY3LjQxaC0yLjkxdi0xNC4wOGgyLjkxdjIuMDRjLjQzLS43Mi45OS0xLjI3LDEuNy0xLjY3WiIvPgogICAgICA8cGF0aCBkPSJNNjkuNDMsMjQuMjRjLTEuMDctLjYtMS45Mi0xLjQ2LTIuNTMtMi41Ni0uNjEtMS4xLS45Mi0yLjM3LS45Mi0zLjgycy4zMi0yLjcuOTUtMy44MWMuNjMtMS4xMSwxLjQ5LTEuOTYsMi41OC0yLjU2LDEuMDktLjYsMi4zMS0uODksMy42Ni0uODlzMi41Ni4zLDMuNjYuODljMS4wOS42LDEuOTUsMS40NSwyLjU4LDIuNTYuNjMsMS4xMS45NSwyLjM4Ljk1LDMuODFzLS4zMiwyLjctLjk3LDMuODFjLS42NSwxLjExLTEuNTMsMS45Ni0yLjY1LDIuNTdzLTIuMzUuOTEtMy42OS45MS0yLjUzLS4zLTMuNi0uOTFaTTc1LjE0LDIyLjA4Yy42Ni0uMzYsMS4xOS0uODksMS42LTEuNjEuNDEtLjcyLjYxLTEuNTguNjEtMi42MXMtLjItMS44OS0uNTktMi41OWMtLjM5LS43MS0uOTEtMS4yNC0xLjU2LTEuNi0uNjUtLjM2LTEuMzUtLjU0LTIuMS0uNTRzLTEuNDQuMTgtMi4wOC41NGMtLjY0LjM2LTEuMTUuODktMS41MiwxLjYtLjM3LjcxLS41NiwxLjU3LS41NiwyLjU5LDAsMS41Mi4zOSwyLjY5LDEuMTYsMy41MS43OC44MywxLjc1LDEuMjQsMi45MywxLjI0Ljc1LDAsMS40NS0uMTgsMi4xMS0uNTRaIi8+CiAgICAgIDxwYXRoIGQ9Ik04NS44OSwxMy4yMnY3LjhjMCwuNTMuMTIuOTEuMzcsMS4xNC4yNS4yMy42Ny4zNSwxLjI3LjM1aDEuNzl2Mi40M2gtMi4zYy0xLjMxLDAtMi4zMi0uMzEtMy4wMi0uOTItLjctLjYxLTEuMDUtMS42MS0xLjA1LTIuOTl2LTcuOGgtMS42NnYtMi4zOGgxLjY2di0zLjVoMi45NHYzLjVoMy40M3YyLjM4aC0zLjQzWiIvPgogICAgICA8cGF0aCBkPSJNMTAzLjk4LDE4Ljk3aC0xMC43NmMuMDksMS4xMi41LDIuMDMsMS4yNSwyLjcxLjc1LjY4LDEuNjcsMS4wMiwyLjc2LDEuMDIsMS41NywwLDIuNjgtLjY2LDMuMzItMS45N2gzLjE0Yy0uNDMsMS4zLTEuMiwyLjM2LTIuMzEsMy4xOC0xLjEyLjgzLTIuNSwxLjI0LTQuMTUsMS4yNC0xLjM1LDAtMi41NS0uMy0zLjYyLS45MXMtMS45LTEuNDYtMi41MS0yLjU2Yy0uNi0xLjEtLjkxLTIuMzctLjkxLTMuODJzLjI5LTIuNzIuODgtMy44MmMuNTktMS4xLDEuNDEtMS45NSwyLjQ4LTIuNTRzMi4yOS0uODksMy42Ny0uODksMi41MS4yOSwzLjU1Ljg3YzEuMDQuNTgsMS44NSwxLjM5LDIuNDMsMi40NC41OCwxLjA1Ljg3LDIuMjUuODcsMy42MiwwLC41My0uMDMsMS4wMS0uMSwxLjQzWk0xMDEuMDQsMTYuNjFjLS4wMi0xLjA3LS40LTEuOTMtMS4xNS0yLjU4LS43NS0uNjUtMS42OC0uOTctMi43OS0uOTctMS4wMSwwLTEuODcuMzItMi41OC45Ni0uNzIuNjQtMS4xNCwxLjUtMS4yOCwyLjU5aDcuOFoiLz4KICAgICAgPHBhdGggZD0iTTExNS4yMSwxMS4yNmMuODQuNDMsMS41Ljk4LDEuOTgsMS42MnYtMi4wNGgyLjk0djE0LjMxYzAsMS4zLS4yNywyLjQ1LS44MiwzLjQ2LS41NSwxLjAxLTEuMzMsMS44MS0yLjM2LDIuMzktMS4wMy41OC0yLjI2Ljg3LTMuNjkuODctMS45MSwwLTMuNDktLjQ1LTQuNzUtMS4zNC0xLjI2LS44OS0xLjk4LTIuMTEtMi4xNS0zLjY0aDIuODljLjIyLjczLjY5LDEuMzIsMS40MiwxLjc4LjcyLjQ1LDEuNTkuNjgsMi41OS42OCwxLjE4LDAsMi4xMy0uMzYsMi44NS0xLjA3LjcyLS43MiwxLjA5LTEuNzYsMS4wOS0zLjEydi0yLjM1Yy0uNDkuNjYtMS4xNiwxLjIyLTIuMDEsMS42Ny0uODQuNDUtMS44LjY4LTIuODguNjgtMS4yMywwLTIuMzUtLjMxLTMuMzYtLjkzLTEuMDEtLjYyLTEuODEtMS40OS0yLjQtMi42MS0uNTktMS4xMi0uODgtMi4zOC0uODgtMy44cy4yOS0yLjY3Ljg4LTMuNzZjLjU5LTEuMDksMS4zOS0xLjk0LDIuNC0yLjU0czIuMTMtLjkxLDMuMzYtLjkxYzEuMDksMCwyLjA2LjIyLDIuOS42NVpNMTE2LjU5LDE1LjM0Yy0uNC0uNzItLjkzLTEuMjYtMS41Ny0xLjY0LS42NS0uMzctMS4zNS0uNTYtMi4xLS41NnMtMS40NS4xOC0yLjEuNTVjLS42NS4zNy0xLjE3LjktMS41NywxLjYxLS40LjcxLS42LDEuNTUtLjYsMi41MnMuMiwxLjgyLjYsMi41NmMuNC43My45MywxLjI5LDEuNTgsMS42Ny42Ni4zOCwxLjM1LjU4LDIuMDguNThzMS40NS0uMTksMi4xLS41NmMuNjUtLjM3LDEuMTctLjkyLDEuNTctMS42NS40LS43Mi42LTEuNTcuNi0yLjU0cy0uMi0xLjgxLS42LTIuNTNaIi8+CiAgICAgIDxwYXRoIGQ9Ik0xMzUuOSwxOC45N2gtMTAuNzZjLjA5LDEuMTIuNSwyLjAzLDEuMjUsMi43MS43NS42OCwxLjY3LDEuMDIsMi43NiwxLjAyLDEuNTcsMCwyLjY4LS42NiwzLjMyLTEuOTdoMy4xNGMtLjQzLDEuMy0xLjIsMi4zNi0yLjMxLDMuMTgtMS4xMi44My0yLjUsMS4yNC00LjE1LDEuMjQtMS4zNSwwLTIuNTUtLjMtMy42Mi0uOTEtMS4wNi0uNi0xLjktMS40Ni0yLjUtMi41Ni0uNjEtMS4xLS45MS0yLjM3LS45MS0zLjgycy4yOS0yLjcyLjg4LTMuODJjLjU5LTEuMSwxLjQxLTEuOTUsMi40OC0yLjU0LDEuMDYtLjYsMi4yOS0uODksMy42Ny0uODlzMi41MS4yOSwzLjU1Ljg3YzEuMDQuNTgsMS44NSwxLjM5LDIuNDMsMi40NC41OCwxLjA1Ljg3LDIuMjUuODcsMy42MiwwLC41My0uMDMsMS4wMS0uMSwxLjQzWk0xMzIuOTYsMTYuNjFjLS4wMi0xLjA3LS40LTEuOTMtMS4xNS0yLjU4cy0xLjY4LS45Ny0yLjc5LS45N2MtMS4wMSwwLTEuODcuMzItMi41OC45Ni0uNzIuNjQtMS4xNCwxLjUtMS4yOCwyLjU5aDcuOFoiLz4KICAgIDwvc3ZnPg==', web:'https://www.withprotege.ai', hq:'New York, NY', founded:'2024',\\n      stage:'Seed', round:'~$10M seed reported (2024)', investors:'Bling Capital and others (reported)',\\n      desc:'A data marketplace that connects owners of proprietary datasets (hospitals, media, enterprises) with AI labs, handling licensing and delivery. Physical AI is one of several verticals.',\\n      note:'Useful when you want licensed, already-existing data rather than a fresh collection program.', checked:'unverified' },\\n    { name:'Mecka AI', fmts:['ego'], logo:LOGO+'mecka_logo.png', web:'https://www.mecka.ai', hq:'New York, NY', founded:'2024',\\n      stage:'Series A', round:'$60M (a $25M Series A plus a $35M follow-on, June 2026); Sequoia-led round at ~$500M valuation reported in talks, Sept 2026', investors:'Framework Ventures, Menlo Ventures, SV Angel, Kindred Ventures, Neo ($8M seed)',\\n      desc:'Pays people to record everyday tasks — cooking, repairs, household work — with body sensors and iPhones, then delivers human-motion datasets to robotics labs. Projected a $100M annual run rate by end of 2026 on signed contracts.',\\n      note:'One disclosed customer (1X Technologies). Custom hardware plus phones means you can specify sensor modalities beyond RGB.', checked:'Sep 2026' },\\n    { name:'MicroAGI', fmts:['ego','synth','infra'], logo:LOGO+'microagi_logo.png', web:null, hq:'Munich, Germany', founded:'2025',\\n      stage:'Seed', round:'$55M seed (July 2026), reported as the largest seed round in German history', investors:'Undisclosed',\\n      desc:'Collects egocentric footage by offering free apartment cleanings in New York in exchange for recording rights, and instruments live factory lines it later automates with leased humanoids. Some data is licensed exclusively to frontier labs.',\\n      note:'Exclusive licensing means the best data may be spoken for. Ask what is available non-exclusively.', checked:'Sep 2026' },\\n    { name:'micro1', fmts:['ego','tele'], logo:LOGO+'Micro1_logo.jpg', web:'https://www.micro1.ai', hq:'Palo Alto, CA', founded:'2022',\\n      stage:'Series A', round:'$35M Series A at a $500M valuation (Sept 2025)', investors:'01 Advisors (Dick Costolo, Adam Bain)',\\n      desc:'Runs thousands of vetted contractors in 50+ countries recording household tasks with head-mounted phones; contributors submit more than 160,000 hours of video a month, the largest publicly reported collection volume. Also builds training environments and expert labeling.',\\n      note:'Volume leader for egocentric video. Contributors are paid around $15/hour, above most offshore programs.', checked:'Sep 2026' },\\n    { name:'Humyn Labs', fmts:['ego','synth','infra'], logo:LOGO+'humyn_labs_logo.png', web:null, hq:'San Francisco / India', founded:'2024',\\n      stage:'Undisclosed', round:'$20M commitment to scale collection (April 2026)', investors:'Undisclosed',\\n      desc:'Source-first human data collection across India, Southeast Asia, Latin America, and West Asia: first-person visuals and movement in commercial, agricultural, and residential settings, plus voice data across 33 languages. Launching simulation environments under a Robotics Labs unit.',\\n      note:'Strong choice if you need Global South environments and multilingual voice commands paired with egocentric video.', checked:'Sep 2026' },\\n    { name:'MatchPoint AI (MatchPoint Studio)', fmts:['ego','gen'], logo:'https://matchpointstudios.ai/wp-content/uploads/2022/07/cropped-favicon-270x270.png', web:'https://matchpointstudios.ai', hq:'Chicago, IL', founded:'—',\\n      stage:'Undisclosed', round:'AI data arm of MatchPoint Studio, a Chicago video production company', investors:'Undisclosed',\\n      desc:'Professional (not crowdsourced) data collection and brokerage: egocentric and multi-angle human-activity video for robotics, aerial drone and helicopter footage, native-speaker audio in 50+ languages, and off-the-shelf datasets. Says it works with a number of frontier labs.',\\n      note:'Worth a look if you want production-grade capture crews and consent-documented (GDPR/HIPAA) datasets across several modalities under one contract.', checked:'unverified' },\\n    { name:'Build AI', fmts:['ego'], logo:LOGO+'build_logo.jpg', web:'https://www.build.ai', hq:'San Francisco, CA', founded:'2025',\\n      stage:'Seed', round:'~$15M reported', investors:'Abstract, Pear, HF0; angels incl. Balaji Srinivasan, Guillermo Rauch, Thomas Wolf',\\n      desc:'Paid 14,000+ factory workers across Southeast Asia to wear camera glasses on shift, then released the 100,405-hour Egocentric-100K corpus under Apache 2.0 (access-gated on Hugging Face). A public benefit corporation founded by Eddy Xu.',\\n      note:'Start here for free industrial egocentric video at scale; commission them for tasks the open corpus does not cover.', checked:'Sep 2026' },\\n    { name:'Poseidon', fmts:['ego','infra'], logo:LOGO+'poseidon_logo.jpg', web:null, hq:'Palo Alto, CA', founded:'2025',\\n      stage:'Seed', round:'$15M seed (July 2025)', investors:'a16z crypto; incubated by Story Protocol',\\n      desc:'A decentralized data layer for physical AI: POV video, sensor feeds, and multilingual voice sourced with explicit consent, registered on-chain for provenance and programmable licensing. Contributor SDKs and licensing tools for developers.',\\n      note:'The pitch is IP-cleared, traceable data. Ask for the actual dataset inventory — the infrastructure story is ahead of the catalog.', checked:'Sep 2026' },\\n    { name:'Vin Dynamics', fmts:['ego','tele'], logo:LOGO+'vindynamics_logo.jpeg', web:null, hq:'—', founded:'—',\\n      stage:'Undisclosed', round:'No public funding disclosure found', investors:'—',\\n      desc:'Robotics data collection spanning egocentric human capture and teleoperated demonstrations. Limited public information.',\\n      note:'Contact directly for capabilities; treat this profile as a placeholder until verified.', checked:'unverified' },\\n    { name:'Human Archive', fmts:['ego','tele'], logo:LOGO+'human_archive_logo.jpeg', web:null, hq:'San Francisco / India', founded:'2025',\\n      stage:'Seed', round:'$8.2M seed (May 2026); Y Combinator W26', investors:'Wing Venture Capital, NVP, Y Combinator',\\n      desc:'Deploys 1,000+ multimodal headsets through India\\\\'s gig economy to capture real service work — cleaning, repairs, deliveries — at very low cost per hour. Founders come from robotics and tactile-sensing research.',\\n      note:'Lowest-cost collection on the map, and the category\\\\'s consent flashpoint: India\\\\'s IT ministry has examined its consent mechanisms. Ask for the consent and privacy documentation up front.', checked:'Sep 2026' },\\n    { name:'Uber AI Solutions', fmts:['ego','anno'], logo:LOGO+'uber_ai_solutions.png', web:'https://www.uber.com/us/en/ai-solutions/', hq:'San Francisco, CA', founded:'2023',\\n      stage:'Public', round:'Business unit of Uber (NYSE: UBER)', investors:'—',\\n      desc:'Uber\\\\'s data business: annotation, collection, and human-in-the-loop work drawn from its global driver and courier network plus a dedicated expert workforce. Offers physical-world data collection through people already moving through cities.',\\n      note:'Unique access to in-the-wild urban and vehicle environments; less specialized in manipulation data.', checked:'unverified' },\\n    { name:'Panoculon Labs', fmts:['ego'], logo:'https://framerusercontent.com/assets/LnvpS95RcLLy66KmV6T1NMGCF4c.png', web:null, hq:'—', founded:'—',\\n      stage:'Undisclosed', round:'No public funding disclosure found', investors:'—',\\n      desc:'Egocentric data capture for physical AI. Limited public information.',\\n      note:'Treat as a placeholder until verified directly.', checked:'unverified' },\\n    { name:'Orbifold AI', fmts:['ego','synth','gen'], logo:'https://cdn.prod.website-files.com/68e58b930f0c3e53f7ea9439/68e93889ab80cffdebb2e730_new_logo_256256.png', web:'https://www.orbifold.ai', hq:'San Francisco, CA', founded:'2023',\\n      stage:'Undisclosed', round:'Venture-backed; round details not disclosed', investors:'Undisclosed',\\n      desc:'Multimodal data curation and synthetic data generation for AI training, with a physical AI line covering egocentric and simulated data.',\\n      note:'Verify current focus — the company\\\\'s positioning has shifted over time.', checked:'unverified' },\\n    { name:'Midcentury Labs', fmts:['ego'], logo:'https://www.midcentury.xyz/icon.png', web:'https://www.midcentury.xyz', hq:'—', founded:'—',\\n      stage:'Undisclosed', round:'No public funding disclosure found', investors:'—',\\n      desc:'Egocentric human data collection for robotics. Limited public information.',\\n      note:'Treat as a placeholder until verified directly.', checked:'unverified' },\\n    { name:'IO-AI Tech', fmts:['ego','tele'], logo:'https://io-ai.io/favicon-32.png', web:'https://io-ai.io', hq:'—', founded:'—',\\n      stage:'Undisclosed', round:'No public funding disclosure found', investors:'—',\\n      desc:'Egocentric and teleoperation data services for embodied AI. Limited public information.',\\n      note:'Treat as a placeholder until verified directly.', checked:'unverified' },\\n    { name:'DeepAnnotate', fmts:['ego','anno','infra'], logo:'https://framerusercontent.com/assets/E5UqHpzS3hLMiOJyxj8JaBdM0SE.png', web:null, hq:'—', founded:'—',\\n      stage:'Undisclosed', round:'No public funding disclosure found', investors:'—',\\n      desc:'Annotation services and tooling with a focus on egocentric and robotics data.',\\n      note:'Treat as a placeholder until verified directly.', checked:'unverified' },\\n    { name:'Labelbox', fmts:['anno','infra'], logo:LOGO+'Labelbox_logo.png', web:'https://labelbox.com', hq:'San Francisco, CA', founded:'2018',\\n      stage:'Series D', round:'$110M Series D (2022); ~$189M total', investors:'SoftBank Vision Fund 2, Andreessen Horowitz, B Capital, Gradient, Kleiner Perkins',\\n      desc:'Data labeling platform plus the Alignerr expert network, covering video, 3D, and multimodal annotation with model-assisted workflows.',\\n      note:'Mature platform if your team wants to run labeling in-house with a managed workforce on tap.', checked:'unverified' },\\n    { name:'Invisible Technologies', fmts:['anno','infra'], logo:'https://cdn.prod.website-files.com/684704669d08b247ce01fc71/6847182d5826d69c7480ba91_Invisible-co%20Favicon_512x512.png', web:'https://www.invisible.co', hq:'New York, NY', founded:'2015',\\n      stage:'Growth', round:'Growth-stage; ~$100M+ raised reported', investors:'Undisclosed',\\n      desc:'Managed AI training data operations with a large trained workforce and process-automation tooling; a major post-training vendor for frontier labs expanding into multimodal and physical data.',\\n      note:'Best for high-touch, process-heavy programs where you want operations run for you.', checked:'unverified' },\\n    { name:'Toloka', fmts:['anno','ego','tele'], logo:'https://framerusercontent.com/images/eWD9yfC6OQvQRzfDGmRGw79giZg.png', web:'https://toloka.ai', hq:'Amsterdam, Netherlands', founded:'2014',\\n      stage:'Growth', round:'$72M investment (May 2025)', investors:'Bezos Expeditions; Mikhail Parakhin; spun out of Nebius',\\n      desc:'Global crowd and expert network for data collection and annotation. Physical AI line covers egocentric data collection (in production) and teleoperation demonstrations, alongside video and multimodal labeling.',\\n      note:'Broad geographic reach; ask specifically about 3D and trajectory annotation experience.', checked:'Sep 2026' },\\n    { name:'Sama', fmts:['anno'], logo:LOGO+'sama_logo.jpg', web:'https://www.sama.com', hq:'San Francisco / Nairobi', founded:'2008',\\n      stage:'Series B', round:'$70M Series B (2021)', investors:'CDPQ, Fidelity, and others',\\n      desc:'Certified B Corp running computer-vision annotation — 2D, 3D, LiDAR, video — from East Africa, with a long AV and robotics track record.',\\n      note:'Deep in dense 3D and video labeling with published labor standards, which matters for procurement reviews.', checked:'unverified' },\\n    { name:'Centific', fmts:['anno'], logo:LOGO+'centific_logo.png', web:'https://www.centific.com', hq:'Bellevue, WA', founded:'2015',\\n      stage:'Growth', round:'Privately held', investors:'—',\\n      desc:'Large-scale data services (\\\"Frontier AI Data Foundry\\\") with a multilingual workforce, covering collection, annotation, and evaluation.',\\n      note:'Enterprise-grade contracting; strongest on language and multimodal, newer to robotics-specific formats.', checked:'unverified' },\\n    { name:'Appen', fmts:['anno'], logo:'https://framerusercontent.com/assets/LsgAj2sDNfFSHd3gGorZlnHYRw.svg', web:'https://www.appen.com', hq:'Sydney, Australia', founded:'1996',\\n      stage:'Public', round:'ASX: APX', investors:'—',\\n      desc:'One of the longest-running crowd data companies: collection and annotation across audio, image, video, and text with a million-plus contributor base.',\\n      note:'Broad crowd reach for diverse environments; a public-company procurement path.', checked:'unverified' },\\n    { name:'SuperAnnotate', fmts:['anno','infra'], logo:'https://framerusercontent.com/assets/0VWcZp1FUXgP4V2uQQ34MmWEws.png', web:'https://www.superannotate.com', hq:'San Francisco, CA', founded:'2018',\\n      stage:'Series B', round:'~$36M Series B (2025, reported)', investors:'Socium Ventures and others (reported)',\\n      desc:'Annotation platform with strong video and multimodal tooling plus a marketplace of managed labeling teams.',\\n      note:'Good if you want platform control with vetted vendors underneath.', checked:'unverified' },\\n    { name:'Prolific', fmts:['anno','tele','infra'], logo:'https://framerusercontent.com/assets/rRVE88HZISP91AyNkMWp94ovpA.ico', web:'https://www.prolific.com', hq:'London, UK', founded:'2014',\\n      stage:'Series A', round:'$32M Series A (2023)', investors:'Partech, Oxford Science Enterprises',\\n      desc:'A vetted, demographically balanced participant pool originally built for academic research, now used for human evaluation, RLHF, and recruiting participants for physical and remote-operation tasks.',\\n      note:'The strongest option for representative participant sampling and consented research-grade data.', checked:'unverified' },\\n    { name:'iMerit', fmts:['anno'], logo:LOGO+'imerit_logo.jpeg', web:'https://imerit.net', hq:'San Jose, CA / Kolkata, India', founded:'2012',\\n      stage:'Series B', round:'$20M Series B (2020)', investors:'British International Investment (CDC Group), Omidyar Network, Khosla Impact',\\n      desc:'Full-time annotation workforce in India and the US with deep ADAS, AV, and medical computer-vision experience, including 3D point cloud labeling.',\\n      note:'Employee (not gig) workforce; useful when you need consistent annotators on long programs.', checked:'unverified' },\\n    { name:'Perle AI', fmts:['anno','ego'], logo:'https://framerusercontent.com/assets/eJlXyL7XtXqyHimMRLgyTSBGOTo.svg', web:'https://www.perle.ai', hq:'San Francisco, CA', founded:'2024',\\n      stage:'Seed', round:'$17.5M seed', investors:'Framework (lead)',\\n      desc:'Expert-driven data labeling and evaluation with deep expertise in linguistics, medical, and robotics egocentric data, built on verified human contributors with provenance tracking.',\\n      note:'Company-confirmed focus areas: linguistics, medical, and robotics egocentric.', checked:'Sep 2026' },\\n    { name:'Welo Data', fmts:['anno'], logo:'https://framerusercontent.com/assets/NkjV929WZxCf6ECoUZP5lkYUTd4.png', web:'https://welodata.ai', hq:'New York, NY', founded:'2023',\\n      stage:'Subsidiary', round:'Division of Welocalize', investors:'Welocalize',\\n      desc:'Data services arm of localization firm Welocalize, offering annotation, evaluation, and expert networks across 250+ languages.',\\n      note:'Strong for multilingual instruction and evaluation layers on top of physical data.', checked:'unverified' },\\n    { name:'AgiBot', fmts:['tele','infra'], logo:LOGO+'agibot_logo.jpeg', web:'https://www.agibot.com', hq:'Shanghai, China', founded:'2023',\\n      stage:'Growth', round:'Robot maker; Hong Kong IPO reported in progress (2026)', investors:'Undisclosed',\\n      desc:'Humanoid maker that collects on fleets of identical robots and open-sources the result. AgiBot World holds more than a million real-robot trajectories and deliberately keeps failed demonstrations, labeled with an error cause.',\\n      note:'Free, large, and unusually honest about failures — a benchmark for what open teleop data looks like.', checked:'unverified' },\\n    { name:'XDOF', fmts:['ego','tele','synth'], logo:LOGO+'xdof_logo.jpeg', web:'https://www.xdof.ai', hq:'San Mateo, CA', founded:'2024',\\n      stage:'Series A', round:'$70M Series A (June 2026); ~$78M total. Series B at ~$1.2B valuation led by 8VC reported in talks, Sept 2026', investors:'Thrive Capital, Spark Capital, Andreessen Horowitz, Lux Capital, WndrCo',\\n      desc:'Founded by the Berkeley researchers behind GELLO, the low-cost teleoperation rig. Combines teleop on deployed robots with wearable-sensor egocentric collectors, plus cleaning, annotation, and tooling. Released ABC-130K: 130,000+ bimanual episodes across ~195 tasks under Apache 2.0.',\\n      note:'About 20 customers including frontier labs; annualized revenue reported near $50M. The CEO says raw data alone is a poor business, so expect the pitch to lead with tooling.', checked:'Sep 2026' },\\n    { name:'NVIDIA', fmts:['synth','infra'], logo:LOGO+'nvidia_logo.jpg', web:'https://www.nvidia.com/en-us/industries/robotics/', hq:'Santa Clara, CA', founded:'1993',\\n      stage:'Public', round:'NASDAQ: NVDA', investors:'—',\\n      desc:'The gravitational center of synthetic data: Isaac Sim, Cosmos world models, GR00T-Dreams (synthetic data for GR00T N1.5 generated in 36 hours), and the Newton physics engine.',\\n      note:'Not a data vendor. Most simulation vendors on this map build on NVIDIA\\\\'s stack, so check compatibility early.', checked:'unverified' },\\n    { name:'TELUS Digital', fmts:['gen'], logo:LOGO+'telus_logo.png', web:'https://www.telusdigital.com', hq:'Vancouver, Canada', founded:'2005',\\n      stage:'Public', round:'NYSE: TIXT (formerly TELUS International)', investors:'—',\\n      desc:'Global data collection and annotation at BPO scale, with a large crowd for multimodal capture and labeling.',\\n      note:'Suits programs that need volume, many countries, and enterprise contracting.', checked:'unverified' },\\n    { name:'Innodata', fmts:['gen'], logo:LOGO+'Innodata-Logo.jpeg', web:'https://innodata.com', hq:'Ridgefield Park, NJ', founded:'1988',\\n      stage:'Public', round:'NASDAQ: INOD', investors:'—',\\n      desc:'Data engineering and annotation for large AI labs, with a large delivery workforce and expanding multimodal capabilities.',\\n      note:'Mature vendor for structured, high-volume labeling under long-term contracts.', checked:'unverified' },\\n    { name:'TP (Teleperformance)', fmts:['gen'], logo:'https://framerusercontent.com/assets/QpURUekHhoQm5Li70OMpTXYLbXc.svg', web:'https://www.tp.com', hq:'Paris, France', founded:'1978',\\n      stage:'Public', round:'Euronext: TEP', investors:'—',\\n      desc:'One of the world\\\\'s largest outsourcing firms, with an AI data services line across collection and annotation in dozens of countries.',\\n      note:'Deep multilingual reach; robotics-specific expertise varies by delivery center.', checked:'unverified' },\\n    { name:'Scale AI', fmts:['gen'], logo:LOGO+'scale_logo.png', web:'https://scale.com', hq:'San Francisco, CA', founded:'2016',\\n      stage:'Growth', round:'Meta acquired a 49% stake for $14.3B (June 2025)', investors:'Meta, Accel, Founders Fund, Tiger Global, Amazon, and others',\\n      desc:'The best-documented generalist physical AI data engine: 150,000+ hours delivered in 2025, a claimed pace of 1,000+ hours of demonstration data daily, data factories plus residential and commercial deployments, and a Universal Robots partnership for force-feedback data on production arms.',\\n      note:'Only vendor with a disclosed customer list: Physical Intelligence, Generalist, Cobot, Dyna. Meta\\\\'s stake led some labs to reduce reliance.', checked:'Sep 2026' },\\n    { name:'Encord', fmts:['infra','anno'], logo:LOGO+'encord_logo.jpg', web:'https://encord.com', hq:'London, UK', founded:'2020',\\n      stage:'Series C', round:'$60M Series C (Feb 2026); $110M total', investors:'Wellington Management, CRV, Y Combinator, and others',\\n      desc:'Data infrastructure for multimodal AI: curation, storage, visualization, and evaluation for video, 3D, and sensor data, plus annotation and labeling delivered with many of the largest physical AI teams.',\\n      note:'Strong if your bottleneck is curating what you already have; also runs annotation programs for major physical AI players.', checked:'Sep 2026' },\\n    { name:'Voxel51', fmts:['infra'], logo:LOGO+'voxel51-logo.png', web:'https://voxel51.com', hq:'Ann Arbor, MI', founded:'2016',\\n      stage:'Series B', round:'~$30M Series B (2025, reported)', investors:'Bessemer Venture Partners, Tru Arrow, and others',\\n      desc:'Makers of FiftyOne, the open-source toolkit for visual dataset curation and evaluation, with an enterprise version for teams.',\\n      note:'Free to start; useful for auditing vendor deliveries before you accept them.', checked:'unverified' },\\n    { name:'Deccan AI', fmts:['infra'], logo:LOGO+'deccan_logo.jpg', web:'https://www.deccan.ai', hq:'Hyderabad, India / US', founded:'2020',\\n      stage:'Undisclosed', round:'Round details not disclosed', investors:'Undisclosed',\\n      desc:'Data services and annotation tooling with a large India-based delivery team, expanding from LLM data into multimodal.',\\n      note:'Verify robotics-specific experience before scoping.', checked:'unverified' },\\n    { name:'Rerun', fmts:['infra'], logo:LOGO+'rerun_logo.jpg', web:'https://rerun.io', hq:'Stockholm, Sweden', founded:'2022',\\n      stage:'Seed', round:'~$17M seed (2025, reported)', investors:'Point Nine, Costanoa, and others (reported)',\\n      desc:'Open-source multimodal data visualization and logging built for robotics: time-synchronized video, 3D, and sensor streams.',\\n      note:'Ask vendors whether deliveries are Rerun-loadable — it makes acceptance testing much faster.', checked:'unverified' },\\n    { name:'Memories AI', fmts:['infra'], logo:LOGO+'memories_ai_logo.jpg', web:'https://memories.ai', hq:'San Jose, CA', founded:'2024',\\n      stage:'Seed', round:'~$8M seed (2025, reported)', investors:'Susa Ventures and others (reported)',\\n      desc:'Large visual memory model that indexes and searches hours of video, useful for finding, deduplicating, and clustering egocentric footage.',\\n      note:'A search layer over raw video, not a collection service.', checked:'unverified' },\\n    { name:'Manus', fmts:['infra'], logo:'https://cdn.prod.website-files.com/6617b472be5db819f4dbdf45/696e3716559de3c5bb89b575_manus-fav_256.png', web:'https://www.manus-meta.com', hq:'Geldrop, Netherlands', founded:'2014',\\n      stage:'Growth', round:'Privately held', investors:'—',\\n      desc:'Motion-capture gloves and finger tracking hardware used to capture precise hand data for animation, VR, and increasingly robot dexterity training.',\\n      note:'Capture hardware, not a data vendor. Relevant if your program needs finger-level fidelity beyond camera-based hand pose.', checked:'unverified' },\\n  ];\\n\\n  C.forEach((c,i)=>{ c.id=i; c.primary=c.fmts[0]; c.imgLoaded=false; c.imgFailed=!c.logo; c.img=null; });\\n  C.forEach(c=>{\\n    if(!c.logo) return;\\n    const img = new Image();\\n    img.onload = ()=>{ c.img=img; c.imgLoaded=true; };\\n    img.onerror = ()=>{ c.imgFailed=true; };\\n    img.src = c.logo;\\n  });\\n\\n  // ---------------------------------------------------------------\\n  // Instances — one node per (company, format)\\n  // ---------------------------------------------------------------\\n  const RING_R = 700;\\n  FORMATS.forEach((f,i)=>{\\n    const a = -Math.PI/2 + i * (Math.PI*2/FORMATS.length);\\n    f.cx = Math.cos(a)*RING_R; f.cy = Math.sin(a)*RING_R;\\n    f.members = C.filter(c=>c.fmts.includes(f.id));\\n    f.count = f.members.length;\\n    f.r = 130 + Math.sqrt(f.count) * 50;\\n  });\\n  const GOLDEN = Math.PI*(3-Math.sqrt(5));\\n  const NODES = [];\\n  FORMATS.forEach(f=>{\\n    f.members.forEach((c,k)=>{\\n      const frac = (k+0.5)/f.count;\\n      const r = f.r*0.74*Math.sqrt(frac);\\n      const ang = k*GOLDEN;\\n      NODES.push({ c, f, wx:f.cx+Math.cos(ang)*r, wy:f.cy+Math.sin(ang)*r,\\n        phase:Math.random()*Math.PI*2, speed:0.35+Math.random()*0.35 });\\n    });\\n  });\\n  const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\\n\\n  // ---------------------------------------------------------------\\n  // State\\n  // ---------------------------------------------------------------\\n  const active = new Set();      // format filters\\n  let matchAll = false;\\n  let query = '';\\n  let selected = null;           // company\\n  let hovered = null;            // node\\n  const shortlist = [];          // company ids\\n  let view = 'map';\\n  const isMobile = () => window.matchMedia('(max-width: 700px)').matches;\\n\\n  function companyMatches(c){\\n    let fmtOk = true;\\n    if(active.size){\\n      fmtOk = matchAll ? [...active].every(id=>c.fmts.includes(id)) : c.fmts.some(id=>active.has(id));\\n    }\\n    if(!fmtOk) return false;\\n    if(!query) return true;\\n    const hay = (c.name+' '+c.desc+' '+c.investors+' '+c.hq+' '+c.stage+' '+c.round).toLowerCase();\\n    return hay.includes(query);\\n  }\\n  function nodeVisible(n){\\n    if(active.size && !active.has(n.f.id)) return false;\\n    return companyMatches(n.c);\\n  }\\n\\n  // ---------------------------------------------------------------\\n  // Rail\\n  // ---------------------------------------------------------------\\n  const fmtsEl = document.getElementById('fmts');\\n  FORMATS.forEach(f=>{\\n    const b = document.createElement('button');\\n    b.className='fmt'; b.dataset.id=f.id; b.setAttribute('aria-pressed','false');\\n    b.innerHTML = `<span class=\\\"sw\\\" style=\\\"color:${f.color};background:${f.color}\\\"></span>\\n      <span class=\\\"lbl\\\">${f.label}<small>${f.sub}</small></span><span class=\\\"n\\\">${f.count}</span>`;\\n    b.addEventListener('click', ()=>{ active.has(f.id)?active.delete(f.id):active.add(f.id); refresh(); });\\n    fmtsEl.appendChild(b);\\n  });\\n  document.getElementById('m-any').addEventListener('click', ()=>{ matchAll=false; refresh(); });\\n  document.getElementById('m-all').addEventListener('click', ()=>{ matchAll=true; refresh(); });\\n  document.getElementById('clear').addEventListener('click', ()=>{\\n    active.clear(); query=''; document.getElementById('search').value=''; hideHits(); refresh();\\n  });\\n\\n  function refresh(){\\n    document.getElementById('rail').classList.toggle('has-filter', active.size>0);\\n    const any = active.size>0;\\n    document.querySelectorAll('.fmt').forEach(el=>{\\n      const on = active.has(el.dataset.id);\\n      el.classList.toggle('on', on); el.classList.toggle('off', any && !on);\\n      el.setAttribute('aria-pressed', on?'true':'false');\\n    });\\n    document.getElementById('m-any').classList.toggle('on', !matchAll);\\n    document.getElementById('m-all').classList.toggle('on', matchAll);\\n    document.getElementById('clear').classList.toggle('show', any || query.length>0);\\n    const n = C.filter(companyMatches).length;\\n    document.getElementById('fmt-note').textContent = (any||query) ? `${n} of ${C.length} companies` : `${C.length} companies`;\\n    if(view==='list') renderList();\\n  }\\n\\n  // ---------------------------------------------------------------\\n  // Search\\n  // ---------------------------------------------------------------\\n  const searchEl = document.getElementById('search');\\n  const hitsEl = document.getElementById('search-hits');\\n  function hideHits(){ hitsEl.classList.remove('show'); hitsEl.innerHTML=''; }\\n  function dotsFor(c){ return `<span class=\\\"dots\\\">${c.fmts.map(id=>`<i style=\\\"background:${FMT[id].color}\\\"></i>`).join('')}</span>`; }\\n  searchEl.addEventListener('input', e=>{\\n    query = e.target.value.trim().toLowerCase();\\n    refresh();\\n    if(!query){ hideHits(); return; }\\n    const hits = C.filter(c=>c.name.toLowerCase().includes(query) || c.investors.toLowerCase().includes(query)).slice(0,8);\\n    if(!hits.length){ hideHits(); return; }\\n    hitsEl.innerHTML = hits.map(c=>`<button class=\\\"hit\\\" data-id=\\\"${c.id}\\\" role=\\\"option\\\">${dotsFor(c)}<span>${c.name}</span><span class=\\\"hit-stage\\\">${c.stage}</span></button>`).join('');\\n    hitsEl.classList.add('show');\\n    hitsEl.querySelectorAll('.hit').forEach(h=>h.addEventListener('click', ()=>{ openCompany(C[+h.dataset.id], true); hideHits(); }));\\n  });\\n  searchEl.addEventListener('keydown', e=>{\\n    if(e.key==='Enter'){ const first = hitsEl.querySelector('.hit'); if(first){ first.click(); } }\\n    if(e.key==='Escape'){ hideHits(); searchEl.blur(); }\\n  });\\n  document.addEventListener('click', e=>{ if(!e.target.closest('#search-wrap')) hideHits(); });\\n\\n  // ---------------------------------------------------------------\\n  // View toggle\\n  // ---------------------------------------------------------------\\n  const listEl = document.getElementById('list');\\n  function setView(v){\\n    view=v;\\n    document.getElementById('v-map').classList.toggle('on', v==='map');\\n    document.getElementById('v-list').classList.toggle('on', v==='list');\\n    document.getElementById('v-map').setAttribute('aria-selected', v==='map');\\n    document.getElementById('v-list').setAttribute('aria-selected', v==='list');\\n    listEl.classList.toggle('show', v==='list');\\n    ['rail','shortlist','controls'].forEach(id=>document.getElementById(id).style.display = v==='list' ? 'none':'');\\n    if(v==='list') renderList();\\n  }\\n  document.getElementById('v-map').addEventListener('click', ()=>setView('map'));\\n  document.getElementById('v-list').addEventListener('click', ()=>setView('list'));\\n\\n  let sortKey='stage', sortDir=1;\\n  function renderList(){\\n    const rows = C.filter(companyMatches).slice().sort((a,b)=>{\\n      let va, vb;\\n      if(sortKey==='stage'){ va=STAGE_RANK[a.stage]??9; vb=STAGE_RANK[b.stage]??9; }\\n      else if(sortKey==='fmts'){ va=-a.fmts.length; vb=-b.fmts.length; }\\n      else { va=(a[sortKey]||'').toString().toLowerCase(); vb=(b[sortKey]||'').toString().toLowerCase(); }\\n      if(va<vb) return -sortDir; if(va>vb) return sortDir; return a.name.localeCompare(b.name);\\n    });\\n    const th = (k,l)=>`<th data-k=\\\"${k}\\\" class=\\\"${sortKey===k?'sorted':''}\\\">${l}${sortKey===k?(sortDir>0?' ↑':' ↓'):''}</th>`;\\n    listEl.innerHTML = `\\n      <div class=\\\"list-intro\\\"><strong>${rows.length} companies</strong>${active.size||query?' matching your filters':''}. Click a column to sort, a row to open the profile. Stage is the last publicly reported round.</div>\\n      <table>\\n        <thead><tr>${th('name','Company')}${th('fmts','Formats')}${th('stage','Stage')}${th('hq','HQ')}<th>Investors</th><th>Checked</th><th></th></tr></thead>\\n        <tbody>${rows.map(c=>`\\n          <tr data-id=\\\"${c.id}\\\">\\n            <td class=\\\"name\\\">${c.name}<span>${c.desc.split('. ')[0]}.</span></td>\\n            <td>${c.fmts.map(id=>`<span class=\\\"chip\\\"><i style=\\\"color:${FMT[id].color};background:${FMT[id].color}\\\"></i>${FMT[id].label}</span>`).join(' ')}</td>\\n            <td class=\\\"stage\\\">${c.stage}</td>\\n            <td class=\\\"muted\\\">${c.hq}</td>\\n            <td class=\\\"muted\\\">${c.investors}</td>\\n            <td class=\\\"muted\\\">${c.checked==='unverified'?'Unverified':c.checked}</td>\\n            <td><button class=\\\"star ${shortlist.includes(c.id)?'on':''}\\\" data-id=\\\"${c.id}\\\" aria-label=\\\"Toggle shortlist\\\">${shortlist.includes(c.id)?'★':'☆'}</button></td>\\n          </tr>`).join('')}\\n        </tbody>\\n      </table>\\n      <div class=\\\"list-intro\\\" style=\\\"margin-top:22px\\\">Published by <a href=\\\"https://www.ai-circle.org\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\" style=\\\"color:var(--ink)\\\">AI Circle</a>.</div>`;\\n    listEl.querySelectorAll('thead th[data-k]').forEach(h=>h.addEventListener('click', ()=>{\\n      const k=h.dataset.k; if(sortKey===k) sortDir*=-1; else { sortKey=k; sortDir=1; } renderList();\\n    }));\\n    listEl.querySelectorAll('tbody tr').forEach(r=>r.addEventListener('click', e=>{\\n      if(e.target.closest('.star')){ toggleShortlist(C[+e.target.closest('.star').dataset.id]); return; }\\n      openCompany(C[+r.dataset.id], false);\\n    }));\\n  }\\n\\n  // ---------------------------------------------------------------\\n  // Shortlist\\n  // ---------------------------------------------------------------\\n  function toggleShortlist(c){\\n    const i = shortlist.indexOf(c.id);\\n    if(i>=0) shortlist.splice(i,1); else shortlist.push(c.id);\\n    renderShortlist();\\n    if(selected===c) renderDrawer(c);\\n    if(view==='list') renderList();\\n  }\\n  function renderShortlist(){\\n    const items = document.getElementById('sl-items');\\n    const empty = document.getElementById('sl-empty');\\n    const copy = document.getElementById('sl-copy');\\n    empty.style.display = shortlist.length ? 'none':'';\\n    document.getElementById('shortlist').classList.toggle('has', shortlist.length>0);\\n    copy.hidden = !shortlist.length;\\n    items.innerHTML = shortlist.map(id=>{ const c=C[id]; return `\\n      <div class=\\\"sl-item\\\">${dotsFor(c)}<button class=\\\"open\\\" data-id=\\\"${id}\\\">${c.name}</button><button class=\\\"rm\\\" data-id=\\\"${id}\\\" aria-label=\\\"Remove\\\">\\xd7</button></div>`; }).join('');\\n    items.querySelectorAll('.open').forEach(b=>b.addEventListener('click', ()=>openCompany(C[+b.dataset.id], true)));\\n    items.querySelectorAll('.rm').forEach(b=>b.addEventListener('click', ()=>toggleShortlist(C[+b.dataset.id])));\\n  }\\n  document.getElementById('sl-copy').addEventListener('click', ()=>{\\n    const text = shortlist.map(id=>{ const c=C[id];\\n      return `${c.name} — ${c.fmts.map(f=>FMT[f].label).join(', ')} — ${c.stage}${c.round?' ('+c.round+')':''}${c.web?' — '+c.web:''}`; }).join('\\\\n');\\n    navigator.clipboard?.writeText(text).then(()=>{\\n      const b=document.getElementById('sl-copy'); b.textContent='Copied'; setTimeout(()=>b.textContent='Copy list',1400);\\n    });\\n  });\\n  renderShortlist();\\n\\n  // ---------------------------------------------------------------\\n  // Drawer\\n  // ---------------------------------------------------------------\\n  const drawer = document.getElementById('drawer');\\n  const dbody = document.getElementById('d-body');\\n  function initials(name){ return name.split(/[\\\\s()]+/).filter(Boolean).slice(0,2).map(w=>w[0]).join('').toUpperCase(); }\\n  function esc(s){ return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }\\n  function renderDrawer(c){\\n    const inList = shortlist.includes(c.id);\\n    const webBtn = c.web\\n      ? `<a class=\\\"btn primary\\\" href=\\\"${c.web}\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\">Visit website ↗</a>`\\n      : `<a class=\\\"btn primary\\\" href=\\\"https://www.google.com/search?q=${encodeURIComponent(c.name+' physical AI data')}\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\">Find their site ↗</a>`;\\n    const primaryColor = FMT[c.primary].color;\\n    dbody.innerHTML = `\\n      <div class=\\\"d-hero\\\">\\n        <div class=\\\"d-logo\\\" style=\\\"${c.imgFailed?`background:${primaryColor}`:''}\\\">${c.img?`<img src=\\\"${c.logo}\\\" alt=\\\"\\\">`:esc(initials(c.name))}</div>\\n        <div><h2 class=\\\"d-name\\\">${esc(c.name)}</h2><div class=\\\"d-sub\\\">${esc(c.hq)}${c.founded&&c.founded!=='—'?' \\xb7 founded '+esc(c.founded):''}</div></div>\\n      </div>\\n      <div class=\\\"d-fmts\\\">${c.fmts.map(id=>`<span class=\\\"chip\\\"><i style=\\\"color:${FMT[id].color};background:${FMT[id].color}\\\"></i>${FMT[id].label}</span>`).join('')}</div>\\n      <div class=\\\"d-desc\\\"><p>${esc(c.desc)}</p></div>\\n      <dl class=\\\"facts\\\">\\n        <dt>Stage</dt><dd class=\\\"stage\\\">${esc(c.stage)}</dd>\\n        <dt>Last round</dt><dd>${esc(c.round)}</dd>\\n        <dt>Investors</dt><dd>${esc(c.investors)}</dd>\\n        <dt>Website</dt><dd>${c.web?`<a href=\\\"${c.web}\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\">${c.web.replace(/^https?:\\\\/\\\\/(www\\\\.)?/,'').replace(/\\\\/$/,'')}</a>`:'<span style=\\\"color:var(--dim)\\\">Not confirmed</span>'}</dd>\\n      </dl>\\n      <div class=\\\"d-note\\\"><b>For buyers.</b> ${esc(c.note)}</div>\\n      <div class=\\\"d-actions\\\">\\n        ${webBtn}\\n        <button class=\\\"btn ${inList?'on':''}\\\" id=\\\"d-star\\\">${inList?'★ On shortlist':'☆ Add to shortlist'}</button>\\n        <button class=\\\"btn\\\" id=\\\"d-locate\\\">Show on map</button>\\n      </div>\\n      <div class=\\\"d-verify ${c.checked==='unverified'?'stale':'fresh'}\\\">${c.checked==='unverified'\\n        ? '<b>Unverified.</b> Compiled from prior knowledge; confirm stage, round, and website before diligence.'\\n        : `<b>Checked ${esc(c.checked)}</b> against public reporting. Rounds described as \\\"reported\\\" or \\\"in talks\\\" were not confirmed by the company.`}</div>\\n    `;\\n    dbody.querySelector('#d-star').addEventListener('click', ()=>toggleShortlist(c));\\n    dbody.querySelector('#d-locate').addEventListener('click', ()=>{ setView('map'); flyTo(c); });\\n    dbody.scrollTop = 0;\\n  }\\n  function openCompany(c, fly){\\n    selected = c; renderDrawer(c); drawer.classList.add('open');\\n    document.getElementById('intro').classList.add('hide');\\n    if(fly && view==='map') flyTo(c);\\n  }\\n  function closeDrawer(){ drawer.classList.remove('open'); selected=null; }\\n  document.getElementById('d-close').addEventListener('click', closeDrawer);\\n  function step(d){\\n    if(!selected) return;\\n    const pool = C.filter(companyMatches); if(!pool.length) return;\\n    let i = pool.indexOf(selected); if(i<0) i=0;\\n    openCompany(pool[(i+d+pool.length)%pool.length], true);\\n  }\\n  document.getElementById('d-prev').addEventListener('click', ()=>step(-1));\\n  document.getElementById('d-next').addEventListener('click', ()=>step(1));\\n  document.addEventListener('keydown', e=>{\\n    if(e.target.tagName==='INPUT') return;\\n    if(e.key==='Escape'){ closeDrawer(); }\\n    if(drawer.classList.contains('open')){\\n      if(e.key==='ArrowRight') step(1);\\n      if(e.key==='ArrowLeft') step(-1);\\n    }\\n  });\\n\\n  // ---------------------------------------------------------------\\n  // Intro\\n  // ---------------------------------------------------------------\\n  document.getElementById('intro-go').addEventListener('click', ()=>document.getElementById('intro').classList.add('hide'));\\n  if(isMobile()){\\n    setView('list');\\n    const go=document.getElementById('intro-go'), il=document.getElementById('intro-list');\\n    go.classList.remove('primary'); il.classList.add('primary');\\n    il.parentNode.insertBefore(il, go);\\n  }\\n  document.getElementById('intro-list').addEventListener('click', ()=>{ document.getElementById('intro').classList.add('hide'); setView('list'); });\\n\\n  // ---------------------------------------------------------------\\n  // Canvas + camera\\n  // ---------------------------------------------------------------\\n  const canvas = document.getElementById('scene');\\n  const ctx = canvas.getContext('2d');\\n  const wrap = document.getElementById('map');\\n  const tip = document.getElementById('tip');\\n  let W,H,DPR;\\n  let camX=0, camY=-70, scale=1;\\n  let tween=null;\\n\\n  function fitInitial(){\\n    const ext = RING_R + 260;\\n    const usableW = W - (drawer.classList.contains('open') && W>900 ? 400 : 0) - 300;\\n    scale = Math.max(0.3, Math.min(1.05, Math.min(usableW, H-150) / (ext*2.05)));\\n    camX = (drawer.classList.contains('open') && W>900) ? 200/scale : 0; camY=-70;\\n  }\\n  function measureTopbar(){ document.documentElement.style.setProperty('--tb', (document.getElementById('topbar').offsetHeight+6)+'px'); }\\n  window.addEventListener('resize', measureTopbar); measureTopbar();\\n  function resize(){\\n    DPR = Math.min(window.devicePixelRatio||1, 2);\\n    W = wrap.clientWidth; H = wrap.clientHeight;\\n    canvas.width=W*DPR; canvas.height=H*DPR; ctx.setTransform(DPR,0,0,DPR,0,0);\\n  }\\n  window.addEventListener('resize', resize);\\n  resize(); fitInitial();\\n\\n  function w2s(wx,wy){ return { x: W/2 + (wx-camX)*scale, y: H/2 + (wy-camY)*scale }; }\\n\\n  function flyTo(c){\\n    const node = NODES.find(n=>n.c===c); if(!node) return;\\n    const targetScale = Math.max(scale, 1.15);\\n    const offset = (drawer.classList.contains('open') && W>900) ? 200/targetScale : 0;\\n    const from = {x:camX,y:camY,s:scale}, to = {x:node.wx+offset, y:node.wy, s:targetScale};\\n    if(reduceMotion){ camX=to.x; camY=to.y; scale=to.s; return; }\\n    tween = { from, to, t0:performance.now(), dur:520 };\\n  }\\n\\n  let dragging=false, lastX=0, lastY=0, dragMoved=false;\\n  const pts=new Map(); let pinch=null;\\n  canvas.addEventListener('pointerdown', e=>{ pts.set(e.pointerId,{x:e.clientX,y:e.clientY}); if(pts.size===2){ const [a,b]=[...pts.values()]; pinch={d:Math.hypot(a.x-b.x,a.y-b.y), s:scale, cx:(a.x+b.x)/2, cy:(a.y+b.y)/2}; dragging=false; } }, {capture:true});\\n  canvas.addEventListener('pointermove', e=>{ if(!pts.has(e.pointerId)) return; pts.set(e.pointerId,{x:e.clientX,y:e.clientY});\\n    if(pinch && pts.size===2){ const [a,b]=[...pts.values()]; const d=Math.hypot(a.x-b.x,a.y-b.y); const r=canvas.getBoundingClientRect();\\n      const target=Math.max(0.3,Math.min(3,pinch.s*d/pinch.d)); zoomAt((a.x+b.x)/2-r.left,(a.y+b.y)/2-r.top, target/scale); e.stopImmediatePropagation(); } }, {capture:true});\\n  window.addEventListener('pointerup', e=>{ pts.delete(e.pointerId); if(pts.size<2) pinch=null; }, {capture:true});\\n  window.addEventListener('pointercancel', e=>{ pts.delete(e.pointerId); if(pts.size<2) pinch=null; }, {capture:true});\\n  canvas.addEventListener('pointerdown', e=>{\\n    dragging=true; dragMoved=false; lastX=e.clientX; lastY=e.clientY; tween=null;\\n    canvas.classList.add('grabbing'); canvas.setPointerCapture(e.pointerId);\\n  });\\n  window.addEventListener('pointerup', e=>{\\n    if(dragging && !dragMoved){\\n      if(hovered) openCompany(hovered.c, false);\\n    }\\n    dragging=false; canvas.classList.remove('grabbing');\\n  });\\n  let mx=-9999, my=-9999;\\n  canvas.addEventListener('pointermove', e=>{\\n    const r = canvas.getBoundingClientRect();\\n    mx=e.clientX-r.left; my=e.clientY-r.top;\\n    if(dragging){\\n      const dx=e.clientX-lastX, dy=e.clientY-lastY;\\n      if(Math.abs(dx)>2||Math.abs(dy)>2) dragMoved=true;\\n      lastX=e.clientX; lastY=e.clientY; camX-=dx/scale; camY-=dy/scale;\\n    }\\n  });\\n  canvas.addEventListener('mouseleave', ()=>{ mx=-9999; my=-9999; tip.classList.remove('show'); });\\n  function zoomAt(x,y,f){\\n    const wx=(x-W/2)/scale+camX, wy=(y-H/2)/scale+camY;\\n    scale = Math.max(0.26, Math.min(2.8, scale*f));\\n    camX = wx-(x-W/2)/scale; camY = wy-(y-H/2)/scale;\\n  }\\n  canvas.addEventListener('wheel', e=>{ e.preventDefault(); tween=null; const r=canvas.getBoundingClientRect(); zoomAt(e.clientX-r.left, e.clientY-r.top, 1-e.deltaY*0.0011); }, {passive:false});\\n  document.getElementById('reset').addEventListener('click', ()=>{ tween=null; fitInitial(); });\\n\\n  // ---------------------------------------------------------------\\n  // Render\\n  // ---------------------------------------------------------------\\n  const t0 = performance.now();\\n  let t=0;\\n  function rgba(hex,a){ const h=hex.replace('#',''); return `rgba(${parseInt(h.slice(0,2),16)},${parseInt(h.slice(2,4),16)},${parseInt(h.slice(4,6),16)},${Math.max(0,Math.min(1,a))})`; }\\n  const easeOut = x=>1-Math.pow(1-x,3);\\n\\n  function drawBackdrop(){\\n    // soft vignette + scan grain suggestion via fine grid\\n    const g = ctx.createRadialGradient(W*0.5,H*0.45,0,W*0.5,H*0.45,Math.max(W,H)*0.75);\\n    g.addColorStop(0,'#0a1220'); g.addColorStop(1,'#060a12');\\n    ctx.fillStyle=g; ctx.fillRect(0,0,W,H);\\n    const gs = 72*scale; const ox=(W/2-camX*scale)%gs, oy=(H/2-camY*scale)%gs;\\n    ctx.strokeStyle='rgba(236,234,226,0.032)'; ctx.lineWidth=1;\\n    ctx.beginPath();\\n    for(let x=ox-gs;x<W+gs;x+=gs){ ctx.moveTo(x,0); ctx.lineTo(x,H); }\\n    for(let y=oy-gs;y<H+gs;y+=gs){ ctx.moveTo(0,y); ctx.lineTo(W,y); }\\n    ctx.stroke();\\n    // crosshair at origin\\n    const o=w2s(0,0);\\n    ctx.strokeStyle='rgba(236,234,226,0.12)'; ctx.beginPath();\\n    ctx.moveTo(o.x-10,o.y); ctx.lineTo(o.x+10,o.y); ctx.moveTo(o.x,o.y-10); ctx.lineTo(o.x,o.y+10); ctx.stroke();\\n  }\\n\\n  function drawField(f, i, introK){\\n    const p = w2s(f.cx,f.cy); const r=f.r*scale*introK;\\n    const dim = active.size>0 && !active.has(f.id);\\n    const a = (dim?0.32:1) * introK;\\n    const g = ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,r*1.4);\\n    g.addColorStop(0,rgba(f.color,0.15*a)); g.addColorStop(0.6,rgba(f.color,0.05*a)); g.addColorStop(1,rgba(f.color,0));\\n    ctx.fillStyle=g; ctx.beginPath(); ctx.arc(p.x,p.y,r*1.4,0,Math.PI*2); ctx.fill();\\n    // contour rings with a slow breathe\\n    const breathe = reduceMotion?0:Math.sin(t*0.006+i)*0.012;\\n    [0.36,0.6,0.84,1.0].forEach((k,j)=>{\\n      ctx.beginPath(); ctx.arc(p.x,p.y,r*(k+breathe*(j+1)),0,Math.PI*2);\\n      ctx.strokeStyle=rgba(f.color,(0.2-j*0.04)*a); ctx.lineWidth=j===3?1.2:1; ctx.stroke();\\n    });\\n    // tick marks on the outer ring\\n    ctx.strokeStyle=rgba(f.color,0.35*a); ctx.lineWidth=1;\\n    for(let k=0;k<24;k++){ const ang=k*Math.PI/12; const r1=r*1.0, r2=r*(k%6===0?1.06:1.03);\\n      ctx.beginPath(); ctx.moveTo(p.x+Math.cos(ang)*r1,p.y+Math.sin(ang)*r1); ctx.lineTo(p.x+Math.cos(ang)*r2,p.y+Math.sin(ang)*r2); ctx.stroke(); }\\n    if(scale>0.3){\\n      const fs = Math.max(15, 22*Math.min(scale,1));\\n      ctx.font=`400 ${fs}px ${'\\\"Instrument Serif\\\"'}, Georgia, serif`;\\n      ctx.fillStyle=rgba('#eceae2',0.9*a); ctx.textAlign='center';\\n      ctx.fillText(f.label, p.x, p.y-r-16);\\n      ctx.font=`400 ${Math.max(11, 12.5*Math.min(scale,1))}px \\\"Schibsted Grotesk\\\", system-ui, sans-serif`;\\n      ctx.fillStyle=rgba(f.color,0.9*a);\\n      ctx.fillText(`${f.count} companies \\xb7 ${f.sub}`, p.x, p.y-r+2);\\n      ctx.textAlign='left';\\n    }\\n  }\\n\\n  function nodePos(n){\\n    const b = reduceMotion?0:2.6;\\n    return w2s(n.wx+Math.sin(t*0.01*n.speed+n.phase)*b, n.wy+Math.cos(t*0.008*n.speed+n.phase)*b);\\n  }\\n\\n  function arc(a,b,color,alpha,dash){\\n    ctx.save(); if(dash) ctx.setLineDash([5,5]);\\n    ctx.strokeStyle=rgba(color,alpha); ctx.lineWidth=1.4;\\n    const midX=(a.x+b.x)/2, midY=(a.y+b.y)/2, dx=b.x-a.x, dy=b.y-a.y;\\n    const nx=-dy, ny=dx; const len=Math.hypot(nx,ny)||1; const bend=Math.min(120*scale, len*0.18);\\n    ctx.beginPath(); ctx.moveTo(a.x,a.y); ctx.quadraticCurveTo(midX+nx/len*bend, midY+ny/len*bend, b.x,b.y); ctx.stroke();\\n    ctx.restore();\\n  }\\n\\n  function draw(now){\\n    t += 1;\\n    if(tween){\\n      const k = Math.min(1,(now-tween.t0)/tween.dur), e=easeOut(k);\\n      camX = tween.from.x+(tween.to.x-tween.from.x)*e; camY = tween.from.y+(tween.to.y-tween.from.y)*e; scale = tween.from.s+(tween.to.s-tween.from.s)*e;\\n      if(k>=1) tween=null;\\n    }\\n    ctx.clearRect(0,0,W,H);\\n    drawBackdrop();\\n\\n    const elapsed = now - t0;\\n    FORMATS.forEach((f,i)=>{\\n      const introK = reduceMotion ? 1 : easeOut(Math.max(0,Math.min(1,(elapsed - i*90)/700)));\\n      drawField(f,i,introK);\\n    });\\n\\n    // hover hit test\\n    hovered=null; let best=Infinity;\\n    NODES.forEach(n=>{\\n      if(!nodeVisible(n)) return;\\n      const p=nodePos(n); const rad=Math.max(16*scale,10)*1.5;\\n      const d2=(mx-p.x)**2+(my-p.y)**2;\\n      if(d2<rad*rad && d2<best){ best=d2; hovered=n; }\\n    });\\n    canvas.classList.toggle('hovering', !!hovered && !dragging);\\n\\n    // highlight company = hovered or selected\\n    const focusC = hovered ? hovered.c : selected;\\n    if(focusC && focusC.fmts.length>1){\\n      const inst = NODES.filter(n=>n.c===focusC && nodeVisible(n)).map(nodePos);\\n      for(let i=0;i<inst.length;i++) for(let j=i+1;j<inst.length;j++) arc(inst[i],inst[j],'#eceae2',0.45,true);\\n    }\\n\\n    // nodes\\n    NODES.forEach(n=>{\\n      const vis=nodeVisible(n); const p=nodePos(n);\\n      if(p.x<-40||p.x>W+40||p.y<-40||p.y>H+40) return;\\n      const c=n.c, isFocus = focusC===c, isHover = hovered===n;\\n      const R=(isFocus?38:32)*scale;\\n      const alpha = vis ? 1 : 0.1;\\n      const col=n.f.color;\\n\\n      if(isFocus){\\n        const g=ctx.createRadialGradient(p.x,p.y,0,p.x,p.y,R*3.2);\\n        g.addColorStop(0,rgba(col,0.4)); g.addColorStop(1,rgba(col,0));\\n        ctx.fillStyle=g; ctx.beginPath(); ctx.arc(p.x,p.y,R*3.2,0,Math.PI*2); ctx.fill();\\n      }\\n      ctx.beginPath(); ctx.arc(p.x,p.y,R+3,0,Math.PI*2);\\n      ctx.strokeStyle=rgba(col,alpha*(isFocus?1:0.7)); ctx.lineWidth=isFocus?2.4:1.5; ctx.stroke();\\n\\n      ctx.save(); ctx.beginPath(); ctx.arc(p.x,p.y,R,0,Math.PI*2); ctx.clip(); ctx.globalAlpha=alpha;\\n      ctx.fillStyle='#f3f1ec'; ctx.fillRect(p.x-R,p.y-R,R*2,R*2);\\n      if(c.imgLoaded && c.img){\\n        const iw=c.img.naturalWidth||1, ih=c.img.naturalHeight||1, s=(2*R*0.92)/Math.hypot(iw,ih);\\n        ctx.drawImage(c.img,p.x-iw*s/2,p.y-ih*s/2,iw*s,ih*s);\\n      } else {\\n        ctx.fillStyle=rgba(col,0.95); ctx.fillRect(p.x-R,p.y-R,R*2,R*2);\\n        ctx.fillStyle='#0b1220'; ctx.font=`600 ${R*0.8}px \\\"Schibsted Grotesk\\\", system-ui, sans-serif`;\\n        ctx.textAlign='center'; ctx.textBaseline='middle'; ctx.fillText(initials(c.name),p.x,p.y+1);\\n        ctx.textAlign='left'; ctx.textBaseline='alphabetic';\\n      }\\n      ctx.restore();\\n\\n      // other-format markers around the badge\\n      if(c.fmts.length>1 && vis && scale>0.42){\\n        c.fmts.forEach((id,idx)=>{ if(id===n.f.id) return;\\n          const ang = idx*2.4 + (reduceMotion?0:t*0.004);\\n          const q={x:p.x+Math.cos(ang)*(R+9), y:p.y+Math.sin(ang)*(R+9)};\\n          ctx.beginPath(); ctx.arc(q.x,q.y,2.6*Math.max(scale,0.6),0,Math.PI*2); ctx.fillStyle=rgba(FMT[id].color,0.95); ctx.fill(); });\\n      }\\n      if(isFocus && (isHover || selected===c) && scale>0.5){\\n        ctx.font=`500 13px \\\"Schibsted Grotesk\\\", system-ui, sans-serif`; ctx.fillStyle='rgba(236,234,226,0.95)';\\n        ctx.textBaseline='middle'; ctx.fillText(c.name,p.x+R+10,p.y); ctx.textBaseline='alphabetic';\\n      }\\n    });\\n\\n    // shortlist rings\\n    if(shortlist.length){\\n      NODES.forEach(n=>{ if(!shortlist.includes(n.c.id)||!nodeVisible(n)) return; const p=nodePos(n);\\n        ctx.beginPath(); ctx.arc(p.x,p.y,(32*scale)+7,0,Math.PI*2); ctx.strokeStyle=rgba('#f5c86b',0.8); ctx.lineWidth=1.2; ctx.setLineDash([2,3]); ctx.stroke(); ctx.setLineDash([]); });\\n    }\\n\\n    // tooltip\\n    if(hovered && !dragging){\\n      const c=hovered.c, p=nodePos(hovered);\\n      tip.innerHTML=`<div class=\\\"tn\\\">${esc(c.name)}</div><div class=\\\"ts\\\">${esc(c.stage)}${c.fmts.length>1?` \\xb7 ${c.fmts.length} formats`:''}</div><div class=\\\"tk\\\">Click for profile</div>`;\\n      let left=p.x+26, top=p.y-14; if(left+270>W) left=p.x-284; if(top+110>H) top=H-116; if(top<70) top=70;\\n      tip.style.left=left+'px'; tip.style.top=top+'px'; tip.classList.add('show');\\n    } else tip.classList.remove('show');\\n\\n    requestAnimationFrame(draw);\\n  }\\n  requestAnimationFrame(draw);\\n  refresh();\\n\\n})();\\n</script>\\n</body>\\n</html>\\n\";const PREVIEW_CSS=\"<style>#topbar,#rail,#shortlist,#controls,#intro,#drawer,#hint,#tip,#aic-foot,#list,#search-hits{display:none!important}#map,#scene{position:absolute!important;inset:0!important;top:0!important;left:0!important;width:100%!important;height:100%!important}html,body{overflow:hidden!important}</style></head>\";const PREVIEW_TOUR=\"\\n  // preview tour: focus one format, then move anti-clockwise to the next\\n  (function(){ if(!window.__aicPreviewTour) return; var i=0; function go(){ var n=FORMATS.length; var f=FORMATS[((i%n)+n)%n]; active.clear(); active.add(f.id); var s=Math.max(0.35, Math.min(2.2, Math.min(W,H)/(f.r*2.3))); tween={t0:performance.now(),dur:1500,from:{x:camX,y:camY,s:scale},to:{x:f.cx,y:f.cy,s:s}}; i--; } setTimeout(function(){ go(); setInterval(go, 4200); }, 1200); })();\\n})();\\n</script>\";const PREVIEW_HTML=ATLAS_HTML.replace(\"</head>\",PREVIEW_CSS).replace(\"<script>\\n(function(){\",\"<script>window.__aicPreviewTour=true;\\n(function(){\").replace(\"\\n})();\\n</script>\",PREVIEW_TOUR);/**\n * @framerSupportedLayoutWidth any\n * @framerSupportedLayoutHeight any\n */export default function HumanDataAtlasEmbed(props){const{minHeight=560,headerOffset=93,preview=false,style}=props;const ref=useRef(null);const[h,setH]=useState(null);// Measure our own top edge so the atlas fills exactly the space below the\n// site header at every breakpoint (header height differs desktop vs phone).\nuseEffect(()=>{if(typeof window===\"undefined\"||preview)return;const fit=()=>{const top=ref.current?ref.current.getBoundingClientRect().top+window.scrollY:headerOffset;setH(Math.max(minHeight,window.innerHeight-top));};fit();window.addEventListener(\"resize\",fit);window.addEventListener(\"orientationchange\",fit);return()=>{window.removeEventListener(\"resize\",fit);window.removeEventListener(\"orientationchange\",fit);};},[headerOffset,minHeight,preview]);return /*#__PURE__*/_jsx(\"div\",{ref:ref,style:{position:\"relative\",width:\"100%\",height:preview?\"100%\":h??`calc(100vh - ${headerOffset}px)`,minHeight:preview?0:minHeight,background:\"#060a12\",...style},children:/*#__PURE__*/_jsx(\"iframe\",{title:\"Physical AI Atlas - companies selling human data for physical AI\",srcDoc:preview?PREVIEW_HTML:ATLAS_HTML,tabIndex:preview?-1:0,sandbox:\"allow-scripts allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-top-navigation-by-user-activation\",style:{position:\"absolute\",inset:0,width:\"100%\",height:\"100%\",border:0,display:\"block\",background:\"#060a12\",pointerEvents:preview?\"none\":\"auto\"}})});}addPropertyControls(HumanDataAtlasEmbed,{headerOffset:{type:ControlType.Number,title:\"Header offset\",defaultValue:93,min:0,max:200,step:1,unit:\"px\"},minHeight:{type:ControlType.Number,title:\"Min height\",defaultValue:560,min:400,max:1400,step:10,unit:\"px\"},preview:{type:ControlType.Boolean,title:\"Preview mode\",defaultValue:false}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"HumanDataAtlasEmbed\",\"slots\":[],\"annotations\":{\"framerSupportedLayoutHeight\":\"any\",\"framerContractVersion\":\"1\",\"framerSupportedLayoutWidth\":\"any\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./HumanDataAtlasEmbed.map"],"mappings":"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"}