Back to Bubbles
SOURCE / PINNED RELEASE

Made of little things.

Bubbles

Release
7fe0b99c0558…
Author-recorded commit
Not provided
License
Check the original source

The hash-verified playable HTML, which may contain bundled or minified code. This view does not execute it.

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="color-scheme" content="dark" />
    <meta name="description" content="A follows feed as a constellation: notes as bubbles, read through the host's outbox." />
    <meta name="napplet-requires" content="identity,outbox,resource,storage" />
    <title>Bubbles</title>
    <script type="module" crossorigin>function Wo(){const e=window;if(!e.napplet)throw new Error("window.napplet is unavailable -- runtime did not inject the napplet namespace");return e.napplet}function D(e){const n=Wo()[e];if(!n)throw new Error(`window.napplet.${String(e)} is unavailable -- runtime did not inject this domain`);return n}var Et={getItem(e){return D("storage").getItem(e)},setItem(e,t){return D("storage").setItem(e,t)},removeItem(e){return D("storage").removeItem(e)},keys(){return D("storage").keys()},instance:{getItem(e){return D("storage").instance.getItem(e)},setItem(e,t){return D("storage").instance.setItem(e,t)},removeItem(e){return D("storage").instance.removeItem(e)},keys(){return D("storage").instance.keys()}}},wn={getPublicKey(){return D("identity").getPublicKey()},onChanged(e){return D("identity").onChanged(e)},getRelays(){return D("identity").getRelays()},getProfile(){return D("identity").getProfile()},getFollows(){return D("identity").getFollows()},getList(e){return D("identity").getList(e)},getZaps(){return D("identity").getZaps()},getMutes(){return D("identity").getMutes()},getBlocked(){return D("identity").getBlocked()},getBadges(){return D("identity").getBadges()}},Fo={info(){return D("resource").info()},bytes(e,t){return D("resource").bytes(e,t)},bytesMany(e,t){return D("resource").bytesMany(e,t)},bytesAsObjectURL(e){return D("resource").bytesAsObjectURL(e)}},Go={getEvent(e,t){return D("outbox").getEvent(e,t)},query(e,t){return D("outbox").query(e,t)},subscribe(e,t){return D("outbox").subscribe(e,t)},publish(e,t){return D("outbox").publish(e,t)},resolveRelays(e){return D("outbox").resolveRelays(e)}};const X={profile:0,note:1,repost:6,reaction:7},Yo=100,zo=1440*60*1e3,Xo=30,qo=50,Vo=1e4,Ko=50,Jo="I work on a decentralized AI marketplace, so my work is a lot about LLMs and AI agents. We also do Bitcoin payments using Lightning and Cashu. I want the posts that are relevant to that work at the top, and the ones that are not at the bottom.";/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Qo(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function Zo(e,t,n=""){const o=Qo(e),r=e?.length;if(!o||t!==void 0){const i=n&&`"${n}" `,c="",d=o?`length=${r}`:`type=${typeof e}`;throw new Error(i+"expected Uint8Array"+c+", got "+d)}return e}const jn=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",er=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function pe(e){if(Zo(e),jn)return e.toHex();let t="";for(let n=0;n<e.length;n++)t+=er[e[n]];return t}const re={_0:48,_9:57,A:65,F:70,a:97,f:102};function vn(e){if(e>=re._0&&e<=re._9)return e-re._0;if(e>=re.A&&e<=re.F)return e-(re.A-10);if(e>=re.a&&e<=re.f)return e-(re.a-10)}function Wn(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);if(jn)return Uint8Array.fromHex(e);const t=e.length,n=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);const o=new Uint8Array(n);for(let r=0,s=0;r<n;r++,s+=2){const i=vn(e.charCodeAt(s)),c=vn(e.charCodeAt(s+1));if(i===void 0||c===void 0){const d=e[s]+e[s+1];throw new Error('hex string expected, got non-hex character "'+d+'" at index '+s)}o[r]=i*16+c}return o}/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Fn(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function Gn(e,t){return Array.isArray(t)?t.length===0?!0:e?t.every(n=>typeof n=="string"):t.every(n=>Number.isSafeInteger(n)):!1}function tr(e){if(typeof e!="function")throw new Error("function expected");return!0}function Ce(e,t){if(typeof t!="string")throw new Error(`${e}: string expected`);return!0}function Yn(e){if(!Number.isSafeInteger(e))throw new Error(`invalid integer: ${e}`)}function St(e){if(!Array.isArray(e))throw new Error("array expected")}function zn(e,t){if(!Gn(!0,t))throw new Error(`${e}: array of strings expected`)}function Xn(e,t){if(!Gn(!1,t))throw new Error(`${e}: array of numbers expected`)}function nr(...e){const t=s=>s,n=(s,i)=>c=>s(i(c)),o=e.map(s=>s.encode).reduceRight(n,t),r=e.map(s=>s.decode).reduce(n,t);return{encode:o,decode:r}}function or(e){const t=typeof e=="string"?e.split(""):e,n=t.length;zn("alphabet",t);const o=new Map(t.map((r,s)=>[r,s]));return{encode:r=>(St(r),r.map(s=>{if(!Number.isSafeInteger(s)||s<0||s>=n)throw new Error(`alphabet.encode: digit index outside alphabet "${s}". Allowed: ${e}`);return t[s]})),decode:r=>(St(r),r.map(s=>{Ce("alphabet.decode",s);const i=o.get(s);if(i===void 0)throw new Error(`Unknown letter: "${s}". Allowed: ${e}`);return i}))}}function rr(e=""){return Ce("join",e),{encode:t=>(zn("join.decode",t),t.join(e)),decode:t=>(Ce("join.decode",t),t.split(e))}}const qn=(e,t)=>t===0?e:qn(t,e%t),Ve=(e,t)=>e+(t-qn(e,t)),ze=(()=>{let e=[];for(let t=0;t<40;t++)e.push(2**t);return e})();function kt(e,t,n,o){if(St(e),t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(n<=0||n>32)throw new Error(`convertRadix2: wrong to=${n}`);if(Ve(t,n)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${n} carryBits=${Ve(t,n)}`);let r=0,s=0;const i=ze[t],c=ze[n]-1,d=[];for(const u of e){if(Yn(u),u>=i)throw new Error(`convertRadix2: invalid data word=${u} from=${t}`);if(r=r<<t|u,s+t>32)throw new Error(`convertRadix2: carry overflow pos=${s} from=${t}`);for(s+=t;s>=n;s-=n)d.push((r>>s-n&c)>>>0);const h=ze[s];if(h===void 0)throw new Error("invalid carry");r&=h-1}if(r=r<<n-s&c,!o&&s>=t)throw new Error("Excess padding");if(!o&&r>0)throw new Error(`Non-zero padding: ${r}`);return o&&s>0&&d.push(r>>>0),d}function sr(e,t=!1){if(Yn(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(Ve(8,e)>32||Ve(e,8)>32)throw new Error("radix2: carry overflow");return{encode:n=>{if(!Fn(n))throw new Error("radix2.encode input should be Uint8Array");return kt(Array.from(n),8,e,!t)},decode:n=>(Xn("radix2.decode",n),Uint8Array.from(kt(n,e,8,t)))}}function En(e){return tr(e),function(...t){try{return e.apply(null,t)}catch{}}}const Mt=nr(or("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),rr("")),Sn=[996825010,642813549,513874426,1027748829,705979059];function xe(e){const t=e>>25;let n=(e&33554431)<<5;for(let o=0;o<Sn.length;o++)(t>>o&1)===1&&(n^=Sn[o]);return n}function kn(e,t,n=1){const o=e.length;let r=1;for(let s=0;s<o;s++){const i=e.charCodeAt(s);if(i<33||i>126)throw new Error(`Invalid prefix (${e})`);r=xe(r)^i>>5}r=xe(r);for(let s=0;s<o;s++)r=xe(r)^e.charCodeAt(s)&31;for(let s of t)r=xe(r)^s;for(let s=0;s<6;s++)r=xe(r);return r^=n,Mt.encode(kt([r%ze[30]],30,5,!1))}function ar(e){const t=e==="bech32"?1:734539939,n=sr(5),o=n.decode,r=n.encode,s=En(o);function i(l,g,y=90){Ce("bech32.encode prefix",l),Fn(g)&&(g=Array.from(g)),Xn("bech32.encode",g);const w=l.length;if(w===0)throw new TypeError(`Invalid prefix length ${w}`);const p=w+7+g.length;if(y!==!1&&p>y)throw new TypeError(`Length ${p} exceeds limit ${y}`);const b=l.toLowerCase(),E=kn(b,g,t);return`${b}1${Mt.encode(g)}${E}`}function c(l,g=90){Ce("bech32.decode input",l);const y=l.length;if(y<8||g!==!1&&y>g)throw new TypeError(`invalid string length: ${y} (${l}). Expected (8..${g})`);const w=l.toLowerCase();if(l!==w&&l!==l.toUpperCase())throw new Error("String must be lowercase or uppercase");const p=w.lastIndexOf("1");if(p===0||p===-1)throw new Error('Letter "1" must be present between prefix and data only');const b=w.slice(0,p),E=w.slice(p+1);if(E.length<6)throw new Error("Data must be at least 6 characters long");const x=Mt.decode(E).slice(0,-6),M=kn(b,x,t);if(!E.endsWith(M))throw new Error(`Invalid checksum in ${l}: expected "${M}"`);return{prefix:b,words:x}}const d=En(c);function u(l){const{prefix:g,words:y}=c(l,!1);return{prefix:g,words:y,bytes:o(y)}}function h(l,g){return i(l,r(g))}return{encode:i,decode:c,encodeFromBytes:h,decodeToBytes:u,decodeUnsafe:d,fromWords:o,fromWordsUnsafe:s,toWords:r}}const Ke=ar("bech32");var je=new TextDecoder("utf-8");new TextEncoder;var Vn=5e3;function Ct(e){let{prefix:t,words:n}=Ke.decode(e,Vn),o=new Uint8Array(Ke.fromWords(n));switch(t){case"nprofile":{let r=pt(o);if(!r[0]?.[0])throw new Error("missing TLV 0 for nprofile");if(r[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");return{type:"nprofile",data:{pubkey:pe(r[0][0]),relays:r[1]?r[1].map(s=>je.decode(s)):[]}}}case"nevent":{let r=pt(o);if(!r[0]?.[0])throw new Error("missing TLV 0 for nevent");if(r[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");if(r[2]&&r[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(r[3]&&r[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"nevent",data:{id:pe(r[0][0]),relays:r[1]?r[1].map(s=>je.decode(s)):[],author:r[2]?.[0]?pe(r[2][0]):void 0,kind:r[3]?.[0]?parseInt(pe(r[3][0]),16):void 0}}}case"naddr":{let r=pt(o);if(!r[0]?.[0])throw new Error("missing TLV 0 for naddr");if(!r[2]?.[0])throw new Error("missing TLV 2 for naddr");if(r[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(!r[3]?.[0])throw new Error("missing TLV 3 for naddr");if(r[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"naddr",data:{identifier:je.decode(r[0][0]),pubkey:pe(r[2][0]),kind:parseInt(pe(r[3][0]),16),relays:r[1]?r[1].map(s=>je.decode(s)):[]}}}case"nsec":return{type:t,data:o};case"npub":case"note":return{type:t,data:pe(o)};default:throw new Error(`unknown prefix ${t}`)}}function pt(e){let t={},n=e;for(;n.length>0;){if(n.length<2)throw new Error("not enough data to read TLV");let o=n[0],r=n[1],s=n.slice(2,2+r);if(n=n.slice(2+r),s.length<r)throw new Error(`not enough data to read on TLV ${o}`);t[o]=t[o]||[],t[o].push(s)}return t}function ir(e){return Jn("npub",Wn(e))}function Kn(e){return Jn("note",Wn(e))}function lr(e,t){let n=Ke.toWords(t);return Ke.encode(e,n,Vn)}function Jn(e,t){return lr(e,t)}function cr(e){const t=Ct(e);if(!t)throw new Error(`not a NIP-19 pointer: ${e}`);return t}function It(e){return ir(e)}function dr(e){return Kn(e)}function ur(e){const t=cr(e.trim());if(t.type!=="note")throw new Error(`not a note id: ${e}`);return t.data}function Lt(e){try{return JSON.parse(e.content)}catch{return}}function fr(e){const t=[],n=/nostr:(npub1[a-z0-9]+|nprofile1[a-z0-9]+|note1[a-z0-9]+)/gi;for(const o of e.matchAll(n)){const r=o[1];if(r)try{t.push(Ct(r))}catch{}}return t}function Qn(e){if(e.type==="npub")return e.data;if(e.type==="nprofile")return e.data.pubkey}function hr(e){try{return Kn(e)}catch{return e}}function pr(e){try{const t=Ct(e),n=Qn(t);return n?{pubkey:n}:void 0}catch{return}}const mr={nostrLink:/nostr:(npub1[a-z0-9]+|nprofile1[a-z0-9]+|note1[a-z0-9]+)/gi};function Je(e,t){const n=[];for(let o=0;o<e.length;o+=t)n.push(e.slice(o,o+t));return n}function Zn(e,t,n){const o=new Set(t.map(i=>i.id)),r=new Map;for(const i of e){if(i.kind!==n)continue;let c;for(const u of i.tags)u[0]==="e"&&u[1]&&o.has(u[1])&&(c=u[1]);if(!c)continue;let d=r.get(c);d||r.set(c,d=new Map),d.set(i.id,i)}const s=new Map;for(const[i,c]of r){const d=[...c.values()].sort((u,h)=>u.created_at-h.created_at);d.length>0&&s.set(i,d)}return s}function gr(e,t){const n=Zn(e,t,X.reaction),o={};for(const[r,s]of n)o[r]=s.map(i=>({id:i.id,pubkey:i.pubkey,content:i.content}));return o}function Xe(e){let t,n;for(const o of e.tags){if(o[0]!=="e"||!o[1])continue;const r=o[3];r!=="mention"&&(r==="reply"&&(t=o[1]),n=o[1])}return t??n}const eo=32;function yr(e,t){const n=e.known.get(t);return n?Xe(n):void 0}function br(e,t){const n=[t],o=new Set([t]);for(;n.length<=eo;){const r=yr(e,n[n.length-1]);if(!r||o.has(r)||!e.known.has(r))break;n.push(r),o.add(r)}return n}async function wr(e,t){const{known:n,runQuery:o,idsPerRequest:r,replyLimit:s,log:i}=e;let c=new Set;for(const b of t){const E=Xe(b);E&&!n.has(E)&&c.add(E)}for(let b=0;c.size>0&&b<eo;b++){const E=[...c];c=new Set;for(const x of Je(E,r))for(const M of await o({kinds:[X.note],ids:x})){const R=Xe(M);R&&!n.has(R)&&c.add(R)}}const d=new Map,u=new Map,h=new Map,l=(b,E)=>{const x=n.get(b);if(!x||(d.set(b,E),!E.parent))return;const M=u.get(E.parent)??[];M.push({id:b,pubkey:x.pubkey,parent:E.parent,created_at:x.created_at}),u.set(E.parent,M),h.set(E.root,(h.get(E.root)??0)+1)};for(const b of t){const E=br(e,b.id),x=E[E.length-1];for(const[M,R]of E.entries())d.has(R)||l(R,{parent:E[M+1],root:x})}const g=[...d.keys()];for(let b=0;b<g.length;b+=r){const E=g.slice(b,b+r),x=await o({kinds:[X.note],"#e":E,limit:s});for(const M of x){if(d.has(M.id))continue;const R=Xe(M);if(!R)continue;const A=d.get(R);A&&((h.get(A.root)??0)>=s||(l(M.id,{parent:R,root:A.root}),g.push(M.id)))}}const y={},w=[];for(const[b,E]of d){if(E.parent)continue;w.push(b);const x=[],M=new Set([b]),R=A=>{for(const C of u.get(A)??[])M.has(C.id)||(M.add(C.id),x.push(C),R(C.id))};R(b),x.length>0&&(x.sort((A,C)=>A.created_at-C.created_at),y[b]=x)}const p=Object.values(y).reduce((b,E)=>b+E.length,0);return i(`threads: ${Object.keys(y).length} roots with ${p} replies (from ${w.length} roots)`),{threads:y,roots:w}}function vr(e){const t=[];for(const n of fr(e)){const o=Qn(n);o&&t.push(o)}return t}function Er(e){let t;for(const n of e.tags)n[0]==="e"&&n[1]&&(t=n[1]);return t}function Sr(e,t){const n={};for(const[o,r]of Zn(e,t,X.repost))n[o]=r.map(s=>({id:s.id,pubkey:s.pubkey}));return n}async function kr(e){const{known:t,follows:n,noteLimit:o,repostLimit:r,idsPerRequest:s,runQuery:i,log:c}=e,d=[...t.values()].filter(y=>y.kind===X.note&&n.has(y.pubkey)).sort((y,w)=>w.created_at-y.created_at).slice(0,o),u=new Map;for(const y of t.values()){if(y.kind!==X.repost||!n.has(y.pubkey))continue;const w=Er(y);if(!w||t.has(w))continue;const p=u.get(w);(!p||p.created_at<y.created_at)&&u.set(w,y)}const h=[...u.entries()].sort((y,w)=>w[1].created_at-y[1].created_at).slice(0,r).map(([y])=>y);if(h.length>0){c(`fetching ${h.length} notes the follows reposted`);for(const y of Je(h,s))await i({kinds:[X.note],ids:y})}const l=h.map(y=>t.get(y)).filter(y=>!!y),g=[...d,...l].sort((y,w)=>w.created_at-y.created_at);return{notes:d,repostNotes:l,kept:g}}async function Mr(e,t,n){try{const o=await Go.query([e],{authors:e.authors,limit:e.limit,timeoutMs:t});return o.error&&n(`outbox query error: ${o.error}`),o.incomplete&&n("outbox query came back incomplete"),o.events.map(r=>r.event).filter(Boolean)}catch(o){return n(`outbox query failed: ${o instanceof Error?o.message:String(o)}`),[]}}async function xr(e={}){const{pubkey:t=await wn.getPublicKey(),noteLimit:n=Yo,since:o=Math.floor((Date.now()-zo)/1e3),authorsPerRequest:r=qo,replyLimit:s=Ko,repostLimit:i=Xo,timeoutMs:c=Vo,log:d=()=>{},onProgress:u=()=>{}}=e,h=new Map,l={follows:0,batches:0,batchesTotal:0,notes:0,threads:0,replies:0},g=()=>{let $=0;for(const G of h.values())G.kind===X.note&&($+=1);return $},y=()=>{u({...l})},w=async($,G)=>{const N=await Mr($,c,d);for(const ve of N)h.set(ve.id,ve);return N},p=await wn.getFollows();if(p.length===0)throw new Error("the account follows nobody yet — follow someone to give the field something to draw");d(`reading ${p.length} follows through the outbox`);const b=Je(p,r),E=Math.ceil(n/b.length)+r,x=o===null?{}:{since:o};l.follows=p.length,l.batchesTotal=b.length,y();for(const $ of b)await Promise.all([w({kinds:[X.note],authors:$,limit:E,...x}),w({kinds:[X.repost],authors:$,limit:E,...x}),w({kinds:[X.profile],authors:$,limit:$.length})]),l.batches+=1,l.notes=g(),y();const{repostNotes:M,kept:R}=await kr({known:h,follows:new Set(p),noteLimit:n,repostLimit:i,idsPerRequest:r,runQuery:w,log:d});l.notes=R.length,y();const{threads:A,roots:C}=await wr({known:h,runQuery:w,idsPerRequest:r,replyLimit:s,log:d},R);l.threads=Object.keys(A).length,l.replies=Object.values(A).reduce(($,G)=>$+G.length,0),y();const[Y,L]=C.length>0?await Promise.all([w({kinds:[X.reaction],"#e":C,limit:500}),w({kinds:[X.repost],"#e":C,limit:500})]):[[],[]],H=C.map($=>h.get($)).filter($=>!!$),U=gr(Y,H),j=Sr(L,H),q=new Set([...R.map($=>$.id),...C,...Object.values(A).flatMap($=>$.map(G=>G.id))]),J=[...q].map($=>h.get($)).filter($=>!!$),Q=[...new Set([...H.map($=>$.pubkey),...Object.values(A).flatMap($=>$.map(G=>G.pubkey))])],S=[...new Set(Object.values(j).flatMap($=>$.map(G=>G.pubkey)))],O=[...new Set(J.flatMap($=>vr($.content)))],P=new Set([...h.values()].filter($=>$.kind===X.profile).map($=>$.pubkey)),V=[...new Set([...Q,...S,...O])].filter($=>!P.has($));for(const $ of Je(V,r))await w({kinds:[X.profile],authors:$,limit:$.length});const W=[...h.values()].filter($=>$.kind===X.note&&q.has($.id)).sort(($,G)=>G.created_at-$.created_at),K=[...h.values()].filter($=>$.kind===X.profile),F=[...K,...W],_=Object.values(A).reduce(($,G)=>$+G.length,0);return d(`built ${W.length} notes (${M.length} reposted by a follow) in ${C.length} roots, ${Object.keys(A).length} threads with ${_} replies and ${K.length} profiles`),{version:2,generatedAt:Date.now(),relays:[],profileRelays:[],npub:It(t),pubkey:t,contacts:{id:"",created_at:0,follows:p},since:o,events:F,reactions:U,reposts:j,threads:A,stats:{follows:p.length,notes:R.length,repostNotes:M.length,profiles:K.length,events:F.length,threads:Object.keys(A).length,replies:_}}}function Ar(){const e=new Map;return{add(t){e.set(t.id,t)},getEvent(t){return e.get(t)},getReplaceable(t,n){let o;for(const r of e.values())r.kind!==t||r.pubkey!==n||(!o||r.created_at>o.created_at)&&(o=r);return o}}}const to=["build","fun","relevant","irrelevant"];function no(e){const t=Math.max(0,Math.floor((Date.now()-e.getTime())/1e3));if(t<60)return`${t}s ago`;const n=Math.floor(t/60);if(n<60)return`${n}m ago`;const o=Math.floor(n/60);if(o<24)return`${o}h ago`;const r=Math.floor(o/24);return r<30?`${r}d ago`:e.toLocaleDateString()}function oo(e){return`${e.slice(0,8)}…${e.slice(-6)}`}function $r(e,t=Date.now()){if(e===null)return"all time";const n=Math.max(0,t-e*1e3)/864e5;if(n>=1.5)return`last ${Math.round(n)}d`;if(n>=1)return"last 24h";const o=n*24;return o>=1?`last ${Math.round(o)}h`:`last ${Math.max(1,Math.round(o*60))}m`}const Nt=new Map;async function Rr(){try{const e=await Et.keys(),t=await Promise.all(e.map(async n=>[n,await Et.getItem(n)]));for(const[n,o]of t)o!==null&&Nt.set(n,o)}catch{}}function Le(e){return Nt.get(e)??null}function Ne(e,t){Nt.set(e,t);try{Et.setItem(e,t).catch(()=>{})}catch{}}const Mn="bubbles.prompt";function Pr(e){const{initialPrompt:t,onStatus:n}=e;let o=Le(Mn)??t;const r=document.createElement("button");r.type="button",r.className="hud-prompt",r.textContent="Edit prompt",r.title="relevance is judged against your own description of your work",r.addEventListener("click",()=>p());const s=document.createElement("div");s.className="prompt",s.hidden=!0;const i=document.createElement("div");i.className="prompt-card",i.setAttribute("role","dialog"),i.setAttribute("aria-modal","true"),i.setAttribute("aria-label","your prompt");const c=document.createElement("h2");c.className="prompt-title",c.textContent="your prompt";const d=document.createElement("p");d.className="prompt-explain",d.textContent="Relevance is judged against this and nothing else. Describe your work; the posts about it rise to the top, and everything else sinks.";const u=document.createElement("textarea");u.className="prompt-field",u.rows=6,u.spellcheck=!1,u.setAttribute("aria-label","your prompt");const h=document.createElement("p");h.className="prompt-source",h.textContent="judgements are not part of this build — the prompt is saved for when jev returns";const l=document.createElement("p");l.className="prompt-error",l.hidden=!0;const g=document.createElement("div");g.className="prompt-actions";const y=document.createElement("button");y.type="button",y.className="prompt-save",y.textContent="Save",y.addEventListener("click",()=>E());const w=document.createElement("button");w.type="button",w.className="prompt-cancel",w.textContent="Cancel",w.addEventListener("click",()=>b()),g.append(y,w),i.append(c,d,u,h,l,g),s.append(i),s.addEventListener("pointerdown",x=>{x.target===s&&b()}),u.addEventListener("keydown",x=>{x.key==="Escape"&&(x.stopPropagation(),b())});function p(){u.value=o,l.hidden=!0,s.hidden=!1,u.focus(),u.setSelectionRange(u.value.length,u.value.length)}function b(){s.hidden=!0,r.focus()}function E(){const x=u.value.trim();if(!x){l.textContent="A prompt is what makes relevance mean anything — say what your work is.",l.hidden=!1;return}const M=x!==o;o=x,Ne(Mn,o),b(),n(M?"prompt saved — judgements are unavailable in this build":null)}return o!==t&&n("your saved prompt will matter again when jev returns"),{button:r,element:s,get prompt(){return o},dispose:()=>s.remove()}}function xn(e){const t=document.createElement("button");t.type="button",t.className="hud-toggle",t.textContent=e.label,t.title=e.title,t.addEventListener("click",()=>{e.onChange(t.getAttribute("aria-pressed")!=="true")});function n(o){t.setAttribute("aria-pressed",String(o))}return n(e.pressed),{element:t,set:n}}const ro="bubbles.seen",so="bubbles.hideSeen",ao=1,We=5e3;function Cr(e){const t=new Set(e),n=new Set(_r().filter(i=>t.has(i))),o=[];function r(){const i=[...n].filter(c=>t.has(c)).slice(-4e3);Ne(ro,JSON.stringify({v:ao,ids:i}))}function s(){r();for(const i of o)i()}return{has:i=>n.has(i),mark(i){!t.has(i)||n.has(i)||(n.add(i),s())},forget(i){n.delete(i)&&s()},reset(){n.size!==0&&(n.clear(),s())},onChange(i){o.push(i)}}}function Ir(){return Le(so)!=="false"}function Lr(e){Ne(so,String(e))}function Nr(e){const t=document.createElement("p");t.className="hud-seen-row";const n=document.createElement("button");n.type="button",n.className="hud-seen",n.textContent="hide seen",n.title="read a note and it dims; hide the ones you have read so the rest get the room (h)",n.addEventListener("click",()=>e.onToggle(!e.isHiding()));const o=document.createElement("span");o.className="hud-seen-count",o.setAttribute("aria-live","polite");const r=document.createElement("button");r.type="button",r.className="hud-seen-reset",r.textContent="reset",r.title="forget every note you have read",r.addEventListener("click",()=>e.onReset()),t.append(n,o,r);function s(){const{seen:i,total:c}=e.counts(),d=e.isHiding();n.setAttribute("aria-pressed",String(d)),o.textContent=i===0?c>0?`nothing read yet · ${c} in the field`:"nothing read yet":i>=c?`all ${c} notes read`:`${i} of ${c} notes read`,r.hidden=i===0}return s(),{element:t,refresh:s}}function _r(){const e=Le(ro);if(!e)return[];try{const t=JSON.parse(e);return t.v!==ao||!Array.isArray(t.ids)?[]:t.ids.filter(n=>typeof n=="string")}catch{return[]}}const Tr={follow:22,repel:5e3,repelRange:120,stiffness:1400,damping:14,holdDamping:12,hold:26,bond:4e3,maxSpeed:900,wall:40},Or=2;class Qe{bubbles=[];poles=[];centroid={x:0,y:0};bounds={minX:0,minY:0,maxX:0,maxY:0};tuning={...Tr};fixedStep=1/120;constructor(t=[]){this.bubbles.push(...t)}static pole(t,n=0,o=0){return{id:t,x:n,y:o}}static bubble(t,n,o,r,s,i=1){return{id:t,x:n,y:o,vx:0,vy:0,r,weights:s,hidden:!1,tailDepth:0,hold:0,holdX:n,holdY:o,scale:i,scaleTarget:i,ax:0,ay:0}}targetFor(t){const n=this.middle();if(this.poles.length<2)return{x:n.x,y:n.y};let o=n.x,r=n.y;const s=Math.min(t.length,this.poles.length);for(let i=0;i+1<s;i+=2){const c=this.poles[i],d=this.poles[i+1],u=Math.max(0,t[i]??0),h=Math.max(0,t[i+1]??0),l=u+h;if(l<=1e-9)continue;const g=(h-u)/l;o+=(d.x-c.x)/2*g,r+=(d.y-c.y)/2*g}return{x:o,y:r}}middle(){if(this.poles.length===0)return{x:this.centroid.x,y:this.centroid.y};let t=0,n=0;for(const o of this.poles)t+=o.x,n+=o.y;return{x:t/this.poles.length,y:n/this.poles.length}}bubbleAt(t,n){let o,r=1/0;for(const s of this.bubbles){if(s.hidden)continue;const i=t-s.x,c=n-s.y,d=s.r*Math.max(s.scale,1)+4;i*i+c*c>d*d||s.r<r&&(o=s,r=s.r)}return o}maxSpeed(){let t=0;for(const n of this.bubbles){const o=Math.sqrt(n.vx*n.vx+n.vy*n.vy);o>t&&(t=o)}return t}isSettled(t=Or){if(this.maxSpeed()>t)return!1;for(const n of this.bubbles)if(n.hold>0||Math.abs(n.scale-n.scaleTarget)>.002)return!1;return!0}step(t){const n=Math.min(6,Math.max(1,Math.ceil(t/this.fixedStep))),o=t/n;for(let r=0;r<n;r++)this.integrate(o);this.easeScale(t)}easeScale(t){const n=1-Math.exp(-16*t);for(const o of this.bubbles)o.scale+=(o.scaleTarget-o.scale)*n}freeze(){for(const t of this.bubbles)t.vx=0,t.vy=0,t.ax=0,t.ay=0;this.measure()}measure(){const{bubbles:t,centroid:n}=this;let o=0,r=0;for(const i of t)o+=i.x,r+=i.y;const s=Math.max(1,t.length);n.x=o/s,n.y=r/s}integrate(t){const{bubbles:n,bounds:o,tuning:r}=this;if(n.length===0)return;this.measure();const s=n.filter(l=>!l.hidden);if(s.length===0)return;const i=s.filter(l=>l.bond),c=s.filter(l=>!l.bond),d=new Map(s.map(l=>[l.id,l]));for(const l of s){if(l.bond){l.ax=0,l.ay=0;continue}const g=this.targetFor(l.weights);l.ax=(g.x-l.x)*r.follow,l.ay=(g.y-l.y)*r.follow}const u=r.repelRange,h=c.length;for(let l=0;l<h;l++){const g=c[l];for(let y=l+1;y<h;y++){const w=c[y],p=g.r+w.r;let b=w.x-g.x,E=w.y-g.y;const x=p+u,M=b*b+E*E;if(M>x*x)continue;let R=Math.sqrt(M);if(R<1e-4){const Q=(l*7+y*13)%360*(Math.PI/180);b=Math.cos(Q),E=Math.sin(Q),R=1}const A=b/R,C=E/R,Y=g.r*g.r,L=w.r*w.r,H=L/(Y+L),U=Y/(Y+L),j=Math.max(0,p-R),q=1-Math.max(0,R-p)/r.repelRange,J=r.repel*q*q+j*r.stiffness;g.ax-=A*J*H,g.ay-=C*J*H,w.ax+=A*J*U,w.ay+=C*J*U}}if(i.length>0)for(const l of i){const g=l.bond,y=d.get(g.id);y&&(l.hold>0||(l.ax+=(y.x+g.dx-l.x)*r.bond,l.ay+=(y.y+g.dy-l.y)*r.bond))}for(const l of s){l.hold>0&&(l.ax+=(l.holdX-l.x)*r.hold*l.hold,l.ay+=(l.holdY-l.y)*r.hold*l.hold);const g=o.minX+l.r,y=o.maxX-l.r,w=o.minY+l.r,p=o.maxY-l.r-l.tailDepth;l.x<g&&(l.ax+=(g-l.x)*r.wall),l.x>y&&(l.ax-=(l.x-y)*r.wall),l.y<w&&(l.ay+=(w-l.y)*r.wall),l.y>p&&(l.ay-=(l.y-p)*r.wall),l.vx+=l.ax*t,l.vy+=l.ay*t;const b=l.hold>0?r.holdDamping:r.damping,E=Math.exp(-b*t);l.vx*=E,l.vy*=E;const x=Math.sqrt(l.vx*l.vx+l.vy*l.vy);if(x>r.maxSpeed){const M=r.maxSpeed/x;l.vx*=M,l.vy*=M}l.x+=l.vx*t,l.y+=l.vy*t,l.x<g?(l.x=g,l.vx<0&&(l.vx=0)):l.x>y&&(l.x=y,l.vx>0&&(l.vx=0)),l.y<w?(l.y=w,l.vy<0&&(l.vy=0)):l.y>p&&(l.y=p,l.vy>0&&(l.vy=0))}}}const we=44,et=1.6,ce=1/4,Br=ce*.8,se=we*Br,Dr=1.06,Hr=1.1,io=3,Ur={build:"Build",fun:"Fun",relevant:"Relevance",irrelevant:"Irrelevant"},jr={build:"Useful",fun:"Fun"};function _t(e,t=1/0){const n=new Map;for(const[o,r]of e.entries()){const s=Wr(r.content),i=n.get(s);i?i.count++:n.set(s,{count:1,first:o})}return[...n].sort((o,r)=>r[1].count-o[1].count||o[1].first-r[1].first).slice(0,t===1/0?void 0:Math.max(0,t)).map(([o,r])=>({glyph:o,count:r.count}))}function Wr(e){const t=e.trim();if(t===""||t==="+")return"♥";if(t==="-")return"▼";if(t.startsWith(":")&&t.endsWith(":")||/^https?:\/\//i.test(t))return"♥";const n=Array.from(t);let o=1;for(;o<n.length;){const r=n[o].codePointAt(0),i=n[o-1].codePointAt(0)===8205||r===65039||r===65038||r===8205,c=r>=127995&&r<=127999;if(!i&&!c)break;o++}return n.slice(0,o).join("")}function Fr(e){const t=e.filter(s=>s.judgement),n=[...t].sort((s,i)=>mt(i.judgement??null)-mt(s.judgement??null));let o=0,r=null;for(const[s,i]of n.entries()){const c=mt(i.judgement??null);(r===null||c!==r)&&(o=s+1,r=c),i.rank={place:o,of:t.length}}}function Gr(e){const t=new Map,n=[];for(const p of e.events)if(p.kind===X.profile){const b=t.get(p.pubkey);(!b||p.created_at>b.created_at)&&t.set(p.pubkey,p)}else p.kind===X.note&&n.push(p);n.sort((p,b)=>b.created_at-p.created_at);const o=e.reactions??{},r=e.reposts??{},s=e.threads??{},i=new Set(e.contacts?.follows??[]);i.add(e.pubkey);const c=new Map(n.map(p=>[p.id,p])),d=p=>{const b=t.get(p);return b?Lt(b):void 0},u=p=>be(d(p),p),h=new Map,l=new Set;for(const p of Object.values(e.threads??{}))for(const b of p){l.add(b.id);const E=h.get(b.parent)??[];E.push(b),h.set(b.parent,E)}const g=n.reduce((p,b)=>{if(l.has(b.id))return p;const E=(o[b.id]?.length??0)+(s[b.id]?.length??0);return Math.max(p,E)},0),y=(p,b)=>{const E=c.get(p.id);if(!E||b.has(p.id))return null;b.add(p.id);const x=(h.get(p.id)??[]).map(R=>y(R,b)).filter(R=>R!==null),M=d(E.pubkey);return{root:!1,placement:i.has(E.pubkey)?"face":"hidden",count:1,id:E.id,pubkey:E.pubkey,name:be(M,E.pubkey),picture:M?.picture??M?.image,hue:Re(E.pubkey),radius:se,parent:p.parent,parentName:u(p.parent),event:E,children:x}},w=n.filter(p=>!l.has(p.id)).map(p=>{const b=d(p.pubkey),E=e.judgements?.[p.id]??null,x=o[p.id]??[],M=(r[p.id]??[]).map(L=>{const H=d(L.pubkey);return{pubkey:L.pubkey,name:be(H,L.pubkey),picture:H?.picture??H?.image,hue:Re(L.pubkey)}}),R=M.filter(L=>i.has(L.pubkey)),A=new Set([p.id]),C=(h.get(p.id)??[]).map(L=>y(L,A)).filter(L=>L!==null);Yr(C);const Y=zr(x.length+tt({children:C}),g);return{root:!0,id:p.id,pubkey:p.pubkey,name:be(b,p.pubkey),picture:b?.picture??b?.image,hue:Re(p.pubkey),baseRadius:Y,radius:Y,reactions:x,reposts:R,repostsHidden:M.length-R.length,event:p,judgement:E,weights:Ot(E),children:C,tail:lo(C,Y)}});return Fr(w),w}function _e(e,t,n){const o=t*2,r=Math.max(2,Math.floor(e*2/o)),s=[];for(let i=0;i<n;i++){const c=Math.floor(i/r),d=Math.min(r,n-c*r);s.push({dx:(i%r-(d-1)/2)*o,dy:e+t+c*o})}return s}function lo(e,t){const n=Tt(e),o=n.filter(c=>c.placement==="face").length,r=n.filter(c=>c.placement==="hidden").length,i=_e(t,se,o).at(-1);return{shown:o,chip:r>0?{dx:i?i.dx+se+io:0,dy:i?i.dy:t+se,align:i?"left":"center",count:r}:void 0,depth:i?i.dy+se:0}}function Yr(e){const t=Tt(e).filter(r=>r.placement==="face"),n=new Map,o=new Map;for(const r of t){const s=n.get(r.pubkey);(!s||r.event.created_at>=s.event.created_at)&&n.set(r.pubkey,r),o.set(r.pubkey,(o.get(r.pubkey)??0)+1)}for(const r of t){const s=n.get(r.pubkey);!s||s===r?r.count=o.get(r.pubkey)??1:r.placement="repeat"}}function Tt(e){const t=[],n=[...e];for(;n.length>0;){const o=n.shift();t.push(o),n.push(...o.children)}return t}function zr(e,t){const n=t>0?Math.min(1,Math.max(0,e)/t):0,o=ce+(et-ce)*n;return we*o}function mt(e){const t=xt(e?.build),n=xt(e?.relevant);return t+(n-.5)}const Xr=.7;function qr(e){return Ot({build:Math.min(1,Math.max(0,e)),relevant:.5})}const Vr=.09,Kr=4;function Jr(e,t,n){const o=Math.PI*se*se;let r=0;for(const i of e)r+=Math.PI*i.radius*i.radius+i.tail.shown*o;const s=r/(Vr*Math.max(1,t));return Math.round(Math.min(Math.max(s,n),n*Kr))}function gt(e,t,n=new Set){const o=we*ce,r=we*et,s=t?Qr(e,n):null;for(const i of e)i.radius=Math.min(r,Math.max(o,i.baseRadius)),i.weights=t?qr((i.root?s.get(i.id):void 0)??.5):Ot(i.judgement),i.tail=lo(i.children,i.radius)}function Qr(e,t=new Set){const n=e.filter(d=>d.root&&d.rank&&!t.has(d.id));n.sort((d,u)=>(d.rank.place??0)-(u.rank.place??0));const o=new Map,r=n.length;let s=0,i=0,c=null;for(const d of n){(c===null||d.rank.place!==c)&&(i=s,c=d.rank.place);const u=r<=1?1:1-i/(r-1);o.set(d.id,1-Math.pow(1-u,Xr)),s++}return o}function be(e,t){for(const n of[e?.display_name,e?.displayName,e?.name])if(n&&n.trim())return n;return oo(t)}function xt(e,t=.5){return Number.isFinite(e)?Math.min(1,Math.max(0,e)):t}function Ot(e){const t=xt,n=t(e?.build),o=t(e?.relevant),r=[n,1-n,o,1-o],s=r.reduce((i,c)=>i+c,0);return s<=1e-9?r.map(()=>1/r.length):r.map(i=>i/s)}function Re(e){let t=0;for(let n=0;n<e.length;n++)t=(t*31+e.charCodeAt(n))%1e5;return 190+t%141}function Zr(e){const t=[],n=o=>{t.push(o);for(const r of o.children)n(r)};for(const o of e)n(o);return t}function tt(e){let t=0;for(const n of e.children)t+=1+tt(n);return t}function es(e,t,n=.6){const o=Math.PI*(3-Math.sqrt(5)),r=[],s=new Map;for(const[i,c]of e.entries()){const d=t(c.weights),u=i*o,h=n*c.radius,l=Qe.bubble(c.id,d.x+Math.cos(u)*h,d.y+Math.sin(u)*h,c.radius,c.weights);l.tailDepth=c.tail.depth,s.set(c.id,l),r.push(l)}for(const i of e){const c=s.get(i.id);if(!c)continue;const d=Tt(i.children).filter(h=>h.placement==="face"),u=_e(c.r,se,i.tail.shown);for(const[h,l]of d.entries()){const{dx:g,dy:y}=u[h],w=Qe.bubble(l.id,c.x+g,c.y+y,l.radius,[]);w.bond={id:c.id,dx:g,dy:y},s.set(l.id,w),r.push(w)}}return r}const At=new Map,$t=new Set;function Te(e){const t=At.get(e);if(t)return t;const n=Fo.bytes(e).then(o=>{const r=URL.createObjectURL(o);return $t.add(r),r});return At.set(e,n),n}function Bt(){for(const e of $t)URL.revokeObjectURL(e);$t.clear(),At.clear()}class ts{constructor(t){this.onReady=t}entries=new Map;get(t){if(!t)return{url:"",element:null,state:"empty"};const n=this.entries.get(t);if(n)return n;const o={url:t,element:null,state:"loading"};return this.entries.set(t,o),this.load(t,o),o}async load(t,n){try{const o=await Te(t);if(n.state!=="loading")return;const r=new Image;r.decoding="async",r.addEventListener("load",()=>{n.state=r.naturalWidth>0?"ready":"failed",this.onReady()}),r.addEventListener("error",()=>{n.state="failed",this.onReady()}),n.element=r,r.src=o}catch{n.state="failed",this.onReady()}}dispose(){for(const t of this.entries.values())t.element&&(t.element.src="");this.entries.clear()}}const ns=/\.(mp4|webm|mov|m4v|mp3|m4a|ogg|wav|pdf|zip|epub|apk)(\?|#|$)/i,os=["nostr.build","nostrcheck.me","void.cat","blossom","nostr.download","imgur.com","catbox.moe","media.tenor.com","pbs.twimg.com"],rs=/\bhttps?:\/\/[^\s<>()"']+/gi;function ss(e){if(ns.test(e))return!1;const t=e.split(/[?#]/)[0]??e;if(/\.(png|jpe?g|gif|webp|avif|bmp)$/i.test(t))return!0;const n=as(e);return n!==null&&os.some(o=>n.endsWith(o))}function as(e){try{return new URL(e).host.toLowerCase()}catch{return null}}function is(e,t=3){const n=[];let o=e;for(const s of e.matchAll(rs)){const i=s[0];ss(i)&&(n.includes(i)||n.push(i),o=o.replace(new RegExp(`\\s*${ls(i)}\\s*`)," "))}const r=n.slice(0,t);return{text:o.replace(/[ \t]+/g," ").replace(/\n{3,}/g,`

`).trim(),images:r,extra:n.length-r.length}}function ls(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function cs(e){const t=[];let n=0;for(const o of e.matchAll(mr.nostrLink)){const r=pr(o[1]);if(!r)continue;const s=o.index??0;s>n&&t.push({kind:"text",text:e.slice(n,s)}),t.push({kind:"mention",pubkey:r.pubkey,raw:o[0]}),n=s+o[0].length}return n<e.length&&t.push({kind:"text",text:e.slice(n)}),t}const ds=60,yt=8;function us(e,t){const n=document.createElement("aside");n.className="panel",n.tabIndex=-1,n.setAttribute("role","region"),n.setAttribute("aria-label","selected note");const o=document.createElement("button");o.className="panel-close",o.type="button",o.title="close (esc)",o.setAttribute("aria-label","close"),o.textContent="×",o.addEventListener("click",()=>t.onClose());const r=document.createElement("button");r.className="panel-expand",r.type="button",r.title="expand (e)",r.setAttribute("aria-label","expand the note"),r.setAttribute("aria-pressed","false"),r.addEventListener("click",()=>C(!x));const s=document.createElement("header");s.className="panel-head";const i=document.createElement("div");i.className="panel-dwell",i.setAttribute("aria-hidden","true");const c=document.createElement("span");c.className="panel-avatar";const d=document.createElement("h2");d.className="panel-name";const u=document.createElement("button");u.type="button",u.className="panel-author",u.title="open their profile",u.append(c,d);const h=document.createElement("p");h.className="panel-meta";const l=document.createElement("button");l.type="button",l.className="panel-seen",l.textContent="seen",l.title="mark this thread unread",l.hidden=!0,l.addEventListener("click",()=>t.onUnsee?.()),s.append(o,r,u,h,l);const g=document.createElement("div");g.className="panel-notes",n.append(i,s,g);let y=null,w=null,p=null,b=null,E=0,x=!1;u.addEventListener("click",()=>{b&&t.onProfile?.(b)});const M=new ResizeObserver(()=>{y=null,t.onResize?.()});M.observe(n);function R(S){p!==S.id&&(p=S.id,y=null,w=null,Y(0),n.classList.remove("open"),n.offsetWidth),n.classList.add("open"),b=S,n.style.setProperty("--hue",String(S.hue)),n.setAttribute("aria-label",`${S.root?"note":"reply"} by ${S.name}`),d.textContent=S.name,u.setAttribute("aria-label",`open the profile of ${S.name}`),Rn(c,S.picture,S.name);const O=S.root?[hs(S),ms(S),$n(S)]:[`replying to ${S.parentName}`,$n(S)];h.textContent=O.filter(Boolean).join(" · ");const P=[],V=j(t.ancestors?.(S)??[]);V&&P.push(V),P.push(ys(S,e,"reactions"in S?S.reactions:[]));const W=J(S);W&&P.push(W),g.replaceChildren(...P)}function A(){n.classList.remove("open"),p=null,b=null,w=null}function C(S){x!==S&&(x=S,n.dataset.expanded=S?"true":"false",r.title=S?"collapse (e)":"expand (e)",r.setAttribute("aria-label",S?"collapse the note":"expand the note"),r.setAttribute("aria-pressed",S?"true":"false"),y=null,w=null,t.onExpand?.(S),n.classList.contains("open")&&(n.classList.remove("open"),n.offsetWidth,n.classList.add("open")))}function Y(S){const O=Math.max(0,Math.min(1,S));O!==E&&(E=O,i.style.transform=`scaleX(${O})`)}function L(S){l.hidden=!S}function H(){return y??={width:n.offsetWidth,height:n.offsetHeight}}function U(S){w&&w.left===S.left&&w.top===S.top&&w.side===S.side||(w=S,n.style.left=`${S.left}px`,n.style.top=`${S.top}px`,n.dataset.side=S.side,n.style.transformOrigin=fs[S.side])}function j(S){if(S.length===0)return null;const O=document.createElement("div");O.className="panel-context",O.setAttribute("aria-label","the thread this answers");const P=S[0],V=S.slice(-2),W=S.length-1-V.length,K=W>0?[P,null,...V]:S;for(const F of K){if(!F){const _=document.createElement("p");_.className="panel-context-gap",_.textContent=`… ${W} more repl${W===1?"y":"ies"} above`,O.append(_);continue}O.append(q(F,F.root))}return O}function q(S,O){const P=document.createElement("button");P.type="button",P.className="panel-context-row",P.style.setProperty("--hue",String(S.hue));const V=O?"root event":"reply event",W=An(S.event.content);P.setAttribute("aria-label",`${V} by ${S.name}: ${W}`);const K=document.createElement("span");K.className="panel-context-role",K.textContent=V;const F=document.createElement("span");F.className="panel-context-name",F.textContent=S.name;const _=document.createElement("span");return _.className="panel-context-text",_.textContent=W||"(empty note)",P.append(K,F,_),P.addEventListener("click",()=>t.onSelect?.(S.id)),P}function J(S){if(S.children.length===0)return null;const O=tt(S),P=document.createElement("div");P.className="panel-replies";const V=document.createElement("p");V.className="panel-replies-head",V.textContent=`${O} repl${O===1?"y":"ies"}`,P.append(V);let W=0;const K=(F,_)=>{for(const $ of F){if(W>=ds)return;W++,P.append(Q($,_)),K($.children,_+1)}};if(K(S.children,0),O>W){const F=document.createElement("p");F.className="panel-replies-more",F.textContent=`+${O-W} more replies`,P.append(F)}return P}function Q(S,O){const P=document.createElement("button");P.type="button",P.className="panel-reply",P.style.setProperty("--hue",String(S.hue)),P.style.setProperty("--indent",`${O*12}px`);const V=An(S.event.content);P.setAttribute("aria-label",`reply by ${S.name}: ${V}`);const W=document.createElement("span");W.className="panel-reply-avatar",Rn(W,S.picture,S.name);const K=document.createElement("span");K.className="panel-reply-body";const F=document.createElement("span");F.className="panel-reply-name",F.textContent=S.name;const _=document.createElement("span");return _.className="panel-reply-text",_.textContent=V||"(empty note)",K.append(F,_),P.append(W,K),P.addEventListener("click",()=>t.onSelect?.(S.id)),P}return{element:n,get open(){return n.classList.contains("open")},get expanded(){return x},setExpanded:C,size:H,show:R,place:U,setDwell:Y,setSeen:L,hide:A,dispose:()=>{M.disconnect(),n.remove()}}}const fs={left:"right center",right:"left center",above:"bottom center",below:"top center",center:"center"};function An(e){return e.replace(/\s+/g," ").trim().slice(0,90)}function hs(e){const t=e.judgement;if(!t)return"not judged";const n=s=>`${Math.round(s*100)}%`,o=e.rank;return`${o?`${ps(o.place)} · `:""}${n(t.build)} build · ${n(t.relevant)} relevant`}function ps(e){const t=Math.abs(e)%100,n=t>=11&&t<=13?"th":e%10===1?"st":e%10===2?"nd":e%10===3?"rd":"th";return`${e}${n}`}function ms(e){const t=e.reactions.length,n=e.reposts.length+e.repostsHidden,o=[];return t>0&&o.push(`${t} reaction${t===1?"":"s"}`),n>0&&o.push(`${n} repost${n===1?"":"s"}`),o.join(" · ")}function $n(e){const t=tt(e);return t===0?"":`${t} repl${t===1?"y":"ies"}`}function bt(e){return(Array.from(e.trim())[0]??"?").toUpperCase()}function Rn(e,t,n){if(e.textContent=bt(n),!t)return;const o=new Image;o.alt="",o.decoding="async",o.addEventListener("error",()=>{o.remove(),e.textContent=bt(n)}),e.textContent="",e.append(o),Te(t).then(r=>{o.src=r}).catch(()=>{o.remove(),e.textContent=bt(n)})}function gs(e){const t=_t(e);if(t.length===0)return null;const n=document.createElement("div");n.className="panel-reactions",n.setAttribute("aria-label",`${e.length} reaction${e.length===1?"":"s"}`);for(const{glyph:o,count:r}of t.slice(0,yt)){const s=document.createElement("span");s.className="panel-reaction",s.title=`${o} ×${r}`,s.setAttribute("aria-label",`${r} with ${o}`);const i=document.createElement("span");i.className="panel-reaction-glyph",i.textContent=o,i.setAttribute("aria-hidden","true");const c=document.createElement("span");c.className="panel-reaction-count",c.textContent=String(r),c.setAttribute("aria-hidden","true"),s.append(i,c),n.append(s)}if(t.length>yt){const o=document.createElement("span");o.className="panel-reaction-more",o.textContent=`+${t.length-yt} more`,n.append(o)}return n}function ys(e,t,n=[]){const o=document.createElement("article");o.className="panel-note";const r=document.createElement("div");if(r.className="panel-note-head",!e.root){const h=document.createElement("span");h.className="panel-note-reply",h.textContent="reply",r.append(h)}const s=document.createElement("a");s.className="panel-note-time",s.href=`https://njump.me/${hr(e.event.id)}`,s.target="_blank",s.rel="noreferrer",s.title=new Date(e.event.created_at*1e3).toISOString(),s.textContent=no(new Date(e.event.created_at*1e3)),r.append(s),o.append(r);const{text:i,images:c,extra:d}=is(e.event.content);if(i){const h=document.createElement("p");h.className="panel-note-text",ws(h,i,t),o.append(h)}else if(c.length===0){const h=document.createElement("p");h.className="panel-note-text muted",h.textContent=e.event.content.trim()||"(empty note)",o.append(h)}for(const h of c){const l=new Image;l.className="panel-note-image",l.loading="lazy",l.decoding="async",l.alt="";const g=()=>l.replaceWith(Es(h));l.addEventListener("error",g),o.append(l),Te(h).then(y=>{l.src=y}).catch(g)}if(d>0){const h=document.createElement("p");h.className="panel-note-more",h.textContent=`+${d} more media`,o.append(h)}const u=gs(n);return u&&o.append(u),o}function bs(e,t){const n=t.getReplaceable(X.profile,e);return be(n?Lt(n):void 0,e)}function ws(e,t,n){for(const o of cs(t)){if(o.kind==="text"){e.append(o.text);continue}e.append(vs(o.pubkey,n))}}function vs(e,t){const n=It(e),o=document.createElement("a");return o.className="panel-mention",o.href=`https://njump.me/${n}`,o.target="_blank",o.rel="noreferrer",o.title=n,o.style.setProperty("--hue",String(Re(e))),o.textContent=bs(e,t),o}function Es(e){const t=document.createElement("a");t.className="panel-note-link",t.href=e,t.target="_blank",t.rel="noreferrer";try{t.textContent=new URL(e).host}catch{t.textContent=e}return t}function Ss(e,t){const n=document.createElement("aside");n.className="profile-card",n.tabIndex=-1,n.setAttribute("role","region"),n.setAttribute("aria-label","profile");const o=document.createElement("button");o.className="profile-close",o.type="button",o.title="close (esc)",o.setAttribute("aria-label","close"),o.textContent="×",o.addEventListener("click",()=>t.onClose());const r=document.createElement("div");r.className="profile-banner",r.setAttribute("aria-hidden","true");const s=document.createElement("div");s.className="profile-body";const i=document.createElement("span");i.className="profile-avatar";const c=document.createElement("h2");c.className="profile-name";const d=document.createElement("p");d.className="profile-handle";const u=document.createElement("p");u.className="profile-about";const h=document.createElement("div");h.className="profile-links",s.append(i,c,d,u,h),n.append(r,o,s);let l=null,g=null,y=null;const w=new ResizeObserver(()=>{l=null,t.onResize?.()});w.observe(n);function p(M){y!==M&&(y=M,l=null,g=null,n.classList.remove("open"),n.offsetWidth),n.classList.add("open");const R=Re(M);n.style.setProperty("--hue",String(R));const A=e.getReplaceable(X.profile,M),C=A?Lt(A):void 0,Y=It(M),L=be(C,M);n.setAttribute("aria-label",`profile of ${L}`);const H=C?.picture??C?.image;Ps(i,H,L),c.textContent=L;const U=Ms(C,L);d.textContent=U,d.hidden=U==="";const j=C?.about?.trim();if(u.textContent=j??"",u.hidden=!j,xs(r,C?.banner),h.replaceChildren(...$s(M,C,Y)),!C){const q=document.createElement("p");q.className="profile-missing",q.textContent="no profile published — this is what the snapshot has",h.append(q)}}function b(){n.classList.remove("open"),y=null,g=null}function E(){return l??={width:n.offsetWidth,height:n.offsetHeight}}function x(M){g&&g.left===M.left&&g.top===M.top&&g.side===M.side||(g=M,n.style.left=`${M.left}px`,n.style.top=`${M.top}px`,n.dataset.side=M.side,n.style.transformOrigin=ks[M.side])}return{element:n,get open(){return n.classList.contains("open")},show:p,place:x,size:E,hide:b,dispose:()=>{w.disconnect(),n.remove()}}}const ks={left:"right center",right:"left center",above:"bottom center",below:"top center",center:"center"};function Ms(e,t){const n=[],o=e?.name?.trim();o&&o!==t&&n.push(`@${o}`);const r=e?.nip05?.trim();return r&&n.push(r),n.join(" · ")}function xs(e,t){if(e.classList.toggle("has-image",!!t),!t){e.style.backgroundImage="";return}Te(t).then(n=>{e.style.backgroundImage=`url("${As(n)}")`}).catch(()=>{e.classList.remove("has-image"),e.style.backgroundImage=""})}function As(e){return e.replace(/["\\]/g,"\\$&")}function $s(e,t,n){const o=[],r=t?.website?.trim();r&&o.push(wt(r,Rs(r),"their link"));const s=t?.lud16?.trim()||t?.lud06?.trim();return s&&o.push(wt(`lightning:${s}`,`⚡ ${s}`,"send sats")),o.push(wt(`https://njump.me/${n}`,oo(e),"their profile on njump")),o}function wt(e,t,n){const o=document.createElement("a");return o.className="profile-link",o.href=e,o.target="_blank",o.rel="noreferrer",o.title=n,o.textContent=t,o}function Rs(e){try{return new URL(e).host}catch{return e}}function vt(e){return(Array.from(e.trim())[0]??"?").toUpperCase()}function Ps(e,t,n){if(e.textContent=vt(n),!t)return;const o=new Image;o.alt="",o.decoding="async",o.addEventListener("error",()=>{o.remove(),e.textContent=vt(n)}),e.textContent="",e.append(o),Te(t).then(r=>{o.src=r}).catch(()=>{o.remove(),e.textContent=vt(n)})}const de='ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif',Cs='"Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif',Pe="169, 112, 255",Is=58,Ae=200,Ls={build:{rgb:"255, 138, 61",alpha:.95},fun:{rgb:"72, 158, 255",alpha:.95},relevant:{rgb:"236, 240, 255",alpha:.9},irrelevant:{rgb:"150, 152, 172",alpha:.4}},Ns=.062,_s=28,Ts=58;function qe(e,t){return Math.max(_s,Math.min(Ts,Math.min(e,t)*Ns))}function co(e){return Math.round(e*.95)}const nt=se,Os=264,uo=1.14,Bs=.42,Ds=0,Pn=.94,$e=1.1,Hs=.65,Fe=6,Us=.36,js=.55,Ws=.42,Dt=nt*uo+$e/2,fo=3,Ze=.6,ho=.82,Cn=`700 11px ${de}`,Ht=.4,Fs=.55,Gs=`700 8px ${de}`,Ys=.92,zs=1.16;function Xs(e,t){const{field:n,width:o,height:r}=t;e.clearRect(0,0,o,r),qs(e,t),Vs(e,t),Ks(e,t);const s=t.selected,i=t.hovered,c=[...n.bubbles].filter(u=>!u.hidden).sort((u,h)=>h.r-u.r),d=[];for(const u of c){const h=t.bubbles.get(u.id);if(!h)continue;const l=u.id===i,g=u.id===s;if(l||g){d.push(u);continue}In(e,t,u,h,"rest")}for(const u of d){const h=t.bubbles.get(u.id);h&&In(e,t,u,h,u.id===s?"selected":"hovered")}for(const u of c){const h=t.bubbles.get(u.id);if(!t.reactionBadges)break;h&&"reactions"in h&&h.reactions.length>0&&ta(e,u,h,Ie(t,u.id))}for(const u of c){if(!t.strangerCounts)break;const h=t.bubbles.get(u.id);if(!h?.root)continue;const l=Ie(t,u.id);h.tail.chip&&Nn(e,u,{...h.tail.chip},l);const g=h.repostsHidden;if(g>0){const y=Qs(u.r,h.reposts.length,g);y&&Nn(e,u,y,l)}}ra(e,t,d),oa(e,t),sa(e,t)}function Ie(e,t){return e.dimmed.has(t)&&t!==e.selected&&t!==e.hovered}function qs(e,t){const{field:n}=t;if(n.poles.length===0)return;const o=t.phone?n.poles.slice(0,2):n.poles;for(const r of o){const s=e.createRadialGradient(r.x,r.y,0,r.x,r.y,Ae);s.addColorStop(0,`rgba(${Pe}, 0.10)`),s.addColorStop(.45,`rgba(${Pe}, 0.035)`),s.addColorStop(1,`rgba(${Pe}, 0)`),e.fillStyle=s,e.fillRect(r.x-Ae,r.y-Ae,Ae*2,Ae*2)}}function Vs(e,t){const{width:n,height:o}=t,r=qe(n,o),s=co(r),i=n/2,c=o/2,d=t.phone?{build:{x:i,y:s,angle:0},fun:{x:i,y:o-s,angle:0},relevant:{x:i,y:c,angle:0},irrelevant:{x:i,y:c,angle:0}}:{build:{x:s,y:c,angle:-Math.PI/2},fun:{x:n-s,y:c,angle:Math.PI/2},relevant:{x:i,y:s,angle:0},irrelevant:{x:i,y:o-s,angle:0}},u=t.phone?["build","fun"]:to;e.save(),e.textAlign="center",e.textBaseline="middle",e.font=`700 ${r}px ${de}`,e.letterSpacing=`${r*.14}px`;for(const h of u){const l=d[h],g=Ls[h],w=((t.phone?jr[h]:void 0)??Ur[h]).toUpperCase();e.save(),e.translate(l.x,l.y),e.rotate(l.angle);for(const[p,b]of[[r*.9,.5],[r*.35,.75]])e.shadowColor=`rgba(${g.rgb}, ${g.alpha*b})`,e.shadowBlur=p,e.fillStyle=`rgba(${g.rgb}, ${g.alpha*b})`,e.fillText(w,0,0);e.shadowBlur=0,e.shadowColor="transparent",e.fillStyle=`rgba(248, 248, 255, ${g.alpha})`,e.fillText(w,0,0),e.restore()}e.restore(),e.letterSpacing="0px"}function Ks(e,t){const{field:n,held:o,anchorDrag:r}=t,s=n.bubbles.filter(d=>!d.bond&&!d.hidden);if(s.length<2)return;const i=o!==null||r,c=n.tuning.repelRange+(i?Is:0);e.lineCap="round";for(let d=0;d<s.length;d++){const u=s[d];for(let h=d+1;h<s.length;h++){const l=s[h],g=u.r+l.r,y=g+c,w=l.x-u.x,p=l.y-u.y,b=w*w+p*p;if(b>y*y)continue;const E=Math.sqrt(b)||1,x=Ut(1-(E-g)/Math.max(1,c)),M=Ie(t,u.id)||Ie(t,l.id)?.35:1,R=(.04+.28*x*(i?1:.3))*M;e.strokeStyle=`rgba(${Pe}, ${R.toFixed(3)})`,e.lineWidth=.7+x*1.3,e.beginPath(),e.moveTo(u.x,u.y),e.lineTo(l.x,l.y),e.stroke()}}}function In(e,t,n,o,r){const s=n.r,i=r==="selected",c=r==="hovered",d=Ie(t,n.id);e.save(),e.translate(n.x,n.y),e.scale(n.scale,n.scale),d&&(e.globalAlpha=Ht),e.beginPath(),e.arc(0,0,s,0,Math.PI*2),e.shadowColor=i?`hsla(${o.hue}, 90%, 62%, 0.55)`:"rgba(0, 0, 0, 0.5)",e.shadowBlur=i?34:c?20:14,e.shadowOffsetY=i||c?0:4,e.fillStyle=`hsl(${o.hue} 30% 10%)`,e.fill(),e.shadowColor="transparent",e.shadowBlur=0,e.shadowOffsetY=0;const u=t.images.get(o.picture),h=u.state==="ready"&&u.element;if(e.save(),e.beginPath(),e.arc(0,0,s,0,Math.PI*2),e.clip(),h){const g=u.element,y=Math.max(s*2/g.naturalWidth,s*2/g.naturalHeight),w=g.naturalWidth*y,p=g.naturalHeight*y;e.drawImage(g,-w/2,-p/2,w,p)}else na(e,o,s);if(d&&(e.beginPath(),e.arc(0,0,s,0,Math.PI*2),e.fillStyle=`rgba(8, 8, 12, ${Fs})`,e.fill()),e.restore(),e.beginPath(),e.arc(0,0,s-.5,0,Math.PI*2),e.lineWidth=1,e.strokeStyle="rgba(255, 255, 255, 0.10)",e.stroke(),!o.root&&o.count>1){e.textAlign="right",e.textBaseline="alphabetic",e.font=Gs,e.shadowColor="rgba(0, 0, 0, 0.95)",e.shadowBlur=4,e.lineJoin="round",e.strokeStyle="rgba(8, 8, 12, 0.75)",e.lineWidth=2;const g=`×${o.count}`,y=s*Ys,w=s*zs;e.strokeText(g,y,w),e.fillStyle="rgba(255, 255, 255, 0.96)",e.fillText(g,y,w),e.shadowColor="transparent",e.shadowBlur=0}const l="reposts"in o?o.reposts:[];if(Js(e,t,s,l,"repostsHidden"in o?o.repostsHidden:0),i||c){const g=i?.72+.28*Math.sin(t.time*2.4):1;e.beginPath(),e.arc(0,0,s+1.5,0,Math.PI*2),e.lineWidth=i?3:2,e.strokeStyle=`hsla(${o.hue}, 92%, 70%, ${(i?.95:.8)*g})`,e.stroke(),i&&(e.beginPath(),e.arc(0,0,s+6,0,Math.PI*2),e.lineWidth=1,e.strokeStyle=`hsla(${o.hue}, 92%, 70%, ${.3*g})`,e.stroke())}else e.beginPath(),e.arc(0,0,s+.5,0,Math.PI*2),e.lineWidth=1.5,e.strokeStyle=d?"rgba(255, 255, 255, 0.05)":"rgba(255, 255, 255, 0.13)",e.stroke();e.restore()}function Js(e,t,n,o,r){if(o.length===0&&r===0)return;const s=nt,i=_e(n,Dt,Math.max(1,o.length));for(const[c,d]of i.entries()){const u=o[c];if(!u)break;Zs(e,t,d.dx,-d.dy,s,u)}}function Rt(e,t){const n=[],o=e.scale,r=_e(e.r,Dt,Math.max(1,t.reposts.length));for(const[s,i]of t.reposts.entries()){const c=r[s];if(!c)break;n.push({repost:i,x:e.x+c.dx*o,y:e.y-c.dy*o,r:nt*o})}return n}function Qs(e,t,n){const o=Dt;if(t===0)return{dx:0,dy:-(e+o),align:"center",count:n};const r=_e(e,o,t).at(-1);return{dx:r.dx+o+io,dy:-r.dy,align:"left",count:n}}function Ln(e,t){const n=Os,o=Math.PI/2,r=nt,s=r*uo,i=s*Bs,c=r*Ds,d=t==="near";e.lineCap="round",e.lineJoin="round";const u=(J,Q)=>{e.beginPath(),e.ellipse(0,c,s,i,0,J,Q)};if(!d){e.strokeStyle=`hsla(${n}, 85%, 62%, 0.5)`,e.lineWidth=Hs,e.shadowColor=`hsla(${n}, 100%, 62%, 0.5)`,e.shadowBlur=Fe*.4,e.beginPath(),e.ellipse(0,c,s*Pn,i*Pn,0,Math.PI,Math.PI*2),e.stroke(),e.shadowBlur=0,e.shadowColor="transparent";return}const h=e.createLinearGradient(0,c,0,c+i);h.addColorStop(0,`hsl(${n} 92% 58%)`),h.addColorStop(.55,`hsl(${n} 98% 72%)`),h.addColorStop(1,`hsl(${n} 100% 90%)`),e.strokeStyle=h,e.shadowColor=`hsla(${n}, 100%, 62%, 0.9)`;for(const[J,Q]of[[$e,Fe],[$e,Fe*.35]])e.lineWidth=J,e.shadowBlur=Q,u(0,o),e.stroke(),u(o+Ws,Math.PI),e.stroke();e.shadowBlur=0,e.shadowColor="transparent";const l=s*Us,g=js,y=Math.cos(o),w=Math.sin(o),p=-s*w,b=i*y,E=Math.hypot(p,b)||1,x=p/E,M=b/E,R=s*y,A=c+i*w,C=-x*l,Y=-M*l,L=C*Math.cos(g)-Y*Math.sin(g),H=C*Math.sin(g)+Y*Math.cos(g),U=C*Math.cos(g)+Y*Math.sin(g),j=-C*Math.sin(g)+Y*Math.cos(g),q=(J,Q,S)=>{e.strokeStyle=J,e.lineWidth=Q,e.shadowColor=`hsla(${n}, 100%, 65%, 0.95)`,e.shadowBlur=S,e.lineJoin="miter",e.miterLimit=4,e.beginPath(),e.moveTo(R+L,A+H),e.lineTo(R,A),e.lineTo(R+U,A+j),e.stroke()};q("rgba(8, 9, 14, 0.75)",$e+1.1,0),q(`hsl(${n} 100% 88%)`,$e,Fe*.8),e.shadowBlur=0,e.shadowColor="transparent"}function Zs(e,t,n,o,r,s){e.save(),e.translate(n,o),Ln(e,"far"),e.beginPath(),e.arc(0,0,r,0,Math.PI*2),e.fillStyle="rgba(10, 10, 15, 0.94)",e.fill();const i=t.images.get(s.picture),c=i.state==="ready"?i.element:null;if(e.save(),e.beginPath(),e.arc(0,0,r-.5,0,Math.PI*2),e.clip(),c){const d=Math.max(r*2/c.naturalWidth,r*2/c.naturalHeight),u=c.naturalWidth*d,h=c.naturalHeight*d;e.drawImage(c,-u/2,-h/2,u,h)}else e.fillStyle=`hsl(${s.hue} 40% 16%)`,e.fillRect(-r,-r,r*2,r*2),e.fillStyle=`hsl(${s.hue} 92% 78%)`,e.font=`700 ${Math.round(r*1.1)}px ${de}`,e.textAlign="center",e.textBaseline="middle",e.fillText("↻",0,.5);e.restore(),Ln(e,"near"),e.restore()}const po=`14px ${Cs}`,mo=`700 12px ${de}`,go=6,yo=2,bo=5,wo=24;function ea(e,t,n){if(t.reactions.length===0)return null;const o=_t(t.reactions,fo).map(h=>h.glyph),r=go*2+o.reduce((h,l)=>h+n(l,po),0)+Math.max(0,o.length-1)*yo+bo+n(String(t.reactions.length),mo),s=(e.r/we-ce)/(et-ce),i=Ze+(ho-Ze)*Ut(s),c=e.x+e.r*e.scale,d=r*i,u=wo*i;return{left:c-d/2,top:e.y-u/2,width:d,height:u}}function ta(e,t,n,o){if(n.reactions.length===0)return;const r=_t(n.reactions,fo).map(x=>x.glyph),s=String(n.reactions.length),i=po,c=mo,d=go,u=yo,h=bo,l=wo;e.save(),o&&(e.globalAlpha=Ht*.6),e.font=i;const g=r.map(x=>e.measureText(x).width),y=g.reduce((x,M)=>x+M,0)+(r.length-1)*u;e.font=c;const w=d*2+y+h+e.measureText(s).width,p=(t.r/we-ce)/(et-ce),b=Ze+(ho-Ze)*Ut(p);e.translate(t.x+t.r*t.scale,t.y),e.scale(b,b),e.beginPath(),e.roundRect(-w/2,-l/2,w,l,l/2),e.fillStyle="rgba(12, 12, 18, 0.94)",e.shadowColor="rgba(0, 0, 0, 0.55)",e.shadowBlur=6,e.fill(),e.shadowColor="transparent",e.shadowBlur=0,e.lineWidth=1,e.strokeStyle=`hsla(${n.hue}, 85%, 72%, 0.6)`,e.stroke(),e.textAlign="left",e.textBaseline="middle",e.font=i,e.fillStyle="rgba(244, 244, 250, 0.96)";let E=-w/2+d;for(const[x,M]of r.entries())e.fillText(M,E,1),E+=g[x]+u;e.font=c,e.fillStyle=`hsl(${n.hue} 92% 80%)`,e.fillText(s,E-u+h,1),e.restore()}function Nn(e,t,n,o){const r=`+${n.count}`,s=20,i=7;e.save(),o&&(e.globalAlpha=Ht*.6),e.font=Cn;const c=Math.max(s,i*2+e.measureText(r).width),d=n.align==="left"?0:-c/2;e.translate(t.x+n.dx,t.y+n.dy),e.beginPath(),e.roundRect(d,-s/2,c,s,s/2),e.fillStyle="rgba(12, 12, 18, 0.9)",e.shadowColor="rgba(0, 0, 0, 0.45)",e.shadowBlur=5,e.fill(),e.shadowColor="transparent",e.shadowBlur=0,e.lineWidth=1,e.strokeStyle=`rgba(${Pe}, 0.5)`,e.stroke(),e.textAlign="center",e.textBaseline="middle",e.font=Cn,e.fillStyle="rgba(228, 224, 240, 0.92)",e.fillText(r,d+c/2,1),e.restore()}function na(e,t,n){const o=e.createRadialGradient(-n*.3,-n*.45,n*.1,0,0,n);o.addColorStop(0,`hsl(${t.hue} 48% 38%)`),o.addColorStop(1,`hsl(${t.hue} 34% 14%)`),e.fillStyle=o,e.fillRect(-n,-n,n*2,n*2);const r=(Array.from(t.name.trim())[0]??"?").toUpperCase();e.fillStyle="rgba(255, 255, 255, 0.82)",e.font=`600 ${Math.round(n*.8)}px ${de}`,e.textAlign="center",e.textBaseline="middle",e.fillText(r,0,n*.04)}function oa(e,t){const n=t.hoveredRepost;if(!n)return;const o=t.field.bubbles.find(l=>l.id===n.bubbleId);if(!o||o.hidden)return;const r=t.bubbles.get(n.bubbleId);if(!r?.root)return;const s=Rt(o,r).find(l=>l.repost.pubkey===n.pubkey);if(!s)return;e.beginPath(),e.arc(s.x,s.y,s.r+2,0,Math.PI*2),e.lineWidth=2,e.strokeStyle=`hsla(${s.repost.hue}, 92%, 70%, 0.95)`,e.stroke();const i=s.repost.name;e.font=`600 13px ${de}`;const c=e.measureText(i).width+20,d=23;let u=s.y-s.r-9-d/2;u-d/2<6&&(u=s.y+s.r+9+d/2);const h=Math.min(Math.max(s.x,c/2+6),Math.max(c/2+6,t.width-c/2-6));e.beginPath(),e.roundRect(h-c/2,u-d/2,c,d,d/2),e.fillStyle="rgba(10, 10, 15, 0.9)",e.fill(),e.strokeStyle=`hsla(${s.repost.hue}, 92%, 70%, 0.7)`,e.lineWidth=1,e.stroke(),e.fillStyle="rgba(238, 238, 246, 0.97)",e.textAlign="center",e.textBaseline="middle",e.fillText(i,h,u+.5)}function ra(e,t,n){for(const o of n){const r=t.bubbles.get(o.id);if(!r)continue;const s=o.id===t.selected;e.font=`600 13px ${de}`;const i=r.name,c=e.measureText(i).width+20,d=23,u=o.r*o.scale;let h=o.y+u+9+d/2;h+d/2>t.height-6&&(h=o.y-u-9-d/2);const l=Math.min(Math.max(o.x,c/2+6),Math.max(c/2+6,t.width-c/2-6));e.beginPath(),e.roundRect(l-c/2,h-d/2,c,d,d/2),e.fillStyle="rgba(10, 10, 15, 0.9)",e.fill(),e.strokeStyle=s?`hsla(${r.hue}, 92%, 70%, 0.7)`:"rgba(255, 255, 255, 0.14)",e.lineWidth=1,e.stroke(),e.fillStyle="rgba(238, 238, 246, 0.97)",e.textAlign="center",e.textBaseline="middle",e.fillText(i,l,h+.5)}}function sa(e,t){const{pointer:n,held:o,field:r}=t;if(!n)return;const s=o?r.bubbles.find(i=>i.id===o):void 0;s&&(e.beginPath(),e.moveTo(s.x,s.y),e.lineTo(n.x,n.y),e.strokeStyle="rgba(255, 255, 255, 0.28)",e.lineWidth=1,e.setLineDash([3,4]),e.stroke(),e.beginPath(),e.arc(n.x,n.y,12,0,Math.PI*2),e.strokeStyle="rgba(255, 255, 255, 0.22)",e.stroke(),e.setLineDash([]))}function Ut(e){return e<0?0:e>1?1:e}const aa=15,_n=24,Ge=6,vo="bubbles.reactionBadges",Eo="bubbles.strangerCounts",ia=660,le=18,oe=12,la=7200,ca=1e7,da=2,ua=.3,fa=3,Tn=40,On=14;function ha(e,t){const n=Gr(t),o=Zr(n),r=new Map(o.map(a=>[a.id,a])),s=Cr(o.map(a=>a.id));let i=Ir(),c=new Set,d=!1,u=!1,h=ga(),l=pa();const g=Ar();for(const a of t.events)g.add(a);let y=null,w=null,p=null,b=null,E=null,x=null,M=!1,R=null;const A={x:0,y:0,vx:0,vy:0};let C=null,Y=!1,L=null,H=!1,U=0,j=0,q=0,J=!1,Q=!1,S=0,O=0,P=!0,V=0,W=performance.now(),K=0,F=0;const _={id:null,elapsed:0};let $=!1;const G=document.createElement("div");G.className="space-scroll";const N=document.createElement("canvas");N.className="space-canvas",N.tabIndex=0,N.setAttribute("role","img");function ve(){const a=fe().size,f=a===0?"":`, ${a} read and hidden`;return`${o.length} notes floating between ${d?"two":"four"} poles${f}`}N.setAttribute("aria-label",ve());const jt=N.getContext("2d");if(!jt)throw new Error("this browser has no 2d canvas context");const me=jt,Wt=new ts(()=>{P=!0}),B=new Qe;B.poles.push(...to.map(a=>Qe.pole(a)));function xo(a){const f=[];let m="parent"in a?a.parent:void 0;for(;m&&f.length<64;){const v=r.get(m);if(!v)break;f.push(v),m="parent"in v?v.parent:void 0}return f.reverse()}const z=us(g,{ancestors:a=>xo(a),onClose:()=>ne(null),onSelect:a=>ne(a,"click"),onProfile:a=>en(a.pubkey,dt(a.id)?.id??a.id),onResize:()=>ie(),onExpand:()=>{ie(),P=!0},onUnsee:()=>Bo()}),ae=Ss(g,{onClose:()=>Me(),onResize:()=>ie()}),Oe=document.createElement("header");Oe.className="hud";const ge=document.createElement("a");ge.className="hud-account",ge.href=`https://njump.me/${t.npub}`,ge.target="_blank",ge.rel="noreferrer",ge.textContent=t.npub;const ot=document.createElement("p");ot.className="hud-stats";const Ao=Object.keys(t.threads??{}).length,Ft=Object.values(t.threads??{}).reduce((a,f)=>a+f.length,0),Gt=t.stats?.repostNotes??0,$o=Gt>0?`, ${Gt} reposted`:"";ot.textContent=`${o.length} notes (${$r(t.since)}${$o}) · `+(Ft>0?`${Ao} threads, ${Ft} replies · `:"")+`fetched ${no(new Date(t.generatedAt))}`;const Be=document.createElement("span");Be.className="hud-status";const Ee=Pr({notes:n.map(a=>({id:a.id,content:a.event.content})),initialPrompt:Jo,onStatus:a=>{Be.textContent=a??"",Be.classList.toggle("live",!!a),te.dataset.busy=a?"true":"false"}}),rt=document.createElement("p");rt.className="hud-prompt-row",rt.append(Ee.button,Be);const Yt=Nr({counts:()=>({seen:n.filter(a=>s.has(a.id)).length,total:n.length}),isHiding:()=>i,onToggle:a=>rn(a),onReset:()=>s.reset()}),zt=xn({label:"emoji reactions",title:"the emoji and the count on each bubble — a note you open still lists them all",pressed:h,onChange:a=>To(a)}),Xt=xn({label:"non-follow counts",title:"the +N beside the replies and reposts from people you don't follow — a note you open still lists them all",pressed:l,onChange:a=>Oo(a)}),ue=document.createElement("div");ue.className="hud-menu",ue.id="feed-menu",ue.hidden=!0,ue.append(ot,ge,rt,Ro(),Yt.element,zt.element,Xt.element);const te=document.createElement("button");te.type="button",te.className="hud-burger",te.title="settings",te.setAttribute("aria-label","settings and account"),te.setAttribute("aria-controls","feed-menu"),te.setAttribute("aria-expanded","false"),te.addEventListener("click",()=>st(!u));function Ro(){const a=document.createElement("span");return a.className="hud-menu-rule",a.setAttribute("aria-hidden","true"),a}function st(a,f=!1){u!==a&&(u=a,ue.hidden=!a,te.setAttribute("aria-expanded",a?"true":"false"),!a&&f&&te.focus())}function qt(a){if(!u)return;const f=a.target;f&&(ue.contains(f)||te.contains(f)||Ee.element.contains(f)||st(!1))}document.addEventListener("pointerdown",qt),Oe.append(te,ue);const Se=document.createElement("p");Se.className="hint",Se.textContent="drag a face to pull it · click to read · click a repost face for their profile · h hides the ones you have read · ↑↓ roots, ←→ thread";const ke=document.createElement("div");ke.className="sr-only",ke.setAttribute("role","list");const at=new Map;for(const a of o){const f=document.createElement("button");f.type="button",f.textContent=a.name;const m=a.event.content.split(`
`)[0]?.slice(0,100)??"",v=a.root?"note":"reply";f.setAttribute("aria-label",`${v} by ${a.name}: ${m}`),f.addEventListener("focus",()=>ne(a.id,"click")),f.addEventListener("click",()=>ne(a.id,"click")),at.set(a.id,f),ke.append(f)}G.append(N,z.element,ae.element),e.classList.add("space"),e.append(G,Oe,Ee.element,Se,ke);function Vt(){return{x:0,y:0,w:U,h:j}}function it(){return{top:G.scrollTop,height:q}}function lt(a){return co(a)+a*.8}function Kt(a){const f=qe(a.w,a.h),m=lt(f),v=a.x+a.w/2,k=a.y+a.h/2,I=d?a.h/2-m:Math.min(a.w/2-m,a.h/2-m);return{cx:v,cy:k,rx:Math.max(60,a.w/2-m),arm:Po(a,Math.max(60,I),k)}}function Jt(a){return d?[{x:a.cx,y:a.cy-a.arm},{x:a.cx,y:a.cy+a.arm},{x:a.cx,y:a.cy},{x:a.cx,y:a.cy}]:[{x:a.cx-a.rx,y:a.cy},{x:a.cx+a.rx,y:a.cy},{x:a.cx,y:a.cy-a.arm},{x:a.cx,y:a.cy+a.arm}]}function Po(a,f,m){const v=d?lt(qe(a.w,a.h)):0,k=a.y+a.h-8-v;let I=f;const T=fe();for(const Z of n){if(T.has(Z.id))continue;const ye=Z.tail.depth,ee=Co(Z);ye===0||ee<=.01||(I=Math.min(I,(k-m-ye)/ee))}return Math.max(60,I)}function Co(a){const[f,m]=d?[0,1]:[2,3],v=a.weights[f]??0,k=a.weights[m]??0,I=v+k;return I<=1e-9?0:(k-v)/I}function Qt(){const a=Kt(Vt()),f=Jt(a);let m=!1;for(const[v,k]of B.poles.entries()){const I=f[v]??{x:a.cx,y:a.cy},T=I.x+A.x,Z=I.y+A.y;(Math.abs(k.x-T)>.01||Math.abs(k.y-Z)>.01)&&(m=!0),k.x=T,k.y=Z}return m}function Io(a,f){const m=Vt(),v=8,k=Jt(Kt(m)),I=Math.min(...k.map(ee=>ee.x)),T=Math.max(...k.map(ee=>ee.x)),Z=Math.min(...k.map(ee=>ee.y)),ye=Math.max(...k.map(ee=>ee.y));return{x:Math.min(Math.max(a,v-I),m.x+m.w-v-T),y:Math.min(Math.max(f,v-Z),m.y+m.h-v-ye)}}function Lo(){B.bubbles.length=0,b=null,y=null,gt(n,d,fe()),B.bubbles.push(...es(n,m=>B.targetFor(m)));for(const m of B.bubbles)m.scaleTarget=ft(m.id);nn();const a=B.bubbles.length,f=Math.min(la,Math.max(1,Math.floor(ca/Math.max(1,a*(a-1)))));for(let m=0;m<f;m++)B.step(1/60);B.freeze(),J=!0}function De(){Q=!0,S=0,O=0}function ct(){const a=e.getBoundingClientRect(),f=Math.max(320,Math.round(a.width)),m=Math.max(320,Math.round(a.height)),v=Math.min(2,window.devicePixelRatio||1),k=f<ia,I=k!==d;d=k,I&&gt(n,d,fe());const T=fe(),Z=d?Jr(n.filter(jo=>!T.has(jo.id)),f,m):m,ye=U!==f||j!==Z||q!==m;U=f,j=Z,q=m,G.classList.toggle("scrolls",j>q),N.width=Math.round(U*v),N.height=Math.round(j*v),N.style.width=`${U}px`,N.style.height=`${j}px`,me.setTransform(v,0,0,v,0,0);const ee=d?lt(qe(U,j)):0;B.bounds={minX:8,minY:8+ee,maxX:U-8,maxY:j-8-ee},d&&z.setExpanded(!1),I&&N.setAttribute("aria-label",ve());const Uo=Qt();!J||I?Lo():(ye||Uo)&&De(),ie(),P=!0}function dt(a){const f=new Set;let m=r.get(a);for(;m&&!f.has(m.id);){f.add(m.id);const v=B.bubbles.find(k=>k.id===m.id);if(v)return v;m="parent"in m?r.get(m.parent):void 0}return null}function No(){if(!z.open||!p)return;if(z.expanded){z.place({left:U-z.size().width-oe,top:oe,side:"right"});return}const a=dt(p);if(!a)return;const f=Bn({x:a.x,y:a.y,r:a.r*a.scale},z.size(),{width:U,...it()});z.place(f)}function ie(){No(),Zt()}function Zt(){if(!ae.open||!x)return;const a=B.bubbles.find(m=>m.id===x.anchorId);if(!a||a.hidden){Me();return}let f={x:a.x,y:a.y,r:a.r*a.scale};if(x.bead){const m=r.get(x.anchorId),v=m?.root&&Rt(a,m).find(k=>k.repost.pubkey===x.bead.pubkey);v&&(f={x:v.x,y:v.y,r:v.r})}ae.place(Bn(f,ae.size(),{width:U,...it()}))}function en(a,f,m){x={pubkey:a,anchorId:f,bead:m},ne(null),ae.show(a),Zt(),P=!0}function Me(){!x&&!ae.open||(x=null,ae.hide(),He(),P=!0)}function _o(a){if(!d||q>=j)return;const f=it(),m=40;if(a.y>=f.top+m&&a.y<=f.top+f.height-m)return;const v=a.r+a.tailDepth,k=a.y-v/2+a.r,I=Math.max(0,Math.min(Math.round(k-f.height/2),j-f.height)),T=window.matchMedia("(prefers-reduced-motion: reduce)").matches;G.scrollTo({top:I,behavior:T?"auto":"smooth"})}function tn(){return new Set(n.filter(a=>s.has(a.id)).map(a=>a.id))}function fe(){const a=new Set;if(!i)return a;const f=p??x?.anchorId??null,m=f?he(f)?.id??null:null;for(const v of tn())v!==m&&a.add(v);return a}function nn(){const a=tn(),f=fe();let m=!1;for(const k of B.bubbles){const I=k.bond?.id??k.id,T=f.has(I);k.hidden!==T&&(k.hidden=T,k.vx=0,k.vy=0,k.ax=0,k.ay=0,m=!0)}c=new Set;const v=new Set;for(const k of B.bubbles){if(k.hidden){v.add(k.id);continue}const I=k.bond?.id??k.id;a.has(I)&&c.add(k.id)}for(const[k,I]of at)I.hidden=v.has(k);return m}function He(){const a=nn();d?(gt(n,!0,fe()),ct()):a&&De(),p&&z.setSeen(on(p)),Yt.refresh(),ie(),P=!0}function on(a){const f=he(a);return f?s.has(f.id):!1}function rn(a){i!==a&&(i=a,Lr(a),He())}function To(a){h!==a&&(h=a,ya(a),zt.set(a),P=!0)}function Oo(a){l!==a&&(l=a,ma(a),Xt.set(a),P=!0)}function Bo(){const a=p?he(p):null;a&&($=!1,_.id=null,_.elapsed=0,z.setDwell(0),s.forget(a.id))}s.onChange(He);function ne(a,f="link"){if(a!==null&&Me(),p!==a){p=a;for(const v of B.bubbles)v.scaleTarget=ft(v.id);for(const[v,k]of at)v===a?k.setAttribute("aria-current","true"):k.removeAttribute("aria-current");if(a){const v=r.get(a);if(v){z.show(v),z.setSeen(on(a));const k=dt(a);k&&_o(k),ie()}Se.classList.add("spent")}else z.hide();const m=a?`#${dr(a)}`:location.pathname;try{history.replaceState(null,"",m)}catch{}if(_.id=null,_.elapsed=0,$=a!==null&&f==="keys",$)z.setDwell(0);else if(a){const v=he(a);v&&s.mark(v.id),z.setDwell(1)}else z.setDwell(0);He()}P=!0}function ut(){const a=location.hash.replace(/^#/,"").trim();if(!a){ne(null);return}let f;try{f=ur(a)}catch{return}r.has(f)&&ne(f,"link")}function ft(a){return a===p?Hr:a===y?Dr:1}function sn(a){if(y!==a){y=a;for(const f of B.bubbles)f.scaleTarget=ft(f.id);N.style.cursor=a?"grab":M?"grabbing":"default",P=!0}}function an(a){const f=B.bubbles.filter(T=>!T.bond&&!T.hidden).sort((T,Z)=>T.y-Z.y||T.x-Z.x);if(f.length===0)return;const m=p?he(p):null,v=m?f.findIndex(T=>T.id===m.id):-1,k=v<0?a>0?0:f.length-1:v+a,I=f[(k+f.length)%f.length];I&&ne(I.id,"keys")}function ln(a){if(!p)return;const f=he(p);if(!f)return;const m=T=>!B.bubbles.find(Z=>Z.id===T)?.hidden,v=[f.id,...Do(f)].filter(m);if(v.length===0)return;const k=Math.max(0,v.indexOf(p)),I=v[(k+a+v.length)%v.length];I&&ne(I,"keys")}function he(a){const f=new Set;let m=r.get(a);for(;m&&"parent"in m&&!f.has(m.id);)f.add(m.id),m=r.get(m.parent);return m&&m.root?m:null}function Do(a){const f=[],m=v=>{for(const k of v)k.placement==="face"&&f.push(k.id),m(k.children)};return m(a.children),f}function Ho(a,f){me.save(),me.font=f;const m=me.measureText(a).width;return me.restore(),m}function cn(a,f){if(h)for(const m of B.bubbles){if(m.hidden)continue;const v=r.get(m.id);if(!v?.root||v.reactions.length===0||Math.abs(f-m.y)>_n||a<m.x||a>m.x+m.r+_n*2)continue;const k=ea(m,v,Ho);if(k&&a>=k.left-Ge&&a<=k.left+k.width+Ge&&f>=k.top-Ge&&f<=k.top+k.height+Ge)return m}return B.bubbleAt(a,f)}function dn(a,f){for(const m of B.bubbles){if(m.hidden)continue;const v=r.get(m.id);if(!(!v?.root||v.reposts.length===0)&&!(f>m.y)&&!(a<m.x-m.r*6||a>m.x+m.r*6)){for(const k of Rt(m,v))if(Math.hypot(a-k.x,f-k.y)<=k.r+2)return{bubble:m,repost:k.repost}}}}function ht(a){const f=N.getBoundingClientRect();return{x:a.clientX-f.left,y:a.clientY-f.top}}function un(a){if(a.button!==0)return;const f=ht(a);C=f,L={x:f.x,y:f.y,time:a.timeStamp},H=!1,N.setPointerCapture(a.pointerId);const m=dn(f.x,f.y);if(m)b=m.bubble,E=m.repost,m.bubble.hold=1,m.bubble.holdX=m.bubble.x,m.bubble.holdY=m.bubble.y,N.style.cursor="pointer";else{const v=cn(f.x,f.y);v?(b=v,v.hold=1,v.holdX=v.x,v.holdY=v.y,N.style.cursor="grabbing"):(M=!0,R={x:f.x-A.x,y:f.y-A.y},A.vx=0,A.vy=0,N.style.cursor="grabbing")}P=!0}function fn(a){const f=ht(a);C=f;const m=L?Math.hypot(f.x-L.x,f.y-L.y):0;if(b)(H||m>=7)&&(H=!0,b.holdX=Dn(f.x,U),b.holdY=Dn(f.y,j),De());else if(M&&R){if(H||m>=7){H=!0;const v=Io(f.x-R.x,f.y-R.y);A.x=v.x,A.y=v.y}}else{const v=dn(f.x,f.y);w=v?{bubbleId:v.bubble.id,pubkey:v.repost.pubkey}:null,sn(v?null:cn(f.x,f.y)?.id??null),N.style.cursor=v?"pointer":y?"grab":M?"grabbing":"default"}P=!0}function Ue(a){N.hasPointerCapture(a.pointerId)&&N.releasePointerCapture(a.pointerId);const f=ht(a),m=L?Math.hypot(f.x-L.x,f.y-L.y):0,v=L?a.timeStamp-L.time<450:!1,k=m<7&&v,I=b,T=E;E=null,L=null,H=!1,I?(I.hold=0,b=null,k&&(T?en(T.pubkey,I.id,T):ne(I.id,"click"))):M&&(M=!1,R=null,k&&(ne(null),Me())),N.style.cursor=y?"grab":"default",P=!0}function hn(a){if(Ee.element.hidden){if(a.key==="Escape"){u?st(!1,!0):x?Me():z.expanded?z.setExpanded(!1):p&&ne(null);return}if(a.key==="ArrowDown")an(1);else if(a.key==="ArrowUp")an(-1);else if(a.key==="ArrowRight")ln(1);else if(a.key==="ArrowLeft")ln(-1);else if(a.key==="h"||a.key==="H")rn(!i);else if((a.key==="e"||a.key==="E")&&!d)z.setExpanded(!z.expanded);else return;a.preventDefault()}}function pn(){Y=!0}function mn(){Y=!1,!(b||M)&&(C=null,w=null,sn(null),P=!0)}function gn(a){F=requestAnimationFrame(gn);const f=Math.min(.05,(a-W)/1e3);W=a,V+=f,$&&p&&!document.hidden&&(_.id!==p&&(_.id=p,_.elapsed=0),_.elapsed<We&&(_.elapsed=Math.min(We,_.elapsed+f*1e3),_.elapsed>=We&&s.mark(he(p)?.id??p)),z.setDwell(_.elapsed/We)),!M&&(A.x!==0||A.y!==0)&&(A.vx+=(-A.x*Tn-A.vx*On)*f,A.vy+=(-A.y*Tn-A.vy*On)*f,A.x+=A.vx*f,A.y+=A.vy*f,Math.hypot(A.x,A.y)<.2&&Math.hypot(A.vx,A.vy)<2&&(A.x=0,A.y=0,A.vx=0,A.vy=0));const m=Qt();m&&De(),Q?(B.step(f),H||m||A.x!==0||A.y!==0?(S=0,O=0):(S+=f,O=B.maxSpeed()<da?O+f:0,(O>=ua||S>=fa)&&(B.freeze(),Q=!1))):B.easeScale(f);const v=B.bubbles.some(T=>Math.abs(T.scale-T.scaleTarget)>.002),k=Q&&!B.isSettled(12);!(b!==null||M||A.x!==0||A.y!==0||Y||v||k)&&!P&&a-K<1e3/aa||(P=!1,K=a,ie(),Xs(me,{field:B,bubbles:r,images:Wt,width:U,height:j,hovered:y,hoveredRepost:w,selected:p,held:b?.id??null,anchorDrag:M,pointer:C,time:V,dimmed:c,phone:d,reactionBadges:h,strangerCounts:l}))}const yn=new ResizeObserver(()=>ct());yn.observe(e),ct();const bn=()=>ie();return G.addEventListener("scroll",bn,{passive:!0}),N.addEventListener("pointerdown",un),N.addEventListener("pointermove",fn),N.addEventListener("pointerup",Ue),N.addEventListener("pointercancel",Ue),N.addEventListener("pointerenter",pn),N.addEventListener("pointerleave",mn),window.addEventListener("keydown",hn),window.addEventListener("hashchange",ut),ut(),F=requestAnimationFrame(gn),()=>{cancelAnimationFrame(F),yn.disconnect(),N.removeEventListener("pointerdown",un),N.removeEventListener("pointermove",fn),N.removeEventListener("pointerup",Ue),N.removeEventListener("pointercancel",Ue),N.removeEventListener("pointerenter",pn),N.removeEventListener("pointerleave",mn),window.removeEventListener("keydown",hn),window.removeEventListener("hashchange",ut),document.removeEventListener("pointerdown",qt),z.dispose(),ae.dispose(),Ee.dispose(),Wt.dispose(),Bt(),G.removeEventListener("scroll",bn),Oe.remove(),Se.remove(),ke.remove(),G.remove()}}function Bn(e,t,n){const o=n.top+n.height,r={left:e.x-e.r-le-oe-t.width,right:n.width-oe-(e.x+e.r+le)-t.width,below:o-oe-(e.y+e.r+le)-t.height,above:e.y-e.r-le-oe-n.top-t.height,center:0},s=e.x>=n.width/2?["right","left"]:["left","right"],i=e.y>=n.top+n.height/2?["above","below"]:["below","above"],c=(g,y)=>r[y]-r[g],u=[...s.sort(c),...i.sort(c)].find(g=>r[g]>=0)??s[0],h=r[u]>=0,l={left:u==="left"?e.x-e.r-le-t.width:u==="right"?e.x+e.r+le:e.x-t.width/2,top:u==="above"?e.y-e.r-le-t.height:u==="below"?e.y+e.r+le:e.y-t.height/2};return{left:Hn(l.left,oe,n.width-oe-t.width),top:Hn(l.top,n.top+oe,o-oe-t.height),side:h?u:"center"}}function pa(){return Le(Eo)!=="false"}function ma(e){Ne(Eo,String(e))}function ga(){return Le(vo)!=="false"}function ya(e){Ne(vo,String(e))}function Dn(e,t){const n=Math.min(48,t*.15);return Math.min(Math.max(e,n),t-n)}function Hn(e,t,n){return Math.min(Math.max(e,t),Math.max(t,n))}const So=document.querySelector("#app");if(!So)throw new Error("#app is missing from index.html");const ko=So;function Ye(e,t,n=`${t}s`){return`${e} ${e===1?t:n}`}function ba(e){const t=[Ye(e.follows,"follow")];return e.batches<e.batchesTotal&&t.push(`${e.batches}/${e.batchesTotal} batches`),e.notes>0&&t.push(Ye(e.notes,"note")),e.threads>0&&t.push(Ye(e.threads,"thread")),e.replies>0&&t.push(Ye(e.replies,"reply","replies")),t.join(" · ")}function Un(e,t){const n=document.createElement("div");n.className="error";const o=document.createElement("p");if(o.textContent=e,n.append(o),t){const s=document.createElement("p");s.className="error-detail",s.textContent=t,n.append(s)}const r=document.createElement("p");return r.className="boot-status",r.setAttribute("aria-live","polite"),t||n.append(r),ko.replaceChildren(n),s=>{r.textContent=s}}let Pt=null;function Mo(){Pt?.(),Pt=null,Bt()}window.addEventListener("pagehide",Mo);window.addEventListener("beforeunload",Mo);try{const e=Un("reading the feed…");await Rr();const t=await xr({log:o=>console.info(o),onProgress:o=>e(ba(o))}),n=ha(ko,t);Pt=()=>{n(),Bt()}}catch(e){console.warn("Bubbles could not read the feed",{error:e});const t=e instanceof Error?e.message:String(e);Un("could not read the feed",`${t} — this napplet reads its feed through the host's outbox. Reload to try again.`)}
</script>
    <style>:root{--bg: #0a0a0d;--panel: #16161c;--border: rgba(255, 255, 255, .075);--text: #e8e8ee;--muted: #86869a;--accent: #a970ff;--hue: 270;--font: ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif;--mono: ui-monospace, SFMono-Regular, Menlo, monospace;color-scheme:dark}*{box-sizing:border-box}html,body{height:100%}body{margin:0;overflow:hidden;background:radial-gradient(130% 110% at 50% -10%,#17171f,#0d0d12 52%,#08080a);color:var(--text);font:15px/1.5 var(--font);-webkit-font-smoothing:antialiased}:focus-visible{outline:2px solid hsl(var(--hue) 90% 66% / .85);outline-offset:2px}#app.space{position:fixed;inset:0;overflow:hidden}.space-scroll{position:absolute;inset:0;overflow:hidden}.space-scroll.scrolls{overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.14) transparent}.space-canvas{position:absolute;top:0;left:0;display:block;touch-action:none;cursor:default}.hud{position:absolute;top:0;left:0;right:0;padding:22px 26px;pointer-events:none}.hud-account{display:inline-block;max-width:min(46vw,420px);margin-top:3px;overflow:hidden;color:var(--muted);font:11px/1.6 var(--mono);text-decoration:none;text-overflow:ellipsis;white-space:nowrap;pointer-events:auto}.hud-account:hover{color:var(--accent)}.hud-stats{margin:6px 0 0;color:var(--muted);font-size:11px;letter-spacing:.01em}.hud-burger{position:absolute;top:20px;right:24px;width:34px;height:34px;padding:0;border:1px solid rgba(255,255,255,.12);border-radius:50%;background:#0c0c118c;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);color:var(--muted);cursor:pointer;pointer-events:auto;transition:color .15s ease,border-color .15s ease,background .15s ease}.hud-burger:before{content:"";position:absolute;top:50%;left:50%;width:15px;height:1.5px;margin:-.75px 0 0 -7.5px;border-radius:2px;background:currentColor;box-shadow:0 -5px 0 currentColor,0 5px 0 currentColor}.hud-burger:hover{border-color:#ffffff47;background:#ffffff14;color:var(--text)}.hud-burger[aria-expanded=true]{border-color:#a970ff8c;background:#a970ff24;color:var(--text)}.hud-burger[data-busy=true]:after{content:"";position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 9px #a970ffe6}.hud-menu{position:absolute;top:64px;right:24px;z-index:4;display:flex;flex-direction:column;align-items:flex-start;gap:13px;max-width:min(86vw,340px);padding:16px 18px;border:1px solid rgba(255,255,255,.085);border-radius:14px;background:#0f0f15e6;-webkit-backdrop-filter:blur(22px) saturate(1.35);backdrop-filter:blur(22px) saturate(1.35);box-shadow:0 26px 55px -22px #000000e6,0 2px 10px #00000059;pointer-events:auto}.hud-menu[hidden]{display:none}.hud-menu .hud-account{display:block;max-width:100%;margin-top:0}.hud-menu .hud-prompt-row,.hud-menu .hud-seen-row{flex-wrap:wrap;gap:8px 10px;margin:0;max-width:100%}.hud-menu .hud-stats{margin:0;max-width:100%;line-height:1.6}.hud-menu .hud-status,.hud-menu .hud-seen-count{max-width:100%}.hud-menu-rule{width:100%;height:1px;background:#ffffff13}.hud-prompt-row{display:flex;align-items:center;gap:10px;margin:10px 0 0;pointer-events:auto}.hud-prompt{padding:4px 11px;border:1px solid var(--border);border-radius:999px;background:#0c0c1199;color:var(--text);font:11px var(--font);letter-spacing:.01em;cursor:pointer;transition:border-color .2s ease,color .2s ease}.hud-prompt:hover{border-color:#a970ff80;color:#fff}.hud-status{max-width:min(38vw,340px);overflow:hidden;color:var(--muted);font-size:11px;text-overflow:ellipsis;white-space:nowrap}.hud-status.live{color:var(--accent)}.hud-seen-row{display:flex;align-items:center;gap:10px;margin:8px 0 0;pointer-events:auto}.hud-toggle,.hud-seen{display:inline-flex;align-items:center;gap:7px;padding:4px 11px;border:1px solid var(--border);border-radius:999px;background:#0c0c1199;color:var(--text);font:11px var(--font);letter-spacing:.01em;cursor:pointer;transition:border-color .2s ease,color .2s ease}.hud-toggle:before,.hud-seen:before{content:"";width:7px;height:7px;border:1px solid var(--muted);border-radius:50%;transition:background .2s ease,border-color .2s ease,box-shadow .2s ease}.hud-toggle:hover,.hud-seen:hover{border-color:#a970ff80;color:#fff}.hud-toggle[aria-pressed=true],.hud-seen[aria-pressed=true]{border-color:#a970ff8c;color:#fff}.hud-toggle[aria-pressed=true]:before,.hud-seen[aria-pressed=true]:before{border-color:var(--accent);background:var(--accent);box-shadow:0 0 9px #a970ffd9}.hud-seen-count{max-width:min(30vw,260px);overflow:hidden;color:var(--muted);font-size:11px;letter-spacing:.01em;text-overflow:ellipsis;white-space:nowrap}.hud-seen-reset{padding:0;border:0;border-bottom:1px dotted rgba(134,134,154,.6);background:none;color:var(--muted);font:11px var(--font);cursor:pointer}.hud-seen-reset[hidden]{display:none}.hud-seen-reset:hover{color:var(--text)}.prompt{position:absolute;inset:0;z-index:5;display:grid;place-items:center;padding:24px;background:#08080b9e;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}.prompt[hidden]{display:none}.prompt-card{width:min(620px,100%);padding:22px 24px 18px;border:1px solid var(--border);border-radius:16px;background:var(--panel);box-shadow:0 24px 70px #0000008c}.prompt-title{margin:0;font-size:13px;font-weight:600;letter-spacing:.14em;text-transform:uppercase}.prompt-explain{margin:8px 0 14px;color:var(--muted);font-size:13px}.prompt-field{width:100%;padding:12px 14px;border:1px solid var(--border);border-radius:10px;background:#09090dbf;color:var(--text);font:13px/1.55 var(--font);resize:vertical}.prompt-field:focus{outline:none;border-color:#a970ff8c}.prompt-source{margin:10px 0 0;color:var(--muted);font:11px/1.5 var(--mono)}.prompt-error{margin:10px 0 0;color:#ff8f8f;font-size:12px}.prompt-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:16px}.prompt-save,.prompt-cancel{padding:8px 15px;border:1px solid var(--border);border-radius:999px;background:transparent;color:var(--text);font:12px var(--font);cursor:pointer}.prompt-save{border-color:#a970ff99;background:#a970ff29}.prompt-save:hover{background:#a970ff42}.prompt-cancel{color:var(--muted)}.prompt-cancel:hover{color:var(--text)}.hint{position:absolute;bottom:22px;left:50%;transform:translate(-50%);margin:0;padding:7px 15px;border:1px solid var(--border);border-radius:999px;background:#0c0c118c;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);color:var(--muted);font-size:12px;white-space:nowrap;pointer-events:none;transition:opacity .6s ease,transform .6s ease}.hint.spent{opacity:0;transform:translate(-50%) translateY(8px)}.panel{position:absolute;left:0;top:0;display:flex;flex-direction:column;width:min(430px,92vw);max-height:min(560px,80vh);overflow:hidden;border:1px solid rgba(255,255,255,.085);border-radius:18px;background:#0f0f15db;-webkit-backdrop-filter:blur(22px) saturate(1.35);backdrop-filter:blur(22px) saturate(1.35);box-shadow:0 30px 60px -24px #000000e6,0 2px 10px #00000059;opacity:0;visibility:hidden;transform:scale(.97);transition:opacity .16s ease,transform .18s cubic-bezier(.22,.8,.24,1),visibility 0s linear .18s}.panel[data-side=right]{transform:translate(-8px) scale(.98)}.panel[data-side=left]{transform:translate(8px) scale(.98)}.panel[data-side=below]{transform:translateY(-8px) scale(.98)}.panel[data-side=above]{transform:translateY(8px) scale(.98)}.panel.open{opacity:1;visibility:visible;transform:none;transition:opacity .16s ease,transform .18s cubic-bezier(.22,.8,.24,1),visibility 0s}.panel-dwell{position:absolute;top:0;left:0;right:0;height:2px;border-radius:18px 18px 0 0;background:#a970ffcc;transform:scaleX(0);transform-origin:left center;pointer-events:none}.panel-seen{grid-column:1 / -1;justify-self:start;padding:3px 9px;border:1px solid rgba(169,112,255,.45);border-radius:999px;background:#a970ff1f;color:#d6c4fff2;font:600 9px var(--font);letter-spacing:.14em;text-transform:uppercase;cursor:pointer;transition:background .15s ease,border-color .15s ease}.panel-seen[hidden]{display:none}.panel-seen:hover{border-color:#a970ffcc;background:#a970ff3d}.panel:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(130% 42% at 78% -12%,hsl(var(--hue) 90% 62% / .2),transparent 68%)}.panel-head{position:relative;flex:none;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:10px 12px;padding:20px 26px 16px;border-bottom:1px solid var(--border)}.panel-close{position:absolute;top:16px;right:16px;width:30px;height:30px;padding:0;border:1px solid rgba(255,255,255,.12);border-radius:50%;background:#ffffff0a;color:var(--muted);font:400 18px/1 var(--font);cursor:pointer;transition:color .15s ease,border-color .15s ease,background .15s ease}.panel-close:hover{border-color:#ffffff47;background:#ffffff17;color:var(--text)}.panel-expand{position:absolute;top:16px;right:52px;width:30px;height:30px;padding:0;border:1px solid rgba(255,255,255,.12);border-radius:50%;background:#ffffff0a;cursor:pointer;transition:border-color .15s ease,background .15s ease}.panel-expand:before{content:"";position:absolute;inset:8px 7px;border:1.5px solid var(--muted);border-radius:3px;transition:border-color .15s ease}.panel-expand:after{content:"";position:absolute;top:9.5px;bottom:9.5px;left:17.5px;width:1.5px;border-radius:1px;background:var(--muted);transition:left .2s cubic-bezier(.22,.8,.24,1),background .15s ease}.panel-expand:hover{border-color:#ffffff47;background:#ffffff17}.panel-expand:hover:before{border-color:var(--text)}.panel-expand:hover:after,.panel[data-expanded=true] .panel-expand:after{left:11.5px;background:var(--text)}.panel[data-expanded=true]{width:min(50vw,780px);height:calc(100vh - 24px);max-height:none}.panel[data-expanded=true] .panel-note-text,.panel[data-expanded=true] .panel-empty,.panel[data-expanded=true] .panel-reply-text{max-width:62ch}.panel[data-expanded=true] .panel-note-image{max-height:68vh}.panel-avatar{grid-column:1;display:grid;width:42px;height:42px;place-items:center;overflow:hidden;border:2px solid hsl(var(--hue) 90% 66% / .65);border-radius:50%;background:hsl(var(--hue) 30% 16%);box-shadow:0 0 26px hsl(var(--hue) 90% 60% / .28);color:hsl(var(--hue) 90% 80%);font-size:16px;font-weight:600}.panel-avatar img,.panel-reply-avatar img{display:block;width:100%;height:100%;object-fit:cover}.panel-name{grid-column:2;margin:0;padding-right:78px;font-size:16px;font-weight:600;letter-spacing:-.01em;overflow-wrap:anywhere}.panel-author{grid-column:1 / -1;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:10px 12px;width:100%;padding:0;border:0;border-radius:12px;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}.panel-author:hover .panel-name,.panel-author:focus-visible .panel-name{color:hsl(var(--hue) 85% 82%)}.panel-author:focus-visible{outline:1px solid hsla(var(--hue),85%,70%,.6);outline-offset:4px}.panel-meta{grid-column:1 / -1;margin:0;padding-right:78px;color:var(--muted);font-size:10px;letter-spacing:.1em;text-transform:uppercase}.panel-notes{position:relative;flex:1;min-height:0;padding:2px 26px 30px;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.14) transparent}.panel-notes::-webkit-scrollbar{width:10px}.panel-notes::-webkit-scrollbar-thumb{border:3px solid transparent;border-radius:999px;background:#ffffff29;background-clip:content-box}.panel-note{padding:18px 0;border-bottom:1px solid rgba(255,255,255,.055)}.panel-note:last-child{border-bottom:0}.panel-note-head{display:flex;align-items:center;gap:8px;margin-bottom:7px}.panel-note-reply{padding:1px 8px;border:1px solid rgba(255,255,255,.13);border-radius:999px;color:var(--muted);font-size:9px;letter-spacing:.09em;text-transform:uppercase}.panel-note-time{color:var(--muted);font:11px/1.5 var(--mono);text-decoration:none}.panel-note-time:hover{color:var(--text)}.panel-note-text{margin:0;font-size:14px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere}.panel-note-text.muted{color:var(--muted)}.panel-mention{padding:1px 6px;border:1px solid hsl(var(--hue) 80% 70% / .3);border-radius:999px;background:hsl(var(--hue) 60% 60% / .13);color:hsl(var(--hue) 90% 82%);font-size:13px;white-space:nowrap;text-decoration:none}.panel-mention:hover{border-color:hsl(var(--hue) 90% 72% / .6);background:hsl(var(--hue) 60% 60% / .22)}.panel-note-image{display:block;width:100%;max-height:58vh;margin-top:11px;border:1px solid rgba(255,255,255,.08);border-radius:12px;background:#00000059;object-fit:contain}.panel-reactions{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:14px}.panel-reaction{display:inline-flex;align-items:center;gap:5px;padding:3px 9px 3px 8px;border:1px solid rgba(255,255,255,.09);border-radius:999px;background:#ffffff09}.panel-reaction-glyph{font-size:13px;line-height:1.3}.panel-reaction-count{color:var(--muted);font:600 11px/1.3 var(--mono)}.panel-reaction-more{color:var(--muted);font-size:11px}.panel-note-link,.panel-note-more{display:inline-block;margin-top:8px;color:var(--muted);font:11px/1.6 var(--mono)}.panel-note-link:hover{color:var(--accent)}.panel-empty{margin:26px 0 0;color:var(--muted);font-size:13px}.panel-context{display:flex;flex-direction:column;gap:1px;margin:2px 0 14px;padding:2px 0 2px 9px;border-left:2px solid var(--border)}.panel-context-row{display:grid;grid-template-columns:auto auto minmax(0,1fr);gap:8px;align-items:baseline;width:100%;padding:5px 8px;border:1px solid transparent;border-radius:8px;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}.panel-context-row:hover,.panel-context-row:focus-visible{border-color:hsla(var(--hue),80%,70%,.3);background:hsla(var(--hue),70%,60%,.06);outline:none}.panel-context-role{color:var(--accent);font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;white-space:nowrap}.panel-context-name{max-width:14ch;overflow:hidden;color:#e8e8eea8;font-size:12px;white-space:nowrap;text-overflow:ellipsis}.panel-context-text{overflow:hidden;color:#e8e8ee70;font-size:12.5px;white-space:nowrap;text-overflow:ellipsis}.panel-context-gap{margin:3px 8px;color:var(--muted);font-size:10px;letter-spacing:.09em;text-transform:uppercase}.panel-replies{padding:14px 0 4px}.panel-replies-head,.panel-replies-more{margin:0 0 8px;color:var(--muted);font-size:10px;letter-spacing:.1em;text-transform:uppercase}.panel-replies-more{margin:10px 0 0}.panel-reply{display:flex;gap:9px;align-items:flex-start;width:100%;padding:7px 8px 7px calc(8px + var(--indent, 0px));border:1px solid transparent;border-radius:10px;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}.panel-reply:hover,.panel-reply:focus-visible{border-color:hsla(var(--hue),80%,70%,.35);background:hsla(var(--hue),70%,60%,.07);outline:none}.panel-reply-avatar{flex:none;display:grid;width:22px;height:22px;margin-top:1px;place-items:center;overflow:hidden;border-radius:50%;background:hsl(var(--hue) 34% 18%);color:hsl(var(--hue) 92% 80%);font-size:11px;font-weight:600}.panel-reply-body{display:flex;min-width:0;flex-direction:column;gap:2px}.panel-reply-name{color:hsl(var(--hue) 80% 82%);font-size:12px;font-weight:600}.panel-reply-text{color:#e8e8f0b8;font-size:12px;line-height:1.45;overflow-wrap:anywhere}.profile-card{position:absolute;left:0;top:0;display:flex;flex-direction:column;width:min(340px,92vw);max-height:min(520px,80vh);overflow:hidden;border:1px solid rgba(255,255,255,.085);border-radius:18px;background:#0f0f15e6;-webkit-backdrop-filter:blur(22px) saturate(1.35);backdrop-filter:blur(22px) saturate(1.35);box-shadow:0 30px 60px -24px #000000e6,0 2px 10px #00000059;opacity:0;visibility:hidden;transform:scale(.97);transition:opacity .16s ease,transform .18s cubic-bezier(.22,.8,.24,1),visibility 0s linear .18s}.profile-card[data-side=right]{transform:translate(-8px) scale(.98)}.profile-card[data-side=left]{transform:translate(8px) scale(.98)}.profile-card[data-side=below]{transform:translateY(-8px) scale(.98)}.profile-card[data-side=above]{transform:translateY(8px) scale(.98)}.profile-card.open{opacity:1;visibility:visible;transform:none;transition:opacity .16s ease,transform .18s cubic-bezier(.22,.8,.24,1),visibility 0s}.profile-banner{position:absolute;top:0;left:0;right:0;height:86px;background-image:linear-gradient(hsl(var(--hue) 58% 30%),hsl(var(--hue) 42% 14%));background-size:cover;background-position:center}.profile-banner.has-image:after{content:"";position:absolute;inset:0;background:linear-gradient(to bottom,#0f0f1500 40%,#0f0f15eb)}.profile-close{position:absolute;top:12px;right:12px;z-index:2;width:28px;height:28px;padding:0;border:1px solid rgba(255,255,255,.16);border-radius:50%;background:#00000059;color:var(--text);font:400 17px/1 var(--font);cursor:pointer;transition:border-color .15s ease,background .15s ease}.profile-close:hover{border-color:#ffffff52;background:#0000008c}.profile-body{position:relative;display:flex;flex:1 1 auto;min-height:0;flex-direction:column;gap:7px;padding:56px 22px 22px;overflow-y:auto;overscroll-behavior:contain}.profile-avatar{display:grid;width:64px;height:64px;place-items:center;overflow:hidden;border:2px solid hsl(var(--hue) 90% 66% / .75);border-radius:50%;background:hsl(var(--hue) 30% 16%);box-shadow:0 0 34px hsl(var(--hue) 90% 60% / .3);color:hsl(var(--hue) 92% 82%);font-size:24px;font-weight:600}.profile-avatar img{display:block;width:100%;height:100%;object-fit:cover}.profile-name{margin:3px 0 0;font-size:20px;font-weight:650;letter-spacing:-.01em;overflow-wrap:anywhere}.profile-handle{margin:0;color:hsl(var(--hue) 70% 78%);font:11px/1.5 var(--mono);overflow-wrap:anywhere}.profile-handle[hidden],.profile-about[hidden]{display:none}.profile-about{margin:4px 0 0;color:#e8e8f0d1;font-size:13px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere}.profile-links{display:flex;flex-direction:column;gap:6px;margin-top:8px}.profile-link{display:inline-block;max-width:100%;padding:5px 10px;border:1px solid hsla(var(--hue),70%,70%,.24);border-radius:9px;background:hsla(var(--hue),60%,60%,.08);color:hsl(var(--hue) 88% 82%);font:11px/1.4 var(--mono);text-decoration:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;transition:border-color .15s ease,background .15s ease}.profile-link:hover{border-color:hsla(var(--hue),85%,72%,.55);background:hsla(var(--hue),60%,60%,.16)}.profile-missing{margin:6px 0 0;color:var(--muted);font-size:11px;letter-spacing:.04em}.boot,.error{position:absolute;inset:0;display:grid;place-content:center;gap:6px;padding:24px;text-align:center;color:var(--muted);font-size:14px}.boot{letter-spacing:.04em}.boot-status{min-height:1.5em;font:12px/1.6 var(--mono);font-variant-numeric:tabular-nums}.error p{margin:0}.error p:first-child{color:var(--text)}.error-detail{font:12px/1.6 var(--mono);overflow-wrap:anywhere}.error code{color:var(--accent);font-family:var(--mono)}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;border:0;clip-path:inset(50%);white-space:nowrap}@media(prefers-reduced-motion:reduce){.panel,.profile-card,.hint,.panel-close,.panel-expand,.panel-expand:before,.panel-expand:after{transition:none}.hud-burger{transition:none}}@media(max-width:659px){.panel-expand{display:none}.hud-burger{top:14px;right:16px}.hud-menu{top:56px;right:16px}.space-canvas{touch-action:pan-y}.panel-name,.panel-meta{padding-right:40px}}@media(max-width:560px){.hud{padding:16px 18px}.hud-account{max-width:60vw}.hint{max-width:92vw;overflow:hidden;text-overflow:ellipsis}.panel-head{padding:20px 20px 16px}.panel-notes{padding:0 20px 40px}}
</style>
  </head>
  <body>
    <main id="app" class="space">
      <p class="boot">loading the room…</p>
    </main>
  </body>
</html>