BiNgoViewer 2.7.2__tar.gz → 2.7.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/BiNgoViewer.egg-info/PKG-INFO +1 -1
  2. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/BiNgoViewer.egg-info/SOURCES.txt +1 -1
  3. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/PKG-INFO +1 -1
  4. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/__init__.py +1 -1
  5. bingoviewer-2.7.2/bingoviewer/frontend_dist/assets/index-BC4ehCBT.js → bingoviewer-2.7.3/bingoviewer/frontend_dist/assets/index-4OAJAWev.js +1 -1
  6. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/frontend_dist/index.html +1 -1
  7. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/install_shortcut.py +8 -9
  8. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/main.py +1 -1
  9. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/pyproject.toml +1 -1
  10. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/BiNgoViewer.egg-info/dependency_links.txt +0 -0
  11. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/BiNgoViewer.egg-info/entry_points.txt +0 -0
  12. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/BiNgoViewer.egg-info/requires.txt +0 -0
  13. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/BiNgoViewer.egg-info/top_level.txt +0 -0
  14. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/README.md +0 -0
  15. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/__main__.py +0 -0
  16. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/cli.py +0 -0
  17. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/icon.py +0 -0
  18. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/__init__.py +0 -0
  19. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/api/__init__.py +0 -0
  20. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/api/data.py +0 -0
  21. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/api/genome.py +0 -0
  22. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/api/tracks.py +0 -0
  23. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/readers/__init__.py +0 -0
  24. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/readers/annotation_reader.py +0 -0
  25. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/readers/bam_reader.py +0 -0
  26. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/readers/bigwig_reader.py +0 -0
  27. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/readers/genbank_reader.py +0 -0
  28. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/readers/genome_reader.py +0 -0
  29. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/readers/vcf_reader.py +0 -0
  30. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/bingoviewer/server/state.py +0 -0
  31. {bingoviewer-2.7.2 → bingoviewer-2.7.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BiNgoViewer
3
- Version: 2.7.2
3
+ Version: 2.7.3
4
4
  Summary: BiNgo Genome Viewer — a lightweight browser-based genomics viewer
5
5
  Author-email: Billy M Ngo <billy.ngo0108@gmail.com>
6
6
  License: Proprietary
@@ -12,7 +12,7 @@ bingoviewer/cli.py
12
12
  bingoviewer/icon.py
13
13
  bingoviewer/install_shortcut.py
14
14
  bingoviewer/frontend_dist/index.html
15
- bingoviewer/frontend_dist/assets/index-BC4ehCBT.js
15
+ bingoviewer/frontend_dist/assets/index-4OAJAWev.js
16
16
  bingoviewer/server/__init__.py
17
17
  bingoviewer/server/main.py
18
18
  bingoviewer/server/state.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BiNgoViewer
3
- Version: 2.7.2
3
+ Version: 2.7.3
4
4
  Summary: BiNgo Genome Viewer — a lightweight browser-based genomics viewer
5
5
  Author-email: Billy M Ngo <billy.ngo0108@gmail.com>
6
6
  License: Proprietary
@@ -1,3 +1,3 @@
1
1
  """BiNgo Genome Viewer — a lightweight browser-based genomics viewer."""
2
2
 
3
- __version__ = "2.7.2"
3
+ __version__ = "2.7.3"
@@ -94,4 +94,4 @@ ${L.join(`
94
94
  `)}
95
95
 
96
96
  Tip: If files were moved, re-add them using the 📂 Path button.`):(y("Session restored"),setTimeout(()=>{y(null),e()},1200))}catch(B){h(B.message)}finally{m(!1)}}const O=Pc(),R=jy(c);return s.jsx("div",{style:R.overlay,onClick:H=>{H.target===H.currentTarget&&e()},children:s.jsxs("div",{style:R.panel,children:[s.jsxs("div",{style:R.header,children:[s.jsx("span",{style:R.title,children:"Session"}),s.jsx("button",{style:R.closeBtn,onClick:e,children:"✕"})]}),s.jsxs("div",{style:R.body,children:[s.jsxs("div",{style:R.section,children:[s.jsx("div",{style:R.sectionTitle,children:"Save"}),s.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:s.jsx("button",{style:R.btn,onClick:S,disabled:!r||f,children:"Save to file"})}),s.jsx("div",{style:{fontSize:10,color:c.textTertiary,marginTop:4},children:"Session is also auto-saved to browser storage."})]}),s.jsxs("div",{style:R.section,children:[s.jsx("div",{style:R.sectionTitle,children:"Restore"}),s.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[s.jsx("button",{style:R.btn,onClick:T,disabled:f,children:"Load from file"}),O&&s.jsx("button",{style:R.btn,onClick:E,disabled:f,children:"Restore last session"})]}),s.jsx("input",{ref:w,type:"file",accept:".json",style:{display:"none"},onChange:b}),O&&s.jsxs("div",{style:{fontSize:10,color:c.textTertiary,marginTop:4},children:["Last auto-save: ",new Date(O.savedAt).toLocaleString(),O.genome&&` — ${O.genome.name}`,O.tracks&&` — ${O.tracks.length} tracks`]})]}),v&&s.jsx("div",{style:{padding:"4px 16px",fontSize:11,color:"#81c784"},children:v}),p&&s.jsx("div",{style:{padding:"4px 16px",fontSize:11,color:"#ef9a9a",whiteSpace:"pre-wrap"},children:p})]}),s.jsx("div",{style:R.footer,children:s.jsx("button",{style:R.btn,onClick:e,children:"Close"})})]})})}function jy(e){return{overlay:{position:"fixed",inset:0,background:e.overlayBg,display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3},panel:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:0,minWidth:380,maxWidth:480,maxHeight:"80vh",display:"flex",flexDirection:"column",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},header:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"10px 16px",borderBottom:`1px solid ${e.border}`},title:{fontSize:14,fontWeight:700,color:e.textPrimary},closeBtn:{background:"none",border:"none",color:e.textSecondary,cursor:"pointer",fontSize:18,lineHeight:1,padding:"0 4px"},body:{padding:"8px 0",overflowY:"auto",flex:1},section:{padding:"8px 16px"},sectionTitle:{fontSize:11,color:e.textSecondary,textTransform:"uppercase",letterSpacing:1,marginBottom:6},btn:{background:e.btnBg,border:"none",borderRadius:4,color:e.btnText,padding:"5px 14px",cursor:"pointer",fontSize:12,fontWeight:600},footer:{display:"flex",justifyContent:"flex-end",padding:"10px 16px",borderTop:`1px solid ${e.border}`}}}const ye=e=>s.jsx("strong",{children:e}),fe=({children:e})=>s.jsxs("div",{style:{display:"flex",gap:6,marginTop:4},children:[s.jsx("span",{style:{opacity:.5},children:"•"}),s.jsx("span",{children:e})]}),Lc=({children:e})=>s.jsx("span",{style:{background:"rgba(255,255,255,0.1)",borderRadius:3,padding:"0 4px",fontSize:11,fontFamily:"monospace"},children:e}),jn=[{target:"file-loader",title:"Load Files",description:s.jsxs(s.Fragment,{children:["Upload genome and track files via:",s.jsxs(fe,{children:[ye("File picker"),' — click "Choose Files"']}),s.jsxs(fe,{children:[ye("Drag & drop")," — drop files anywhere on the app"]}),s.jsxs(fe,{children:[ye("Local path")," — paste a file path (best for large files)"]}),s.jsx("div",{style:{marginTop:8,opacity:.7},children:"Supported: FASTA, GenBank, BAM, BigWig, WIG, BedGraph, VCF, BED, GTF, GFF"})]}),position:"bottom"},{target:"nav-bar",title:"Navigation",description:s.jsxs(s.Fragment,{children:[s.jsxs(fe,{children:[ye("Chromosome selector")," — switch between chromosomes"]}),s.jsxs(fe,{children:[ye("Coordinate input")," — type ",s.jsx(Lc,{children:"chr1:1000-5000"})," and press Go"]}),s.jsxs(fe,{children:[ye("- +")," — zoom out / zoom in"]}),s.jsxs(fe,{children:[ye("◀ ▶")," — pan left / pan right"]}),s.jsxs(fe,{children:[ye("Blue scrubber bar")," — click or drag to jump across the chromosome"]})]}),position:"bottom"},{target:"track-area",title:"Track Interaction",description:s.jsxs(s.Fragment,{children:[s.jsxs(fe,{children:[ye("Left-click drag")," — pan the viewport"]}),s.jsxs(fe,{children:[ye("Scroll wheel")," — zoom in/out at cursor position"]}),s.jsxs(fe,{children:[ye("Right-click drag")," — select a region (hover for stats)"]}),s.jsxs(fe,{children:[ye("Double-click gene")," — zoom to fit that gene with context"]}),s.jsxs(fe,{children:[ye("Hover features")," — view detailed tooltips"]})]}),position:"inside"},{target:"skeleton-track-label",title:"Track Labels",description:s.jsxs(s.Fragment,{children:[s.jsxs(fe,{children:[ye("≡ Drag handle")," — reorder tracks by dragging"]}),s.jsxs(fe,{children:[ye("Color swatch")," — click to pick a color"]}),s.jsxs(fe,{children:[ye("× Button")," — remove the track"]}),s.jsxs(fe,{children:[ye("Bottom edge")," — drag to resize track height"]})]}),position:"right"},{target:"btn-settings",title:"Track Settings",description:s.jsxs(s.Fragment,{children:["Select one or more tracks to adjust:",s.jsx(fe,{children:"Height, visibility, and fill color"}),s.jsx(fe,{children:"Bar width, peak outline trace + smoothness"}),s.jsxs(fe,{children:["Y-axis scale (auto / manual / log","₂",")"]}),s.jsx(fe,{children:"Annotation colors per feature type"}),s.jsx(fe,{children:"Read appearance — strand colors, arrow style & size"}),s.jsx(fe,{children:"Nucleotide display with mismatch highlighting"}),s.jsx("div",{style:{marginTop:6,opacity:.7},children:"The panel is draggable — adjust settings while viewing your data."})]}),position:"bottom",action:"open-settings"},{target:"header-btns",title:"Themes",description:s.jsxs(s.Fragment,{children:[s.jsxs(fe,{children:[ye("5 built-in themes")," — Dark, Light, Colorblind, Soft, High Contrast"]}),s.jsxs(fe,{children:[ye("Custom themes")," — clone any preset and edit every color"]}),s.jsx("div",{style:{marginTop:6,opacity:.7},children:"Theme preferences persist across sessions."})]}),position:"bottom",action:"open-theme"},{target:"btn-export",title:"Export Image",description:s.jsxs(s.Fragment,{children:["Export the current view as ",ye("SVG")," or ",ye("PNG"),".",s.jsx(fe,{children:"Background, bars, outlines, and labels are separate SVG groups"}),s.jsx(fe,{children:"All track settings (colors, outlines, visibility) are respected"}),s.jsx(fe,{children:"Edit exported SVGs in Illustrator, Inkscape, or Figma"})]}),position:"bottom"},{target:"header-btns",title:"Sessions",description:s.jsxs(s.Fragment,{children:[s.jsxs(fe,{children:[ye("Save to file")," — exports genome, tracks, region, zoom, colors, and all settings as JSON"]}),s.jsxs(fe,{children:[ye("Restore")," — reload a saved session or the last auto-save"]}),s.jsxs(fe,{children:[ye("Auto-save")," — your session saves to the browser automatically"]}),s.jsx("div",{style:{marginTop:6,opacity:.7},children:"An exit guard warns you before closing with unsaved work."})]}),position:"bottom"},{target:"file-loader",title:"Tips",description:s.jsxs(s.Fragment,{children:[s.jsxs(fe,{children:[ye("Large BAM files")," — use the ",s.jsxs(Lc,{children:["📂"," Path"]})," button to load by file path (no upload needed)"]}),s.jsxs(fe,{children:[ye("Large WIG files")," — convert to BigWig for instant loading"]}),s.jsxs(fe,{children:[ye("BAM + BAI")," — select both together, or load by path (index auto-discovered)"]}),s.jsxs(fe,{children:[ye("Updates")," — the app checks for updates automatically on launch"]})]}),position:"bottom"}],Tn=8,En=14,Et=340,Ty=230,$r="rgba(0,0,0,0.55)";function Ey({onClose:e,theme:t,onAction:n}){const[r,o]=k.useState(0),[l,i]=k.useState(null),[a,u]=k.useState(Ty),c=k.useRef(null),g=jn[r],d=r===0,x=r===jn.length-1;k.useEffect(()=>{var b;const T=(b=jn[r])==null?void 0:b.action;T&&n&&n(T)},[r,n]);const j=k.useCallback(T=>{var E;((E=jn[T])==null?void 0:E.action)&&n&&n(null)},[n]),v=k.useCallback(()=>{j(r),r<jn.length-1?o(T=>T+1):e()},[r,e,j]),y=k.useCallback(()=>{j(r),r>0&&o(T=>T-1)},[r,j]);k.useEffect(()=>{function T(b){b.key==="Escape"?e():b.key==="ArrowRight"||b.key==="Enter"?v():b.key==="ArrowLeft"&&y()}return window.addEventListener("keydown",T),()=>window.removeEventListener("keydown",T)},[e,v,y]),k.useEffect(()=>{function T(){const b=document.querySelector(`[data-tour="${g.target}"]`);if(b){const E=b.getBoundingClientRect();i({top:E.top,left:E.left,width:E.width,height:E.height})}else i(null)}return T(),window.addEventListener("resize",T),window.addEventListener("scroll",T,!0),()=>{window.removeEventListener("resize",T),window.removeEventListener("scroll",T,!0)}},[g.target]),k.useEffect(()=>{c.current&&u(c.current.getBoundingClientRect().height)});const p=l?{top:l.top-Tn,left:l.left-Tn,width:l.width+Tn*2,height:l.height+Tn*2}:null;let h,f,m=null,w=Et/2;if(!l)h=(window.innerHeight-a)/2,f=(window.innerWidth-Et)/2;else{const T=g.position||"bottom",b=l.top+l.height+Tn,E=l.top-Tn,N=l.left+l.width+Tn,O=l.left+l.width/2;T==="inside"?(h=l.top+Math.max(20,(l.height-a)/2),f=l.left+Math.max(16,(l.width-Et)/2)):T==="right"?(h=l.top+l.height/2-a/2,f=N+En,m="left",w=a/2,f+Et>window.innerWidth-12&&(h=b+En,f=O-Et/2,m="up",w=Math.max(20,Math.min(Et-20,O-f)))):(b+En+a<=window.innerHeight?(h=b+En,m="up"):E-En-a>=0?(h=E-En-a,m="down"):(h=b+En,m="up"),l.width<200?(f=Math.max(12,l.left+l.width-Et),f<12&&(f=12)):f=O-Et/2,w=Math.max(20,Math.min(Et-20,O-f))),f=Math.max(12,Math.min(window.innerWidth-Et-12,f)),h=Math.max(12,Math.min(window.innerHeight-a-12,h))}const S={card:{position:"fixed",top:h,left:f,width:Et,zIndex:10002,background:t.panelBg,border:`1px solid ${t.borderAccent}`,borderRadius:10,padding:"20px 24px 16px",color:t.textPrimary,boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},stepCounter:{fontSize:11,fontWeight:600,color:t.textTertiary,textTransform:"uppercase",letterSpacing:1.2,marginBottom:10},title:{fontSize:16,fontWeight:700,marginBottom:6,color:t.textPrimary},description:{fontSize:13,lineHeight:1.6,color:t.textSecondary,marginBottom:20},dots:{display:"flex",justifyContent:"center",gap:8,marginBottom:14},dot:T=>({width:7,height:7,borderRadius:"50%",background:T?"#42a5f5":t.borderStrong,cursor:"pointer"}),nav:{display:"flex",alignItems:"center",justifyContent:"space-between"},btnPrimary:{background:"#1976d2",border:"none",borderRadius:5,color:"#fff",padding:"6px 18px",cursor:"pointer",fontSize:12,fontWeight:600},btnSecondary:{background:t.btnBg,border:`1px solid ${t.borderStrong}`,borderRadius:5,color:t.btnText,padding:"6px 14px",cursor:"pointer",fontSize:12,fontWeight:600},btnDisabled:{background:t.btnBg,border:`1px solid ${t.border}`,borderRadius:5,color:t.textMuted,padding:"6px 14px",fontSize:12,fontWeight:600,cursor:"default",opacity:.5},skip:{background:"none",border:"none",color:t.textTertiary,fontSize:11,cursor:"pointer",textDecoration:"underline",padding:0},arrowUp:{position:"absolute",top:-7,left:w-7,width:0,height:0,borderLeft:"7px solid transparent",borderRight:"7px solid transparent",borderBottom:`7px solid ${t.panelBg}`},arrowDown:{position:"absolute",bottom:-7,left:w-7,width:0,height:0,borderLeft:"7px solid transparent",borderRight:"7px solid transparent",borderTop:`7px solid ${t.panelBg}`},arrowLeft:{position:"absolute",left:-7,top:w-7,width:0,height:0,borderTop:"7px solid transparent",borderBottom:"7px solid transparent",borderRight:`7px solid ${t.panelBg}`}};return s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{position:"fixed",inset:0,zIndex:1e4},onClick:e}),p?s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{position:"fixed",top:0,left:0,right:0,height:Math.max(0,p.top),background:$r,zIndex:10001,pointerEvents:"none"}}),s.jsx("div",{style:{position:"fixed",top:p.top+p.height,left:0,right:0,bottom:0,background:$r,zIndex:10001,pointerEvents:"none"}}),s.jsx("div",{style:{position:"fixed",top:p.top,left:0,width:Math.max(0,p.left),height:p.height,background:$r,zIndex:10001,pointerEvents:"none"}}),s.jsx("div",{style:{position:"fixed",top:p.top,left:p.left+p.width,right:0,height:p.height,background:$r,zIndex:10001,pointerEvents:"none"}}),s.jsx("div",{style:{position:"fixed",top:p.top,left:p.left,width:p.width,height:p.height,borderRadius:6,border:"2px solid rgba(255,255,255,0.22)",zIndex:10001,pointerEvents:"none",boxSizing:"border-box"}})]}):s.jsx("div",{style:{position:"fixed",inset:0,background:$r,zIndex:10001,pointerEvents:"none"}}),s.jsxs("div",{ref:c,style:S.card,onClick:T=>T.stopPropagation(),children:[m==="up"&&s.jsx("div",{style:S.arrowUp}),m==="down"&&s.jsx("div",{style:S.arrowDown}),m==="left"&&s.jsx("div",{style:S.arrowLeft}),s.jsxs("div",{style:S.stepCounter,children:["Step ",r+1," of ",jn.length]}),s.jsx("div",{style:S.title,children:g.title}),s.jsx("div",{style:S.description,children:g.description}),s.jsx("div",{style:S.dots,children:jn.map((T,b)=>s.jsx("div",{style:S.dot(b===r),onClick:()=>o(b)},b))}),s.jsxs("div",{style:S.nav,children:[s.jsx("button",{style:S.skip,onClick:e,children:"Skip Tour"}),s.jsxs("div",{style:{display:"flex",gap:8},children:[s.jsx("button",{style:d?S.btnDisabled:S.btnSecondary,onClick:y,disabled:d,children:"Previous"}),s.jsx("button",{style:S.btnPrimary,onClick:v,children:x?"Finish":"Next"})]})]})]})]})}function Ry(){const{theme:e}=Ge(),{genome:t,region:n,selection:r,navigateTo:o,zoom:l,pan:i}=nt(),[a,u]=k.useState(""),c=k.useRef(null),g=k.useRef(!1),d=k.useMemo(()=>{if(!t)return{toShort:{},toLong:{}};const S={},T={};return t.chromosomes.forEach((b,E)=>{const N=`chr${E+1}`;S[b.name]=N,T[N.toLowerCase()]=b.name,T[b.name.toLowerCase()]=b.name}),{toShort:S,toLong:T}},[t]);k.useEffect(()=>{if(n){const S=d.toShort[n.chrom]||n.chrom;u(`${S}:${n.start.toLocaleString()}-${n.end.toLocaleString()}`)}},[n,d]);const x=k.useMemo(()=>{if(!t||!n)return 0;const S=t.chromosomes.find(T=>T.name===n.chrom);return S?S.length:0},[t,n==null?void 0:n.chrom]),j=k.useCallback(S=>{if(!c.current||!n||!x)return;const T=c.current.getBoundingClientRect(),b=Math.max(0,Math.min(1,(S-T.left)/T.width)),E=n.end-n.start,N=b*x;o(n.chrom,N-E/2,N+E/2)},[n,x,o]),v=k.useCallback(S=>{S.preventDefault(),g.current=!0,j(S.clientX);function T(E){g.current&&j(E.clientX)}function b(){g.current=!1,window.removeEventListener("mousemove",T),window.removeEventListener("mouseup",b),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="grabbing",document.body.style.userSelect="none",window.addEventListener("mousemove",T),window.addEventListener("mouseup",b)},[j]),y={bar:{background:e.headerBg,borderBottom:`1px solid ${e.border}`,padding:"6px 12px",display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},select:{background:e.inputBg,border:`1px solid ${e.borderAccent}`,borderRadius:4,color:e.textPrimary,padding:"4px 6px",fontSize:12},coordInput:{background:e.inputBg,border:`1px solid ${e.borderAccent}`,borderRadius:4,color:e.textPrimary,padding:"4px 8px",fontSize:12,width:220,fontFamily:"monospace"},btn:{background:e.btnBg,border:"none",borderRadius:4,color:e.btnText,padding:"4px 10px",cursor:"pointer",fontSize:13},info:{color:e.textSecondary,fontSize:11,marginLeft:8},scrubberWrap:{flex:1,minWidth:120,height:14,position:"relative",background:e.inputBg,borderRadius:7,border:`1px solid ${e.borderAccent}`,cursor:"pointer",overflow:"hidden"}};function p(S){if(!t)return;const T=t.chromosomes.find(b=>b.name===S.target.value);T&&o(T.name,0,Math.min(T.length,5e4))}function h(S){S.preventDefault();const b=a.replace(/,/g,"").trim().match(/^(\S+):(\d+)-(\d+)$/);if(b){const E=d.toLong[b[1].toLowerCase()]||b[1];o(E,parseInt(b[2]),parseInt(b[3]))}}if(!t)return s.jsx("div",{style:{...y.bar,opacity:.4},"data-tour":"nav-bar",children:s.jsx("span",{style:{fontSize:12,color:e.textMuted,fontStyle:"italic"},children:"Load a genome to enable navigation"})});const f=n?n.end-n.start:0;let m=0,w=100;return n&&x>0&&(m=n.start/x*100,w=Math.max(1,f/x*100)),s.jsxs("div",{style:y.bar,"data-tour":"nav-bar",children:[s.jsx("select",{style:y.select,value:(n==null?void 0:n.chrom)||"",onChange:p,children:t.chromosomes.map((S,T)=>s.jsxs("option",{value:S.name,children:["chr",T+1," ","—"," ",S.name," (",(S.length/1e3).toFixed(0)," kbp)"]},S.name))}),s.jsxs("form",{onSubmit:h,style:{display:"flex",gap:4},children:[s.jsx("input",{style:y.coordInput,value:a,onChange:S=>u(S.target.value),placeholder:"chr1:start-end"}),s.jsx("button",{style:y.btn,type:"submit",children:"Go"})]}),s.jsx("button",{style:y.btn,onClick:()=>l(2),title:"Zoom out",children:"-"}),s.jsx("button",{style:y.btn,onClick:()=>l(.5),title:"Zoom in",children:"+"}),s.jsx("button",{style:y.btn,onClick:()=>i(-f*.5),title:"Pan left",children:"◀"}),s.jsx("button",{style:y.btn,onClick:()=>i(f*.5),title:"Pan right",children:"▶"}),s.jsx("button",{style:{...y.btn,opacity:r?1:.3,cursor:r?"pointer":"default"},onClick:()=>{if(r&&n){const T=(r.end-r.start)*.15;o(r.chrom,r.start-T,r.end+T)}},disabled:!r,title:r?`Snap to selection (${r.start.toLocaleString()}-${r.end.toLocaleString()})`:"No region selected (right-click drag to select)",children:s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round",style:{display:"block"},children:[s.jsx("circle",{cx:"6",cy:"6",r:"4"}),s.jsx("line",{x1:"6",y1:"0",x2:"6",y2:"3"}),s.jsx("line",{x1:"6",y1:"9",x2:"6",y2:"12"}),s.jsx("line",{x1:"0",y1:"6",x2:"3",y2:"6"}),s.jsx("line",{x1:"9",y1:"6",x2:"12",y2:"6"})]})}),n&&x>0&&s.jsx("div",{ref:c,style:y.scrubberWrap,onMouseDown:v,title:"Drag to scroll across the chromosome",children:s.jsx("div",{style:{position:"absolute",left:`${m}%`,width:`${w}%`,top:1,bottom:1,background:"#42a5f5",borderRadius:6,minWidth:8,opacity:.7,transition:g.current?"none":"left 0.1s ease"}})}),n&&s.jsxs("span",{style:y.info,children:[f.toLocaleString()," bp"]})]})}function Lp(e){const{region:t,zoom:n,navigateTo:r,setSelection:o,clearSelection:l}=nt(),i=k.useRef(null),a=k.useRef(null),u=k.useRef(t);u.current=t,k.useEffect(()=>{const c=e.current;if(!c)return;function g(y){const p=u.current;if(p){if(y.button===2){y.preventDefault();const h=c.getBoundingClientRect(),f=(y.clientX-h.left)/h.width,m=p.start+f*(p.end-p.start);a.current={startX:y.clientX,startBp:m,region:{...p},containerWidth:h.width};return}y.button===0&&(l(),i.current={x:y.clientX,startRegion:{...p},containerWidth:c.offsetWidth||c.clientWidth||1})}}function d(y){if(a.current){const T=a.current,b=c.getBoundingClientRect(),E=Math.max(0,Math.min(1,(y.clientX-b.left)/b.width)),N=T.region.start+E*(T.region.end-T.region.start),O=Math.min(T.startBp,N),R=Math.max(T.startBp,N);Math.abs(R-O)>=1&&o({chrom:T.region.chrom,start:Math.floor(O),end:Math.ceil(R)});return}if(!i.current)return;const p=y.clientX-i.current.x,{chrom:h,start:f,end:m}=i.current.startRegion,w=(m-f)/i.current.containerWidth,S=-p*w;r(h,f+S,m+S)}function x(y){if(a.current){a.current=null;return}i.current=null}function j(y){y.preventDefault(),window.dispatchEvent(new CustomEvent("bingo-track-context",{detail:{x:y.clientX,y:y.clientY}}))}function v(y){y.preventDefault();const p=c.getBoundingClientRect(),h=(y.clientX-p.left)/p.width,f=y.deltaY>0?1.4:.7;n(f,h)}return c.addEventListener("mousedown",g),c.addEventListener("contextmenu",j),window.addEventListener("mousemove",d),window.addEventListener("mouseup",x),c.addEventListener("wheel",v,{passive:!1}),()=>{c.removeEventListener("mousedown",g),c.removeEventListener("contextmenu",j),window.removeEventListener("mousemove",d),window.removeEventListener("mouseup",x),c.removeEventListener("wheel",v)}},[n,r,o,l,e])}const Rn=30;function Py({width:e}){const t=k.useRef(null),n=k.useRef(null),{region:r,selection:o}=nt(),{theme:l}=Ge();return Lp(t),k.useEffect(()=>{const i=n.current;if(!i||!r)return;const a=window.devicePixelRatio||1;i.width=e*a,i.height=Rn*a;const u=i.getContext("2d");u.scale(a,a);const{start:c,end:g}=r,d=g-c;if(u.clearRect(0,0,e,Rn),u.fillStyle=l.canvasBg,u.fillRect(0,0,e,Rn),o&&o.chrom===r.chrom){const f=(o.start-c)/d,m=(o.end-c)/d,w=Math.max(0,f*e),S=Math.min(e,m*e);S-w>=1&&(u.fillStyle="rgba(100, 181, 246, 0.25)",u.fillRect(w,0,S-w,Rn),u.strokeStyle="rgba(100, 181, 246, 0.6)",u.lineWidth=1,u.beginPath(),u.moveTo(w,0),u.lineTo(w,Rn),u.moveTo(S,0),u.lineTo(S,Rn),u.stroke())}const x=Math.min(10,Math.floor(e/80)),j=d/x,v=Math.pow(10,Math.floor(Math.log10(j))),y=[1,2,5,10].map(f=>f*v),p=y.find(f=>f>=j)||y[y.length-1],h=Math.ceil(c/p)*p;u.strokeStyle=l.rulerTick,u.fillStyle=l.rulerLabel,u.font="10px Arial, Helvetica, sans-serif",u.textAlign="center",u.beginPath(),u.moveTo(0,20),u.lineTo(e,20),u.lineWidth=1,u.stroke();for(let f=h;f<=g;f+=p){const m=(f-c)/d*e;u.beginPath(),u.moveTo(m,14),u.lineTo(m,20),u.stroke(),u.fillText(_y(f),m,11)}},[r,o,e,l]),s.jsx("div",{ref:t,style:{position:"relative"},children:s.jsx("canvas",{ref:n,style:{display:"block",width:"100%",height:Rn}})})}function _y(e){return e>=1e6?`${(e/1e6).toFixed(2)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function Ni(e,t){if(t<=0||e.length===0)return e;const n=new Array(e.length);for(let r=0;r<e.length;r++){let o=0,l=0;const i=Math.max(0,r-t),a=Math.min(e.length-1,r+t);for(let u=i;u<=a;u++)o+=e[u],l++;n[r]=o/l}return n}function Kn(e,t){return e<=0||t<=0?0:Math.log2(e+1)/Math.log2(t+1)}function Mc(e,t,n){if(!e||e.length===0)return null;for(const r of e)if(r.barColor&&r.chrom===t&&n>=r.start&&n<r.end)return r.barColor;return null}function Ly({track:e,width:t,height:n,onWarning:r}){const o=k.useRef(null),{region:l}=nt(),{theme:i}=Ge(),{data:a,loading:u,error:c}=ti(e,l,t);return k.useEffect(()=>{var I,F;const g=o.current;if(!g)return;const d=window.devicePixelRatio||1;g.width=t*d,g.height=n*d;const x=g.getContext("2d");if(x.scale(d,d),x.clearRect(0,0,t,n),x.fillStyle=i.canvasBg,x.fillRect(0,0,t,n),u&&!((I=a==null?void 0:a.bins)!=null&&I.length)){x.fillStyle=i.textTertiary,x.font="11px Arial, Helvetica, sans-serif",x.fillText("Loading…",8,n/2+4),r&&r(null);return}if(c){x.fillStyle="#ef9a9a",x.font="11px Arial, Helvetica, sans-serif",x.fillText(typeof c=="string"?c:JSON.stringify(c),8,n/2+4),r&&r(null);return}if(!((F=a==null?void 0:a.bins)!=null&&F.length)){r&&r(null);return}const j=a.max_value||0,v=a.min_value||0,y=v<0,p=l.start,h=l.end-l.start,f=e.color||"#78909c",m=e.scaleMax!=null?e.scaleMax:null,w=e.scaleMin!=null?e.scaleMin:null,S=e.logScale===!0,T=e.barAutoWidth!==!1,b=e.barWidth||2,E=e.showOutline===!0,N=e.outlineColor||null,O=e.outlineSmooth||0,R=e.showBars!==!1,H=e.regionOverlays||[],_=f,$=My(f,-40),X=t/h;function B(z){return T?X>=1?Math.max(1,Math.min(X,z)):Math.max(1,z):Math.min(b,z)}if(y){const D=Math.round(n/2),L=D-12/2,U=n-D-12/2,V=m??(j||1),M=w??(Math.abs(v)||1);if(x.strokeStyle=i.centerLine,x.lineWidth=1,x.beginPath(),x.moveTo(0,D),x.lineTo(t,D),x.stroke(),R)for(const W of a.bins){const q=(W.start+W.end)/2,le=Mc(H,l.chrom,q),se=(W.end-W.start)/h*t,ce=B(se),Te=(W.start-p)/h*t,Ce=W.forward!=null?W.forward:Math.max(0,W.value),ee=W.reverse!=null?W.reverse:Math.min(0,W.value);if(Ce>0){const ae=S?Kn(Ce,V):Ce/V;x.fillStyle=le||_,x.fillRect(Te,D-ae*L,ce,ae*L)}if(ee<0){const ae=S?Kn(Math.abs(ee),M):Math.abs(ee)/M;x.fillStyle=le||$,x.fillRect(Te,D,ce,ae*U)}}if(E&&a.bins.length>0){const W=N||i.textPrimary||"#fff",q=N||i.textPrimary||"#fff",le=a.bins.map(ee=>{const ae=ee.forward!=null?ee.forward:Math.max(0,ee.value);return ae>0?S?Kn(ae,V):ae/V:0}),se=a.bins.map(ee=>{const ae=ee.reverse!=null?ee.reverse:Math.min(0,ee.value);return ae<0?S?Kn(Math.abs(ae),M):Math.abs(ae)/M:0}),ce=Ni(le,O),Te=Ni(se,O),Ce=a.bins.map(ee=>((ee.start+ee.end)/2-p)/h*t);Oi(x,Ce,ce.map(ee=>D-ee*L),W,O>0),Oi(x,Ce,Te.map(ee=>D+ee*U),q,O>0)}const C=S?" log₂":"";Nr(x,`+${V.toFixed(1)}${C}`,2,2,i),Nr(x,`−${M.toFixed(1)}${C}`,2,n-12,i),Nr(x,"0",2,D-6,i,!0)}else{const z=m??(j||1);if(R)for(const L of a.bins){const U=(L.start+L.end)/2,V=Mc(H,l.chrom,U);x.fillStyle=V||_;const M=(L.end-L.start)/h*t,C=B(M),W=(L.start-p)/h*t,le=(S?Kn(L.value,z):L.value/z)*(n-14);x.fillRect(W,n-le-2,C,le)}if(E&&a.bins.length>0){const L=a.bins.map(C=>S?Kn(C.value,z):C.value/z),U=Ni(L,O),V=a.bins.map(C=>((C.start+C.end)/2-p)/h*t),M=U.map(C=>n-C*(n-14)-2);Oi(x,V,M,N||i.textPrimary||"#fff",O>0)}const D=S?" log₂":"";Nr(x,`${z.toFixed(1)}${D}`,2,2,i),Nr(x,"0",2,n-12,i,!0)}if(r){const z=[];m!=null&&j>m&&z.push(`Bars clipped: max value ${j.toFixed(1)} exceeds scale ${m.toFixed(1)}`),y&&w!=null&&Math.abs(v)>w&&z.push(`Negative bars clipped: min value ${Math.abs(v).toFixed(1)} exceeds scale ${w.toFixed(1)}`),r(z.length>0?z.join(`
97
- `):null)}},[a,u,c,t,n,l,e.color,e.scaleMax,e.scaleMin,e.logScale,e.barAutoWidth,e.barWidth,e.showOutline,e.outlineColor,e.outlineSmooth,e.showBars,e.regionOverlays,i]),s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n}})}function Oi(e,t,n,r,o){if(!(t.length<2)){if(e.beginPath(),e.moveTo(t[0],n[0]),o){for(let l=0;l<t.length-1;l++){const i=(t[l]+t[l+1])/2,a=(n[l]+n[l+1])/2;e.quadraticCurveTo(t[l],n[l],i,a)}e.lineTo(t[t.length-1],n[n.length-1])}else for(let l=0;l<t.length;l++)e.lineTo(t[l],n[l]);e.strokeStyle=r,e.lineWidth=1.5,e.stroke()}}function Nr(e,t,n,r,o,l=!1){e.font="10px Arial, Helvetica, sans-serif",e.textAlign="left",e.textBaseline="top";const i=e.measureText(t),a=2,u=i.width+a*2,c=12;e.fillStyle=o.canvasBg||"#1e1e1e",e.globalAlpha=.75,e.fillRect(n,r,u,c),e.globalAlpha=1,e.fillStyle=l?o.textTertiary||"#666":o.textSecondary||"#aaa",e.fillText(t,n+a,r+1),e.textBaseline="alphabetic"}function My(e,t){const n=e.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);if(!n)return e;const r=o=>Math.max(0,Math.min(255,o+t));return`rgb(${r(parseInt(n[1],16))},${r(parseInt(n[2],16))},${r(parseInt(n[3],16))})`}const Bc=6,Fi=8,Ii=14,Di=2,By="#9c27b0",Go=10,Ay={A:"#4caf50",T:"#f44336",C:"#2196f3",G:"#ff9800",N:"#9e9e9e"},zy="#ffeb3b";function Ac(e,t){return e<=0||t<=0?0:Math.log2(e+1)/Math.log2(t+1)}function $y({track:e,width:t,height:n,onWarning:r}){const o=k.useRef(null),{region:l}=nt(),{theme:i}=Ge(),{data:a,loading:u}=ti(e,l,t),[c,g]=k.useState(null),d=k.useRef(null),[x,j]=k.useState(0),v=k.useRef(null),y=e.showNucleotides!==!1,p=e.useArrows!==!1,h=e.logScale===!0,f=e.fwdColor||"#90a4ae",m=e.revColor||"#f06292",w=e.arrowStyle||"pointed",S=e.arrowSize||4,T=k.useRef(null);k.useEffect(()=>{if(l&&T.current){const N=T.current;(N.chrom!==l.chrom||Math.abs(N.start-l.start)>N.end-N.start)&&j(0)}T.current=l},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end]),k.useEffect(()=>{if(!l||!y){g(null);return}const N=l.end-l.start;if(t/N<Bc||N>2e3){g(null);return}if(c&&c.chrom===l.chrom&&c.start<=l.start&&c.end>=l.end)return;const R=Math.max(0,l.start-500),H=l.end+500,_=`${l.chrom}:${R}-${H}`;d.current!==_&&(d.current=_,yn.sequence(l.chrom,R,H).then($=>g({chrom:l.chrom,start:R,end:H,sequence:$.data.sequence})).catch(()=>{}))},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end,t,y]);const b=k.useCallback(N=>{var $;if(!(($=a==null?void 0:a.reads)!=null&&$.length)||!N.shiftKey&&Math.abs(N.deltaX)>Math.abs(N.deltaY))return;const O=y&&c?Ii:Fi,R=Math.max(0,...a.reads.map(X=>X.row)),H=Math.floor(n/(O+Di)),_=Math.max(0,R-H+2);_<=0||(N.preventDefault(),N.stopPropagation(),j(X=>Math.max(0,Math.min(_,X+Math.sign(N.deltaY)*3))))},[a,n,y,c]);k.useEffect(()=>{var C;const N=o.current;if(!N)return;const O=window.devicePixelRatio||1;N.width=t*O,N.height=n*O;const R=N.getContext("2d");if(R.scale(O,O),R.clearRect(0,0,t,n),R.fillStyle=i.canvasBg,R.fillRect(0,0,t,n),u&&!a){R.fillStyle=i.textTertiary,R.font="11px Arial, Helvetica, sans-serif",R.fillText("Loading…",8,n/2+4),r&&r(null);return}if(!a){r&&r(null);return}const H=l.start,_=l.end-l.start;if(a.bins){const W=a.max_value||1,q=e.scaleMax!=null?e.scaleMax:W,le=e.color||"#78909c",se=e.barAutoWidth!==!1,ce=e.barWidth||2,Te=t/_;if(e.showBars!==!1){R.fillStyle=le;for(const ee of a.bins){const ae=(ee.end-ee.start)/_*t,de=se?Te>=1?Math.max(1,Math.min(Te,ae)):Math.max(1,ae):Math.min(ce,ae),xe=(ee.start-H)/_*t,Ae=(h?Ac(ee.value,q):Math.min(1,ee.value/q))*(n-14);R.fillRect(xe,n-Ae-2,de,Ae)}}if(e.showOutline&&a.bins.length>0){const ee=e.outlineSmooth||0,ae=a.bins.map(pe=>h?Ac(pe.value,q):Math.min(1,pe.value/q)),de=Oy(ae,ee),xe=a.bins.map(pe=>((pe.start+pe.end)/2-H)/_*t),ve=de.map(pe=>n-pe*(n-14)-2),Ae=e.outlineColor||i.textPrimary||"#fff";if(R.beginPath(),R.moveTo(xe[0],ve[0]),ee>0){for(let pe=0;pe<xe.length-1;pe++)R.quadraticCurveTo(xe[pe],ve[pe],(xe[pe]+xe[pe+1])/2,(ve[pe]+ve[pe+1])/2);R.lineTo(xe[xe.length-1],ve[ve.length-1])}else for(let pe=0;pe<xe.length;pe++)R.lineTo(xe[pe],ve[pe]);R.strokeStyle=Ae,R.lineWidth=1.5,R.stroke()}const Ce=h?" log₂":"";zc(R,`${q.toFixed(1)}${Ce}`,2,2,i),zc(R,"0",2,n-12,i,!0),R.fillStyle="#ffb74d",R.font="10px Arial, Helvetica, sans-serif",R.textAlign="right",R.fillText("zoom in for reads",t-4,10),r&&r(e.scaleMax!=null&&W>e.scaleMax?`Bars clipped: max value ${W.toFixed(1)} exceeds scale ${e.scaleMax.toFixed(1)}`:null);return}if(!((C=a.reads)!=null&&C.length)){R.fillStyle=i.textTertiary,R.font="11px Arial, Helvetica, sans-serif",R.fillText("No reads in region",8,n/2+4),r&&r(null);return}const $=W=>(W-H)/_*t,X=t/_,B=y&&X>=Bc&&c!=null,I=B?Ii:Fi,F=Di,D=Math.max(0,...a.reads.map(W=>W.row))+1,L=Math.floor(n/(I+F)),U=D>L,V=Math.min(x,Math.max(0,D-L+1));let M=0;for(const W of a.reads){const q=(W.row-V)*(I+F)+2;if(q+I<0||q>n){M++;continue}const le=W.strand==="+"?f:m,se=W.segments;if(se&&se.length>0){const ce=$(W.start),Te=$(W.end);R.strokeStyle=le,R.lineWidth=1,R.beginPath(),R.moveTo(ce,q+I/2),R.lineTo(Te,q+I/2),R.stroke();let Ce=0;for(const ee of se)if(ee.type==="M"){const ae=$(ee.start),de=Math.max(1,$(ee.end)-ae);if(R.fillStyle=le,R.fillRect(ae,q,de,I),B&&W.sequence){const xe=ee.end-ee.start;for(let ve=0;ve<xe;ve++){const Ae=ee.start+ve,pe=$(Ae),Ne=$(Ae+1)-pe,Y=(W.sequence[Ce+ve]||"").toUpperCase();let Z="";c&&Ae>=c.start&&Ae<c.end&&(Z=(c.sequence[Ae-c.start]||"").toUpperCase());const ne=Z&&Y&&Y!==Z&&Y!=="N";ne&&(R.fillStyle=zy,R.fillRect(pe,q,Ne,I)),Ne>=6&&(R.fillStyle=ne?"#000":Ay[Y]||"#999",R.font=`bold ${Math.min(11,Ne-1)}px monospace`,R.textAlign="center",R.textBaseline="middle",R.fillText(Y,pe+Ne/2,q+I/2))}Ce+=xe}}else if(ee.type==="D"){const ae=$(ee.start),de=$(ee.end)-ae;de>=1&&(R.strokeStyle=le,R.lineWidth=1,R.beginPath(),R.moveTo(ae,q+I/2),R.lineTo(ae+de,q+I/2),R.stroke())}else if(ee.type==="N"){const ae=$(ee.start),de=$(ee.end)-ae;de>=2&&(R.setLineDash([2,2]),R.strokeStyle=le,R.lineWidth=1,R.beginPath(),R.moveTo(ae,q+I/2),R.lineTo(ae+de,q+I/2),R.stroke(),R.setLineDash([]))}else ee.type==="I"?(R.fillStyle=By,R.fillRect($(ee.pos)-1,q-1,2,I+2),B&&(Ce+=ee.length)):ee.type==="S"&&B&&(Ce+=ee.length)}else{const ce=$(W.start),Te=Math.max(2,$(W.end)-ce);R.fillStyle=W.strand==="+"?f:m,R.fillRect(ce,q,Te,I)}if(p&&w!=="flat"){const ce=$(W.start),Te=Math.max(2,$(W.end)-ce),Ce=Math.min(S,Te/2);Ce>=2&&Ny(R,w,W.strand,ce,q,Te,I,Ce,le,i.canvasBg)}if(!B&&!y){const ce=$(W.start);Math.max(2,$(W.end)-ce)>60&&(R.fillStyle=i.canvasBg,R.font="8px Arial, Helvetica, sans-serif",R.textAlign="left",R.fillText(W.name.slice(0,20),ce+2,q+I-1))}}if(U){const W=t-Go;R.fillStyle=i.inputBg||"#2a2a2a",R.fillRect(W,0,Go,n);const q=L/D,le=Math.max(20,q*n),ce=(D>L?V/(D-L):0)*(n-le);R.fillStyle="#555",R.fillRect(W+1,ce,Go-2,le)}r&&(M>0&&!U?r(`${M} read${M>1?"s":""} hidden — increase track height to show all`):r(U?`${D} rows · Shift+scroll or drag scrollbar to navigate`:null))},[a,u,t,n,l,c,x,e.color,e.scaleMax,e.scaleMin,e.barAutoWidth,e.barWidth,e.showOutline,e.outlineColor,e.outlineSmooth,e.showBars,e.showNucleotides,e.useArrows,e.logScale,e.fwdColor,e.revColor,e.arrowStyle,e.arrowSize,i]);const E=k.useCallback(N=>{var D;if(!((D=a==null?void 0:a.reads)!=null&&D.length))return;const O=o.current;if(!O)return;const R=O.getBoundingClientRect();if((N.clientX-R.left)*(t/R.width)<t-Go)return;const _=y&&c?Ii:Fi,X=Math.max(0,...a.reads.map(L=>L.row))+1,B=Math.floor(n/(_+Di)),I=Math.max(0,X-B+1);if(I<=0)return;N.preventDefault(),v.current={maxScroll:I,startY:N.clientY,startRow:x};function F(L){if(!v.current)return;const U=L.clientY-v.current.startY,V=Math.round(U/n*v.current.maxScroll);j(Math.max(0,Math.min(v.current.maxScroll,v.current.startRow+V)))}function z(){v.current=null,window.removeEventListener("mousemove",F),window.removeEventListener("mouseup",z)}window.addEventListener("mousemove",F),window.addEventListener("mouseup",z)},[a,t,n,x,y,c]);return s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n},onWheel:b,onMouseDown:E})}function Ny(e,t,n,r,o,l,i,a,u,c){const g=n==="+";if(t==="pointed")e.fillStyle=c,g?(e.beginPath(),e.moveTo(r+l,o+i/2),e.lineTo(r+l-a,o),e.lineTo(r+l-a,o+i),e.fill()):(e.beginPath(),e.moveTo(r,o+i/2),e.lineTo(r+a,o),e.lineTo(r+a,o+i),e.fill());else if(t==="chevron")e.strokeStyle=c,e.lineWidth=1.5,g?(e.beginPath(),e.moveTo(r+l-a,o),e.lineTo(r+l,o+i/2),e.lineTo(r+l-a,o+i),e.stroke()):(e.beginPath(),e.moveTo(r+a,o),e.lineTo(r,o+i/2),e.lineTo(r+a,o+i),e.stroke());else if(t==="fade")if(g){const d=e.createLinearGradient(r+l-a*2,0,r+l,0);d.addColorStop(0,"rgba(0,0,0,0)"),d.addColorStop(1,c),e.fillStyle=d,e.fillRect(r+l-a*2,o,a*2,i)}else{const d=e.createLinearGradient(r,0,r+a*2,0);d.addColorStop(0,c),d.addColorStop(1,"rgba(0,0,0,0)"),e.fillStyle=d,e.fillRect(r,o,a*2,i)}}function Oy(e,t){if(t<=0||e.length===0)return e;const n=new Array(e.length);for(let r=0;r<e.length;r++){let o=0,l=0;const i=Math.max(0,r-t),a=Math.min(e.length-1,r+t);for(let u=i;u<=a;u++)o+=e[u],l++;n[r]=o/l}return n}function zc(e,t,n,r,o,l=!1){e.font="10px Arial, Helvetica, sans-serif",e.textAlign="left",e.textBaseline="top";const i=2,a=e.measureText(t).width+i*2;e.fillStyle=o.canvasBg||"#1e1e1e",e.globalAlpha=.75,e.fillRect(n,r,a,12),e.globalAlpha=1,e.fillStyle=l?o.textTertiary||"#666":o.textSecondary||"#aaa",e.fillText(t,n+i,r+1),e.textBaseline="alphabetic"}const Fy=16,Iy=22,Dy=4,Mp=8,$c=6,Nc={A:"#4caf50",T:"#f44336",C:"#2196f3",G:"#ff9800",N:"#9e9e9e"};function Uy({track:e,width:t,height:n,onWarning:r}){var O,R,H,_;const o=k.useRef(null),{region:l,navigateTo:i,setSelection:a}=nt(),{tracks:u}=zt(),{theme:c}=Ge(),{data:g,loading:d,error:x}=ti(e,l,t),j=e.useArrows!==!1,v=e.showNucleotides!==!1,y=k.useRef([]),[p,h]=k.useState(null),[f,m]=k.useState(null),w=k.useRef(null);k.useEffect(()=>{if(!l||!v){m(null);return}const $=l.end-l.start;if(t/$<$c||$>2e3){m(null);return}if(f&&f.chrom===l.chrom&&f.start<=l.start&&f.end>=l.end)return;const B=Math.max(0,l.start-500),I=l.end+500,F=`${l.chrom}:${B}-${I}`;w.current!==F&&(w.current=F,yn.sequence(l.chrom,B,I).then(z=>m({chrom:l.chrom,start:B,end:I,sequence:z.data.sequence})).catch(()=>{}))},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end,t,v]),k.useEffect(()=>{var M,C;const $=o.current;if(!$)return;const X=window.devicePixelRatio||1;$.width=t*X,$.height=n*X;const B=$.getContext("2d");if(B.scale(X,X),B.clearRect(0,0,t,n),B.fillStyle=c.canvasBg,B.fillRect(0,0,t,n),y.current=[],d&&!((M=g==null?void 0:g.features)!=null&&M.length)){B.fillStyle=c.textTertiary,B.font="11px Arial, Helvetica, sans-serif",B.fillText("Loading…",8,n/2+4),r&&r(null);return}if(x){B.fillStyle="#ef9a9a",B.font="11px Arial, Helvetica, sans-serif",B.fillText(typeof x=="string"?x:JSON.stringify(x),8,n/2+4),r&&r(null);return}if(!((C=g==null?void 0:g.features)!=null&&C.length)){g&&(B.fillStyle=c.textTertiary,B.font="11px Arial, Helvetica, sans-serif",B.fillText("No features in region",8,n/2+4)),r&&r(null);return}const I=l.end-l.start,F=t/I,z=v&&F>=$c&&f!=null,D=z?Iy:Fy,L=[],U=[];let V=0;if(z){const q=n-14;B.fillStyle=c.canvasBg,B.fillRect(0,q,t,14),B.strokeStyle=c.border||"#333",B.lineWidth=.5,B.beginPath(),B.moveTo(0,q),B.lineTo(t,q),B.stroke();const le=Math.min(10,F-1);if(le>=5){B.font=`bold ${le}px monospace`,B.textAlign="center",B.textBaseline="middle";for(let se=Math.floor(l.start);se<Math.ceil(l.end);se++)if(f&&se>=f.start&&se<f.end){const ce=(f.sequence[se-f.start]||"").toUpperCase(),Te=(se-l.start)/I*t;B.fillStyle=Nc[ce]||"#999",B.fillText(ce,Te+F/2,q+14/2)}}}for(const W of g.features){let q=L.findIndex(de=>W.start>=de);q===-1&&(q=L.length),L[q]=W.end;const le=(W.start-l.start)/I*t,se=Math.max(2,(W.end-W.start)/I*t),ce=q*(D+Dy)+2;if(ce+D>n){V++;continue}const Te=e.regionOverlays||[];let Ce=null;const ee=(W.start+W.end)/2;for(const de of Te)if(de.barColor&&de.chrom===l.chrom&&ee>=de.start&&ee<de.end){Ce=de.barColor;break}const ae=Ce||Fc(W.feature_type,e,c);if(W.sub_features&&W.sub_features.length>0){B.fillStyle=ae+"66",B.fillRect(le,ce+D/2-1,se,2);for(const de of W.sub_features){const xe=(de.start-l.start)/I*t,ve=Math.max(1,(de.end-de.start)/I*t),Ae=Fc(de.feature_type,e,c),pe=de.feature_type==="CDS"?D:D-6,Ne=de.feature_type==="CDS"?ce:ce+3;j?Oc(B,Ae,xe,Ne,ve,pe,de.strand||W.strand):(B.fillStyle=Ae,B.fillRect(xe,Ne,ve,pe))}}else j?Oc(B,ae,le,ce,se,D,W.strand):(B.fillStyle=ae,B.fillRect(le,ce,se,D));if(z){const de=Math.max(W.start,l.start),xe=Math.min(W.end,l.end);for(let ve=de;ve<xe;ve++)if(f&&ve>=f.start&&ve<f.end){const Ae=(f.sequence[ve-f.start]||"").toUpperCase(),pe=(ve-l.start)/I*t,Ne=F;Ne>=6&&(B.fillStyle=Nc[Ae]||"#999",B.font=`bold ${Math.min(10,Ne-1)}px monospace`,B.textAlign="center",B.textBaseline="middle",B.fillText(Ae,pe+Ne/2,ce+D/2))}}else if(se>20){B.fillStyle="#fff",B.font="10px Arial, Helvetica, sans-serif",B.textAlign="left",B.textBaseline="alphabetic";const de=W.name||W.feature_type,xe=Math.floor((se-(j?Mp:0)-4)/6);xe>0&&B.fillText(de.slice(0,xe),le+3,ce+D-4)}U.push({feat:W,x:le,y:ce,w:se,h:D})}y.current=U,r&&r(V>0?`${V} feature${V>1?"s":""} hidden — increase track height to show all`:null)},[g,d,x,t,n,l,f,e.color,e.annotationColors,j,e.showNucleotides,e.regionOverlays,c]);const S=k.useCallback($=>{const X=o.current;if(!X)return;const B=X.getBoundingClientRect(),I=($.clientX-B.left)*(t/B.width),F=($.clientY-B.top)*(n/B.height);for(const z of y.current)if(I>=z.x&&I<=z.x+z.w&&F>=z.y&&F<=z.y+z.h){const D=Math.min($.clientX+14,window.innerWidth-300),L=Math.min($.clientY+14,window.innerHeight-260);h({feat:z.feat,x:Math.max(4,D),y:Math.max(4,L)});return}h(null)},[t,n]),T=k.useCallback(()=>h(null),[]),b=k.useCallback($=>{const X=o.current;if(!X||!l)return;const B=X.getBoundingClientRect(),I=($.clientX-B.left)*(t/B.width),F=($.clientY-B.top)*(n/B.height);for(const z of y.current)if(I>=z.x&&I<=z.x+z.w&&F>=z.y&&F<=z.y+z.h){const D=z.feat,U=(D.end-D.start)*.15/(1-.3),V=D.start-U,M=D.end+U;i(l.chrom,V,M),a({chrom:l.chrom,start:D.start,end:D.end}),h(null);return}},[t,n,l,i]),E=p?Wy(p.feat,u,l==null?void 0:l.chrom):[],N=p?wn.createPortal(s.jsxs("div",{style:{position:"fixed",left:p.x,top:p.y,background:c.tooltipBg,border:`1px solid ${c.tooltipBorder}`,borderRadius:4,padding:"6px 10px",color:c.textPrimary,fontSize:11,lineHeight:1.5,maxWidth:280,zIndex:1e4,pointerEvents:"none",boxShadow:"0 4px 12px rgba(0,0,0,0.5)",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:[s.jsx("div",{style:{fontWeight:700,fontSize:12,marginBottom:2},children:p.feat.name||p.feat.feature_type}),s.jsx(en,{label:"Type",value:p.feat.feature_type}),s.jsx(en,{label:"Strand",value:p.feat.strand||"."}),s.jsx(en,{label:"Location",value:`${p.feat.start.toLocaleString()}–${p.feat.end.toLocaleString()}`}),s.jsx(en,{label:"Length",value:`${(p.feat.end-p.feat.start).toLocaleString()} bp`}),((O=p.feat.attributes)==null?void 0:O.gene)&&p.feat.attributes.gene!==p.feat.name&&s.jsx(en,{label:"Gene",value:p.feat.attributes.gene}),((R=p.feat.attributes)==null?void 0:R.locus_tag)&&s.jsx(en,{label:"Locus",value:p.feat.attributes.locus_tag}),((H=p.feat.attributes)==null?void 0:H.product)&&s.jsx(en,{label:"Product",value:p.feat.attributes.product}),((_=p.feat.attributes)==null?void 0:_.note)&&s.jsx(en,{label:"Note",value:String(p.feat.attributes.note).slice(0,120)}),E.length>0&&s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{borderTop:`1px solid ${c.tooltipBorder}`,margin:"4px 0",paddingTop:4},children:s.jsx("span",{style:{color:c.textSecondary,fontWeight:600,fontSize:10,textTransform:"uppercase"},children:"Track totals in gene"})}),E.map($=>s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",gap:8},children:[s.jsx("span",{style:{color:c.textSecondary,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1},children:$.name}),s.jsx("span",{style:{color:c.textPrimary,fontWeight:600,flexShrink:0},children:$.total.toFixed(1)})]},$.trackId))]})]}),document.body):null;return s.jsxs("div",{style:{position:"relative",width:"100%",height:n},children:[s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n},onMouseMove:S,onMouseLeave:T,onDoubleClick:b}),N]})}function en({label:e,value:t}){return t?s.jsxs("div",{style:{display:"flex",gap:6},children:[s.jsxs("span",{style:{opacity:.6,flexShrink:0},children:[e,":"]}),s.jsx("span",{children:t})]}):null}function Wy(e,t,n){var o;if(!e||!n)return[];const r=[];for(const l of t){if(l.track_type!=="coverage"&&l.track_type!=="reads")continue;const i=Q0(l.id,n);if(!((o=i==null?void 0:i.bins)!=null&&o.length))continue;let a=0;for(const u of i.bins){if(u.end<=e.start||u.start>=e.end)continue;const c=u.forward!=null?u.forward:Math.max(0,u.value||0),g=u.reverse!=null?Math.abs(u.reverse):Math.abs(Math.min(0,u.value||0));a+=c+g}a>0&&r.push({trackId:l.id,name:l.name,total:a})}return r}function Oc(e,t,n,r,o,l,i){e.fillStyle=t;const a=Math.min(Mp,o*.4);e.beginPath(),i==="+"?(e.moveTo(n,r),e.lineTo(n+o-a,r),e.lineTo(n+o,r+l/2),e.lineTo(n+o-a,r+l),e.lineTo(n,r+l),e.closePath()):i==="-"?(e.moveTo(n+a,r),e.lineTo(n+o,r),e.lineTo(n+o,r+l),e.lineTo(n+a,r+l),e.lineTo(n,r+l/2),e.closePath()):e.rect(n,r,o,l),e.fill(),e.strokeStyle="rgba(0,0,0,0.25)",e.lineWidth=.5,e.stroke()}function Fc(e,t,n){const r=t.annotationColors;switch(e==null?void 0:e.toLowerCase()){case"cds":return(r==null?void 0:r.cds)||(n==null?void 0:n.geneCds)||"#66bb6a";case"exon":return(r==null?void 0:r.exon)||(n==null?void 0:n.geneExon)||"#42a5f5";case"gene":return(r==null?void 0:r.gene)||(n==null?void 0:n.geneGene)||"#7e57c2";case"mrna":case"transcript":return(r==null?void 0:r.transcript)||(n==null?void 0:n.geneTranscript)||"#ab47bc";case"utr":case"3utr":case"5utr":return(r==null?void 0:r.utr)||(n==null?void 0:n.geneUtr)||"#26c6da";case"rrna":return(r==null?void 0:r.rrna)||(n==null?void 0:n.geneRrna)||"#ffa726";case"trna":return(r==null?void 0:r.trna)||(n==null?void 0:n.geneTrna)||"#ef5350";case"repeat_region":return(r==null?void 0:r.repeat)||(n==null?void 0:n.geneRepeat)||"#8d6e63";default:return(r==null?void 0:r.default)||t.color||(n==null?void 0:n.geneDefault)||"#80cbc4"}}function Hy({track:e,width:t,height:n,onWarning:r}){const o=k.useRef(null),{region:l}=nt(),{theme:i}=Ge(),{data:a,loading:u}=ti(e,l,t);return k.useEffect(()=>{var h,f;const c=o.current;if(!c)return;const g=window.devicePixelRatio||1;c.width=t*g,c.height=n*g;const d=c.getContext("2d");if(d.scale(g,g),d.clearRect(0,0,t,n),d.fillStyle=i.canvasBg,d.fillRect(0,0,t,n),u&&!((h=a==null?void 0:a.variants)!=null&&h.length)){d.fillStyle=i.textTertiary,d.font="11px Arial, Helvetica, sans-serif",d.fillText("Loading…",8,n/2+4),r&&r(null);return}if(!((f=a==null?void 0:a.variants)!=null&&f.length)){a&&(d.fillStyle=i.textTertiary,d.font="11px Arial, Helvetica, sans-serif",d.fillText("No variants in region",8,n/2+4)),r&&r(null);return}const x=l.end-l.start,j=e.barAutoWidth!==!1,v=e.barWidth||2,y=j?1:Math.max(.5,v),p=j?5:Math.max(2,v*2);for(const m of a.variants){const w=(m.pos-l.start)/x*t,S=Vy(m.ref,m.alt);d.strokeStyle=S,d.lineWidth=y,d.beginPath(),d.moveTo(w,n-4),d.lineTo(w,14),d.stroke(),d.fillStyle=S,d.beginPath(),d.arc(w,10,p,0,Math.PI*2),d.fill(),x<5e3&&(d.fillStyle=i.textPrimary,d.font="9px Arial, Helvetica, sans-serif",d.textAlign="center",d.fillText(`${m.ref}>${m.alt[0]||"?"}`,w,n-6))}if(r){const m=a.variants.filter(w=>w.pos>=l.start&&w.pos<=l.end).length;r(m>50?`${m} variants overlapping — zoom in for detail`:null)}},[a,u,t,n,l,e.color,e.barAutoWidth,e.barWidth,i]),s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n}})}function Vy(e,t){const n=t[0]||"";return e.length===1&&n.length===1?"#ffb74d":n.length>e.length?"#81c784":n.length<e.length?"#e57373":"#b0bec5"}function Gy({message:e,theme:t}){const[n,r]=k.useState(!1),o=k.useRef(null),l=o.current?o.current.getBoundingClientRect():null;return s.jsxs(s.Fragment,{children:[s.jsx("span",{ref:o,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:12,height:12,borderRadius:"50%",background:"rgba(229, 57, 53, 0.85)",color:"#fff",fontSize:9,fontWeight:800,lineHeight:1,cursor:"default",flexShrink:0,fontFamily:"Arial, Helvetica, sans-serif"},children:"!"}),n&&l&&wn.createPortal(s.jsx("div",{style:{position:"fixed",left:Math.min(l.right+6,window.innerWidth-220),top:l.top-4,background:t.tooltipBg||"#333",border:`1px solid ${t.tooltipBorder||"#555"}`,borderRadius:4,padding:"4px 8px",color:t.textPrimary||"#e0e0e0",fontSize:11,lineHeight:1.4,maxWidth:200,zIndex:10001,pointerEvents:"none",boxShadow:"0 3px 10px rgba(0,0,0,0.5)",whiteSpace:"pre-wrap",fontFamily:"Arial, Helvetica, sans-serif"},children:e}),document.body)]})}function Yy({width:e,height:t,trackData:n,trackType:r,trackId:o}){const{region:l,selection:i,clearSelection:a}=nt(),{tracks:u}=zt(),{theme:c}=Ge(),[g,d]=k.useState(!1),[x,j]=k.useState({x:0,y:0}),v=u.find($=>$.id===o),y=(v==null?void 0:v.regionOverlays)||[],p=r==="reads",h=k.useCallback($=>{j({x:$.clientX,y:$.clientY}),d(!0)},[]),f=k.useCallback(()=>d(!1),[]),m=k.useCallback($=>{p||($.preventDefault(),$.stopPropagation(),window.dispatchEvent(new CustomEvent("bingo-region-context",{detail:{x:$.clientX,y:$.clientY}})))},[p]);if(!l)return null;const w=l.end-l.start;if(w<=0)return null;const S=$=>($-l.start)/w*e;let T=0,b=0,E=!1;i&&i.chrom===l.chrom&&(T=Math.max(0,S(i.start)),b=Math.min(e,S(i.end))-T,E=b>=1);const N=E?Xy(i,n,r):[],O=i?i.end-i.start:0,R=260,H=Math.min(x.x+14,window.innerWidth-R-10),_=Math.min(x.y+14,window.innerHeight-200);return s.jsxs("div",{style:{position:"absolute",top:0,left:0,width:e,height:t,pointerEvents:"none"},children:[y.map(($,X)=>{if($.chrom!==l.chrom)return null;const B=Math.max(0,S($.start)),I=Math.min(e,S($.end))-B;return I<1?null:s.jsx("div",{style:{position:"absolute",left:B,top:0,width:I,height:"100%",background:$.color,opacity:$.opacity||.35,pointerEvents:"none"}},X)}),E&&s.jsx("div",{style:{position:"absolute",left:T,top:0,width:b,height:"100%",background:"rgba(100, 181, 246, 0.2)",borderLeft:"1px solid rgba(100, 181, 246, 0.6)",borderRight:"1px solid rgba(100, 181, 246, 0.6)",pointerEvents:"auto",cursor:"crosshair"},onMouseMove:h,onMouseLeave:f,onClick:$=>{$.stopPropagation(),a()},onContextMenu:m}),g&&E&&wn.createPortal(s.jsxs("div",{style:{position:"fixed",left:H,top:_,background:c.panelBg,border:`1px solid ${c.borderAccent}`,borderRadius:6,padding:"8px 12px",fontSize:11,color:c.textPrimary,lineHeight:1.6,pointerEvents:"none",zIndex:1e4,boxShadow:"0 4px 16px rgba(0,0,0,0.4)",minWidth:180,maxWidth:R},children:[s.jsx("div",{style:{fontWeight:700,marginBottom:4,fontSize:12},children:"Selected Region"}),s.jsxs("div",{children:[s.jsx("span",{style:{color:c.textSecondary},children:"Region:"})," ",i.chrom,":",i.start.toLocaleString(),"-",i.end.toLocaleString()]}),s.jsxs("div",{children:[s.jsx("span",{style:{color:c.textSecondary},children:"Length:"})," ",O.toLocaleString()," bp"]}),N.map(($,X)=>s.jsxs("div",{children:[s.jsxs("span",{style:{color:c.textSecondary},children:[$.label,":"]})," ",$.value]},X)),s.jsxs("div",{style:{fontSize:9,color:c.textTertiary,marginTop:4},children:["Click to dismiss",p?"":" · Right-click for region colors"]})]}),document.body)]})}function Xy(e,t,n){const r=[];if(!t)return r;if(n==="reads"&&t.reads){const o=t.reads.filter(i=>i.end>e.start&&i.start<e.end);r.push({label:"Reads in region",value:o.length.toLocaleString()});let l=0;for(const i of o)if(i.cigar){const a=i.cigar.match(/(\d+)I/g);if(a)for(const u of a)l+=parseInt(u)}l>0&&r.push({label:"Insertion bases",value:l.toLocaleString()}),o.length>0&&r.push({label:"Avg MAPQ",value:(o.reduce((i,a)=>i+(a.mapq||0),0)/o.length).toFixed(1)})}if((n==="coverage"||n==="reads")&&t.bins){const o=t.bins.filter(l=>l.end>e.start&&l.start<e.end);if(o.length>0){const l=o.map(i=>i.value);r.push({label:"Avg coverage",value:(l.reduce((i,a)=>i+a,0)/l.length).toFixed(1)}),r.push({label:"Max coverage",value:Math.max(...l).toFixed(1)})}}return n==="variants"&&t.variants&&r.push({label:"Variants",value:t.variants.filter(o=>o.pos>=e.start&&o.pos<e.end).length.toLocaleString()}),(n==="annotations"||n==="genome_annotations")&&t.features&&r.push({label:"Features",value:t.features.filter(o=>o.end>e.start&&o.start<e.end).length.toLocaleString()}),r}class Ky extends k.Component{constructor(t){super(t),this.state={hasError:!1,error:null}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}render(){var t;return this.state.hasError?s.jsxs("div",{style:{padding:8,color:"#ef9a9a",fontSize:11},children:["Track error: ",((t=this.state.error)==null?void 0:t.message)||"Unknown error"]}):this.props.children}}function Qy({track:e,containerWidth:t,labelWidth:n=140,onLabelResizeStart:r,isDragging:o,isDropTarget:l,onDragStart:i,onDragOver:a,onDrop:u,onDragEnd:c}){const{theme:g}=Ge(),{updateTrack:d,removeTrack:x}=zt(),j=k.useRef(null),v=k.useRef(null),[y,p]=k.useState(!1),[h,f]=k.useState(!1),[m,w]=k.useState(null),S=k.useRef(null),T=k.useRef(null),b=e.track_type==="annotations"||e.track_type==="genome_annotations";Lp(j);const E=["#f44336","#ef5350","#e57373","#ff5722","#ff8a65","#ff9800","#ffa726","#ffb74d","#ffc107","#fff176","#4caf50","#66bb6a","#81c784","#aed581","#009688","#26c6da","#80cbc4","#2196f3","#42a5f5","#64b5f6","#7e57c2","#9575cd","#9c27b0","#ab47bc","#ce93d8","#e91e63","#f06292","#795548","#8d6e63","#607d8b","#78909c"],N=t-n,O={row:{display:"flex",borderBottom:`1px solid ${g.border}`,minHeight:40},label:{width:n,minWidth:n,background:g.panelBg,borderRight:`1px solid ${g.border}`,display:"flex",flexDirection:"column",justifyContent:"center",padding:"4px 8px",overflow:"hidden",position:"relative"},trackName:{fontSize:11,color:g.trackName,fontWeight:600,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},trackType:{fontSize:10,color:g.textTertiary,marginTop:2},trackArea:{flex:1,overflow:"hidden",position:"relative"}},R=k.useCallback(_=>{_.preventDefault(),_.stopPropagation();const $=_.clientY,X=e.height;function B(F){const z=Math.max(30,Math.min(500,X+(F.clientY-$)));d(e.id,{height:z})}function I(){window.removeEventListener("mousemove",B),window.removeEventListener("mouseup",I),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="ns-resize",document.body.style.userSelect="none",window.addEventListener("mousemove",B),window.addEventListener("mouseup",I)},[e.id,e.height,d]);function H(){const _={track:e,width:N,height:e.height,onWarning:w};switch(e.track_type){case"reads":return s.jsx($y,{..._});case"coverage":return s.jsx(Ly,{..._});case"variants":return s.jsx(Hy,{..._});case"annotations":case"genome_annotations":return s.jsx(Uy,{..._});default:return s.jsx("div",{style:{padding:8,color:g.textTertiary,fontSize:11},children:"Unknown track type"})}}return s.jsxs("div",{style:{...O.row,height:e.height,position:"relative",opacity:o?.4:1,borderTop:l?"2px solid #888":void 0},onDragOver:_=>{_.preventDefault(),_.dataTransfer.dropEffect="move",a==null||a()},onDrop:_=>{_.preventDefault(),u==null||u()},onDragEnd:c,children:[s.jsxs("div",{style:O.label,children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsx("div",{draggable:!0,onDragStart:_=>{_.dataTransfer.effectAllowed="move",_.dataTransfer.setData("text/plain",e.id),i==null||i()},style:{cursor:"grab",color:g.textMuted,fontSize:14,lineHeight:1,userSelect:"none",flexShrink:0,padding:"0 2px"},title:"Drag to reorder tracks",children:"≡"}),s.jsx("div",{ref:S,children:b?s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:2,background:"#888",cursor:"pointer",verticalAlign:"middle",border:"1px solid rgba(255,255,255,0.2)",backgroundImage:"linear-gradient(135deg, #ef5350 25%, #66bb6a 25%, #66bb6a 50%, #42a5f5 50%, #42a5f5 75%, #ffa726 75%)"},title:"Click to customize annotation colors",onMouseDown:_=>{_.stopPropagation(),f($=>!$)}}),h&&wn.createPortal(s.jsx(ex,{track:e,theme:g,anchorRef:S,onClose:()=>f(!1),onChange:(_,$)=>{const X={...e.annotationColors||{},[_]:$};d(e.id,{annotationColors:X})},onReset:()=>d(e.id,{annotationColors:null})}),document.body)]}):s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:2,background:e.color,cursor:"pointer",verticalAlign:"middle",border:"1px solid rgba(255,255,255,0.2)"},title:"Click to pick color, double-click for full palette",onMouseDown:_=>{_.stopPropagation(),p(!0)},onDoubleClick:_=>{var $;_.stopPropagation(),p(!1),($=T.current)==null||$.click()}}),s.jsx("input",{ref:T,type:"color",value:e.color||"#78909c",onChange:_=>d(e.id,{color:_.target.value}),style:{position:"absolute",left:-9999,top:-9999,opacity:0,width:0,height:0}}),y&&wn.createPortal(s.jsx("div",{style:{position:"fixed",left:S.current?S.current.getBoundingClientRect().left:0,top:S.current?S.current.getBoundingClientRect().bottom+4:0,zIndex:10001,background:g.panelBg,border:`1px solid ${g.borderAccent}`,borderRadius:4,padding:6,boxShadow:"0 4px 12px rgba(0,0,0,0.5)",display:"grid",gridTemplateColumns:"repeat(5, 18px)",gap:3},onMouseLeave:()=>p(!1),children:E.map(_=>s.jsx("span",{style:{width:18,height:18,borderRadius:3,background:_,cursor:"pointer",border:_===e.color?`2px solid ${g.textPrimary}`:"1px solid rgba(255,255,255,0.15)",boxSizing:"border-box"},onMouseUp:()=>{d(e.id,{color:_}),p(!1)}},_))}),document.body)]})}),s.jsx("div",{style:{...O.trackName,flex:1},title:e.name,children:e.name}),s.jsx("span",{title:"Remove track",onClick:_=>{_.stopPropagation(),x(e.id)},style:{color:"#e53935",fontSize:13,fontWeight:700,cursor:"pointer",lineHeight:1,flexShrink:0,padding:"0 2px",opacity:.7,transition:"opacity 0.15s"},onMouseEnter:_=>_.currentTarget.style.opacity="1",onMouseLeave:_=>_.currentTarget.style.opacity="0.7",children:"×"})]}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsxs("div",{style:O.trackType,children:[e.file_format," · ",e.track_type]}),m&&s.jsx(Gy,{message:m,theme:g})]}),r&&s.jsx("div",{onMouseDown:r,style:{position:"absolute",right:-3,top:0,bottom:0,width:6,cursor:"ew-resize",zIndex:10},onMouseEnter:_=>_.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:_=>_.currentTarget.style.background="transparent"})]}),s.jsxs("div",{style:O.trackArea,ref:j,children:[s.jsx(Ky,{children:H()}),s.jsx(Yy,{width:N,height:e.height,trackData:Ua(e.id),trackType:e.track_type,trackId:e.id})]}),s.jsx("div",{ref:v,onMouseDown:R,title:"Drag to resize track height",style:{position:"absolute",left:0,right:0,bottom:-2,height:5,cursor:"ns-resize",zIndex:10,background:"transparent"},onMouseEnter:_=>_.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:_=>_.currentTarget.style.background="transparent"})]})}const qy=[{key:"cds",label:"CDS"},{key:"exon",label:"Exon"},{key:"gene",label:"Gene"},{key:"transcript",label:"Transcript"},{key:"utr",label:"UTR"},{key:"rrna",label:"rRNA"},{key:"trna",label:"tRNA"},{key:"repeat",label:"Repeat"},{key:"default",label:"Other"}],Jy=["#f44336","#ef5350","#e57373","#ff5722","#ff8a65","#ff9800","#ffa726","#ffb74d","#ffc107","#fff176","#4caf50","#66bb6a","#81c784","#aed581","#009688","#26c6da","#80cbc4","#2196f3","#42a5f5","#64b5f6","#7e57c2","#9575cd","#9c27b0","#ab47bc","#ce93d8","#e91e63","#f06292","#795548","#8d6e63","#607d8b","#78909c"],Zy={cds:"geneCds",exon:"geneExon",gene:"geneGene",transcript:"geneTranscript",utr:"geneUtr",rrna:"geneRrna",trna:"geneTrna",repeat:"geneRepeat",default:"geneDefault"};function ex({track:e,theme:t,anchorRef:n,onClose:r,onChange:o,onReset:l}){var y;const[i,a]=k.useState(null),u=k.useRef(null),[c,g]=k.useState(null),d=e.annotationColors||{},x=(y=n.current)==null?void 0:y.getBoundingClientRect();function j(p){return d[p]||t[Zy[p]]||jp[p]}function v(p){g(p),u.current&&(u.current.value=j(p),u.current.click())}return s.jsxs("div",{style:{position:"fixed",left:x?Math.min(x.left,window.innerWidth-220):0,top:x?x.bottom+4:0,zIndex:10001,background:t.panelBg,border:`1px solid ${t.borderAccent}`,borderRadius:6,padding:"8px 0",boxShadow:"0 6px 20px rgba(0,0,0,0.5)",width:210,maxHeight:340,overflowY:"auto"},onMouseLeave:r,children:[s.jsx("div",{style:{fontSize:10,fontWeight:700,color:t.textSecondary,textTransform:"uppercase",letterSpacing:1,padding:"0 10px 6px",borderBottom:`1px solid ${t.border}`,marginBottom:4},children:"Annotation Colors"}),qy.map(({key:p,label:h})=>{const f=j(p);return s.jsxs("div",{children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"4px 10px",cursor:"pointer",fontSize:11,color:t.textPrimary},onMouseEnter:m=>m.currentTarget.style.background=t.selectedRow,onMouseLeave:m=>m.currentTarget.style.background="transparent",onClick:()=>a(i===p?null:p),children:[s.jsx("span",{style:{display:"inline-block",width:14,height:14,borderRadius:3,background:f,border:"1px solid rgba(255,255,255,0.15)",flexShrink:0,cursor:"pointer"},onDoubleClick:m=>{m.stopPropagation(),v(p)},title:"Click to expand, double-click for full picker"}),s.jsx("span",{style:{flex:1},children:h}),s.jsx("span",{style:{fontSize:9,color:t.textTertiary},children:i===p?"▲":"▼"})]}),i===p&&s.jsxs("div",{style:{padding:"4px 10px 6px 32px"},children:[s.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:3,marginBottom:6},children:Jy.map(m=>s.jsx("span",{style:{width:18,height:18,borderRadius:3,background:m,cursor:"pointer",border:m===f?`2px solid ${t.textPrimary}`:"1px solid rgba(255,255,255,0.15)",boxSizing:"border-box"},onClick:()=>{o(p,m),a(null)},onDoubleClick:w=>{w.stopPropagation(),v(p)}},m))}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsx("span",{style:{fontSize:10,color:t.textTertiary},children:"Hex:"}),s.jsx("input",{type:"text",defaultValue:f,placeholder:"#ff0000",style:{background:t.inputBg,border:`1px solid ${t.borderAccent}`,borderRadius:3,color:t.textPrimary,padding:"2px 5px",fontSize:10,fontFamily:"monospace",width:70},onKeyDown:m=>{if(m.key==="Enter"){let w=m.target.value.trim();w&&!w.startsWith("#")&&(w="#"+w),/^#[0-9a-fA-F]{3,8}$/.test(w)&&(o(p,w),a(null))}},onBlur:m=>{let w=m.target.value.trim();w&&!w.startsWith("#")&&(w="#"+w),/^#[0-9a-fA-F]{3,8}$/.test(w)&&o(p,w)},onClick:m=>m.stopPropagation()}),s.jsx("span",{style:{width:14,height:14,borderRadius:3,background:f,border:"1px solid rgba(255,255,255,0.2)",cursor:"pointer",flexShrink:0},onDoubleClick:m=>{m.stopPropagation(),v(p)},title:"Double-click for color picker"})]})]})]},p)}),s.jsx("div",{style:{borderTop:`1px solid ${t.border}`,marginTop:4,paddingTop:4},children:s.jsx("div",{style:{padding:"4px 10px",fontSize:10,color:t.textTertiary,cursor:"pointer",textAlign:"center"},onMouseEnter:p=>{p.currentTarget.style.color=t.textPrimary},onMouseLeave:p=>{p.currentTarget.style.color=t.textTertiary},onClick:l,children:"Reset to defaults"})}),s.jsx("input",{ref:u,type:"color",style:{position:"absolute",left:-9999,top:-9999,opacity:0,width:0,height:0},onChange:p=>{c&&o(c,p.target.value)}})]})}function tx({labelWidth:e}){const{genome:t,region:n}=nt(),{tracks:r}=zt(),{theme:o,themeName:l,customTheme:i}=Ge(),[a,u]=k.useState(!1),[c,g]=k.useState(!1),d=!!t;k.useEffect(()=>{if(!d)return;function y(p){p.preventDefault(),p.returnValue=""}return window.addEventListener("beforeunload",y),()=>window.removeEventListener("beforeunload",y)},[d]),k.useEffect(()=>{if(!d)return;function y(p){(p.ctrlKey||p.metaKey)&&p.key==="w"&&(p.preventDefault(),u(!0))}return window.addEventListener("keydown",y),()=>window.removeEventListener("keydown",y)},[d]);const x=k.useCallback(()=>u(!1),[]),j=k.useCallback(()=>{window.onbeforeunload=null,window.close(),window.location.href="about:blank"},[]),v=k.useCallback(()=>{g(!0);try{const y=Ha(t,n,r,l,i,e);Va(y),_p(y)}catch{}g(!1),window.onbeforeunload=null,window.close(),window.location.href="about:blank"},[t,n,r,l,i,e]);return a?s.jsx("div",{style:{position:"fixed",inset:0,zIndex:1e4,background:"rgba(0,0,0,0.5)",display:"flex",alignItems:"center",justifyContent:"center"},onClick:x,children:s.jsxs("div",{style:{background:o.panelBg,border:`1px solid ${o.borderAccent}`,borderRadius:8,padding:"24px 28px",maxWidth:400,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.6)"},onClick:y=>y.stopPropagation(),children:[s.jsx("div",{style:{fontSize:16,fontWeight:700,color:o.textPrimary,marginBottom:8},children:"Leave BiNgo Genome Viewer?"}),s.jsxs("div",{style:{fontSize:12,color:o.textSecondary,lineHeight:1.7,marginBottom:20},children:["You have an active session with"," ",s.jsxs("strong",{style:{color:o.textPrimary},children:[r.length," track",r.length!==1?"s":""]})," loaded. Unsaved changes will be lost."]}),s.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[s.jsx("button",{onClick:x,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:"Return to App"}),s.jsx("button",{onClick:v,disabled:c,style:{background:o.btnBg,border:`1px solid ${o.borderStrong}`,borderRadius:4,color:o.btnText,padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:c?"Saving...":"Save Session & Exit"}),s.jsx("button",{onClick:j,style:{background:"transparent",border:`1px solid ${o.border}`,borderRadius:4,color:"#e57373",padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:"Exit Without Saving"})]})]})}):null}function nx(){const{selection:e}=nt(),{tracks:t,updateTrack:n}=zt(),{theme:r}=Ge(),[o,l]=k.useState(null),[i,a]=k.useState(null),u=t.filter(y=>y.visible!==!1&&y.track_type!=="reads"),c=t.some(y=>{var p;return((p=y.regionOverlays)==null?void 0:p.length)>0});k.useEffect(()=>{function y(h){l({x:h.detail.x,y:h.detail.y,hasSelection:!0})}function p(h){c&&l({x:h.detail.x,y:h.detail.y,hasSelection:!1})}return window.addEventListener("bingo-region-context",y),window.addEventListener("bingo-track-context",p),()=>{window.removeEventListener("bingo-region-context",y),window.removeEventListener("bingo-track-context",p)}},[c]);const g=k.useCallback(()=>{if(!e)return;l(null);const y=new Set(u.map(p=>p.id));a({chrom:e.chrom,start:e.start,end:e.end,highlightColor:"#42a5f5",highlightOpacity:.3,useHighlight:!0,barColor:"#ff9800",useBarColor:!1,selectedTracks:y})},[e,u]),d=k.useCallback(()=>{var y;l(null);for(const p of t)((y=p.regionOverlays)==null?void 0:y.length)>0&&n(p.id,{regionOverlays:[]})},[t,n]),x=k.useCallback(()=>{if(!i)return;const y={chrom:i.chrom,start:i.start,end:i.end,highlightColor:i.useHighlight?i.highlightColor:null,highlightOpacity:i.highlightOpacity,barColor:i.useBarColor?i.barColor:null};for(const p of i.selectedTracks){const h=t.find(m=>m.id===p);if(!h)continue;const f=(h.regionOverlays||[]).filter(m=>!(m.chrom===y.chrom&&m.start===y.start&&m.end===y.end));n(p,{regionOverlays:[...f,y]})}a(null)},[i,t,n]),j=k.useCallback(y=>{a(p=>{if(!p)return p;const h=new Set(p.selectedTracks);return h.has(y)?h.delete(y):h.add(y),{...p,selectedTracks:h}})},[]),v=r;return s.jsxs(s.Fragment,{children:[o&&wn.createPortal(s.jsx("div",{style:{position:"fixed",inset:0,zIndex:10001},onClick:()=>l(null),onContextMenu:y=>{y.preventDefault(),l(null)},children:s.jsxs("div",{style:{position:"fixed",left:Math.min(o.x,window.innerWidth-220),top:Math.min(o.y,window.innerHeight-100),background:v.panelBg,border:`1px solid ${v.borderAccent}`,borderRadius:6,boxShadow:"0 4px 16px rgba(0,0,0,0.5)",padding:"4px 0",minWidth:210,zIndex:10002},onClick:y=>y.stopPropagation(),children:[e&&s.jsxs("div",{style:{padding:"5px 14px 7px",fontSize:11,color:v.textTertiary,borderBottom:`1px solid ${v.border}`},children:[e.chrom,":",e.start.toLocaleString(),"\\u2013",e.end.toLocaleString()]}),o.hasSelection&&e&&s.jsx("div",{style:{padding:"7px 14px",fontSize:13,color:v.textPrimary,cursor:"pointer"},onMouseEnter:y=>y.currentTarget.style.background=v.selectedRow||"rgba(255,255,255,0.06)",onMouseLeave:y=>y.currentTarget.style.background="transparent",onClick:g,children:"Edit region colors\\u2026"}),c&&s.jsx("div",{style:{padding:"7px 14px",fontSize:13,color:"#e57373",cursor:"pointer"},onMouseEnter:y=>y.currentTarget.style.background=v.selectedRow||"rgba(255,255,255,0.06)",onMouseLeave:y=>y.currentTarget.style.background="transparent",onClick:d,children:"Reset all region colors"})]})}),document.body),i&&s.jsx(Wa,{title:"Region Colors",onClose:()=>a(null),theme:v,defaultWidth:360,defaultHeight:420,children:s.jsxs("div",{style:{padding:"14px 18px"},children:[s.jsxs("div",{style:{fontSize:12,color:v.textSecondary,marginBottom:14},children:[i.chrom,":",i.start.toLocaleString(),"\\u2013",i.end.toLocaleString(),s.jsxs("span",{style:{color:v.textTertiary},children:[" (",(i.end-i.start).toLocaleString()," bp)"]})]}),s.jsxs("div",{style:{marginBottom:12},children:[s.jsxs("label",{style:{display:"flex",alignItems:"center",gap:6,fontSize:13,color:v.textPrimary,cursor:"pointer",marginBottom:6},children:[s.jsx("input",{type:"checkbox",checked:i.useHighlight,onChange:y=>a(p=>({...p,useHighlight:y.target.checked})),style:{cursor:"pointer",width:14,height:14}}),"Highlight color"]}),i.useHighlight&&s.jsxs("div",{style:{paddingLeft:22},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:6},children:[s.jsx("input",{type:"color",value:i.highlightColor,onChange:y=>a(p=>({...p,highlightColor:y.target.value})),style:{width:28,height:20,border:"none",background:"none",cursor:"pointer",padding:0}}),s.jsx("input",{type:"text",value:i.highlightColor,onChange:y=>{let p=y.target.value.trim();p&&!p.startsWith("#")&&(p="#"+p),/^#[0-9a-fA-F]{3,8}$/.test(p)&&a(h=>({...h,highlightColor:p}))},style:{background:v.inputBg,border:`1px solid ${v.borderAccent}`,borderRadius:3,color:v.textPrimary,padding:"3px 6px",fontSize:12,fontFamily:"monospace",width:72}})]}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[s.jsx("span",{style:{fontSize:12,color:v.textSecondary},children:"Opacity"}),s.jsx("input",{type:"range",min:.1,max:.8,step:.05,value:i.highlightOpacity,onChange:y=>a(p=>({...p,highlightOpacity:parseFloat(y.target.value)})),style:{flex:1,cursor:"pointer",accentColor:v.textSecondary}}),s.jsxs("span",{style:{fontSize:12,color:v.textTertiary,width:32},children:[Math.round(i.highlightOpacity*100),"%"]})]})]})]}),s.jsxs("div",{style:{marginBottom:14},children:[s.jsxs("label",{style:{display:"flex",alignItems:"center",gap:6,fontSize:13,color:v.textPrimary,cursor:"pointer",marginBottom:6},children:[s.jsx("input",{type:"checkbox",checked:i.useBarColor,onChange:y=>a(p=>({...p,useBarColor:y.target.checked})),style:{cursor:"pointer",width:14,height:14}}),"Recolor bars / features"]}),i.useBarColor&&s.jsxs("div",{style:{paddingLeft:22,display:"flex",alignItems:"center",gap:8},children:[s.jsx("input",{type:"color",value:i.barColor,onChange:y=>a(p=>({...p,barColor:y.target.value})),style:{width:28,height:20,border:"none",background:"none",cursor:"pointer",padding:0}}),s.jsx("input",{type:"text",value:i.barColor,onChange:y=>{let p=y.target.value.trim();p&&!p.startsWith("#")&&(p="#"+p),/^#[0-9a-fA-F]{3,8}$/.test(p)&&a(h=>({...h,barColor:p}))},style:{background:v.inputBg,border:`1px solid ${v.borderAccent}`,borderRadius:3,color:v.textPrimary,padding:"3px 6px",fontSize:12,fontFamily:"monospace",width:72}})]})]}),s.jsx("div",{style:{display:"flex",gap:4,height:16,borderRadius:3,marginBottom:14,overflow:"hidden",border:`1px solid ${v.border}`},children:s.jsxs("div",{style:{flex:1,background:v.canvasBg,position:"relative"},children:[i.useBarColor&&s.jsx("div",{style:{position:"absolute",inset:0,background:i.barColor}}),i.useHighlight&&s.jsx("div",{style:{position:"absolute",inset:0,background:i.highlightColor,opacity:i.highlightOpacity}})]})}),s.jsx("div",{style:{fontSize:12,color:v.textSecondary,textTransform:"uppercase",letterSpacing:1,marginBottom:8},children:"Apply to tracks"}),s.jsx("div",{style:{maxHeight:150,overflowY:"auto",marginBottom:14,border:`1px solid ${v.border}`,borderRadius:4},children:u.length===0?s.jsx("div",{style:{fontSize:12,color:v.textTertiary,padding:8},children:"No applicable tracks"}):u.map(y=>{const p=i.selectedTracks.has(y.id);return s.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,padding:"5px 8px",cursor:"pointer",background:p?v.selectedRow||"rgba(255,255,255,0.04)":"transparent"},children:[s.jsx("input",{type:"checkbox",checked:p,onChange:()=>j(y.id),style:{cursor:"pointer",width:14,height:14,flexShrink:0}}),s.jsx("span",{style:{width:10,height:10,borderRadius:2,background:y.color,flexShrink:0}}),s.jsx("span",{style:{fontSize:12,color:v.textPrimary,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:y.name}),s.jsx("span",{style:{fontSize:10,color:v.textTertiary,flexShrink:0},children:y.track_type})]},y.id)})}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end"},children:[s.jsx("button",{style:{background:v.btnBg,border:`1px solid ${v.borderStrong}`,borderRadius:4,color:v.btnText,padding:"6px 16px",cursor:"pointer",fontSize:12},onClick:()=>a(null),children:"Cancel"}),s.jsxs("button",{style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"6px 16px",cursor:"pointer",fontSize:12,fontWeight:600,opacity:i.selectedTracks.size>0&&(i.useHighlight||i.useBarColor)?1:.4},disabled:i.selectedTracks.size===0||!i.useHighlight&&!i.useBarColor,onClick:x,children:["Apply to ",i.selectedTracks.size," track",i.selectedTracks.size!==1?"s":""]})]})]})})]})}const Ic="2.7.2";let rx=0;function Dc({size:e=32}){const[t]=Vs.useState(()=>`blogo${++rx}`);return s.jsxs("svg",{width:e,height:e,viewBox:"0 0 100 100",style:{flexShrink:0},xmlns:"http://www.w3.org/2000/svg",children:[s.jsxs("defs",{children:[s.jsxs("radialGradient",{id:`${t}_bg`,cx:"35%",cy:"30%",r:"65%",children:[s.jsx("stop",{offset:"0%",stopColor:"#5eb8ff"}),s.jsx("stop",{offset:"50%",stopColor:"#1976d2"}),s.jsx("stop",{offset:"100%",stopColor:"#0d47a1"})]}),s.jsxs("radialGradient",{id:`${t}_sh`,cx:"30%",cy:"25%",r:"30%",children:[s.jsx("stop",{offset:"0%",stopColor:"#ffffff",stopOpacity:"0.7"}),s.jsx("stop",{offset:"100%",stopColor:"#ffffff",stopOpacity:"0"})]})]}),s.jsx("circle",{cx:"50",cy:"50",r:"48",fill:`url(#${t}_bg)`}),s.jsx("circle",{cx:"50",cy:"48",r:"28",fill:"white"}),s.jsx("circle",{cx:"50",cy:"48",r:"28",fill:"none",stroke:"#1565c0",strokeWidth:"2.5"}),s.jsx("text",{x:"50",y:"39",textAnchor:"middle",fontSize:"13",fontWeight:"800",fontFamily:"Arial, sans-serif",fill:"#0d47a1",children:"BN"}),s.jsx("text",{x:"50",y:"64",textAnchor:"middle",fontSize:"30",fontWeight:"900",fontFamily:"Arial, sans-serif",fill:"#0d47a1",children:"1"}),s.jsx("circle",{cx:"50",cy:"50",r:"48",fill:`url(#${t}_sh)`})]})}function ox({theme:e,labelWidth:t}){return s.jsxs("div",{style:{display:"flex",borderBottom:`1px solid ${e.border}`,height:60,opacity:.45},children:[s.jsx("div",{"data-tour":"skeleton-track-label",style:{width:t,minWidth:t,background:e.panelBg,borderRight:`1px solid ${e.border}`,padding:"6px 8px",display:"flex",flexDirection:"column",justifyContent:"center",gap:4},children:s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[s.jsx("span",{style:{fontSize:14,color:e.textTertiary,userSelect:"none",lineHeight:1},children:"≡"}),s.jsx("span",{style:{width:10,height:10,borderRadius:2,background:"#78909c",flexShrink:0}}),s.jsx("span",{style:{fontSize:11,fontWeight:600,color:e.textSecondary,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:"Track Name"}),s.jsx("span",{style:{fontSize:13,color:e.textTertiary,lineHeight:1,padding:"0 2px"},children:"×"})]})}),s.jsx("div",{style:{flex:1,background:e.canvasBg}})]})}function lx(){const{theme:e}=Ge(),{genome:t,region:n,setGenome:r,navigateTo:o}=nt(),{tracks:l,reorderTracks:i,addTrack:a,uploadTrack:u,commitTrack:c,discardTrack:g,addGenomeAnnotationTrack:d,restoreAnnotationTracks:x}=zt(),j=k.useRef(null),[v,y]=k.useState(800),[p,h]=k.useState(!1),[f,m]=k.useState(!1),[w,S]=k.useState(!1),[T,b]=k.useState(!1),[E,N]=k.useState(!1),[O,R]=k.useState(!1),[H,_]=k.useState(140),[$,X]=k.useState(null),[B,I]=k.useState(null),[F,z]=k.useState(!1),[D,L]=k.useState(null),[U,V]=k.useState(null),[M,C]=k.useState(null),W=k.useRef(0);ky(H),k.useEffect(()=>{const A=()=>fetch("/api/heartbeat").catch(()=>{});A();const J=setInterval(A,1e4);return()=>clearInterval(J)},[]);const q=k.useRef(n==null?void 0:n.chrom);k.useEffect(()=>{n!=null&&n.chrom&&n.chrom!==q.current&&(q.current=n.chrom,x())},[n==null?void 0:n.chrom,x]);const le=new Set([".gb",".gbk",".genbank",".fasta",".fa"]),se=new Set([".bam",".bw",".bigwig",".wig",".bedgraph",".bdg",".vcf",".bed",".gtf",".gff",".gff2",".gff3"]),ce=new Set([".bai"]);function Te(A){if(!A)return"";if(A.toLowerCase().endsWith(".vcf.gz"))return".vcf.gz";const J=A.lastIndexOf(".");return J>=0?A.slice(J).toLowerCase():""}const Ce=k.useCallback(A=>{var J,K;A.preventDefault(),A.stopPropagation(),(K=(J=A.dataTransfer)==null?void 0:J.types)!=null&&K.includes("Files")&&(W.current++,W.current===1&&z(!0))},[]),ee=k.useCallback(A=>{var J,K;A.preventDefault(),A.stopPropagation(),(K=(J=A.dataTransfer)==null?void 0:J.types)!=null&&K.includes("Files")&&(W.current--,W.current<=0&&(W.current=0,z(!1)))},[]),ae=k.useCallback(A=>{A.preventDefault(),A.stopPropagation()},[]);function de(A){const J=A==null?void 0:A.compatibility;return J&&J.status!=="ok"&&J.status!=="no_genome"}const xe=k.useCallback(async A=>{var Ue,ct,Ga,Ya,Xa;if(A.preventDefault(),A.stopPropagation(),W.current=0,z(!1),!((ct=(Ue=A.dataTransfer)==null?void 0:Ue.types)!=null&&ct.includes("Files")))return;const J=Array.from(A.dataTransfer.files);if(!J.length)return;const K=[],te=[],ie=[],oe=[];for(const _e of J){const ze=Te(_e.name),yt=_e.name.toLowerCase();le.has(ze)?K.push(_e):se.has(ze)||ze===".vcf.gz"?te.push(_e):ce.has(ze)||yt.endsWith(".bam.bai")?ie.push(_e):oe.push(_e)}const ge=te.filter(_e=>_e.name.toLowerCase().endsWith(".bam")&&_e.size>50*1024*1024),we=ie.filter(_e=>_e.size>10*1024*1024);if(ge.length||we.length){const _e=[...ge,...we].map(yt=>yt.name).join(", "),ze=[...ge,...we].reduce((yt,Eo)=>yt+Eo.size,0)/(1024*1024);L({error:`${_e} (${ze.toFixed(0)} MB) — large files load faster via the Path button. Click 📂 Path in the toolbar and paste the file path instead of uploading.`}),setTimeout(()=>L(null),1e4);return}if(oe.length&&!K.length&&!te.length&&!ie.length){L({error:`Unsupported file${oe.length>1?"s":""}: ${oe.map(_e=>_e.name).join(", ")}`}),setTimeout(()=>L(null),4e3);return}try{if(K.length>0&&!t){L({msg:`Loading genome: ${K[0].name}...`});const ze=(await yn.load(K[0])).data;if(ze.name&&(ze.name=It(ze.name)),r(ze),((Ga=ze.chromosomes)==null?void 0:Ga.length)>0){const yt=ze.chromosomes[0];o(yt.name,0,Math.min(yt.length,5e4))}ze.is_annotated&&d({id:"genome_annotations",name:`${ze.name} (annotations)`,track_type:"genome_annotations",file_format:"genbank",targetChromosomes:ze.annotated_chromosomes||null})}else K.length>0&&t&&V({files:K});if(te.length>0){if(!t&&K.length===0){L({error:"Load a genome file first (.fasta, .gb, .genbank)"}),setTimeout(()=>L(null),4e3);return}L({msg:`Loading ${te.length} track${te.length>1?"s":""}...`});const _e=[],ze=[],yt=[];for(const Eo of te)try{const Cn=await u(Eo,void 0);de(Cn)?ze.push(Cn):(c(Cn),_e.push(Cn))}catch(Cn){yt.push(`${Eo.name}: ${((Xa=(Ya=Cn.response)==null?void 0:Ya.data)==null?void 0:Xa.detail)||Cn.message}`)}if(yt.length){L({error:yt.join("; ")}),setTimeout(()=>L(null),5e3);return}ze.length>0&&C({tracks:ze})}oe.length?(L({error:`Skipped unsupported: ${oe.map(_e=>_e.name).join(", ")}`}),setTimeout(()=>L(null),4e3)):(L({msg:"Files loaded"}),setTimeout(()=>L(null),2e3))}catch(_e){L({error:_e.message||"Drop failed"}),setTimeout(()=>L(null),5e3)}},[t,r,o,a,d]),ve=k.useCallback(async()=>{var J,K;if(!U)return;const A=U.files;V(null);try{const te=[];for(const ie of A){L({msg:`Adding chromosomes from ${ie.name}...`});try{const ge=(await yn.addChromosomes(ie)).data;ge.name&&(ge.name=It(ge.name)),r(ge),ge.is_annotated&&d({id:"genome_annotations",name:`${ge.name} (annotations)`,track_type:"genome_annotations",file_format:"genbank",targetChromosomes:ge.annotated_chromosomes||null})}catch(oe){te.push(`${ie.name}: ${((K=(J=oe.response)==null?void 0:J.data)==null?void 0:K.detail)||oe.message}`)}}te.length?(L({error:te.join("; ")}),setTimeout(()=>L(null),5e3)):(L({msg:`Added chromosomes from ${A.length} file${A.length>1?"s":""}`}),setTimeout(()=>L(null),3e3))}catch(te){L({error:te.message||"Failed to add chromosomes"}),setTimeout(()=>L(null),5e3)}},[U,r,d]),Ae=k.useCallback(async()=>{var J,K;if(!U)return;const A=U.files;V(null);try{L({msg:`Loading ${A.length} track${A.length>1?"s":""}...`});const te=[];for(const ie of A)try{await a(ie,void 0)}catch(oe){te.push(`${ie.name}: ${((K=(J=oe.response)==null?void 0:J.data)==null?void 0:K.detail)||oe.message}`)}te.length?(L({error:te.join("; ")}),setTimeout(()=>L(null),5e3)):(L({msg:`Added ${A.length} track${A.length>1?"s":""}`}),setTimeout(()=>L(null),3e3))}catch(te){L({error:te.message||"Failed to load tracks"}),setTimeout(()=>L(null),5e3)}},[U,a]),pe=k.useCallback(async()=>{if(M){for(const A of M.tracks)await g(A.id);C(null)}},[M,g]),Ne=k.useCallback(()=>{if(M){for(const A of M.tracks)c(A);C(null),L({msg:`Added ${M.tracks.length} track${M.tracks.length>1?"s":""}`}),setTimeout(()=>L(null),3e3)}},[M,c]),Y=k.useCallback(A=>{A.preventDefault();const J=A.clientX,K=H;function te(oe){_(Math.max(60,Math.min(400,K+(oe.clientX-J))))}function ie(){window.removeEventListener("mousemove",te),window.removeEventListener("mouseup",ie),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="ew-resize",document.body.style.userSelect="none",window.addEventListener("mousemove",te),window.addEventListener("mouseup",ie)},[H]);k.useEffect(()=>{if(!j.current)return;const A=new ResizeObserver(J=>{for(const K of J)y(K.contentRect.width)});return A.observe(j.current),()=>A.disconnect()},[]);const Z=k.useCallback(A=>A.visible?!A.targetChromosomes||!(n!=null&&n.chrom)?!0:A.targetChromosomes.includes(n.chrom):!1,[n==null?void 0:n.chrom]),ne={app:{display:"flex",flexDirection:"column",height:"100vh",background:e.appBg,color:e.textPrimary},header:{background:e.headerBg,borderBottom:`2px solid ${e.borderAccent}`,padding:"8px 16px",display:"flex",alignItems:"center",justifyContent:"space-between"},headerLeft:{display:"flex",alignItems:"center",gap:12},title:{fontSize:18,fontWeight:700,color:e.textPrimary,letterSpacing:1},subtitle:{fontSize:11,color:e.textTertiary},headerBtns:{display:"flex",gap:8},btn:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 14px",cursor:"pointer",fontSize:12,fontWeight:600,display:"flex",alignItems:"center",gap:6},trackArea:{flex:1,overflowY:"auto",overflowX:"hidden",display:"flex",flexDirection:"column"},emptyState:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",flex:1,color:e.textMuted,gap:12},emptyTitle:{fontSize:22,fontWeight:300},emptyHint:{fontSize:13}};return s.jsxs("div",{style:ne.app,onDragEnter:Ce,onDragLeave:ee,onDragOver:ae,onDrop:xe,children:[s.jsxs("div",{style:ne.header,children:[s.jsxs("div",{style:ne.headerLeft,children:[s.jsx(Dc,{size:34}),s.jsxs("div",{children:[s.jsx("div",{style:ne.title,children:"BiNgo Genome Viewer"}),t&&s.jsxs("div",{style:ne.subtitle,children:[t.name," · ",t.chromosomes.length," chr"]})]}),s.jsxs("button",{onClick:()=>N(!0),title:"About / References",style:{background:"none",border:`1px solid ${e.border}`,borderRadius:10,padding:"2px 8px",display:"flex",alignItems:"center",gap:4,cursor:"pointer",color:e.textSecondary,fontSize:11,fontWeight:600,lineHeight:1,flexShrink:0},onMouseEnter:A=>{A.currentTarget.style.color=e.textPrimary,A.currentTarget.style.borderColor=e.textSecondary},onMouseLeave:A=>{A.currentTarget.style.color=e.textSecondary,A.currentTarget.style.borderColor=e.border},children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"currentColor",style:{flexShrink:0},children:[s.jsx("path",{d:"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"}),s.jsx("circle",{cx:"8",cy:"4.5",r:"1.2"}),s.jsx("rect",{x:"7",y:"6.5",width:"2",height:"5.5",rx:"0.8"})]}),"Info"]}),s.jsxs("button",{onClick:()=>R(!0),title:"Guided Tour",style:{background:"none",border:`1px solid ${e.border}`,borderRadius:10,padding:"2px 8px",display:"flex",alignItems:"center",gap:4,cursor:"pointer",color:e.textSecondary,fontSize:11,fontWeight:600,lineHeight:1,flexShrink:0},onMouseEnter:A=>{A.currentTarget.style.color=e.textPrimary,A.currentTarget.style.borderColor=e.textSecondary},onMouseLeave:A=>{A.currentTarget.style.color=e.textSecondary,A.currentTarget.style.borderColor=e.border},children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"currentColor",style:{flexShrink:0},children:[s.jsx("path",{d:"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"}),s.jsx("path",{d:"M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zM8 13.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"})]}),"Help"]})]}),s.jsxs("div",{style:ne.headerBtns,"data-tour":"header-btns",children:[s.jsxs("button",{style:ne.btn,onClick:()=>b(!0),title:"Save or restore a session",children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0},children:[s.jsx("path",{d:"M2 2h8v8H2z"}),s.jsx("path",{d:"M4 2v4h4V2"}),s.jsx("path",{d:"M5 3h2"})]}),"Save Session"]}),s.jsxs("button",{style:ne.btn,onClick:()=>m(!0),title:"Customize color theme",children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",style:{flexShrink:0},children:[s.jsx("rect",{x:"0",y:"0",width:"5.5",height:"5.5",rx:"1",fill:"#66bb6a"}),s.jsx("rect",{x:"6.5",y:"0",width:"5.5",height:"5.5",rx:"1",fill:"#42a5f5"}),s.jsx("rect",{x:"0",y:"6.5",width:"5.5",height:"5.5",rx:"1",fill:"#ffa726"}),s.jsx("rect",{x:"6.5",y:"6.5",width:"5.5",height:"5.5",rx:"1",fill:"#ab47bc"})]}),"Theme"]}),s.jsxs("button",{"data-tour":"btn-export",style:{...ne.btn,...n&&l.length>0?{}:{opacity:.35,cursor:"default"}},onClick:()=>{n&&l.length>0&&S(!0)},title:"Export current view as SVG or PNG",children:[s.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0},children:s.jsx("path",{d:"M6 1v7M3 5.5L6 8.5 9 5.5M2 11h8"})}),"Export Image"]}),s.jsxs("button",{"data-tour":"btn-settings",style:{...ne.btn,...l.length===0?{opacity:.35,cursor:"default"}:{}},onClick:()=>{l.length>0&&h(!0)},title:"Adjust height, scale, color, and bar width for tracks",children:["⚙"," Track Settings"]})]})]}),s.jsx(V0,{}),s.jsx(Ry,{}),s.jsxs("div",{style:ne.trackArea,ref:j,"data-tour":"track-area",children:[l.filter(Z).length===0&&s.jsx(ox,{theme:e,labelWidth:H}),t?n?s.jsxs(s.Fragment,{children:[s.jsxs("div",{style:{display:"flex"},children:[s.jsx("div",{style:{width:H,minWidth:H,background:e.panelBg,borderRight:`1px solid ${e.border}`,position:"relative"},children:s.jsx("div",{onMouseDown:Y,style:{position:"absolute",right:-3,top:0,bottom:0,width:6,cursor:"ew-resize",zIndex:10},onMouseEnter:A=>A.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:A=>A.currentTarget.style.background="transparent"})}),s.jsx(Py,{width:v-H})]}),l.filter(Z).map(A=>s.jsx(Qy,{track:A,containerWidth:v,labelWidth:H,onLabelResizeStart:Y,isDragging:$===A.id,isDropTarget:B===A.id,onDragStart:()=>X(A.id),onDragOver:()=>I(A.id),onDrop:()=>{$&&$!==A.id&&i($,A.id),X(null),I(null)},onDragEnd:()=>{X(null),I(null)}},A.id)),l.length===0&&s.jsx("div",{style:{padding:24,color:e.textMuted,fontSize:13},children:"Add tracks above — BAM, VCF, BigWig, BED, GTF, GFF, WIG..."})]}):s.jsx("div",{style:ne.emptyState,children:s.jsx("div",{style:ne.emptyHint,children:"Select a chromosome to begin"})}):s.jsxs("div",{style:ne.emptyState,children:[s.jsx("div",{style:ne.emptyTitle,children:"No genome loaded"}),s.jsx("div",{style:ne.emptyHint,children:"Load a FASTA or GenBank file above to get started"})]})]}),p&&s.jsx(ty,{onClose:()=>h(!1)}),f&&s.jsx(iy,{onClose:()=>m(!1)}),w&&s.jsx(cy,{onClose:()=>S(!1)}),T&&s.jsx(Cy,{onClose:()=>b(!1),labelWidth:H,setLabelWidth:_}),O&&s.jsx(Ey,{onClose:()=>{R(!1),h(!1),m(!1)},theme:e,onAction:A=>{A==="open-settings"?(h(!0),m(!1)):A==="open-theme"?(m(!0),h(!1)):(h(!1),m(!1))}}),E&&s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},onClick:()=>N(!1),children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.border}`,borderRadius:8,padding:"28px 36px",maxWidth:520,maxHeight:"85vh",overflowY:"auto",color:e.textPrimary,lineHeight:1.7},onClick:A=>A.stopPropagation(),children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:16},children:[s.jsx(Dc,{size:44}),s.jsx("div",{style:{fontSize:20,fontWeight:700},children:"BiNgo Genome Viewer"})]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:12},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Version:"})," ",Ic]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:12},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Publisher:"})," Billy M Ngo"]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:20},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Published:"})," April 2026"]}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,background:e.canvasBg,border:`1px solid ${e.border}`,borderRadius:4,padding:"10px 14px",fontFamily:"monospace",lineHeight:1.6,marginBottom:20,userSelect:"all"},children:["Ngo, B.M. (2026). BiNgo Genome Viewer (v",Ic,") [Software]."]}),s.jsxs("details",{style:{marginBottom:20},children:[s.jsx("summary",{style:{cursor:"pointer",fontSize:13,fontWeight:600,color:e.textPrimary,marginBottom:8},children:"References & Acknowledgments"}),s.jsxs("div",{style:{fontSize:11,color:e.textSecondary,lineHeight:1.8,paddingTop:8},children:[s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginBottom:4},children:"Software Dependencies"}),s.jsxs("div",{children:[s.jsx("strong",{children:"FastAPI"})," ","—"," Ram","í","rez, S. (2018). A modern web framework for building APIs with Python."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"Uvicorn"})," ","—"," Encode OSS. ASGI server implementation for Python."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BioPython"})," ","—"," Cock, P.J.A. et al. (2009). ",s.jsx("em",{children:"Bioinformatics"}),", 25(11), 1422","–","1423."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"pyfaidx"})," ","—"," Shirley, M.D. et al. (2015). ",s.jsx("em",{children:"PeerJ PrePrints"}),", 3:e1196."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"bamnostic"})," ","—"," Sherman, M.A. & Mills, R.E. (2019). Pure Python BAM parser."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"React"})," ","—"," Meta Platforms, Inc. JavaScript UI library."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"Vite"})," ","—"," You, E. (2020). Next generation frontend tooling."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"File Format Specifications"}),s.jsxs("div",{children:[s.jsx("strong",{children:"SAM/BAM"})," ","—"," Li, H. et al. (2009). ",s.jsx("em",{children:"Bioinformatics"}),", 25(16), 2078","–","2079."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"VCF"})," ","—"," Danecek, P. et al. (2011). ",s.jsx("em",{children:"Bioinformatics"}),", 27(15), 2156","–","2158."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BigWig/WIG"})," ","—"," Kent, W.J. et al. (2010). ",s.jsx("em",{children:"Bioinformatics"}),", 26(17), 2204","–","2207."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BED"})," ","—"," UCSC Genome Browser, UC Santa Cruz."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GFF3"})," ","—"," Sequence Ontology Project."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GTF"})," ","—"," Ensembl genome database project."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GenBank"})," ","—"," Benson, D.A. et al. (2013). ",s.jsx("em",{children:"Nucleic Acids Res."}),", 41(D1), D36","–","D42."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"Inspiration"}),s.jsxs("div",{children:[s.jsx("strong",{children:"IGV"})," ","—"," Robinson, J.T. et al. (2011). ",s.jsx("em",{children:"Nature Biotechnology"}),", 29(1), 24","–","26."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"Acknowledgments"}),s.jsx("div",{children:"Early version testing and feedback:"}),s.jsx("div",{children:"Amanda Antoch, Isaac Poarch, Otto Chipashvili, Jake Colautti"})]})]}),s.jsx("div",{style:{textAlign:"right"},children:s.jsx("button",{onClick:()=>N(!1),style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 18px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Close"})})]})}),U&&(()=>{const A=U.files.length>1,J=U.files.map(K=>K.name).join(", ");return s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:"20px 24px",maxWidth:440,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},onClick:K=>K.stopPropagation(),children:[s.jsxs("div",{style:{fontSize:14,fontWeight:700,color:e.textPrimary,marginBottom:8},children:["Genome file",A?"s":""," detected"]}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,lineHeight:1.6,marginBottom:16},children:[s.jsx("strong",{style:{color:e.textPrimary},children:J}),A?" appear to be genome files. A genome is already loaded.":" appears to be a genome file. A genome is already loaded.",s.jsx("br",{}),"How would you like to handle ",A?"them":"it","?"]}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",flexWrap:"wrap"},children:[s.jsx("button",{onClick:()=>V(null),style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Skip"}),s.jsxs("button",{onClick:Ae,style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:["Add as Track",A?"s":""]}),s.jsxs("button",{onClick:ve,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:["Add as Chromosome",A?"s":""]})]})]})})})(),M&&s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:"20px 24px",maxWidth:480,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},onClick:A=>A.stopPropagation(),children:[s.jsx("div",{style:{fontSize:14,fontWeight:700,color:e.textPrimary,marginBottom:8},children:"Track compatibility warning"}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,lineHeight:1.6,marginBottom:16},children:[M.tracks.map(A=>{var J;return s.jsxs("div",{style:{marginBottom:6},children:[s.jsx("strong",{style:{color:e.textPrimary},children:A.name})," — ",((J=A.compatibility)==null?void 0:J.message)||"Possible mismatch with loaded genome"]},A.id)}),s.jsx("div",{style:{marginTop:8},children:M.tracks.length>1?"These tracks may not match the loaded genome.":"This track may not match the loaded genome."})]}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",flexWrap:"wrap"},children:[s.jsx("button",{onClick:pe,style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Skip"}),s.jsx("button",{onClick:Ne,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Load Anyway"})]})]})}),F&&s.jsx("div",{style:{position:"fixed",inset:0,zIndex:9998,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:s.jsxs("div",{style:{border:`3px dashed ${e.textSecondary}`,borderRadius:16,padding:"40px 60px",textAlign:"center"},children:[s.jsx("div",{style:{fontSize:28,fontWeight:300,color:e.textPrimary,marginBottom:8},children:"Drop files here"}),s.jsx("div",{style:{fontSize:13,color:e.textSecondary},children:"Genome (.gb, .fasta) or track files (.bam, .bw, .wig, .vcf, .bed, .gff, .gtf)"})]})}),D&&s.jsx("div",{style:{position:"fixed",bottom:20,left:"50%",transform:"translateX(-50%)",zIndex:10001,padding:"8px 20px",borderRadius:6,background:D.error?"#c62828":e.panelBg,border:`1px solid ${D.error?"#e53935":e.borderAccent}`,color:D.error?"#fff":"#81c784",fontSize:12,fontWeight:600,boxShadow:"0 4px 16px rgba(0,0,0,0.5)"},children:D.error||D.msg}),t&&s.jsx(tx,{labelWidth:H}),s.jsx(nx,{})]})}function ix(){return s.jsx(D0,{children:s.jsx(lm,{children:s.jsx(O0,{children:s.jsx(lx,{})})})})}Ui.createRoot(document.getElementById("root")).render(s.jsx(Vs.StrictMode,{children:s.jsx(ix,{})}));
97
+ `):null)}},[a,u,c,t,n,l,e.color,e.scaleMax,e.scaleMin,e.logScale,e.barAutoWidth,e.barWidth,e.showOutline,e.outlineColor,e.outlineSmooth,e.showBars,e.regionOverlays,i]),s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n}})}function Oi(e,t,n,r,o){if(!(t.length<2)){if(e.beginPath(),e.moveTo(t[0],n[0]),o){for(let l=0;l<t.length-1;l++){const i=(t[l]+t[l+1])/2,a=(n[l]+n[l+1])/2;e.quadraticCurveTo(t[l],n[l],i,a)}e.lineTo(t[t.length-1],n[n.length-1])}else for(let l=0;l<t.length;l++)e.lineTo(t[l],n[l]);e.strokeStyle=r,e.lineWidth=1.5,e.stroke()}}function Nr(e,t,n,r,o,l=!1){e.font="10px Arial, Helvetica, sans-serif",e.textAlign="left",e.textBaseline="top";const i=e.measureText(t),a=2,u=i.width+a*2,c=12;e.fillStyle=o.canvasBg||"#1e1e1e",e.globalAlpha=.75,e.fillRect(n,r,u,c),e.globalAlpha=1,e.fillStyle=l?o.textTertiary||"#666":o.textSecondary||"#aaa",e.fillText(t,n+a,r+1),e.textBaseline="alphabetic"}function My(e,t){const n=e.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);if(!n)return e;const r=o=>Math.max(0,Math.min(255,o+t));return`rgb(${r(parseInt(n[1],16))},${r(parseInt(n[2],16))},${r(parseInt(n[3],16))})`}const Bc=6,Fi=8,Ii=14,Di=2,By="#9c27b0",Go=10,Ay={A:"#4caf50",T:"#f44336",C:"#2196f3",G:"#ff9800",N:"#9e9e9e"},zy="#ffeb3b";function Ac(e,t){return e<=0||t<=0?0:Math.log2(e+1)/Math.log2(t+1)}function $y({track:e,width:t,height:n,onWarning:r}){const o=k.useRef(null),{region:l}=nt(),{theme:i}=Ge(),{data:a,loading:u}=ti(e,l,t),[c,g]=k.useState(null),d=k.useRef(null),[x,j]=k.useState(0),v=k.useRef(null),y=e.showNucleotides!==!1,p=e.useArrows!==!1,h=e.logScale===!0,f=e.fwdColor||"#90a4ae",m=e.revColor||"#f06292",w=e.arrowStyle||"pointed",S=e.arrowSize||4,T=k.useRef(null);k.useEffect(()=>{if(l&&T.current){const N=T.current;(N.chrom!==l.chrom||Math.abs(N.start-l.start)>N.end-N.start)&&j(0)}T.current=l},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end]),k.useEffect(()=>{if(!l||!y){g(null);return}const N=l.end-l.start;if(t/N<Bc||N>2e3){g(null);return}if(c&&c.chrom===l.chrom&&c.start<=l.start&&c.end>=l.end)return;const R=Math.max(0,l.start-500),H=l.end+500,_=`${l.chrom}:${R}-${H}`;d.current!==_&&(d.current=_,yn.sequence(l.chrom,R,H).then($=>g({chrom:l.chrom,start:R,end:H,sequence:$.data.sequence})).catch(()=>{}))},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end,t,y]);const b=k.useCallback(N=>{var $;if(!(($=a==null?void 0:a.reads)!=null&&$.length)||!N.shiftKey&&Math.abs(N.deltaX)>Math.abs(N.deltaY))return;const O=y&&c?Ii:Fi,R=Math.max(0,...a.reads.map(X=>X.row)),H=Math.floor(n/(O+Di)),_=Math.max(0,R-H+2);_<=0||(N.preventDefault(),N.stopPropagation(),j(X=>Math.max(0,Math.min(_,X+Math.sign(N.deltaY)*3))))},[a,n,y,c]);k.useEffect(()=>{var C;const N=o.current;if(!N)return;const O=window.devicePixelRatio||1;N.width=t*O,N.height=n*O;const R=N.getContext("2d");if(R.scale(O,O),R.clearRect(0,0,t,n),R.fillStyle=i.canvasBg,R.fillRect(0,0,t,n),u&&!a){R.fillStyle=i.textTertiary,R.font="11px Arial, Helvetica, sans-serif",R.fillText("Loading…",8,n/2+4),r&&r(null);return}if(!a){r&&r(null);return}const H=l.start,_=l.end-l.start;if(a.bins){const W=a.max_value||1,q=e.scaleMax!=null?e.scaleMax:W,le=e.color||"#78909c",se=e.barAutoWidth!==!1,ce=e.barWidth||2,Te=t/_;if(e.showBars!==!1){R.fillStyle=le;for(const ee of a.bins){const ae=(ee.end-ee.start)/_*t,de=se?Te>=1?Math.max(1,Math.min(Te,ae)):Math.max(1,ae):Math.min(ce,ae),xe=(ee.start-H)/_*t,Ae=(h?Ac(ee.value,q):Math.min(1,ee.value/q))*(n-14);R.fillRect(xe,n-Ae-2,de,Ae)}}if(e.showOutline&&a.bins.length>0){const ee=e.outlineSmooth||0,ae=a.bins.map(pe=>h?Ac(pe.value,q):Math.min(1,pe.value/q)),de=Oy(ae,ee),xe=a.bins.map(pe=>((pe.start+pe.end)/2-H)/_*t),ve=de.map(pe=>n-pe*(n-14)-2),Ae=e.outlineColor||i.textPrimary||"#fff";if(R.beginPath(),R.moveTo(xe[0],ve[0]),ee>0){for(let pe=0;pe<xe.length-1;pe++)R.quadraticCurveTo(xe[pe],ve[pe],(xe[pe]+xe[pe+1])/2,(ve[pe]+ve[pe+1])/2);R.lineTo(xe[xe.length-1],ve[ve.length-1])}else for(let pe=0;pe<xe.length;pe++)R.lineTo(xe[pe],ve[pe]);R.strokeStyle=Ae,R.lineWidth=1.5,R.stroke()}const Ce=h?" log₂":"";zc(R,`${q.toFixed(1)}${Ce}`,2,2,i),zc(R,"0",2,n-12,i,!0),R.fillStyle="#ffb74d",R.font="10px Arial, Helvetica, sans-serif",R.textAlign="right",R.fillText("zoom in for reads",t-4,10),r&&r(e.scaleMax!=null&&W>e.scaleMax?`Bars clipped: max value ${W.toFixed(1)} exceeds scale ${e.scaleMax.toFixed(1)}`:null);return}if(!((C=a.reads)!=null&&C.length)){R.fillStyle=i.textTertiary,R.font="11px Arial, Helvetica, sans-serif",R.fillText("No reads in region",8,n/2+4),r&&r(null);return}const $=W=>(W-H)/_*t,X=t/_,B=y&&X>=Bc&&c!=null,I=B?Ii:Fi,F=Di,D=Math.max(0,...a.reads.map(W=>W.row))+1,L=Math.floor(n/(I+F)),U=D>L,V=Math.min(x,Math.max(0,D-L+1));let M=0;for(const W of a.reads){const q=(W.row-V)*(I+F)+2;if(q+I<0||q>n){M++;continue}const le=W.strand==="+"?f:m,se=W.segments;if(se&&se.length>0){const ce=$(W.start),Te=$(W.end);R.strokeStyle=le,R.lineWidth=1,R.beginPath(),R.moveTo(ce,q+I/2),R.lineTo(Te,q+I/2),R.stroke();let Ce=0;for(const ee of se)if(ee.type==="M"){const ae=$(ee.start),de=Math.max(1,$(ee.end)-ae);if(R.fillStyle=le,R.fillRect(ae,q,de,I),B&&W.sequence){const xe=ee.end-ee.start;for(let ve=0;ve<xe;ve++){const Ae=ee.start+ve,pe=$(Ae),Ne=$(Ae+1)-pe,Y=(W.sequence[Ce+ve]||"").toUpperCase();let Z="";c&&Ae>=c.start&&Ae<c.end&&(Z=(c.sequence[Ae-c.start]||"").toUpperCase());const ne=Z&&Y&&Y!==Z&&Y!=="N";ne&&(R.fillStyle=zy,R.fillRect(pe,q,Ne,I)),Ne>=6&&(R.fillStyle=ne?"#000":Ay[Y]||"#999",R.font=`bold ${Math.min(11,Ne-1)}px monospace`,R.textAlign="center",R.textBaseline="middle",R.fillText(Y,pe+Ne/2,q+I/2))}Ce+=xe}}else if(ee.type==="D"){const ae=$(ee.start),de=$(ee.end)-ae;de>=1&&(R.strokeStyle=le,R.lineWidth=1,R.beginPath(),R.moveTo(ae,q+I/2),R.lineTo(ae+de,q+I/2),R.stroke())}else if(ee.type==="N"){const ae=$(ee.start),de=$(ee.end)-ae;de>=2&&(R.setLineDash([2,2]),R.strokeStyle=le,R.lineWidth=1,R.beginPath(),R.moveTo(ae,q+I/2),R.lineTo(ae+de,q+I/2),R.stroke(),R.setLineDash([]))}else ee.type==="I"?(R.fillStyle=By,R.fillRect($(ee.pos)-1,q-1,2,I+2),B&&(Ce+=ee.length)):ee.type==="S"&&B&&(Ce+=ee.length)}else{const ce=$(W.start),Te=Math.max(2,$(W.end)-ce);R.fillStyle=W.strand==="+"?f:m,R.fillRect(ce,q,Te,I)}if(p&&w!=="flat"){const ce=$(W.start),Te=Math.max(2,$(W.end)-ce),Ce=Math.min(S,Te/2);Ce>=2&&Ny(R,w,W.strand,ce,q,Te,I,Ce,le,i.canvasBg)}if(!B&&!y){const ce=$(W.start);Math.max(2,$(W.end)-ce)>60&&(R.fillStyle=i.canvasBg,R.font="8px Arial, Helvetica, sans-serif",R.textAlign="left",R.fillText(W.name.slice(0,20),ce+2,q+I-1))}}if(U){const W=t-Go;R.fillStyle=i.inputBg||"#2a2a2a",R.fillRect(W,0,Go,n);const q=L/D,le=Math.max(20,q*n),ce=(D>L?V/(D-L):0)*(n-le);R.fillStyle="#555",R.fillRect(W+1,ce,Go-2,le)}r&&(M>0&&!U?r(`${M} read${M>1?"s":""} hidden — increase track height to show all`):r(U?`${D} rows · Shift+scroll or drag scrollbar to navigate`:null))},[a,u,t,n,l,c,x,e.color,e.scaleMax,e.scaleMin,e.barAutoWidth,e.barWidth,e.showOutline,e.outlineColor,e.outlineSmooth,e.showBars,e.showNucleotides,e.useArrows,e.logScale,e.fwdColor,e.revColor,e.arrowStyle,e.arrowSize,i]);const E=k.useCallback(N=>{var D;if(!((D=a==null?void 0:a.reads)!=null&&D.length))return;const O=o.current;if(!O)return;const R=O.getBoundingClientRect();if((N.clientX-R.left)*(t/R.width)<t-Go)return;const _=y&&c?Ii:Fi,X=Math.max(0,...a.reads.map(L=>L.row))+1,B=Math.floor(n/(_+Di)),I=Math.max(0,X-B+1);if(I<=0)return;N.preventDefault(),v.current={maxScroll:I,startY:N.clientY,startRow:x};function F(L){if(!v.current)return;const U=L.clientY-v.current.startY,V=Math.round(U/n*v.current.maxScroll);j(Math.max(0,Math.min(v.current.maxScroll,v.current.startRow+V)))}function z(){v.current=null,window.removeEventListener("mousemove",F),window.removeEventListener("mouseup",z)}window.addEventListener("mousemove",F),window.addEventListener("mouseup",z)},[a,t,n,x,y,c]);return s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n},onWheel:b,onMouseDown:E})}function Ny(e,t,n,r,o,l,i,a,u,c){const g=n==="+";if(t==="pointed")e.fillStyle=c,g?(e.beginPath(),e.moveTo(r+l,o+i/2),e.lineTo(r+l-a,o),e.lineTo(r+l-a,o+i),e.fill()):(e.beginPath(),e.moveTo(r,o+i/2),e.lineTo(r+a,o),e.lineTo(r+a,o+i),e.fill());else if(t==="chevron")e.strokeStyle=c,e.lineWidth=1.5,g?(e.beginPath(),e.moveTo(r+l-a,o),e.lineTo(r+l,o+i/2),e.lineTo(r+l-a,o+i),e.stroke()):(e.beginPath(),e.moveTo(r+a,o),e.lineTo(r,o+i/2),e.lineTo(r+a,o+i),e.stroke());else if(t==="fade")if(g){const d=e.createLinearGradient(r+l-a*2,0,r+l,0);d.addColorStop(0,"rgba(0,0,0,0)"),d.addColorStop(1,c),e.fillStyle=d,e.fillRect(r+l-a*2,o,a*2,i)}else{const d=e.createLinearGradient(r,0,r+a*2,0);d.addColorStop(0,c),d.addColorStop(1,"rgba(0,0,0,0)"),e.fillStyle=d,e.fillRect(r,o,a*2,i)}}function Oy(e,t){if(t<=0||e.length===0)return e;const n=new Array(e.length);for(let r=0;r<e.length;r++){let o=0,l=0;const i=Math.max(0,r-t),a=Math.min(e.length-1,r+t);for(let u=i;u<=a;u++)o+=e[u],l++;n[r]=o/l}return n}function zc(e,t,n,r,o,l=!1){e.font="10px Arial, Helvetica, sans-serif",e.textAlign="left",e.textBaseline="top";const i=2,a=e.measureText(t).width+i*2;e.fillStyle=o.canvasBg||"#1e1e1e",e.globalAlpha=.75,e.fillRect(n,r,a,12),e.globalAlpha=1,e.fillStyle=l?o.textTertiary||"#666":o.textSecondary||"#aaa",e.fillText(t,n+i,r+1),e.textBaseline="alphabetic"}const Fy=16,Iy=22,Dy=4,Mp=8,$c=6,Nc={A:"#4caf50",T:"#f44336",C:"#2196f3",G:"#ff9800",N:"#9e9e9e"};function Uy({track:e,width:t,height:n,onWarning:r}){var O,R,H,_;const o=k.useRef(null),{region:l,navigateTo:i,setSelection:a}=nt(),{tracks:u}=zt(),{theme:c}=Ge(),{data:g,loading:d,error:x}=ti(e,l,t),j=e.useArrows!==!1,v=e.showNucleotides!==!1,y=k.useRef([]),[p,h]=k.useState(null),[f,m]=k.useState(null),w=k.useRef(null);k.useEffect(()=>{if(!l||!v){m(null);return}const $=l.end-l.start;if(t/$<$c||$>2e3){m(null);return}if(f&&f.chrom===l.chrom&&f.start<=l.start&&f.end>=l.end)return;const B=Math.max(0,l.start-500),I=l.end+500,F=`${l.chrom}:${B}-${I}`;w.current!==F&&(w.current=F,yn.sequence(l.chrom,B,I).then(z=>m({chrom:l.chrom,start:B,end:I,sequence:z.data.sequence})).catch(()=>{}))},[l==null?void 0:l.chrom,l==null?void 0:l.start,l==null?void 0:l.end,t,v]),k.useEffect(()=>{var M,C;const $=o.current;if(!$)return;const X=window.devicePixelRatio||1;$.width=t*X,$.height=n*X;const B=$.getContext("2d");if(B.scale(X,X),B.clearRect(0,0,t,n),B.fillStyle=c.canvasBg,B.fillRect(0,0,t,n),y.current=[],d&&!((M=g==null?void 0:g.features)!=null&&M.length)){B.fillStyle=c.textTertiary,B.font="11px Arial, Helvetica, sans-serif",B.fillText("Loading…",8,n/2+4),r&&r(null);return}if(x){B.fillStyle="#ef9a9a",B.font="11px Arial, Helvetica, sans-serif",B.fillText(typeof x=="string"?x:JSON.stringify(x),8,n/2+4),r&&r(null);return}if(!((C=g==null?void 0:g.features)!=null&&C.length)){g&&(B.fillStyle=c.textTertiary,B.font="11px Arial, Helvetica, sans-serif",B.fillText("No features in region",8,n/2+4)),r&&r(null);return}const I=l.end-l.start,F=t/I,z=v&&F>=$c&&f!=null,D=z?Iy:Fy,L=[],U=[];let V=0;if(z){const q=n-14;B.fillStyle=c.canvasBg,B.fillRect(0,q,t,14),B.strokeStyle=c.border||"#333",B.lineWidth=.5,B.beginPath(),B.moveTo(0,q),B.lineTo(t,q),B.stroke();const le=Math.min(10,F-1);if(le>=5){B.font=`bold ${le}px monospace`,B.textAlign="center",B.textBaseline="middle";for(let se=Math.floor(l.start);se<Math.ceil(l.end);se++)if(f&&se>=f.start&&se<f.end){const ce=(f.sequence[se-f.start]||"").toUpperCase(),Te=(se-l.start)/I*t;B.fillStyle=Nc[ce]||"#999",B.fillText(ce,Te+F/2,q+14/2)}}}for(const W of g.features){let q=L.findIndex(de=>W.start>=de);q===-1&&(q=L.length),L[q]=W.end;const le=(W.start-l.start)/I*t,se=Math.max(2,(W.end-W.start)/I*t),ce=q*(D+Dy)+2;if(ce+D>n){V++;continue}const Te=e.regionOverlays||[];let Ce=null;const ee=(W.start+W.end)/2;for(const de of Te)if(de.barColor&&de.chrom===l.chrom&&ee>=de.start&&ee<de.end){Ce=de.barColor;break}const ae=Ce||Fc(W.feature_type,e,c);if(W.sub_features&&W.sub_features.length>0){B.fillStyle=ae+"66",B.fillRect(le,ce+D/2-1,se,2);for(const de of W.sub_features){const xe=(de.start-l.start)/I*t,ve=Math.max(1,(de.end-de.start)/I*t),Ae=Fc(de.feature_type,e,c),pe=de.feature_type==="CDS"?D:D-6,Ne=de.feature_type==="CDS"?ce:ce+3;j?Oc(B,Ae,xe,Ne,ve,pe,de.strand||W.strand):(B.fillStyle=Ae,B.fillRect(xe,Ne,ve,pe))}}else j?Oc(B,ae,le,ce,se,D,W.strand):(B.fillStyle=ae,B.fillRect(le,ce,se,D));if(z){const de=Math.max(W.start,l.start),xe=Math.min(W.end,l.end);for(let ve=de;ve<xe;ve++)if(f&&ve>=f.start&&ve<f.end){const Ae=(f.sequence[ve-f.start]||"").toUpperCase(),pe=(ve-l.start)/I*t,Ne=F;Ne>=6&&(B.fillStyle=Nc[Ae]||"#999",B.font=`bold ${Math.min(10,Ne-1)}px monospace`,B.textAlign="center",B.textBaseline="middle",B.fillText(Ae,pe+Ne/2,ce+D/2))}}else if(se>20){B.fillStyle="#fff",B.font="10px Arial, Helvetica, sans-serif",B.textAlign="left",B.textBaseline="alphabetic";const de=W.name||W.feature_type,xe=Math.floor((se-(j?Mp:0)-4)/6);xe>0&&B.fillText(de.slice(0,xe),le+3,ce+D-4)}U.push({feat:W,x:le,y:ce,w:se,h:D})}y.current=U,r&&r(V>0?`${V} feature${V>1?"s":""} hidden — increase track height to show all`:null)},[g,d,x,t,n,l,f,e.color,e.annotationColors,j,e.showNucleotides,e.regionOverlays,c]);const S=k.useCallback($=>{const X=o.current;if(!X)return;const B=X.getBoundingClientRect(),I=($.clientX-B.left)*(t/B.width),F=($.clientY-B.top)*(n/B.height);for(const z of y.current)if(I>=z.x&&I<=z.x+z.w&&F>=z.y&&F<=z.y+z.h){const D=Math.min($.clientX+14,window.innerWidth-300),L=Math.min($.clientY+14,window.innerHeight-260);h({feat:z.feat,x:Math.max(4,D),y:Math.max(4,L)});return}h(null)},[t,n]),T=k.useCallback(()=>h(null),[]),b=k.useCallback($=>{const X=o.current;if(!X||!l)return;const B=X.getBoundingClientRect(),I=($.clientX-B.left)*(t/B.width),F=($.clientY-B.top)*(n/B.height);for(const z of y.current)if(I>=z.x&&I<=z.x+z.w&&F>=z.y&&F<=z.y+z.h){const D=z.feat,U=(D.end-D.start)*.15/(1-.3),V=D.start-U,M=D.end+U;i(l.chrom,V,M),a({chrom:l.chrom,start:D.start,end:D.end}),h(null);return}},[t,n,l,i]),E=p?Wy(p.feat,u,l==null?void 0:l.chrom):[],N=p?wn.createPortal(s.jsxs("div",{style:{position:"fixed",left:p.x,top:p.y,background:c.tooltipBg,border:`1px solid ${c.tooltipBorder}`,borderRadius:4,padding:"6px 10px",color:c.textPrimary,fontSize:11,lineHeight:1.5,maxWidth:280,zIndex:1e4,pointerEvents:"none",boxShadow:"0 4px 12px rgba(0,0,0,0.5)",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:[s.jsx("div",{style:{fontWeight:700,fontSize:12,marginBottom:2},children:p.feat.name||p.feat.feature_type}),s.jsx(en,{label:"Type",value:p.feat.feature_type}),s.jsx(en,{label:"Strand",value:p.feat.strand||"."}),s.jsx(en,{label:"Location",value:`${p.feat.start.toLocaleString()}–${p.feat.end.toLocaleString()}`}),s.jsx(en,{label:"Length",value:`${(p.feat.end-p.feat.start).toLocaleString()} bp`}),((O=p.feat.attributes)==null?void 0:O.gene)&&p.feat.attributes.gene!==p.feat.name&&s.jsx(en,{label:"Gene",value:p.feat.attributes.gene}),((R=p.feat.attributes)==null?void 0:R.locus_tag)&&s.jsx(en,{label:"Locus",value:p.feat.attributes.locus_tag}),((H=p.feat.attributes)==null?void 0:H.product)&&s.jsx(en,{label:"Product",value:p.feat.attributes.product}),((_=p.feat.attributes)==null?void 0:_.note)&&s.jsx(en,{label:"Note",value:String(p.feat.attributes.note).slice(0,120)}),E.length>0&&s.jsxs(s.Fragment,{children:[s.jsx("div",{style:{borderTop:`1px solid ${c.tooltipBorder}`,margin:"4px 0",paddingTop:4},children:s.jsx("span",{style:{color:c.textSecondary,fontWeight:600,fontSize:10,textTransform:"uppercase"},children:"Track totals in gene"})}),E.map($=>s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",gap:8},children:[s.jsx("span",{style:{color:c.textSecondary,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1},children:$.name}),s.jsx("span",{style:{color:c.textPrimary,fontWeight:600,flexShrink:0},children:$.total.toFixed(1)})]},$.trackId))]})]}),document.body):null;return s.jsxs("div",{style:{position:"relative",width:"100%",height:n},children:[s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n},onMouseMove:S,onMouseLeave:T,onDoubleClick:b}),N]})}function en({label:e,value:t}){return t?s.jsxs("div",{style:{display:"flex",gap:6},children:[s.jsxs("span",{style:{opacity:.6,flexShrink:0},children:[e,":"]}),s.jsx("span",{children:t})]}):null}function Wy(e,t,n){var o;if(!e||!n)return[];const r=[];for(const l of t){if(l.track_type!=="coverage"&&l.track_type!=="reads")continue;const i=Q0(l.id,n);if(!((o=i==null?void 0:i.bins)!=null&&o.length))continue;let a=0;for(const u of i.bins){if(u.end<=e.start||u.start>=e.end)continue;const c=u.forward!=null?u.forward:Math.max(0,u.value||0),g=u.reverse!=null?Math.abs(u.reverse):Math.abs(Math.min(0,u.value||0));a+=c+g}a>0&&r.push({trackId:l.id,name:l.name,total:a})}return r}function Oc(e,t,n,r,o,l,i){e.fillStyle=t;const a=Math.min(Mp,o*.4);e.beginPath(),i==="+"?(e.moveTo(n,r),e.lineTo(n+o-a,r),e.lineTo(n+o,r+l/2),e.lineTo(n+o-a,r+l),e.lineTo(n,r+l),e.closePath()):i==="-"?(e.moveTo(n+a,r),e.lineTo(n+o,r),e.lineTo(n+o,r+l),e.lineTo(n+a,r+l),e.lineTo(n,r+l/2),e.closePath()):e.rect(n,r,o,l),e.fill(),e.strokeStyle="rgba(0,0,0,0.25)",e.lineWidth=.5,e.stroke()}function Fc(e,t,n){const r=t.annotationColors;switch(e==null?void 0:e.toLowerCase()){case"cds":return(r==null?void 0:r.cds)||(n==null?void 0:n.geneCds)||"#66bb6a";case"exon":return(r==null?void 0:r.exon)||(n==null?void 0:n.geneExon)||"#42a5f5";case"gene":return(r==null?void 0:r.gene)||(n==null?void 0:n.geneGene)||"#7e57c2";case"mrna":case"transcript":return(r==null?void 0:r.transcript)||(n==null?void 0:n.geneTranscript)||"#ab47bc";case"utr":case"3utr":case"5utr":return(r==null?void 0:r.utr)||(n==null?void 0:n.geneUtr)||"#26c6da";case"rrna":return(r==null?void 0:r.rrna)||(n==null?void 0:n.geneRrna)||"#ffa726";case"trna":return(r==null?void 0:r.trna)||(n==null?void 0:n.geneTrna)||"#ef5350";case"repeat_region":return(r==null?void 0:r.repeat)||(n==null?void 0:n.geneRepeat)||"#8d6e63";default:return(r==null?void 0:r.default)||t.color||(n==null?void 0:n.geneDefault)||"#80cbc4"}}function Hy({track:e,width:t,height:n,onWarning:r}){const o=k.useRef(null),{region:l}=nt(),{theme:i}=Ge(),{data:a,loading:u}=ti(e,l,t);return k.useEffect(()=>{var h,f;const c=o.current;if(!c)return;const g=window.devicePixelRatio||1;c.width=t*g,c.height=n*g;const d=c.getContext("2d");if(d.scale(g,g),d.clearRect(0,0,t,n),d.fillStyle=i.canvasBg,d.fillRect(0,0,t,n),u&&!((h=a==null?void 0:a.variants)!=null&&h.length)){d.fillStyle=i.textTertiary,d.font="11px Arial, Helvetica, sans-serif",d.fillText("Loading…",8,n/2+4),r&&r(null);return}if(!((f=a==null?void 0:a.variants)!=null&&f.length)){a&&(d.fillStyle=i.textTertiary,d.font="11px Arial, Helvetica, sans-serif",d.fillText("No variants in region",8,n/2+4)),r&&r(null);return}const x=l.end-l.start,j=e.barAutoWidth!==!1,v=e.barWidth||2,y=j?1:Math.max(.5,v),p=j?5:Math.max(2,v*2);for(const m of a.variants){const w=(m.pos-l.start)/x*t,S=Vy(m.ref,m.alt);d.strokeStyle=S,d.lineWidth=y,d.beginPath(),d.moveTo(w,n-4),d.lineTo(w,14),d.stroke(),d.fillStyle=S,d.beginPath(),d.arc(w,10,p,0,Math.PI*2),d.fill(),x<5e3&&(d.fillStyle=i.textPrimary,d.font="9px Arial, Helvetica, sans-serif",d.textAlign="center",d.fillText(`${m.ref}>${m.alt[0]||"?"}`,w,n-6))}if(r){const m=a.variants.filter(w=>w.pos>=l.start&&w.pos<=l.end).length;r(m>50?`${m} variants overlapping — zoom in for detail`:null)}},[a,u,t,n,l,e.color,e.barAutoWidth,e.barWidth,i]),s.jsx("canvas",{ref:o,style:{display:"block",width:"100%",height:n}})}function Vy(e,t){const n=t[0]||"";return e.length===1&&n.length===1?"#ffb74d":n.length>e.length?"#81c784":n.length<e.length?"#e57373":"#b0bec5"}function Gy({message:e,theme:t}){const[n,r]=k.useState(!1),o=k.useRef(null),l=o.current?o.current.getBoundingClientRect():null;return s.jsxs(s.Fragment,{children:[s.jsx("span",{ref:o,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:12,height:12,borderRadius:"50%",background:"rgba(229, 57, 53, 0.85)",color:"#fff",fontSize:9,fontWeight:800,lineHeight:1,cursor:"default",flexShrink:0,fontFamily:"Arial, Helvetica, sans-serif"},children:"!"}),n&&l&&wn.createPortal(s.jsx("div",{style:{position:"fixed",left:Math.min(l.right+6,window.innerWidth-220),top:l.top-4,background:t.tooltipBg||"#333",border:`1px solid ${t.tooltipBorder||"#555"}`,borderRadius:4,padding:"4px 8px",color:t.textPrimary||"#e0e0e0",fontSize:11,lineHeight:1.4,maxWidth:200,zIndex:10001,pointerEvents:"none",boxShadow:"0 3px 10px rgba(0,0,0,0.5)",whiteSpace:"pre-wrap",fontFamily:"Arial, Helvetica, sans-serif"},children:e}),document.body)]})}function Yy({width:e,height:t,trackData:n,trackType:r,trackId:o}){const{region:l,selection:i,clearSelection:a}=nt(),{tracks:u}=zt(),{theme:c}=Ge(),[g,d]=k.useState(!1),[x,j]=k.useState({x:0,y:0}),v=u.find($=>$.id===o),y=(v==null?void 0:v.regionOverlays)||[],p=r==="reads",h=k.useCallback($=>{j({x:$.clientX,y:$.clientY}),d(!0)},[]),f=k.useCallback(()=>d(!1),[]),m=k.useCallback($=>{p||($.preventDefault(),$.stopPropagation(),window.dispatchEvent(new CustomEvent("bingo-region-context",{detail:{x:$.clientX,y:$.clientY}})))},[p]);if(!l)return null;const w=l.end-l.start;if(w<=0)return null;const S=$=>($-l.start)/w*e;let T=0,b=0,E=!1;i&&i.chrom===l.chrom&&(T=Math.max(0,S(i.start)),b=Math.min(e,S(i.end))-T,E=b>=1);const N=E?Xy(i,n,r):[],O=i?i.end-i.start:0,R=260,H=Math.min(x.x+14,window.innerWidth-R-10),_=Math.min(x.y+14,window.innerHeight-200);return s.jsxs("div",{style:{position:"absolute",top:0,left:0,width:e,height:t,pointerEvents:"none"},children:[y.map(($,X)=>{if($.chrom!==l.chrom)return null;const B=Math.max(0,S($.start)),I=Math.min(e,S($.end))-B;return I<1?null:s.jsx("div",{style:{position:"absolute",left:B,top:0,width:I,height:"100%",background:$.color,opacity:$.opacity||.35,pointerEvents:"none"}},X)}),E&&s.jsx("div",{style:{position:"absolute",left:T,top:0,width:b,height:"100%",background:"rgba(100, 181, 246, 0.2)",borderLeft:"1px solid rgba(100, 181, 246, 0.6)",borderRight:"1px solid rgba(100, 181, 246, 0.6)",pointerEvents:"auto",cursor:"crosshair"},onMouseMove:h,onMouseLeave:f,onClick:$=>{$.stopPropagation(),a()},onContextMenu:m}),g&&E&&wn.createPortal(s.jsxs("div",{style:{position:"fixed",left:H,top:_,background:c.panelBg,border:`1px solid ${c.borderAccent}`,borderRadius:6,padding:"8px 12px",fontSize:11,color:c.textPrimary,lineHeight:1.6,pointerEvents:"none",zIndex:1e4,boxShadow:"0 4px 16px rgba(0,0,0,0.4)",minWidth:180,maxWidth:R},children:[s.jsx("div",{style:{fontWeight:700,marginBottom:4,fontSize:12},children:"Selected Region"}),s.jsxs("div",{children:[s.jsx("span",{style:{color:c.textSecondary},children:"Region:"})," ",i.chrom,":",i.start.toLocaleString(),"-",i.end.toLocaleString()]}),s.jsxs("div",{children:[s.jsx("span",{style:{color:c.textSecondary},children:"Length:"})," ",O.toLocaleString()," bp"]}),N.map(($,X)=>s.jsxs("div",{children:[s.jsxs("span",{style:{color:c.textSecondary},children:[$.label,":"]})," ",$.value]},X)),s.jsxs("div",{style:{fontSize:9,color:c.textTertiary,marginTop:4},children:["Click to dismiss",p?"":" · Right-click for region colors"]})]}),document.body)]})}function Xy(e,t,n){const r=[];if(!t)return r;if(n==="reads"&&t.reads){const o=t.reads.filter(i=>i.end>e.start&&i.start<e.end);r.push({label:"Reads in region",value:o.length.toLocaleString()});let l=0;for(const i of o)if(i.cigar){const a=i.cigar.match(/(\d+)I/g);if(a)for(const u of a)l+=parseInt(u)}l>0&&r.push({label:"Insertion bases",value:l.toLocaleString()}),o.length>0&&r.push({label:"Avg MAPQ",value:(o.reduce((i,a)=>i+(a.mapq||0),0)/o.length).toFixed(1)})}if((n==="coverage"||n==="reads")&&t.bins){const o=t.bins.filter(l=>l.end>e.start&&l.start<e.end);if(o.length>0){const l=o.map(i=>i.value);r.push({label:"Avg coverage",value:(l.reduce((i,a)=>i+a,0)/l.length).toFixed(1)}),r.push({label:"Max coverage",value:Math.max(...l).toFixed(1)})}}return n==="variants"&&t.variants&&r.push({label:"Variants",value:t.variants.filter(o=>o.pos>=e.start&&o.pos<e.end).length.toLocaleString()}),(n==="annotations"||n==="genome_annotations")&&t.features&&r.push({label:"Features",value:t.features.filter(o=>o.end>e.start&&o.start<e.end).length.toLocaleString()}),r}class Ky extends k.Component{constructor(t){super(t),this.state={hasError:!1,error:null}}static getDerivedStateFromError(t){return{hasError:!0,error:t}}render(){var t;return this.state.hasError?s.jsxs("div",{style:{padding:8,color:"#ef9a9a",fontSize:11},children:["Track error: ",((t=this.state.error)==null?void 0:t.message)||"Unknown error"]}):this.props.children}}function Qy({track:e,containerWidth:t,labelWidth:n=140,onLabelResizeStart:r,isDragging:o,isDropTarget:l,onDragStart:i,onDragOver:a,onDrop:u,onDragEnd:c}){const{theme:g}=Ge(),{updateTrack:d,removeTrack:x}=zt(),j=k.useRef(null),v=k.useRef(null),[y,p]=k.useState(!1),[h,f]=k.useState(!1),[m,w]=k.useState(null),S=k.useRef(null),T=k.useRef(null),b=e.track_type==="annotations"||e.track_type==="genome_annotations";Lp(j);const E=["#f44336","#ef5350","#e57373","#ff5722","#ff8a65","#ff9800","#ffa726","#ffb74d","#ffc107","#fff176","#4caf50","#66bb6a","#81c784","#aed581","#009688","#26c6da","#80cbc4","#2196f3","#42a5f5","#64b5f6","#7e57c2","#9575cd","#9c27b0","#ab47bc","#ce93d8","#e91e63","#f06292","#795548","#8d6e63","#607d8b","#78909c"],N=t-n,O={row:{display:"flex",borderBottom:`1px solid ${g.border}`,minHeight:40},label:{width:n,minWidth:n,background:g.panelBg,borderRight:`1px solid ${g.border}`,display:"flex",flexDirection:"column",justifyContent:"center",padding:"4px 8px",overflow:"hidden",position:"relative"},trackName:{fontSize:11,color:g.trackName,fontWeight:600,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},trackType:{fontSize:10,color:g.textTertiary,marginTop:2},trackArea:{flex:1,overflow:"hidden",position:"relative"}},R=k.useCallback(_=>{_.preventDefault(),_.stopPropagation();const $=_.clientY,X=e.height;function B(F){const z=Math.max(30,Math.min(500,X+(F.clientY-$)));d(e.id,{height:z})}function I(){window.removeEventListener("mousemove",B),window.removeEventListener("mouseup",I),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="ns-resize",document.body.style.userSelect="none",window.addEventListener("mousemove",B),window.addEventListener("mouseup",I)},[e.id,e.height,d]);function H(){const _={track:e,width:N,height:e.height,onWarning:w};switch(e.track_type){case"reads":return s.jsx($y,{..._});case"coverage":return s.jsx(Ly,{..._});case"variants":return s.jsx(Hy,{..._});case"annotations":case"genome_annotations":return s.jsx(Uy,{..._});default:return s.jsx("div",{style:{padding:8,color:g.textTertiary,fontSize:11},children:"Unknown track type"})}}return s.jsxs("div",{style:{...O.row,height:e.height,position:"relative",opacity:o?.4:1,borderTop:l?"2px solid #888":void 0},onDragOver:_=>{_.preventDefault(),_.dataTransfer.dropEffect="move",a==null||a()},onDrop:_=>{_.preventDefault(),u==null||u()},onDragEnd:c,children:[s.jsxs("div",{style:O.label,children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsx("div",{draggable:!0,onDragStart:_=>{_.dataTransfer.effectAllowed="move",_.dataTransfer.setData("text/plain",e.id),i==null||i()},style:{cursor:"grab",color:g.textMuted,fontSize:14,lineHeight:1,userSelect:"none",flexShrink:0,padding:"0 2px"},title:"Drag to reorder tracks",children:"≡"}),s.jsx("div",{ref:S,children:b?s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:2,background:"#888",cursor:"pointer",verticalAlign:"middle",border:"1px solid rgba(255,255,255,0.2)",backgroundImage:"linear-gradient(135deg, #ef5350 25%, #66bb6a 25%, #66bb6a 50%, #42a5f5 50%, #42a5f5 75%, #ffa726 75%)"},title:"Click to customize annotation colors",onMouseDown:_=>{_.stopPropagation(),f($=>!$)}}),h&&wn.createPortal(s.jsx(ex,{track:e,theme:g,anchorRef:S,onClose:()=>f(!1),onChange:(_,$)=>{const X={...e.annotationColors||{},[_]:$};d(e.id,{annotationColors:X})},onReset:()=>d(e.id,{annotationColors:null})}),document.body)]}):s.jsxs(s.Fragment,{children:[s.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:2,background:e.color,cursor:"pointer",verticalAlign:"middle",border:"1px solid rgba(255,255,255,0.2)"},title:"Click to pick color, double-click for full palette",onMouseDown:_=>{_.stopPropagation(),p(!0)},onDoubleClick:_=>{var $;_.stopPropagation(),p(!1),($=T.current)==null||$.click()}}),s.jsx("input",{ref:T,type:"color",value:e.color||"#78909c",onChange:_=>d(e.id,{color:_.target.value}),style:{position:"absolute",left:-9999,top:-9999,opacity:0,width:0,height:0}}),y&&wn.createPortal(s.jsx("div",{style:{position:"fixed",left:S.current?S.current.getBoundingClientRect().left:0,top:S.current?S.current.getBoundingClientRect().bottom+4:0,zIndex:10001,background:g.panelBg,border:`1px solid ${g.borderAccent}`,borderRadius:4,padding:6,boxShadow:"0 4px 12px rgba(0,0,0,0.5)",display:"grid",gridTemplateColumns:"repeat(5, 18px)",gap:3},onMouseLeave:()=>p(!1),children:E.map(_=>s.jsx("span",{style:{width:18,height:18,borderRadius:3,background:_,cursor:"pointer",border:_===e.color?`2px solid ${g.textPrimary}`:"1px solid rgba(255,255,255,0.15)",boxSizing:"border-box"},onMouseUp:()=>{d(e.id,{color:_}),p(!1)}},_))}),document.body)]})}),s.jsx("div",{style:{...O.trackName,flex:1},title:e.name,children:e.name}),s.jsx("span",{title:"Remove track",onClick:_=>{_.stopPropagation(),x(e.id)},style:{color:"#e53935",fontSize:13,fontWeight:700,cursor:"pointer",lineHeight:1,flexShrink:0,padding:"0 2px",opacity:.7,transition:"opacity 0.15s"},onMouseEnter:_=>_.currentTarget.style.opacity="1",onMouseLeave:_=>_.currentTarget.style.opacity="0.7",children:"×"})]}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsxs("div",{style:O.trackType,children:[e.file_format," · ",e.track_type]}),m&&s.jsx(Gy,{message:m,theme:g})]}),r&&s.jsx("div",{onMouseDown:r,style:{position:"absolute",right:-3,top:0,bottom:0,width:6,cursor:"ew-resize",zIndex:10},onMouseEnter:_=>_.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:_=>_.currentTarget.style.background="transparent"})]}),s.jsxs("div",{style:O.trackArea,ref:j,children:[s.jsx(Ky,{children:H()}),s.jsx(Yy,{width:N,height:e.height,trackData:Ua(e.id),trackType:e.track_type,trackId:e.id})]}),s.jsx("div",{ref:v,onMouseDown:R,title:"Drag to resize track height",style:{position:"absolute",left:0,right:0,bottom:-2,height:5,cursor:"ns-resize",zIndex:10,background:"transparent"},onMouseEnter:_=>_.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:_=>_.currentTarget.style.background="transparent"})]})}const qy=[{key:"cds",label:"CDS"},{key:"exon",label:"Exon"},{key:"gene",label:"Gene"},{key:"transcript",label:"Transcript"},{key:"utr",label:"UTR"},{key:"rrna",label:"rRNA"},{key:"trna",label:"tRNA"},{key:"repeat",label:"Repeat"},{key:"default",label:"Other"}],Jy=["#f44336","#ef5350","#e57373","#ff5722","#ff8a65","#ff9800","#ffa726","#ffb74d","#ffc107","#fff176","#4caf50","#66bb6a","#81c784","#aed581","#009688","#26c6da","#80cbc4","#2196f3","#42a5f5","#64b5f6","#7e57c2","#9575cd","#9c27b0","#ab47bc","#ce93d8","#e91e63","#f06292","#795548","#8d6e63","#607d8b","#78909c"],Zy={cds:"geneCds",exon:"geneExon",gene:"geneGene",transcript:"geneTranscript",utr:"geneUtr",rrna:"geneRrna",trna:"geneTrna",repeat:"geneRepeat",default:"geneDefault"};function ex({track:e,theme:t,anchorRef:n,onClose:r,onChange:o,onReset:l}){var y;const[i,a]=k.useState(null),u=k.useRef(null),[c,g]=k.useState(null),d=e.annotationColors||{},x=(y=n.current)==null?void 0:y.getBoundingClientRect();function j(p){return d[p]||t[Zy[p]]||jp[p]}function v(p){g(p),u.current&&(u.current.value=j(p),u.current.click())}return s.jsxs("div",{style:{position:"fixed",left:x?Math.min(x.left,window.innerWidth-220):0,top:x?x.bottom+4:0,zIndex:10001,background:t.panelBg,border:`1px solid ${t.borderAccent}`,borderRadius:6,padding:"8px 0",boxShadow:"0 6px 20px rgba(0,0,0,0.5)",width:210,maxHeight:340,overflowY:"auto"},onMouseLeave:r,children:[s.jsx("div",{style:{fontSize:10,fontWeight:700,color:t.textSecondary,textTransform:"uppercase",letterSpacing:1,padding:"0 10px 6px",borderBottom:`1px solid ${t.border}`,marginBottom:4},children:"Annotation Colors"}),qy.map(({key:p,label:h})=>{const f=j(p);return s.jsxs("div",{children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"4px 10px",cursor:"pointer",fontSize:11,color:t.textPrimary},onMouseEnter:m=>m.currentTarget.style.background=t.selectedRow,onMouseLeave:m=>m.currentTarget.style.background="transparent",onClick:()=>a(i===p?null:p),children:[s.jsx("span",{style:{display:"inline-block",width:14,height:14,borderRadius:3,background:f,border:"1px solid rgba(255,255,255,0.15)",flexShrink:0,cursor:"pointer"},onDoubleClick:m=>{m.stopPropagation(),v(p)},title:"Click to expand, double-click for full picker"}),s.jsx("span",{style:{flex:1},children:h}),s.jsx("span",{style:{fontSize:9,color:t.textTertiary},children:i===p?"▲":"▼"})]}),i===p&&s.jsxs("div",{style:{padding:"4px 10px 6px 32px"},children:[s.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:3,marginBottom:6},children:Jy.map(m=>s.jsx("span",{style:{width:18,height:18,borderRadius:3,background:m,cursor:"pointer",border:m===f?`2px solid ${t.textPrimary}`:"1px solid rgba(255,255,255,0.15)",boxSizing:"border-box"},onClick:()=>{o(p,m),a(null)},onDoubleClick:w=>{w.stopPropagation(),v(p)}},m))}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[s.jsx("span",{style:{fontSize:10,color:t.textTertiary},children:"Hex:"}),s.jsx("input",{type:"text",defaultValue:f,placeholder:"#ff0000",style:{background:t.inputBg,border:`1px solid ${t.borderAccent}`,borderRadius:3,color:t.textPrimary,padding:"2px 5px",fontSize:10,fontFamily:"monospace",width:70},onKeyDown:m=>{if(m.key==="Enter"){let w=m.target.value.trim();w&&!w.startsWith("#")&&(w="#"+w),/^#[0-9a-fA-F]{3,8}$/.test(w)&&(o(p,w),a(null))}},onBlur:m=>{let w=m.target.value.trim();w&&!w.startsWith("#")&&(w="#"+w),/^#[0-9a-fA-F]{3,8}$/.test(w)&&o(p,w)},onClick:m=>m.stopPropagation()}),s.jsx("span",{style:{width:14,height:14,borderRadius:3,background:f,border:"1px solid rgba(255,255,255,0.2)",cursor:"pointer",flexShrink:0},onDoubleClick:m=>{m.stopPropagation(),v(p)},title:"Double-click for color picker"})]})]})]},p)}),s.jsx("div",{style:{borderTop:`1px solid ${t.border}`,marginTop:4,paddingTop:4},children:s.jsx("div",{style:{padding:"4px 10px",fontSize:10,color:t.textTertiary,cursor:"pointer",textAlign:"center"},onMouseEnter:p=>{p.currentTarget.style.color=t.textPrimary},onMouseLeave:p=>{p.currentTarget.style.color=t.textTertiary},onClick:l,children:"Reset to defaults"})}),s.jsx("input",{ref:u,type:"color",style:{position:"absolute",left:-9999,top:-9999,opacity:0,width:0,height:0},onChange:p=>{c&&o(c,p.target.value)}})]})}function tx({labelWidth:e}){const{genome:t,region:n}=nt(),{tracks:r}=zt(),{theme:o,themeName:l,customTheme:i}=Ge(),[a,u]=k.useState(!1),[c,g]=k.useState(!1),d=!!t;k.useEffect(()=>{if(!d)return;function y(p){p.preventDefault(),p.returnValue=""}return window.addEventListener("beforeunload",y),()=>window.removeEventListener("beforeunload",y)},[d]),k.useEffect(()=>{if(!d)return;function y(p){(p.ctrlKey||p.metaKey)&&p.key==="w"&&(p.preventDefault(),u(!0))}return window.addEventListener("keydown",y),()=>window.removeEventListener("keydown",y)},[d]);const x=k.useCallback(()=>u(!1),[]),j=k.useCallback(()=>{window.onbeforeunload=null,window.close(),window.location.href="about:blank"},[]),v=k.useCallback(()=>{g(!0);try{const y=Ha(t,n,r,l,i,e);Va(y),_p(y)}catch{}g(!1),window.onbeforeunload=null,window.close(),window.location.href="about:blank"},[t,n,r,l,i,e]);return a?s.jsx("div",{style:{position:"fixed",inset:0,zIndex:1e4,background:"rgba(0,0,0,0.5)",display:"flex",alignItems:"center",justifyContent:"center"},onClick:x,children:s.jsxs("div",{style:{background:o.panelBg,border:`1px solid ${o.borderAccent}`,borderRadius:8,padding:"24px 28px",maxWidth:400,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.6)"},onClick:y=>y.stopPropagation(),children:[s.jsx("div",{style:{fontSize:16,fontWeight:700,color:o.textPrimary,marginBottom:8},children:"Leave BiNgo Genome Viewer?"}),s.jsxs("div",{style:{fontSize:12,color:o.textSecondary,lineHeight:1.7,marginBottom:20},children:["You have an active session with"," ",s.jsxs("strong",{style:{color:o.textPrimary},children:[r.length," track",r.length!==1?"s":""]})," loaded. Unsaved changes will be lost."]}),s.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[s.jsx("button",{onClick:x,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:"Return to App"}),s.jsx("button",{onClick:v,disabled:c,style:{background:o.btnBg,border:`1px solid ${o.borderStrong}`,borderRadius:4,color:o.btnText,padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:c?"Saving...":"Save Session & Exit"}),s.jsx("button",{onClick:j,style:{background:"transparent",border:`1px solid ${o.border}`,borderRadius:4,color:"#e57373",padding:"8px 16px",cursor:"pointer",fontSize:13,fontWeight:600,width:"100%"},children:"Exit Without Saving"})]})]})}):null}function nx(){const{selection:e}=nt(),{tracks:t,updateTrack:n}=zt(),{theme:r}=Ge(),[o,l]=k.useState(null),[i,a]=k.useState(null),u=t.filter(y=>y.visible!==!1&&y.track_type!=="reads"),c=t.some(y=>{var p;return((p=y.regionOverlays)==null?void 0:p.length)>0});k.useEffect(()=>{function y(h){l({x:h.detail.x,y:h.detail.y,hasSelection:!0})}function p(h){c&&l({x:h.detail.x,y:h.detail.y,hasSelection:!1})}return window.addEventListener("bingo-region-context",y),window.addEventListener("bingo-track-context",p),()=>{window.removeEventListener("bingo-region-context",y),window.removeEventListener("bingo-track-context",p)}},[c]);const g=k.useCallback(()=>{if(!e)return;l(null);const y=new Set(u.map(p=>p.id));a({chrom:e.chrom,start:e.start,end:e.end,highlightColor:"#42a5f5",highlightOpacity:.3,useHighlight:!0,barColor:"#ff9800",useBarColor:!1,selectedTracks:y})},[e,u]),d=k.useCallback(()=>{var y;l(null);for(const p of t)((y=p.regionOverlays)==null?void 0:y.length)>0&&n(p.id,{regionOverlays:[]})},[t,n]),x=k.useCallback(()=>{if(!i)return;const y={chrom:i.chrom,start:i.start,end:i.end,highlightColor:i.useHighlight?i.highlightColor:null,highlightOpacity:i.highlightOpacity,barColor:i.useBarColor?i.barColor:null};for(const p of i.selectedTracks){const h=t.find(m=>m.id===p);if(!h)continue;const f=(h.regionOverlays||[]).filter(m=>!(m.chrom===y.chrom&&m.start===y.start&&m.end===y.end));n(p,{regionOverlays:[...f,y]})}a(null)},[i,t,n]),j=k.useCallback(y=>{a(p=>{if(!p)return p;const h=new Set(p.selectedTracks);return h.has(y)?h.delete(y):h.add(y),{...p,selectedTracks:h}})},[]),v=r;return s.jsxs(s.Fragment,{children:[o&&wn.createPortal(s.jsx("div",{style:{position:"fixed",inset:0,zIndex:10001},onClick:()=>l(null),onContextMenu:y=>{y.preventDefault(),l(null)},children:s.jsxs("div",{style:{position:"fixed",left:Math.min(o.x,window.innerWidth-220),top:Math.min(o.y,window.innerHeight-100),background:v.panelBg,border:`1px solid ${v.borderAccent}`,borderRadius:6,boxShadow:"0 4px 16px rgba(0,0,0,0.5)",padding:"4px 0",minWidth:210,zIndex:10002},onClick:y=>y.stopPropagation(),children:[e&&s.jsxs("div",{style:{padding:"5px 14px 7px",fontSize:11,color:v.textTertiary,borderBottom:`1px solid ${v.border}`},children:[e.chrom,":",e.start.toLocaleString(),"–",e.end.toLocaleString()]}),o.hasSelection&&e&&s.jsxs("div",{style:{padding:"7px 14px",fontSize:13,color:v.textPrimary,cursor:"pointer"},onMouseEnter:y=>y.currentTarget.style.background=v.selectedRow||"rgba(255,255,255,0.06)",onMouseLeave:y=>y.currentTarget.style.background="transparent",onClick:g,children:["Edit region colors","…"]}),c&&s.jsx("div",{style:{padding:"7px 14px",fontSize:13,color:"#e57373",cursor:"pointer"},onMouseEnter:y=>y.currentTarget.style.background=v.selectedRow||"rgba(255,255,255,0.06)",onMouseLeave:y=>y.currentTarget.style.background="transparent",onClick:d,children:"Reset all region colors"})]})}),document.body),i&&s.jsx(Wa,{title:"Region Colors",onClose:()=>a(null),theme:v,defaultWidth:360,defaultHeight:420,children:s.jsxs("div",{style:{padding:"14px 18px"},children:[s.jsxs("div",{style:{fontSize:12,color:v.textSecondary,marginBottom:14},children:[i.chrom,":",i.start.toLocaleString(),"–",i.end.toLocaleString(),s.jsxs("span",{style:{color:v.textTertiary},children:[" (",(i.end-i.start).toLocaleString()," bp)"]})]}),s.jsxs("div",{style:{marginBottom:12},children:[s.jsxs("label",{style:{display:"flex",alignItems:"center",gap:6,fontSize:13,color:v.textPrimary,cursor:"pointer",marginBottom:6},children:[s.jsx("input",{type:"checkbox",checked:i.useHighlight,onChange:y=>a(p=>({...p,useHighlight:y.target.checked})),style:{cursor:"pointer",width:14,height:14}}),"Highlight color"]}),i.useHighlight&&s.jsxs("div",{style:{paddingLeft:22},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:6},children:[s.jsx("input",{type:"color",value:i.highlightColor,onChange:y=>a(p=>({...p,highlightColor:y.target.value})),style:{width:28,height:20,border:"none",background:"none",cursor:"pointer",padding:0}}),s.jsx("input",{type:"text",value:i.highlightColor,onChange:y=>{let p=y.target.value.trim();p&&!p.startsWith("#")&&(p="#"+p),/^#[0-9a-fA-F]{3,8}$/.test(p)&&a(h=>({...h,highlightColor:p}))},style:{background:v.inputBg,border:`1px solid ${v.borderAccent}`,borderRadius:3,color:v.textPrimary,padding:"3px 6px",fontSize:12,fontFamily:"monospace",width:72}})]}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[s.jsx("span",{style:{fontSize:12,color:v.textSecondary},children:"Opacity"}),s.jsx("input",{type:"range",min:.1,max:.8,step:.05,value:i.highlightOpacity,onChange:y=>a(p=>({...p,highlightOpacity:parseFloat(y.target.value)})),style:{flex:1,cursor:"pointer",accentColor:v.textSecondary}}),s.jsxs("span",{style:{fontSize:12,color:v.textTertiary,width:32},children:[Math.round(i.highlightOpacity*100),"%"]})]})]})]}),s.jsxs("div",{style:{marginBottom:14},children:[s.jsxs("label",{style:{display:"flex",alignItems:"center",gap:6,fontSize:13,color:v.textPrimary,cursor:"pointer",marginBottom:6},children:[s.jsx("input",{type:"checkbox",checked:i.useBarColor,onChange:y=>a(p=>({...p,useBarColor:y.target.checked})),style:{cursor:"pointer",width:14,height:14}}),"Recolor bars / features"]}),i.useBarColor&&s.jsxs("div",{style:{paddingLeft:22,display:"flex",alignItems:"center",gap:8},children:[s.jsx("input",{type:"color",value:i.barColor,onChange:y=>a(p=>({...p,barColor:y.target.value})),style:{width:28,height:20,border:"none",background:"none",cursor:"pointer",padding:0}}),s.jsx("input",{type:"text",value:i.barColor,onChange:y=>{let p=y.target.value.trim();p&&!p.startsWith("#")&&(p="#"+p),/^#[0-9a-fA-F]{3,8}$/.test(p)&&a(h=>({...h,barColor:p}))},style:{background:v.inputBg,border:`1px solid ${v.borderAccent}`,borderRadius:3,color:v.textPrimary,padding:"3px 6px",fontSize:12,fontFamily:"monospace",width:72}})]})]}),s.jsx("div",{style:{display:"flex",gap:4,height:16,borderRadius:3,marginBottom:14,overflow:"hidden",border:`1px solid ${v.border}`},children:s.jsxs("div",{style:{flex:1,background:v.canvasBg,position:"relative"},children:[i.useBarColor&&s.jsx("div",{style:{position:"absolute",inset:0,background:i.barColor}}),i.useHighlight&&s.jsx("div",{style:{position:"absolute",inset:0,background:i.highlightColor,opacity:i.highlightOpacity}})]})}),s.jsx("div",{style:{fontSize:12,color:v.textSecondary,textTransform:"uppercase",letterSpacing:1,marginBottom:8},children:"Apply to tracks"}),s.jsx("div",{style:{maxHeight:150,overflowY:"auto",marginBottom:14,border:`1px solid ${v.border}`,borderRadius:4},children:u.length===0?s.jsx("div",{style:{fontSize:12,color:v.textTertiary,padding:8},children:"No applicable tracks"}):u.map(y=>{const p=i.selectedTracks.has(y.id);return s.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,padding:"5px 8px",cursor:"pointer",background:p?v.selectedRow||"rgba(255,255,255,0.04)":"transparent"},children:[s.jsx("input",{type:"checkbox",checked:p,onChange:()=>j(y.id),style:{cursor:"pointer",width:14,height:14,flexShrink:0}}),s.jsx("span",{style:{width:10,height:10,borderRadius:2,background:y.color,flexShrink:0}}),s.jsx("span",{style:{fontSize:12,color:v.textPrimary,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:y.name}),s.jsx("span",{style:{fontSize:10,color:v.textTertiary,flexShrink:0},children:y.track_type})]},y.id)})}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end"},children:[s.jsx("button",{style:{background:v.btnBg,border:`1px solid ${v.borderStrong}`,borderRadius:4,color:v.btnText,padding:"6px 16px",cursor:"pointer",fontSize:12},onClick:()=>a(null),children:"Cancel"}),s.jsxs("button",{style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"6px 16px",cursor:"pointer",fontSize:12,fontWeight:600,opacity:i.selectedTracks.size>0&&(i.useHighlight||i.useBarColor)?1:.4},disabled:i.selectedTracks.size===0||!i.useHighlight&&!i.useBarColor,onClick:x,children:["Apply to ",i.selectedTracks.size," track",i.selectedTracks.size!==1?"s":""]})]})]})})]})}const Ic="2.7.3";let rx=0;function Dc({size:e=32}){const[t]=Vs.useState(()=>`blogo${++rx}`);return s.jsxs("svg",{width:e,height:e,viewBox:"0 0 100 100",style:{flexShrink:0},xmlns:"http://www.w3.org/2000/svg",children:[s.jsxs("defs",{children:[s.jsxs("radialGradient",{id:`${t}_bg`,cx:"35%",cy:"30%",r:"65%",children:[s.jsx("stop",{offset:"0%",stopColor:"#5eb8ff"}),s.jsx("stop",{offset:"50%",stopColor:"#1976d2"}),s.jsx("stop",{offset:"100%",stopColor:"#0d47a1"})]}),s.jsxs("radialGradient",{id:`${t}_sh`,cx:"30%",cy:"25%",r:"30%",children:[s.jsx("stop",{offset:"0%",stopColor:"#ffffff",stopOpacity:"0.7"}),s.jsx("stop",{offset:"100%",stopColor:"#ffffff",stopOpacity:"0"})]})]}),s.jsx("circle",{cx:"50",cy:"50",r:"48",fill:`url(#${t}_bg)`}),s.jsx("circle",{cx:"50",cy:"48",r:"28",fill:"white"}),s.jsx("circle",{cx:"50",cy:"48",r:"28",fill:"none",stroke:"#1565c0",strokeWidth:"2.5"}),s.jsx("text",{x:"50",y:"39",textAnchor:"middle",fontSize:"13",fontWeight:"800",fontFamily:"Arial, sans-serif",fill:"#0d47a1",children:"BN"}),s.jsx("text",{x:"50",y:"64",textAnchor:"middle",fontSize:"30",fontWeight:"900",fontFamily:"Arial, sans-serif",fill:"#0d47a1",children:"1"}),s.jsx("circle",{cx:"50",cy:"50",r:"48",fill:`url(#${t}_sh)`})]})}function ox({theme:e,labelWidth:t}){return s.jsxs("div",{style:{display:"flex",borderBottom:`1px solid ${e.border}`,height:60,opacity:.45},children:[s.jsx("div",{"data-tour":"skeleton-track-label",style:{width:t,minWidth:t,background:e.panelBg,borderRight:`1px solid ${e.border}`,padding:"6px 8px",display:"flex",flexDirection:"column",justifyContent:"center",gap:4},children:s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[s.jsx("span",{style:{fontSize:14,color:e.textTertiary,userSelect:"none",lineHeight:1},children:"≡"}),s.jsx("span",{style:{width:10,height:10,borderRadius:2,background:"#78909c",flexShrink:0}}),s.jsx("span",{style:{fontSize:11,fontWeight:600,color:e.textSecondary,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:"Track Name"}),s.jsx("span",{style:{fontSize:13,color:e.textTertiary,lineHeight:1,padding:"0 2px"},children:"×"})]})}),s.jsx("div",{style:{flex:1,background:e.canvasBg}})]})}function lx(){const{theme:e}=Ge(),{genome:t,region:n,setGenome:r,navigateTo:o}=nt(),{tracks:l,reorderTracks:i,addTrack:a,uploadTrack:u,commitTrack:c,discardTrack:g,addGenomeAnnotationTrack:d,restoreAnnotationTracks:x}=zt(),j=k.useRef(null),[v,y]=k.useState(800),[p,h]=k.useState(!1),[f,m]=k.useState(!1),[w,S]=k.useState(!1),[T,b]=k.useState(!1),[E,N]=k.useState(!1),[O,R]=k.useState(!1),[H,_]=k.useState(140),[$,X]=k.useState(null),[B,I]=k.useState(null),[F,z]=k.useState(!1),[D,L]=k.useState(null),[U,V]=k.useState(null),[M,C]=k.useState(null),W=k.useRef(0);ky(H),k.useEffect(()=>{const A=()=>fetch("/api/heartbeat").catch(()=>{});A();const J=setInterval(A,1e4);return()=>clearInterval(J)},[]);const q=k.useRef(n==null?void 0:n.chrom);k.useEffect(()=>{n!=null&&n.chrom&&n.chrom!==q.current&&(q.current=n.chrom,x())},[n==null?void 0:n.chrom,x]);const le=new Set([".gb",".gbk",".genbank",".fasta",".fa"]),se=new Set([".bam",".bw",".bigwig",".wig",".bedgraph",".bdg",".vcf",".bed",".gtf",".gff",".gff2",".gff3"]),ce=new Set([".bai"]);function Te(A){if(!A)return"";if(A.toLowerCase().endsWith(".vcf.gz"))return".vcf.gz";const J=A.lastIndexOf(".");return J>=0?A.slice(J).toLowerCase():""}const Ce=k.useCallback(A=>{var J,K;A.preventDefault(),A.stopPropagation(),(K=(J=A.dataTransfer)==null?void 0:J.types)!=null&&K.includes("Files")&&(W.current++,W.current===1&&z(!0))},[]),ee=k.useCallback(A=>{var J,K;A.preventDefault(),A.stopPropagation(),(K=(J=A.dataTransfer)==null?void 0:J.types)!=null&&K.includes("Files")&&(W.current--,W.current<=0&&(W.current=0,z(!1)))},[]),ae=k.useCallback(A=>{A.preventDefault(),A.stopPropagation()},[]);function de(A){const J=A==null?void 0:A.compatibility;return J&&J.status!=="ok"&&J.status!=="no_genome"}const xe=k.useCallback(async A=>{var Ue,ct,Ga,Ya,Xa;if(A.preventDefault(),A.stopPropagation(),W.current=0,z(!1),!((ct=(Ue=A.dataTransfer)==null?void 0:Ue.types)!=null&&ct.includes("Files")))return;const J=Array.from(A.dataTransfer.files);if(!J.length)return;const K=[],te=[],ie=[],oe=[];for(const _e of J){const ze=Te(_e.name),yt=_e.name.toLowerCase();le.has(ze)?K.push(_e):se.has(ze)||ze===".vcf.gz"?te.push(_e):ce.has(ze)||yt.endsWith(".bam.bai")?ie.push(_e):oe.push(_e)}const ge=te.filter(_e=>_e.name.toLowerCase().endsWith(".bam")&&_e.size>50*1024*1024),we=ie.filter(_e=>_e.size>10*1024*1024);if(ge.length||we.length){const _e=[...ge,...we].map(yt=>yt.name).join(", "),ze=[...ge,...we].reduce((yt,Eo)=>yt+Eo.size,0)/(1024*1024);L({error:`${_e} (${ze.toFixed(0)} MB) — large files load faster via the Path button. Click 📂 Path in the toolbar and paste the file path instead of uploading.`}),setTimeout(()=>L(null),1e4);return}if(oe.length&&!K.length&&!te.length&&!ie.length){L({error:`Unsupported file${oe.length>1?"s":""}: ${oe.map(_e=>_e.name).join(", ")}`}),setTimeout(()=>L(null),4e3);return}try{if(K.length>0&&!t){L({msg:`Loading genome: ${K[0].name}...`});const ze=(await yn.load(K[0])).data;if(ze.name&&(ze.name=It(ze.name)),r(ze),((Ga=ze.chromosomes)==null?void 0:Ga.length)>0){const yt=ze.chromosomes[0];o(yt.name,0,Math.min(yt.length,5e4))}ze.is_annotated&&d({id:"genome_annotations",name:`${ze.name} (annotations)`,track_type:"genome_annotations",file_format:"genbank",targetChromosomes:ze.annotated_chromosomes||null})}else K.length>0&&t&&V({files:K});if(te.length>0){if(!t&&K.length===0){L({error:"Load a genome file first (.fasta, .gb, .genbank)"}),setTimeout(()=>L(null),4e3);return}L({msg:`Loading ${te.length} track${te.length>1?"s":""}...`});const _e=[],ze=[],yt=[];for(const Eo of te)try{const Cn=await u(Eo,void 0);de(Cn)?ze.push(Cn):(c(Cn),_e.push(Cn))}catch(Cn){yt.push(`${Eo.name}: ${((Xa=(Ya=Cn.response)==null?void 0:Ya.data)==null?void 0:Xa.detail)||Cn.message}`)}if(yt.length){L({error:yt.join("; ")}),setTimeout(()=>L(null),5e3);return}ze.length>0&&C({tracks:ze})}oe.length?(L({error:`Skipped unsupported: ${oe.map(_e=>_e.name).join(", ")}`}),setTimeout(()=>L(null),4e3)):(L({msg:"Files loaded"}),setTimeout(()=>L(null),2e3))}catch(_e){L({error:_e.message||"Drop failed"}),setTimeout(()=>L(null),5e3)}},[t,r,o,a,d]),ve=k.useCallback(async()=>{var J,K;if(!U)return;const A=U.files;V(null);try{const te=[];for(const ie of A){L({msg:`Adding chromosomes from ${ie.name}...`});try{const ge=(await yn.addChromosomes(ie)).data;ge.name&&(ge.name=It(ge.name)),r(ge),ge.is_annotated&&d({id:"genome_annotations",name:`${ge.name} (annotations)`,track_type:"genome_annotations",file_format:"genbank",targetChromosomes:ge.annotated_chromosomes||null})}catch(oe){te.push(`${ie.name}: ${((K=(J=oe.response)==null?void 0:J.data)==null?void 0:K.detail)||oe.message}`)}}te.length?(L({error:te.join("; ")}),setTimeout(()=>L(null),5e3)):(L({msg:`Added chromosomes from ${A.length} file${A.length>1?"s":""}`}),setTimeout(()=>L(null),3e3))}catch(te){L({error:te.message||"Failed to add chromosomes"}),setTimeout(()=>L(null),5e3)}},[U,r,d]),Ae=k.useCallback(async()=>{var J,K;if(!U)return;const A=U.files;V(null);try{L({msg:`Loading ${A.length} track${A.length>1?"s":""}...`});const te=[];for(const ie of A)try{await a(ie,void 0)}catch(oe){te.push(`${ie.name}: ${((K=(J=oe.response)==null?void 0:J.data)==null?void 0:K.detail)||oe.message}`)}te.length?(L({error:te.join("; ")}),setTimeout(()=>L(null),5e3)):(L({msg:`Added ${A.length} track${A.length>1?"s":""}`}),setTimeout(()=>L(null),3e3))}catch(te){L({error:te.message||"Failed to load tracks"}),setTimeout(()=>L(null),5e3)}},[U,a]),pe=k.useCallback(async()=>{if(M){for(const A of M.tracks)await g(A.id);C(null)}},[M,g]),Ne=k.useCallback(()=>{if(M){for(const A of M.tracks)c(A);C(null),L({msg:`Added ${M.tracks.length} track${M.tracks.length>1?"s":""}`}),setTimeout(()=>L(null),3e3)}},[M,c]),Y=k.useCallback(A=>{A.preventDefault();const J=A.clientX,K=H;function te(oe){_(Math.max(60,Math.min(400,K+(oe.clientX-J))))}function ie(){window.removeEventListener("mousemove",te),window.removeEventListener("mouseup",ie),document.body.style.cursor="",document.body.style.userSelect=""}document.body.style.cursor="ew-resize",document.body.style.userSelect="none",window.addEventListener("mousemove",te),window.addEventListener("mouseup",ie)},[H]);k.useEffect(()=>{if(!j.current)return;const A=new ResizeObserver(J=>{for(const K of J)y(K.contentRect.width)});return A.observe(j.current),()=>A.disconnect()},[]);const Z=k.useCallback(A=>A.visible?!A.targetChromosomes||!(n!=null&&n.chrom)?!0:A.targetChromosomes.includes(n.chrom):!1,[n==null?void 0:n.chrom]),ne={app:{display:"flex",flexDirection:"column",height:"100vh",background:e.appBg,color:e.textPrimary},header:{background:e.headerBg,borderBottom:`2px solid ${e.borderAccent}`,padding:"8px 16px",display:"flex",alignItems:"center",justifyContent:"space-between"},headerLeft:{display:"flex",alignItems:"center",gap:12},title:{fontSize:18,fontWeight:700,color:e.textPrimary,letterSpacing:1},subtitle:{fontSize:11,color:e.textTertiary},headerBtns:{display:"flex",gap:8},btn:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 14px",cursor:"pointer",fontSize:12,fontWeight:600,display:"flex",alignItems:"center",gap:6},trackArea:{flex:1,overflowY:"auto",overflowX:"hidden",display:"flex",flexDirection:"column"},emptyState:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",flex:1,color:e.textMuted,gap:12},emptyTitle:{fontSize:22,fontWeight:300},emptyHint:{fontSize:13}};return s.jsxs("div",{style:ne.app,onDragEnter:Ce,onDragLeave:ee,onDragOver:ae,onDrop:xe,children:[s.jsxs("div",{style:ne.header,children:[s.jsxs("div",{style:ne.headerLeft,children:[s.jsx(Dc,{size:34}),s.jsxs("div",{children:[s.jsx("div",{style:ne.title,children:"BiNgo Genome Viewer"}),t&&s.jsxs("div",{style:ne.subtitle,children:[t.name," · ",t.chromosomes.length," chr"]})]}),s.jsxs("button",{onClick:()=>N(!0),title:"About / References",style:{background:"none",border:`1px solid ${e.border}`,borderRadius:10,padding:"2px 8px",display:"flex",alignItems:"center",gap:4,cursor:"pointer",color:e.textSecondary,fontSize:11,fontWeight:600,lineHeight:1,flexShrink:0},onMouseEnter:A=>{A.currentTarget.style.color=e.textPrimary,A.currentTarget.style.borderColor=e.textSecondary},onMouseLeave:A=>{A.currentTarget.style.color=e.textSecondary,A.currentTarget.style.borderColor=e.border},children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"currentColor",style:{flexShrink:0},children:[s.jsx("path",{d:"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"}),s.jsx("circle",{cx:"8",cy:"4.5",r:"1.2"}),s.jsx("rect",{x:"7",y:"6.5",width:"2",height:"5.5",rx:"0.8"})]}),"Info"]}),s.jsxs("button",{onClick:()=>R(!0),title:"Guided Tour",style:{background:"none",border:`1px solid ${e.border}`,borderRadius:10,padding:"2px 8px",display:"flex",alignItems:"center",gap:4,cursor:"pointer",color:e.textSecondary,fontSize:11,fontWeight:600,lineHeight:1,flexShrink:0},onMouseEnter:A=>{A.currentTarget.style.color=e.textPrimary,A.currentTarget.style.borderColor=e.textSecondary},onMouseLeave:A=>{A.currentTarget.style.color=e.textSecondary,A.currentTarget.style.borderColor=e.border},children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"currentColor",style:{flexShrink:0},children:[s.jsx("path",{d:"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"}),s.jsx("path",{d:"M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zM8 13.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"})]}),"Help"]})]}),s.jsxs("div",{style:ne.headerBtns,"data-tour":"header-btns",children:[s.jsxs("button",{style:ne.btn,onClick:()=>b(!0),title:"Save or restore a session",children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0},children:[s.jsx("path",{d:"M2 2h8v8H2z"}),s.jsx("path",{d:"M4 2v4h4V2"}),s.jsx("path",{d:"M5 3h2"})]}),"Save Session"]}),s.jsxs("button",{style:ne.btn,onClick:()=>m(!0),title:"Customize color theme",children:[s.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",style:{flexShrink:0},children:[s.jsx("rect",{x:"0",y:"0",width:"5.5",height:"5.5",rx:"1",fill:"#66bb6a"}),s.jsx("rect",{x:"6.5",y:"0",width:"5.5",height:"5.5",rx:"1",fill:"#42a5f5"}),s.jsx("rect",{x:"0",y:"6.5",width:"5.5",height:"5.5",rx:"1",fill:"#ffa726"}),s.jsx("rect",{x:"6.5",y:"6.5",width:"5.5",height:"5.5",rx:"1",fill:"#ab47bc"})]}),"Theme"]}),s.jsxs("button",{"data-tour":"btn-export",style:{...ne.btn,...n&&l.length>0?{}:{opacity:.35,cursor:"default"}},onClick:()=>{n&&l.length>0&&S(!0)},title:"Export current view as SVG or PNG",children:[s.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",style:{flexShrink:0},children:s.jsx("path",{d:"M6 1v7M3 5.5L6 8.5 9 5.5M2 11h8"})}),"Export Image"]}),s.jsxs("button",{"data-tour":"btn-settings",style:{...ne.btn,...l.length===0?{opacity:.35,cursor:"default"}:{}},onClick:()=>{l.length>0&&h(!0)},title:"Adjust height, scale, color, and bar width for tracks",children:["⚙"," Track Settings"]})]})]}),s.jsx(V0,{}),s.jsx(Ry,{}),s.jsxs("div",{style:ne.trackArea,ref:j,"data-tour":"track-area",children:[l.filter(Z).length===0&&s.jsx(ox,{theme:e,labelWidth:H}),t?n?s.jsxs(s.Fragment,{children:[s.jsxs("div",{style:{display:"flex"},children:[s.jsx("div",{style:{width:H,minWidth:H,background:e.panelBg,borderRight:`1px solid ${e.border}`,position:"relative"},children:s.jsx("div",{onMouseDown:Y,style:{position:"absolute",right:-3,top:0,bottom:0,width:6,cursor:"ew-resize",zIndex:10},onMouseEnter:A=>A.currentTarget.style.background="rgba(255,255,255,0.15)",onMouseLeave:A=>A.currentTarget.style.background="transparent"})}),s.jsx(Py,{width:v-H})]}),l.filter(Z).map(A=>s.jsx(Qy,{track:A,containerWidth:v,labelWidth:H,onLabelResizeStart:Y,isDragging:$===A.id,isDropTarget:B===A.id,onDragStart:()=>X(A.id),onDragOver:()=>I(A.id),onDrop:()=>{$&&$!==A.id&&i($,A.id),X(null),I(null)},onDragEnd:()=>{X(null),I(null)}},A.id)),l.length===0&&s.jsx("div",{style:{padding:24,color:e.textMuted,fontSize:13},children:"Add tracks above — BAM, VCF, BigWig, BED, GTF, GFF, WIG..."})]}):s.jsx("div",{style:ne.emptyState,children:s.jsx("div",{style:ne.emptyHint,children:"Select a chromosome to begin"})}):s.jsxs("div",{style:ne.emptyState,children:[s.jsx("div",{style:ne.emptyTitle,children:"No genome loaded"}),s.jsx("div",{style:ne.emptyHint,children:"Load a FASTA or GenBank file above to get started"})]})]}),p&&s.jsx(ty,{onClose:()=>h(!1)}),f&&s.jsx(iy,{onClose:()=>m(!1)}),w&&s.jsx(cy,{onClose:()=>S(!1)}),T&&s.jsx(Cy,{onClose:()=>b(!1),labelWidth:H,setLabelWidth:_}),O&&s.jsx(Ey,{onClose:()=>{R(!1),h(!1),m(!1)},theme:e,onAction:A=>{A==="open-settings"?(h(!0),m(!1)):A==="open-theme"?(m(!0),h(!1)):(h(!1),m(!1))}}),E&&s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},onClick:()=>N(!1),children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.border}`,borderRadius:8,padding:"28px 36px",maxWidth:520,maxHeight:"85vh",overflowY:"auto",color:e.textPrimary,lineHeight:1.7},onClick:A=>A.stopPropagation(),children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:16},children:[s.jsx(Dc,{size:44}),s.jsx("div",{style:{fontSize:20,fontWeight:700},children:"BiNgo Genome Viewer"})]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:12},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Version:"})," ",Ic]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:12},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Publisher:"})," Billy M Ngo"]}),s.jsxs("div",{style:{fontSize:13,color:e.textSecondary,marginBottom:20},children:[s.jsx("strong",{style:{color:e.textPrimary},children:"Published:"})," April 2026"]}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,background:e.canvasBg,border:`1px solid ${e.border}`,borderRadius:4,padding:"10px 14px",fontFamily:"monospace",lineHeight:1.6,marginBottom:20,userSelect:"all"},children:["Ngo, B.M. (2026). BiNgo Genome Viewer (v",Ic,") [Software]."]}),s.jsxs("details",{style:{marginBottom:20},children:[s.jsx("summary",{style:{cursor:"pointer",fontSize:13,fontWeight:600,color:e.textPrimary,marginBottom:8},children:"References & Acknowledgments"}),s.jsxs("div",{style:{fontSize:11,color:e.textSecondary,lineHeight:1.8,paddingTop:8},children:[s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginBottom:4},children:"Software Dependencies"}),s.jsxs("div",{children:[s.jsx("strong",{children:"FastAPI"})," ","—"," Ram","í","rez, S. (2018). A modern web framework for building APIs with Python."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"Uvicorn"})," ","—"," Encode OSS. ASGI server implementation for Python."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BioPython"})," ","—"," Cock, P.J.A. et al. (2009). ",s.jsx("em",{children:"Bioinformatics"}),", 25(11), 1422","–","1423."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"pyfaidx"})," ","—"," Shirley, M.D. et al. (2015). ",s.jsx("em",{children:"PeerJ PrePrints"}),", 3:e1196."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"bamnostic"})," ","—"," Sherman, M.A. & Mills, R.E. (2019). Pure Python BAM parser."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"React"})," ","—"," Meta Platforms, Inc. JavaScript UI library."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"Vite"})," ","—"," You, E. (2020). Next generation frontend tooling."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"File Format Specifications"}),s.jsxs("div",{children:[s.jsx("strong",{children:"SAM/BAM"})," ","—"," Li, H. et al. (2009). ",s.jsx("em",{children:"Bioinformatics"}),", 25(16), 2078","–","2079."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"VCF"})," ","—"," Danecek, P. et al. (2011). ",s.jsx("em",{children:"Bioinformatics"}),", 27(15), 2156","–","2158."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BigWig/WIG"})," ","—"," Kent, W.J. et al. (2010). ",s.jsx("em",{children:"Bioinformatics"}),", 26(17), 2204","–","2207."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"BED"})," ","—"," UCSC Genome Browser, UC Santa Cruz."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GFF3"})," ","—"," Sequence Ontology Project."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GTF"})," ","—"," Ensembl genome database project."]}),s.jsxs("div",{children:[s.jsx("strong",{children:"GenBank"})," ","—"," Benson, D.A. et al. (2013). ",s.jsx("em",{children:"Nucleic Acids Res."}),", 41(D1), D36","–","D42."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"Inspiration"}),s.jsxs("div",{children:[s.jsx("strong",{children:"IGV"})," ","—"," Robinson, J.T. et al. (2011). ",s.jsx("em",{children:"Nature Biotechnology"}),", 29(1), 24","–","26."]}),s.jsx("div",{style:{fontWeight:600,color:e.textPrimary,marginTop:12,marginBottom:4},children:"Acknowledgments"}),s.jsx("div",{children:"Early version testing and feedback:"}),s.jsx("div",{children:"Amanda Antoch, Isaac Poarch, Otto Chipashvili, Jake Colautti"})]})]}),s.jsx("div",{style:{textAlign:"right"},children:s.jsx("button",{onClick:()=>N(!1),style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 18px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Close"})})]})}),U&&(()=>{const A=U.files.length>1,J=U.files.map(K=>K.name).join(", ");return s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:"20px 24px",maxWidth:440,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},onClick:K=>K.stopPropagation(),children:[s.jsxs("div",{style:{fontSize:14,fontWeight:700,color:e.textPrimary,marginBottom:8},children:["Genome file",A?"s":""," detected"]}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,lineHeight:1.6,marginBottom:16},children:[s.jsx("strong",{style:{color:e.textPrimary},children:J}),A?" appear to be genome files. A genome is already loaded.":" appears to be a genome file. A genome is already loaded.",s.jsx("br",{}),"How would you like to handle ",A?"them":"it","?"]}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",flexWrap:"wrap"},children:[s.jsx("button",{onClick:()=>V(null),style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Skip"}),s.jsxs("button",{onClick:Ae,style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:["Add as Track",A?"s":""]}),s.jsxs("button",{onClick:ve,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:["Add as Chromosome",A?"s":""]})]})]})})})(),M&&s.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:s.jsxs("div",{style:{background:e.panelBg,border:`1px solid ${e.borderAccent}`,borderRadius:8,padding:"20px 24px",maxWidth:480,width:"90%",boxShadow:"0 8px 32px rgba(0,0,0,0.5)"},onClick:A=>A.stopPropagation(),children:[s.jsx("div",{style:{fontSize:14,fontWeight:700,color:e.textPrimary,marginBottom:8},children:"Track compatibility warning"}),s.jsxs("div",{style:{fontSize:12,color:e.textSecondary,lineHeight:1.6,marginBottom:16},children:[M.tracks.map(A=>{var J;return s.jsxs("div",{style:{marginBottom:6},children:[s.jsx("strong",{style:{color:e.textPrimary},children:A.name})," — ",((J=A.compatibility)==null?void 0:J.message)||"Possible mismatch with loaded genome"]},A.id)}),s.jsx("div",{style:{marginTop:8},children:M.tracks.length>1?"These tracks may not match the loaded genome.":"This track may not match the loaded genome."})]}),s.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",flexWrap:"wrap"},children:[s.jsx("button",{onClick:pe,style:{background:e.btnBg,border:`1px solid ${e.borderStrong}`,borderRadius:4,color:e.btnText,padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Skip"}),s.jsx("button",{onClick:Ne,style:{background:"#1976d2",border:"none",borderRadius:4,color:"#fff",padding:"5px 16px",cursor:"pointer",fontSize:12,fontWeight:600},children:"Load Anyway"})]})]})}),F&&s.jsx("div",{style:{position:"fixed",inset:0,zIndex:9998,background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:s.jsxs("div",{style:{border:`3px dashed ${e.textSecondary}`,borderRadius:16,padding:"40px 60px",textAlign:"center"},children:[s.jsx("div",{style:{fontSize:28,fontWeight:300,color:e.textPrimary,marginBottom:8},children:"Drop files here"}),s.jsx("div",{style:{fontSize:13,color:e.textSecondary},children:"Genome (.gb, .fasta) or track files (.bam, .bw, .wig, .vcf, .bed, .gff, .gtf)"})]})}),D&&s.jsx("div",{style:{position:"fixed",bottom:20,left:"50%",transform:"translateX(-50%)",zIndex:10001,padding:"8px 20px",borderRadius:6,background:D.error?"#c62828":e.panelBg,border:`1px solid ${D.error?"#e53935":e.borderAccent}`,color:D.error?"#fff":"#81c784",fontSize:12,fontWeight:600,boxShadow:"0 4px 16px rgba(0,0,0,0.5)"},children:D.error||D.msg}),t&&s.jsx(tx,{labelWidth:H}),s.jsx(nx,{})]})}function ix(){return s.jsx(D0,{children:s.jsx(lm,{children:s.jsx(O0,{children:s.jsx(lx,{})})})})}Ui.createRoot(document.getElementById("root")).render(s.jsx(Vs.StrictMode,{children:s.jsx(ix,{})}));
@@ -10,7 +10,7 @@
10
10
  body { font-family: Arial, Helvetica, sans-serif; background: #1a1a1a; color: #e0e0e0; height: 100vh; overflow: hidden; }
11
11
  #root { height: 100vh; display: flex; flex-direction: column; }
12
12
  </style>
13
- <script type="module" crossorigin src="/assets/index-BC4ehCBT.js"></script>
13
+ <script type="module" crossorigin src="/assets/index-4OAJAWev.js"></script>
14
14
  </head>
15
15
  <body>
16
16
  <div id="root"></div>
@@ -73,26 +73,25 @@ def _install_windows(target_dir):
73
73
  ico_path = config_dir / "bingo_icon.ico"
74
74
  ico_path.write_bytes(generate_ico())
75
75
 
76
- # Create a VBScript launcher that runs python hidden (no console flash)
77
- # This avoids pythonw.exe issues (no stdout crashes) while hiding the window
76
+ # Create a batch launcher that runs python with minimized window
78
77
  python_exe = sys.executable
79
- vbs_path = config_dir / "launch_bingo.vbs"
80
- vbs_path.write_text(
81
- f'Set ws = CreateObject("WScript.Shell")\n'
82
- f'ws.Run """{python_exe}"" -m bingoviewer --no-update", 0, False\n'
78
+ bat_path = config_dir / "launch_bingo.bat"
79
+ bat_path.write_text(
80
+ '@echo off\n'
81
+ f'start /min "" "{python_exe}" -m bingoviewer --no-update\n'
83
82
  )
84
83
 
85
84
  lnk_path = target_dir / f"{_APP_NAME}.lnk"
86
85
 
87
- # PowerShell one-liner to create a .lnk pointing to the VBS launcher
86
+ # PowerShell one-liner to create a .lnk pointing to the batch launcher
88
87
  ps_script = (
89
88
  "$ws = New-Object -ComObject WScript.Shell; "
90
89
  f"$s = $ws.CreateShortcut('{lnk_path}'); "
91
- f"$s.TargetPath = 'wscript.exe'; "
92
- f"$s.Arguments = '\"{vbs_path}\"'; "
90
+ f"$s.TargetPath = '{bat_path}'; "
93
91
  f"$s.IconLocation = '{ico_path},0'; "
94
92
  f"$s.Description = '{_APP_NAME}'; "
95
93
  f"$s.WorkingDirectory = '{Path.home()}'; "
94
+ "$s.WindowStyle = 7; " # 7 = minimized
96
95
  "$s.Save()"
97
96
  )
98
97
 
@@ -24,7 +24,7 @@ from api.genome import router as genome_router
24
24
  from api.tracks import router as tracks_router
25
25
  from api.data import router as data_router
26
26
 
27
- app = FastAPI(title="BiNgo Genome Viewer API", version="2.7.2")
27
+ app = FastAPI(title="BiNgo Genome Viewer API", version="2.7.3")
28
28
 
29
29
  app.add_middleware(
30
30
  CORSMiddleware,
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "BiNgoViewer"
7
- version = "2.7.2"
7
+ version = "2.7.3"
8
8
  description = "BiNgo Genome Viewer — a lightweight browser-based genomics viewer"
9
9
  readme = "README.md"
10
10
  license = {text = "Proprietary"}
File without changes
File without changes