@apollo-annotation/jbrowse-plugin-apollo 0.1.5 → 1.2.3
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.
- package/dist/index.esm.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/package.json +4 -4
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@apollo-annotation/apollo-common"),t=require("@apollo-annotation/apollo-shared"),n=require("@jbrowse/core/configuration"),a=require("@jbrowse/core/pluggableElementTypes"),o=require("@jbrowse/core/Plugin"),r=require("@jbrowse/core/util"),s=require("@mui/icons-material/Add"),l=require("mobx"),i=require("mobx-state-tree"),c=require("socket.io-client"),u=require("@gmod/gff"),d=require("nanoid"),f=require("@mui/icons-material/Link"),m=require("@mui/material"),g=require("@mui/material/InputAdornment"),p=require("@mui/material/LinearProgress"),h=require("bson-objectid"),y=require("react"),b=require("@jbrowse/core/ui"),w=require("@mui/icons-material/Close"),S=require("mobx-react"),v=require("tss-react/mui"),E=require("@jbrowse/core/util/types/mst"),C=require("jsonpath"),x=require("@jbrowse/core/util/io"),F=require("fast-deep-equal/es6"),A=require("idb/with-async-ittr"),D=require("file-saver"),k=require("@mui/material/Checkbox"),N=require("@mui/material/FormControlLabel"),R=require("@mui/icons-material/Delete"),M=require("@mui/x-data-grid"),T=require("@mui/material/utils"),L=require("autosuggest-highlight/match"),I=require("autosuggest-highlight/parse"),P=require("@mui/icons-material/AccountCircle"),q=require("@jbrowse/core/pluggableElementTypes/AdapterType"),_=require("@jbrowse/core/data_adapters/BaseAdapter"),U=require("@jbrowse/core/util/rxjs"),O=require("@jbrowse/core/util/simpleFeature"),B=require("@jbrowse/core/TextSearch/BaseResults"),j=require("@apollo-annotation/apollo-mst"),$=require("@mui/icons-material/Clear"),G=require("@mui/icons-material/UnfoldLess"),W=require("@jbrowse/core/util/tracks"),H=require("@mui/icons-material/ExpandLess"),z=require("@mui/icons-material/ExpandMore"),V=require("@mui/icons-material/Error");function J(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function X(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var a=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,a.get?a:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,t}var Y=J(o),K=J(s),Z=J(u),Q=J(f),ee=J(g),te=J(p),ne=J(h),ae=J(y),oe=X(y),re=J(w),se=J(C),le=J(F),ie=J(k),ce=J(N),ue=J(R),de=J(L),fe=J(I),me=J(P),ge=J(q),pe=J(O),he=J(B),ye=J($),be=J(G),we=J(H),Se=J(z),ve=J(V);const Ee=n.ConfigurationSchema("ApolloInternetAccount",{baseURL:{description:"Location of Apollo server",type:"string",defaultValue:""},tokenType:{description:"A custom name for a token to include in the header",type:"string",defaultValue:"Bearer"}},{baseConfiguration:a.BaseInternetAccountConfig,explicitlyTyped:!0});async function Ce(e,t,n){const a=Z.default.parseStringSync(t,{parseSequences:!0,parseComments:!0,parseDirectives:!1,parseFeatures:!0});if(0===a.length)throw new Error("No features found in GFF3 file");let o=0,r=n.assemblies.get(e);r||(r=n.addAssembly(e));for(const e of a)if(Array.isArray(e)){const t=Fe(e),n=r.refSeqs.get(t.refSeq)??r.addRefSeq(t.refSeq,t.refSeq);n.features.has(t._id)||n.addFeature(t)}else if("comment"in e)r.addComment(e.comment);else{o++;let t=r.refSeqs.get(e.id);t||(t=r.addRefSeq(e.id,e.id,e.description)),e.description&&!t.description&&t.setDescription(e.description),t.addSequence({start:0,stop:e.sequence.length,sequence:e.sequence})}if(0===o)throw new Error("No embedded FASTA section found in GFF3");const s=await xe(r);return n.addCheckResults(s),r}async function xe(t){const n=[];for(const a of t.refSeqs.values())for(const t of a.features.values())for(const o of e.checkRegistry.getChecks().values()){const e=await o.checkFeature(i.getSnapshot(t),(async(e,t)=>a.getSequence(e,t)));n.push(...e)}return n}function Fe(e){const[t]=e,{attributes:n,child_features:a,end:o,phase:r,score:s,seq_id:l,source:i,start:c,strand:u,type:f}=t;if(!l)throw new Error(`feature does not have seq_id: ${JSON.stringify(t)}`);if(!f)throw new Error(`feature does not have type: ${JSON.stringify(t)}`);if(null===c)throw new Error(`feature does not have start: ${JSON.stringify(t)}`);if(null===o)throw new Error(`feature does not have end: ${JSON.stringify(t)}`);const m={_id:d.nanoid(),gffId:"",refSeq:l,type:f,start:c-1,end:o};if(e.length>1&&(m.discontinuousLocations=e.map((e=>{const{end:t,phase:n,start:a}=e;if(null===a||null===t)throw new Error(`feature does not have start and/or end: ${JSON.stringify(e)}`);let o;if(n)switch(n){case"0":o=0;break;case"1":o=1;break;case"2":o=2;break;default:throw new Error(`Unknown phase: "${n}"`)}return{start:a-1,end:t,phase:o}}))),u)if("+"===u)m.strand=1;else{if("-"!==u)throw new Error(`Unknown strand: "${u}"`);m.strand=-1}if(null!==s&&(m.score=s),r)switch(r){case"0":m.phase=0;break;case"1":m.phase=1;break;case"2":m.phase=2;break;default:throw new Error(`Unknown phase: "${r}"`)}if(a?.length){const e={};for(const t of a){const n=Fe(t);e[n._id]=n,n.gffId=n.attributes?._id?n.attributes?._id.toString():n._id}m.children=e}if(i??n){const e={};if(i&&(e.source=[i]),n)for(const[t,a]of Object.entries(n))if(a&&"parent"!==t.toLowerCase())switch(t){case"ID":e._id=a;break;case"Name":e.gff_name=a;break;case"Alias":e.gff_alias=a;break;case"Target":e.gff_target=a;break;case"Gap":e.gff_gap=a;break;case"Derives_from":e.gff_derives_from=a;break;case"Note":e.gff_note=a;break;case"Dbxref":e.gff_dbxref=a;break;case"Ontology_term":{const t=[],n=[];for(const e of a)e.startsWith("GO:")?t.push(e):n.push(e);t.length>0&&(e["Gene Ontology"]=t),n.length>0&&(e.gff_ontology_term=n);break}case"Is_circular":e.gff_is_circular=a;break;default:e[t.toLowerCase()]=a}m.attributes=e}return m}async function Ae(e,t){let n;try{n=await e.text()}catch{n=""}return`${t?`${t} — `:""}${e.status} ${e.statusText}${n?` (${n})`:""}`}const De=v.makeStyles()((e=>({dialogTitle:{background:e.palette.primary.main,color:e.palette.primary.contrastText,padding:e.spacing(2)},closeButton:{position:"absolute",right:e.spacing(1),top:e.spacing(1.5),color:e.palette.primary.contrastText}}))),ke=S.observer((function(e){const{classes:t}=De(),{handleClose:n,title:a,...o}=e;return ae.default.createElement(b.Dialog,{...o,header:ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogTitle,{className:t.dialogTitle},a),ae.default.createElement(m.IconButton,{"aria-label":"close",onClick:n,className:t.closeButton},ae.default.createElement(re.default,null)))})}));var Ne;function Re({changeManager:e,handleClose:a,session:o}){const{internetAccounts:r}=i.getRoot(o),{notify:s}=o,l=r.filter((e=>"ApolloInternetAccount"===e.type));if(0===l.length)throw new Error("No Apollo internet account found");const[c,u]=y.useState(""),[d,f]=y.useState(""),[g,p]=y.useState(!1),[h,b]=y.useState(null),[w,S]=y.useState(Ne.GFF3),[v,E]=y.useState(!0),[C,x]=y.useState(!1),[F,A]=y.useState(l[0]),[D,k]=y.useState(""),[N,R]=y.useState(""),[M,T]=y.useState(""),[L,I]=y.useState(!1);let P=!1;try{const e=new URL(D);"http:"!==e.protocol&&"https:"!==e.protocol||(P=!0)}catch{}let q=!1;try{const e=new URL(N);"http:"!==e.protocol&&"https:"!==e.protocol||(q=!0)}catch{}let _=!1;try{const e=new URL(M);"http:"!==e.protocol&&"https:"!==e.protocol||(_=!0)}catch{}return ae.default.createElement(ke,{open:!0,maxWidth:!1,"data-testid":"add-assembly-dialog",title:"Add new assembly",handleClose:a},L?ae.default.createElement(te.default,null):null,ae.default.createElement("form",{onSubmit:async function(n){n.preventDefault(),f(""),x(!0),I(!0),s(`Assembly "${c}" is being added`,"info"),a(),n.preventDefault();const{jobsManager:r}=o,l=new AbortController,i={name:`UploadAssemblyFile for ${c}`,statusMessage:"Pre-validating",progressPct:0,cancelCallback:()=>{l.abort(),r.abortJob(i.name)}};r.runJob(i);let u="";const{baseURL:d,getFetcher:m,internetAccountId:g}=F;if(w!==Ne.EXTERNAL&&h){const e=new URL("/files",d).href,t=new FormData;t.append("file",h),t.append("fileName",h.name),t.append("type",w);const n=m({locationType:"UriLocation",uri:e});if(n){r.update(i.name,"Uploading file, this may take awhile");const{signal:a}=l,o=await n(e,{method:"POST",body:t,signal:a});if(!o.ok){const e=await Ae(o,"Error when inserting new assembly (while uploading file)");return r.abortJob(i.name,e),void f(e)}u=(await o.json())._id}}let p;if(w===Ne.EXTERNAL)p=new t.AddAssemblyFromExternalChange({typeName:"AddAssemblyFromExternalChange",assembly:(new ne.default).toHexString(),assemblyName:c,externalLocation:{fa:D,fai:N,...M?{gzi:M}:{}}});else{const e={assembly:(new ne.default).toHexString(),assemblyName:c,fileId:u};p=w===Ne.GFF3&&v?new t.AddAssemblyAndFeaturesFromFileChange({typeName:"AddAssemblyAndFeaturesFromFileChange",...e}):new t.AddAssemblyFromFileChange({typeName:"AddAssemblyFromFileChange",...e})}r.done(i),await e.submit(p,{internetAccountId:g,updateJobsManager:!0}),x(!1),I(!1)}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},l.length>1?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogContentText,null,"Select account"),ae.default.createElement(m.Select,{value:F.internetAccountId,onChange:function(e){x(!1);const t=l.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);A(t)},disabled:C&&!d},r.map((e=>ae.default.createElement(m.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,ae.default.createElement(m.TextField,{margin:"dense",id:"name",label:"Assembly name",type:"TextField",fullWidth:!0,variant:"outlined",onChange:e=>{x(!1),u(e.target.value),function(e){const{assemblies:t}=o;t.find((t=>n.readConfObject(t,"displayName")===e))?(p(!1),f(`Assembly ${e} already exists.`)):(p(!0),f(""))}(e.target.value)},disabled:C&&!d}),ae.default.createElement(m.FormControl,{style:{marginTop:20}},ae.default.createElement(m.FormLabel,null,"Select GFF3, FASTA or EXTERNAL option"),ae.default.createElement(m.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:Ne.GFF3,name:"radio-buttons-group",onChange:function(e){S(e.target.value),E(e.target.value===Ne.GFF3),k(""),R(""),b(null)},value:w},ae.default.createElement(m.FormControlLabel,{value:Ne.GFF3,control:ae.default.createElement(m.Radio,null),label:"GFF3",disabled:C&&!d}),ae.default.createElement(m.FormControlLabel,{value:Ne.FASTA,control:ae.default.createElement(m.Radio,null),label:"FASTA",disabled:C&&!d}),ae.default.createElement(m.FormControlLabel,{value:Ne.EXTERNAL,control:ae.default.createElement(m.Radio,null),label:"External",disabled:C&&!d}))),w===Ne.EXTERNAL?ae.default.createElement(m.Box,{style:{marginTop:20}},ae.default.createElement(m.Typography,{variant:"caption"},"Enter FASTA and FASTA index(es) URL"),ae.default.createElement(m.TextField,{margin:"dense",helperText:"Can be bgz-compressed",id:"fasta",label:"FASTA",type:"TextField",fullWidth:!0,variant:"outlined",error:!P,onChange:e=>k(e.target.value),disabled:C&&!d,InputProps:{startAdornment:ae.default.createElement(ee.default,{position:"start"},ae.default.createElement(Q.default,null))}}),ae.default.createElement(m.TextField,{margin:"dense",id:"fasta-index",label:"FASTA Index",helperText:".fai or .gz.fai",type:"TextField",fullWidth:!0,variant:"outlined",error:!q,onChange:e=>R(e.target.value),disabled:C&&!d,InputProps:{startAdornment:ae.default.createElement(ee.default,{position:"start"},ae.default.createElement(Q.default,null))}}),ae.default.createElement(m.TextField,{margin:"dense",id:"fasta-gzi-index",label:"FASTA GZI Index",helperText:"Only for bgz-compressed FASTA, .gz.gzi",type:"TextField",fullWidth:!0,variant:"outlined",error:Boolean(M)&&!_,onChange:e=>T(e.target.value),disabled:C&&!d,InputProps:{startAdornment:ae.default.createElement(ee.default,{position:"start"},ae.default.createElement(Q.default,null))}})):ae.default.createElement(m.Box,{style:{marginTop:20}},ae.default.createElement("input",{type:"file",onChange:function(e){if(!e.target.files)return;const t=e.target.files.item(0);b(t),t?.name.toLowerCase().endsWith(".fasta")??t?.name.toLowerCase().endsWith(".fna")??t?.name.toLowerCase().endsWith(".fa")?S(Ne.FASTA):(t?.name.toLowerCase().endsWith(".gff3")??t?.name.toLowerCase().endsWith(".gff"))&&S(Ne.GFF3)},disabled:C&&!d}),ae.default.createElement(m.FormGroup,null,ae.default.createElement(m.FormControlLabel,{control:ae.default.createElement(m.Checkbox,{checked:w===Ne.GFF3&&v,onChange:()=>E(!v),disabled:w!==Ne.GFF3||C&&!d}),label:"Also load features from GFF3 file"})))),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!g||!((c&&h)??(c&&D&&N&&P&&q))||C,variant:"contained",type:"submit"},C?"Submitting...":"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:a},"Cancel"))),d?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},d)):null)}!function(e){e.GFF3="text/x-gff3",e.FASTA="text/x-fasta",e.EXTERNAL="text/x-external"}(Ne||(Ne={}));const Me=new Set(["i","me","my","myself","we","our","ours","ourselves","you","your","yours","yourself","yourselves","he","him","his","himself","she","her","hers","herself","it","its","itself","they","them","their","theirs","themselves","what","which","who","whom","this","that","these","those","am","is","are","was","were","be","been","being","have","has","had","having","do","does","did","doing","a","an","the","and","but","if","or","because","as","until","while","of","at","by","for","with","about","against","between","into","through","during","before","after","above","below","to","from","up","down","in","out","on","off","over","under","again","further","then","once","here","there","when","where","why","how","all","any","both","each","few","more","most","other","some","such","no","nor","not","only","own","same","so","than","too","very","s","t","can","will","just","don","should","now",..."1234567890"]);function Te(e,t){for(const[n,a]of t.entries())if(e.startsWith(a))return e.replace(a,n);return e}const Le="$PREFIXED_ID";function Ie(e,t,n){return t===Le?[Te(e.id,n)]:se.default.query(e,t)}function Pe(e){return e.toLowerCase().split(/[^\d:A-Za-z]+/).filter((e=>e&&!Me.has(e)))}function*qe(e){for(const t of e)yield*Pe(t)}function*_e(e){for(const t of e)if("string"==typeof t)yield t;else if("object"==typeof t){const e=se.default.query(t,"$..*");yield*_e(e)}}function*Ue(e,t,n){for(const a of t){const t=Ie(e,a,n);if(t.length>0)for(const e of qe(_e(t)))yield[a,e]}}async function Oe(e,t,n){const a=await this.db,o=t??a.transaction(["nodes"]);r.checkAbortSignal(n);const s=[...Pe(e)],l=[],i=new Map;l.push(...s.map((async(e,t)=>{r.checkAbortSignal(n);const a=o.objectStore("nodes").index("full-text-words");for await(const o of a.iterate(IDBKeyRange.bound(e,`${e}`,!1,!1))){r.checkAbortSignal(n);const e=o.value,a=i.get(e.id)??[e,new Set];a[1].add(t),i.set(e.id,a)}}))),await Promise.all(l),r.checkAbortSignal(n);const c=[];for(const[,[e,t]]of i)r.checkAbortSignal(n),c.push(...Be(this.textIndexFields,e,t,s,this.prefixes));return c.sort(((e,t)=>t.score-e.score)),c.slice(0,this.options.maxSearchResults??this.DEFAULT_MAX_SEARCH_RESULTS)}function Be(e,t,n,a,o){const r=[...n].sort().map((e=>a[e])),s=r.map((e=>{const t=e.replaceAll(/[$()*+./?[\\\]^{|}-]/g,"\\$&");return new RegExp(`\\b${t}`,"gi")}));let l=[],i=0;for(const[n,r]of e.entries()){const c=new Set,u=e.length-n-1,d=[..._e(Ie(t,r.jsonPath,o))];for(const e of d){let n=0;const o=[];for(const[t,r]of s.entries())for(const s of e.matchAll(r)){n+=1+1*u,c.add(t);const r=s.index,l=a[t];void 0!==r&&(n+=.01*l.length,n+=l.length/e.length*100*.05,o.push({wordIndex:t,position:r}))}n+=100*c.size,i<n&&(i=n),o.sort(((e,t)=>e.position-t.position)),o.length>0&&l.push({term:t,field:r,str:e,score:n,wordMatches:o})}}l=l.filter((e=>e.score===i));for(const e of l){const{wordMatches:t}=e;for(let n=0;n<t.length-1;n++){const a=t[n],o=t[n+1],s=o.wordIndex-a.wordIndex;if(1===s||-1===s){e.score+=1,1===s&&(e.score+=1);const t=Math.abs(o.position-(a.position+r[a.wordIndex].length))-1;e.score-=.05*t}}}return l}function je(e){return"string"==typeof e.id}function $e(e){return"string"==typeof e.sub&&"string"==typeof e.pred&&"string"==typeof e.obj}function Ge(e){return Boolean(e.meta?.deprecated)}async function We(e){return A.openDB(e,2,{upgrade(e,t,n,a,o){if(t<2&&(e.objectStoreNames.contains("meta")&&e.deleteObjectStore("meta"),e.objectStoreNames.contains("nodes")&&e.deleteObjectStore("nodes"),e.objectStoreNames.contains("edges")&&e.deleteObjectStore("edges")),e.objectStoreNames.contains("meta")||e.createObjectStore("meta"),!e.objectStoreNames.contains("nodes")){e.createObjectStore("nodes",{keyPath:"id"});const t=a.objectStore("nodes");t.createIndex("by-label","lbl"),t.createIndex("by-type","type"),t.createIndex("by-synonym",["meta","synonyms","val"]),t.createIndex("full-text-words","fullTextWords",{multiEntry:!0})}if(!e.objectStoreNames.contains("edges")){e.createObjectStore("edges",{autoIncrement:!0});const t=a.objectStore("edges");t.createIndex("by-subject","sub"),t.createIndex("by-object","obj"),t.createIndex("by-predicate","pred")}}})}function He(e){const t=new Set;for(const[,n]of e)t.add(n);return[...t]}async function ze(e){const t=Date.now(),n=JSON.parse(await x.openLocation(this.sourceLocation).readFile("utf8")),a=Date.now(),[o,...r]=n.graphs??[];if(o){if(r.length>0)throw new Error("multiple graphs not supported");try{const n=e.transaction(["meta","nodes","edges"],"readwrite");await n.objectStore("meta").clear(),await n.objectStore("nodes").clear(),await n.objectStore("edges").clear();const r=n.objectStore("nodes"),s=Ve.call(this).map((e=>e.jsonPath));for(const e of o.nodes??[])je(e)&&await r.add({...e,fullTextWords:He(Ue(e,s,this.prefixes))});const l=n.objectStore("edges");for(const e of o.edges??[])$e(e)&&await l.add(e);await n.done;const i=e.transaction("meta","readwrite");await i.objectStore("meta").add({ontologyRecord:{name:this.ontologyName,version:this.ontologyVersion,sourceLocation:this.sourceLocation},storeOptions:this.options,graphMeta:o.meta,timestamp:String(new Date),schemaVersion:2,timings:{overall:Date.now()-t,load:Date.now()-a}},"meta"),await i.done}catch(t){throw await e.transaction("meta","readwrite").objectStore("meta").clear(),t}}}function Ve(){return[{displayName:"ID",jsonPath:Le},...this.options.textIndexing?.indexFields??Ze]}async function Je(e){const[t]=await e.transaction("meta").objectStore("meta").getAll();return!!t&&le.default(this.options.prefixes,t.storeOptions?.prefixes)&&le.default(this.options.textIndexing,t.storeOptions?.textIndexing)}class Xe{ontologyName;ontologyVersion;sourceLocation;db;options;loadOboGraphJson=ze;getTermsByFulltext=Oe;openDatabase=We;isDatabaseCurrent=Je;get textIndexFields(){return Ve.call(this)}get prefixes(){return this.options.prefixes??new Map}DEFAULT_MAX_SEARCH_RESULTS=100;constructor(e,t,n,a){this.ontologyName=e,this.ontologyVersion=t,this.sourceLocation=n,this.db=this.prepareDatabase(),this.options=a??{}}validate(){const e=[],{sourceLocation:t,sourceType:n}=this;return n?"obo-graph-json"!==n&&e.push(new Error(`ontology source file ${JSON.stringify(t)} has type ${n}, which is not yet supported`)):e.push(new Error(`unable to determine format of ontology source file ${JSON.stringify(t)}, file name must end with ".json", ".obo", or ".owl"`)),e}get sourceType(){if(r.isUriLocation(this.sourceLocation)){if(this.sourceLocation.uri.endsWith(".json"))return"obo-graph-json"}else if("object"==typeof(e=this.sourceLocation)&&null!==e&&"localPath"in e&&this.sourceLocation.localPath.endsWith(".json"))return"obo-graph-json";var e}get dbName(){return`Apollo Ontology "${this.ontologyName}" "${this.ontologyVersion}"`}async prepareDatabase(){const e=this.validate();if(e.length>0)throw e;const t=await this.openDatabase(this.dbName);if(await this.isDatabaseCurrent(t))return t;const{sourceLocation:n,sourceType:a}=this;if("obo-graph-json"!==a)throw new Error(`ontology source file ${JSON.stringify(n)} has type ${a}, which is not yet supported`);return await this.loadOboGraphJson(t),t}async termCount(e){const t=await this.db;return(e??t.transaction("nodes")).objectStore("nodes").count()}async unique(e){const t=new Map,n=[];for(const a of e)t.has(a.id)||(t.set(a.id,!0),n.push(a));return n}async getTermsWithLabelOrSynonym(e,t,n){const a=t?.includeSubclasses??!0,o=await this.db,r=n??o.transaction(["nodes","edges"]),s=r.objectStore("nodes"),l=[...await s.index("by-label").getAll(e),...await s.index("by-synonym").getAll(e)];if(a){const e=await this.recurseEdges("by-object",l.map((e=>e.id)),(e=>"is_a"===e.pred),"sub",r);for(const t of e){const e=await s.get(t);e&&l.push(e)}}return l}async getPropertiesByLabel(e,t,n){const a=t?.includeSubProperties??!0,o=await this.db,r=n??o.transaction(["nodes","edges"]),s=(await this.getTermsWithLabelOrSynonym(e,{includeSubclasses:!1},r)).filter((e=>tt(e)));if(a){const e=await this.recurseEdges("by-object",s.map((e=>e.id)),(e=>"subPropertyOf"===e.pred),"sub",r),t=r.objectStore("nodes");for(const n of e){const e=await t.get(n);e&&tt(e)&&s.push(e)}}return s}async recurseEdges(e,t,n,a,o){const r=new Set;return await async function t(s){await Promise.all([...s].map((async s=>{const l=(await o.objectStore("edges").index(e).getAll(s)).filter((e=>n(e))).map((e=>e[a]));if(l.length>0){for(const e of l)r.add(e);await t(l)}})))}(t),r.values()}async*expandNodeSet(e,t="is_a",n,a){const o=await this.db,r=a??o.transaction(["edges"]),s=[...e],l=await this.recurseEdges("subclasses"===n?"by-object":"by-subject",s,(e=>e.pred===t),"subclasses"===n?"sub":"obj",r);for(const e of s)yield e;for(const e of l)yield e}expandSubclasses(e,t="is_a",n){return this.expandNodeSet(e,t,"subclasses",n)}expandSuperclasses(e,t="is_a",n){return this.expandNodeSet(e,t,"superclasses",n)}async getClassesThat(e,t,n){const a=await this.db,o=n??a.transaction(["nodes","edges"]),r=await this.getPropertiesByLabel(e,{includeSubProperties:!0},o),s=new Set(r.map((e=>e.id))),l=await async function(e){const t=[];for await(const n of e)t.push(n);return t}(this.expandSuperclasses(t.map((e=>e.id)),"is_a",o)),i=await this.recurseEdges("by-object",l,(e=>s.has(e.pred)),"sub",o),c=this.expandSubclasses(i,"is_a",o),u=[];for await(const e of c){const t=await o.objectStore("nodes").get(e);t&&et(t)&&!Ge(t)&&u.push(t)}return u}async getClassesWithoutPropertyLabeled(e,t,n){const a=await this.db,o=n??a.transaction(["nodes","edges"]),r=o.objectStore("nodes"),s=o.objectStore("edges"),l=(await this.getPropertiesByLabel(e,t,o)).map((e=>e.id)),i=await(async()=>{const e=new Set;for(const t of l)for await(const n of s.index("by-predicate").iterate(t))e.add(n.value.sub);const t=new Set;for await(const n of this.expandSubclasses(e,"is_a",o))t.add(n);return t})(),c=[];for await(const e of r){const t=e.value;et(t)&&!i.has(t.id)&&c.push(t.id)}const u=[];for await(const e of c){const t=await o.objectStore("nodes").get(e);t&&et(t)&&!Ge(t)&&u.push(t)}return u}async getAllClasses(e){const t=await this.db,n=e??t.transaction(["nodes"]);return(await n.objectStore("nodes").index("by-type").getAll("CLASS")).filter((e=>!Ge(e)))}async getAllTerms(e){const t=await this.db,n=e??t.transaction(["nodes"]);return(await n.objectStore("nodes").getAll()).filter((e=>!Ge(e)))}}const Ye=i.types.model("OntologyRecord",{name:i.types.string,version:"unversioned",source:i.types.union(E.LocalPathLocation,E.UriLocation,E.BlobLocation),options:i.types.frozen()}).volatile((e=>({dataStore:void 0}))).actions((e=>({ping(){},initDataStore(){e.dataStore=new Xe(e.name,e.version,i.getSnapshot(e.source),e.options)},afterCreate(){i.addDisposer(e,l.autorun((()=>{this.initDataStore()})))}}))),Ke=i.types.model("OntologyManager",{ontologies:i.types.array(Ye),prefixes:i.types.optional(i.types.map(i.types.string),{"GO:":"http://purl.obolibrary.org/obo/GO_","SO:":"http://purl.obolibrary.org/obo/SO_"})}).views((e=>({get featureTypeOntology(){return this.findOntology("Sequence Ontology")},findOntology:(t,n)=>e.ontologies.find((e=>e.name===t&&(void 0===n||e.version===n))),openOntology(e,t){return this.findOntology(e,t)?.dataStore},applyPrefixes:t=>Te(t,e.prefixes),expandPrefixes:t=>function(e,t){for(const[n,a]of t.entries())if(e.startsWith(n))return e.replace(n,a);return e}(t,e.prefixes)}))).actions((e=>({addOntology(t,n,a,o){const r=e.ontologies.push({name:t,version:n,source:a,options:{prefixes:new Map(e.prefixes.entries()),...o}});e.ontologies[r-1].ping()}}))),Ze=[{displayName:"Label",jsonPath:"$.lbl"},{displayName:"Synonym",jsonPath:"$.meta.synonyms[*].val"},{displayName:"Definition",jsonPath:"$.meta.definition.val"}],Qe=n.ConfigurationSchema("OntologyRecord",{name:{type:"string",description:'the full name of the ontology, e.g. "Gene Ontology"',defaultValue:"My Ontology"},version:{type:"string",description:"the ontology's version string",defaultValue:"unversioned"},source:{type:"fileLocation",description:"the download location for the ontology's source file",defaultValue:{locationType:"UriLocation",uri:"http://example.com/myontology.json"}},textIndexFields:{type:"frozen",description:"JSON paths for text fields that will be indexed for text searching",defaultValue:Ze}});function et(e){return"CLASS"===e.type}function tt(e){return"PROPERTY"===e.type}async function nt(e,t,n){if(!e)return;const a=await t.getTermsWithLabelOrSynonym(e.type,{includeSubclasses:!1}),o=a.filter(et);if(0===a.length)return;const r=await t.getClassesThat("part_of",o);return 0!==r.length?r:void 0}function at({fetchValidTerms:e,filterTerms:t,includeDeprecated:n,onChange:a,ontologyName:o,ontologyVersion:s,renderInput:l,session:i,style:c,value:u}){const[d,f]=y.useState(!1),[g,p]=y.useState(),[h,b]=y.useState(""),[w,S]=y.useState(),v=i.apolloDataStore.ontologyManager,E=v.findOntology(o,s)?.dataStore,C=E&&d&&!g,x=E&&!w,F=y.useCallback((e=>(n||!Ge(e))&&(!t||t(e))),[t,n]);y.useEffect((()=>{d||p(void 0)}),[d]),y.useEffect((()=>{const e=new AbortController,{signal:t}=e;return x&&(b(""),async function(e,t,n,a){if(!t)return;const o=(await e.getTermsWithLabelOrSynonym(t,{includeSubclasses:!1})).find(n??(()=>!0));if(!o)throw new Error(`not a valid ${e.ontologyName} term`);return o}(E,u,F).then((e=>{t.aborted||S(e)}),(e=>{t.aborted||r.isAbortException(e)||b(String(e))}))),()=>{e.abort()}}),[i,u,F,E,x]),y.useEffect((()=>{const t=new AbortController,{signal:n}=t;return C&&async function(e,t,n,a){let o;if(t){const n=await t(e,a);n&&(o=n)}return o||(o=await e.getAllTerms()),n?o.filter((e=>n(e))):o}(E,e,F,n).then((e=>{e&&!n.aborted&&p(e)}),(e=>{n.aborted||r.isAbortException(e)||i.notify(e.message,"error")})),()=>{t.abort()}}),[C,F,E,i,e]);const A={};return h&&(A.error=!0,A.helperText=h),ae.default.createElement(m.Autocomplete,{style:c,autoComplete:!0,filterSelectedOptions:!0,disableClearable:!0,selectOnFocus:!0,clearOnBlur:!0,handleHomeEndKeys:!0,freeSolo:!0,value:u,options:g??[],onOpen:()=>{f(!0)},onClose:()=>{f(!1)},loading:C,renderInput:l??(e=>ae.default.createElement(m.TextField,{...e,...A})),getOptionLabel:e=>"string"==typeof e?e:e.lbl??"",isOptionEqualToValue:(e,t)=>e.lbl===t.lbl,onChange:async(e,t)=>{t&&("string"==typeof t?(S(void 0),a(u,t)):t.lbl!==u&&(b(""),S(t),a(u,t.lbl)))}})}var ot;function rt({changeManager:e,handleClose:n,session:a,sourceAssemblyId:o,sourceFeature:r}){const{notify:s}=a,[l,i]=y.useState(String(r.end)),[c,u]=y.useState(String(r.start+1)),[d,f]=y.useState(""),[g,p]=y.useState(""),[h,b]=y.useState(),[w,S]=y.useState(!1),[v,E]=y.useState(""),[C,x]=y.useState(""),F=Number(l)<=Number(c);return ae.default.createElement(ke,{open:!0,title:"Add new child feature",handleClose:n,maxWidth:!1,"data-testid":"add-feature-dialog"},ae.default.createElement("form",{onSubmit:async function(a){if(a.preventDefault(),E(""),w&&""===g)return void E("The phase is REQUIRED for all CDS features.");const i=new t.AddFeatureChange({changedIds:[r._id],typeName:"AddFeatureChange",assembly:o,addedFeature:{_id:(new ne.default).toHexString(),gffId:"",refSeq:r.refSeq,start:Number(c)-1,end:Number(l),type:d,phase:h},parentFeatureId:r._id});await(e.submit?.(i)),s("Feature added successfully","success"),n(),a.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.TextField,{margin:"dense",id:"start",label:"Start",type:"number",fullWidth:!0,variant:"outlined",value:c,onChange:e=>u(e.target.value)}),ae.default.createElement(m.TextField,{margin:"dense",id:"end",label:"End",type:"number",fullWidth:!0,variant:"outlined",value:l,onChange:e=>i(e.target.value),error:F,helperText:F?'"End" must be greater than "Start"':null}),ae.default.createElement(at,{session:a,ontologyName:"Sequence Ontology",style:{width:170},value:d,filterTerms:et,fetchValidTerms:async function(e,t,n){const a=await nt(e,t);if(a)return a;x(`Type "${e?.type}" does not have any children in the ontology`)}.bind(null,r),renderInput:e=>ae.default.createElement(m.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0,error:Boolean(C),helperText:C}),onChange:(e,t)=>{var n;t&&(n=t,E(""),f(n),n.startsWith("CDS")?(S(!0),p("")):S(!1))}}),w?ae.default.createElement(m.FormControl,null,ae.default.createElement(m.InputLabel,null,"Phase"),ae.default.createElement(m.Select,{value:g,onChange:async function(e){switch(E(""),p(e.target.value),Number(e.target.value)){case 0:b(ot.zero);break;case 1:b(ot.one);break;case 2:b(ot.two);break;default:b(void 0)}}},ae.default.createElement(m.MenuItem,{value:0},"0"),ae.default.createElement(m.MenuItem,{value:1},"1"),ae.default.createElement(m.MenuItem,{value:2},"2"))):null),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit",disabled:F||!(c&&l&&d)},"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),v?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},v)):null)}function st(e,t){const n=(new ne.default).toHexString();t.push(n);const a={};if(e.children)for(const n of Object.values(e.children)){const e=st(n,t);a[e._id]=e}const o="string"==typeof e.refSeq?e.refSeq:e.refSeq.toHexString();return{...e,refSeq:o,children:e.children&&a,_id:n}}function lt({changeManager:e,handleClose:a,session:o,sourceAssemblyId:r,sourceFeature:s}){const{assemblyManager:l,notify:c}=o,u=l.assemblyList,[d,f]=y.useState(u.find((e=>e.name!==r))?.name),[g,p]=y.useState([]),[h,b]=y.useState(""),[w,S]=y.useState(s.start),[v,E]=y.useState("");function C(e,t){const n={};if(e.children)for(const a of Object.values(e.children)){const e=C(a,t);ne.default.isValid(e.gffId.toString())&&(e.gffId=e._id),e.refSeq=h,e.start=e.start+t,e.end=e.end+t,n[e._id]=e}const a="string"==typeof e.refSeq?e.refSeq:e.refSeq.toHexString(),o="string"==typeof e._id?e._id:e._id.toHexString();return{...e,refSeq:a,children:e.children&&n,_id:o}}return y.useEffect((()=>{b(""),async function(){if(!d)return void E("No assemblies to copy to");const e=await l.waitForAssembly(d);if(!e)return;const{refNameAliases:t}=e;if(!t)return;const n=[...Object.entries(t)].filter((([e,t])=>e!==t)).map((([e,t])=>({_id:e,name:t??""})));p(n),b(n[0]?._id||"")}().catch((e=>E(String(e))))}),[d,l]),ae.default.createElement(ke,{open:!0,title:"Copy features and annotations",handleClose:a,maxWidth:!1,"data-testid":"copy-feature"},ae.default.createElement("form",{onSubmit:async function(n){if(!d)return;n.preventDefault(),E("");const o=s.length,r=await l.waitForAssembly(d);if(!r)return void E(`Assembly not found: ${d}.`);const u=r?.getCanonicalRefName(h),f=r.regions?.find((e=>e.refName===u));if(!f)return void E(`RefSeq not found: ${h}.`);const m=w+o;if(m>f.end)return void E(`Feature would extend beyond the bounds of the selected reference sequence. (Feature would end at ${m}, but reference sequence ends at ${f.end})`);if(w<f.start)return void E(`Reference sequence starts at ${f.start}, feature cannot start before that.`);const g=[],p=st(i.getSnapshot(s),g),y={...p.attributes};"Parent"in y&&delete y.Parent,p.gffId&&ne.default.isValid(p.gffId.toString())&&(p.gffId=p._id),p.refSeq=h;const b=w-p.start;p.start=w,p.end=w+o;const S=C(p,b),v=new t.AddFeatureChange({changedIds:[p._id],typeName:"AddFeatureChange",assembly:d,addedFeature:{_id:p._id,refSeq:p.refSeq,start:p.start,end:p.end,type:p.type,children:S.children,attributes:y,discontinuousLocations:p.discontinuousLocations,strand:p.strand,score:p.score,phase:p.phase},copyFeature:!0,allIds:g});await(e.submit?.(v)),c("Feature copied successfully","success"),a(),n.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Target assembly"),ae.default.createElement(m.Select,{labelId:"label",value:d,onChange:async function(e){f(e.target.value)}},u.filter((e=>e.name!==r)).map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},n.readConfObject(e,"displayName"))))),ae.default.createElement(m.DialogContentText,null,"Target reference sequence"),ae.default.createElement(m.Select,{labelId:"label",value:h,onChange:async function(e){b(e.target.value)}},g.map((e=>ae.default.createElement(m.MenuItem,{key:e._id,value:e._id},e.name)))),ae.default.createElement(m.DialogContentText,null,"Start position in target reference sequence"),ae.default.createElement(m.TextField,{margin:"dense",type:"number",fullWidth:!0,variant:"outlined",value:w,onChange:e=>{S(Number(e.target.value))}})),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!d||!h||!w,variant:"contained",type:"submit"},"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:a},"Cancel"))),v?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},v)):null)}function it({changeManager:e,handleClose:n,session:a}){const{internetAccounts:o}=i.getRoot(a),[r,s]=y.useState(),[l,c]=y.useState(""),[u,d]=y.useState(!1),[f,g]=y.useState(!1),p=o.filter((e=>"ApolloInternetAccount"===e.type));if(0===p.length)throw new Error("No Apollo internet account found");const[h,b]=y.useState(p[0]),{collaborationServerDriver:w}=a.apolloDataStore,S=w.getAssemblies();return y.useEffect((()=>{S.length>0&&void 0===r&&s(S[0])}),[S,r]),ae.default.createElement(ke,{open:!0,title:"Delete Assembly",handleClose:n,maxWidth:!1,"data-testid":"delete-assembly"},ae.default.createElement("form",{onSubmit:async function(a){if(a.preventDefault(),g(!0),c(""),!r)return void c("Must select assembly!");const o=new t.DeleteAssemblyChange({typeName:"DeleteAssemblyChange",assembly:r.name});await(e.submit?.(o,{internetAccountId:h.internetAccountId})),n(),a.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},p.length>1?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogContentText,null,"Select account"),ae.default.createElement(m.Select,{value:h.internetAccountId,onChange:function(e){g(!1);const t=p.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);b(t)},disabled:f&&!l},o.map((e=>ae.default.createElement(m.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,ae.default.createElement(m.DialogContentText,null,"Select assembly"),ae.default.createElement(m.Select,{labelId:"label",value:r?.name??"",onChange:function(e){const t=S.find((t=>t.name===e.target.value));s(t)},disabled:0===S.length},S.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),ae.default.createElement(m.DialogContentText,null,ae.default.createElement("strong",{style:{color:"red"}},"NOTE: All assembly data will be deleted and this operation cannot be undone!")),ae.default.createElement(m.FormGroup,null,ae.default.createElement(m.FormControlLabel,{control:ae.default.createElement(m.Checkbox,{checked:u,onChange:()=>d(!u)}),label:"I understand that all assembly data will be deleted"}))),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!r||!u,variant:"contained",type:"submit"},"Delete"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),l?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},l)):null)}function ct({changeManager:e,handleClose:n,selectedFeature:a,session:o,setSelectedFeature:r,sourceAssemblyId:s,sourceFeature:l}){const{notify:c}=o,[u,d]=y.useState("");return ae.default.createElement(ke,{open:!0,title:"Delete feature",handleClose:n,maxWidth:!1,"data-testid":"delete-feature"},ae.default.createElement("form",{onSubmit:async function(o){o.preventDefault(),d(""),a?._id===l._id&&r();const u=new t.DeleteFeatureChange({changedIds:[l._id],typeName:"DeleteFeatureChange",assembly:s,deletedFeature:i.getSnapshot(l),parentFeatureId:l.parent?._id});await(e.submit?.(u)),c("Feature deleted successfully","success"),n(),o.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Are you sure you want to delete the selected feature?")),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit"},"Yes"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),u?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},u)):null)}function ut({handleClose:e,session:a}){const[o,r]=y.useState(),[s,l]=y.useState(""),{collaborationServerDriver:c,getInternetAccount:u,inMemoryFileDriver:d}=a.apolloDataStore,f=[...c.getAssemblies(),...d.getAssemblies()];return ae.default.createElement(ke,{open:!0,title:"Export GFF3",handleClose:e,maxWidth:!1,"data-testid":"download-gff3"},ae.default.createElement("form",{onSubmit:async function(r){if(r.preventDefault(),l(""),!o)return void l("Must select assembly to download");const{internetAccountConfigId:s}=n.getConf(o,["sequence","metadata"]);s?await async function(e){if(!o)return void l("Must select assembly to download");const t=u(o.configuration.name,e),n=new URL("export/getID",t.baseURL),a=new URLSearchParams({assembly:o.name});n.search=a.toString();const r=n.toString(),s=t.getFetcher({locationType:"UriLocation",uri:r}),i=await s(r,{method:"GET"});if(!i.ok){const e=await Ae(i,"Error when exporting ID");return void l(e)}const{exportID:c}=await i.json(),d=new URL("export",t.baseURL),f=new URLSearchParams({exportID:c});d.search=f.toString();const m=d.toString();window.open(m,"_blank")}(s):function(e){if(!o)return void l("Must select assembly to download");const{assemblies:a}=e.apolloDataStore,r=a.get(o.name),s=r?.refSeqs;if(!s)return void l(`No refSeqs found for assembly "${o.name}"`);const c=[{directive:"gff-version",value:"3"}],u=n.getConf(o,["sequence","adapter","features"]);for(const e of u){const{end:t,refName:n,start:a}=e;c.push({directive:"sequence-region",value:`${n} ${a+1} ${t}`})}for(const[,e]of s){const n=e?.features;if(n)for(const[,e]of n)c.push(t.makeGFF3Feature(i.getSnapshot(e)))}for(const e of u){const{refName:t,seq:n}=e;c.push({id:t,description:"",sequence:n})}const d=Z.default.formatSync(c),f=new Blob([d],{type:"text/plain;charset=utf-8"});D.saveAs(f,`${o.displayName??o.name}.gff3`)}(a),e()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Select assembly"),ae.default.createElement(m.Select,{labelId:"label",value:o?.name??"",onChange:function(e){const t=f.find((t=>t.name===e.target.value));r(t)},disabled:0===f.length},f.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),ae.default.createElement(m.DialogContentText,null,"Select assembly to export to GFF3")),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!o,variant:"contained",type:"submit"},"Download"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),s?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},s)):null)}function dt({changeManager:e,handleClose:a,session:o}){const{apolloDataStore:r}=o,[s,l]=y.useState(),[i,c]=y.useState(),[u,d]=y.useState(""),[f,g]=y.useState(!1),[p,h]=y.useState(),[b,w]=y.useState(!1),[S,v]=y.useState(!1),{collaborationServerDriver:E,getInternetAccount:C}=r,x=E.getAssemblies();return y.useEffect((()=>{i&&(async()=>{const{internetAccountConfigId:e}=n.getConf(i,["sequence","metadata"]),t=C(i.name,e);if(!t)throw new Error("No Apollo internet account found");const{baseURL:a}=t,o=new URL("/features/count",a),r=new URLSearchParams({assemblyId:i.name});o.search=r.toString();const s=t?.getFetcher({locationType:"UriLocation",uri:o.toString()});v(!0);const l=await s(o.toString(),{method:"GET"});if(!l.ok)throw new Error(await Ae(l));{const e=await l.json();h(e.count)}v(!1)})().catch((e=>{console.error(e),d(e.message??e)}))}),[C,o,i]),ae.default.createElement(ke,{open:!0,title:"Import Features from GFF3 file",handleClose:a,maxWidth:!1,"data-testid":"import-features-dialog"},S?ae.default.createElement(te.default,null):null,ae.default.createElement("form",{onSubmit:async function(r){r.preventDefault(),d(""),v(!0),g(!0);let l="";if(!s)return void d("must select a file");if(!i)return void d("Must select assembly to download");const{internetAccountConfigId:c}=n.getConf(i,["sequence","metadata"]),u=C(i.name,c),{baseURL:f}=u,m=new URL("/files",f).href,p=new FormData;p.append("file",s),p.append("fileName",s.name),p.append("type","text/x-gff3");const h=u?.getFetcher({locationType:"UriLocation",uri:m});a();const{jobsManager:y}=o,w=new AbortController,S={name:`Importing features for ${i.displayName}`,statusMessage:"Uploading file, this may take awhile",progressPct:0,cancelCallback:()=>{w.abort(),y.abortJob(S.name)}};if(y.runJob(S),h){const{signal:e}=w,t=await h(m,{method:"POST",body:p,signal:e});if(!t.ok){const e=await Ae(t,"Error when inserting new features (while uploading file)");return y.abortJob(S.name,e),void d(e)}l=(await t.json())._id}const E=new t.AddFeaturesFromFileChange({typeName:"AddFeaturesFromFileChange",assembly:i.name,fileId:l,deleteExistingFeatures:b});y.done(S),await e.submit(E,{updateJobsManager:!0})}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Select assembly"),ae.default.createElement(m.Select,{labelId:"label",value:i?.name??"",onChange:function(e){const t=x.find((t=>t.name===e.target.value));c(t),g(!1)},disabled:f&&!u},x.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name))))),ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Upload GFF3 to load features"),ae.default.createElement("input",{type:"file",onChange:function(e){g(!1),e.target.files&&l(e.target.files[0])},disabled:f&&!u})),p&&p>0?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,null,"This assembly already has ",p," features, would you like to delete the existing features before importing new ones?"),ae.default.createElement(ce.default,{label:"Yes, delete existing features",disabled:f&&!u,control:ae.default.createElement(ie.default,{checked:b,onChange:function(e){w(e.target.checked)},inputProps:{"aria-label":"controlled"},color:"warning"})})):null,ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!(i&&s&&void 0!==p)||f,variant:"contained",type:"submit"},f?"Submitting...":"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:a},"Close"))),u?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},u)):null)}function ft({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),[a,o]=y.useState(),[r,s]=y.useState(""),[l,c]=y.useState(!1),u=n.filter((e=>"ApolloInternetAccount"===e.type));if(0===u.length)throw new Error("No Apollo internet account found");const[d,f]=y.useState(u[0]),[g,p]=y.useState([]),[h,b]=y.useState([]),{collaborationServerDriver:w}=t.apolloDataStore,S=w.getAssemblies();function v(e,t){const n=[...h],a=e.target.value;if(t)n.includes(a)||(n.push(a),b(n));else{const e=n.indexOf(a,0);e>-1&&n.splice(e,1),b(n)}}return y.useEffect((()=>{(async function(){const{baseURL:e,getFetcher:t}=d,n=new URL("/checks/types",e).href,a=t({locationType:"UriLocation",uri:n}),o=await a(n,{method:"GET"});if(!o.ok){const e=await Ae(o,"Error when retrieving checks from server");return void s(e)}const r=await o.json();p(r)})().catch((e=>s(String(e))))}),[d]),y.useEffect((()=>{S.length>0&&void 0===a&&o(S[0])}),[S,a]),y.useEffect((()=>{(async function(){if(!a)return;const{baseURL:e,getFetcher:t}=d,n=new URL(`/assemblies/${a.name}`,e).href,o=t({locationType:"UriLocation",uri:n}),r=await o(n,{method:"GET"});if(!r.ok){const e=await Ae(r,"Error when retrieving assembly from server");return void s(e)}const l=await r.json();b(l.checks)})().catch((e=>s(String(e))))}),[a,d]),ae.default.createElement(ke,{open:!0,title:"Manage Checks",handleClose:e,"data-testid":"manage-checks"},ae.default.createElement("form",{onSubmit:async function(n){if(n.preventDefault(),!a)return void s("Must select assembly!");const{notify:o}=t,{baseURL:r,getFetcher:l}=d,i=new URL("/assemblies/checks",r).href,c=l({locationType:"UriLocation",uri:i}),u=await c(i,{method:"POST",body:JSON.stringify({_id:a.name,checks:h,name:""}),headers:{"Content-Type":"application/json"}});if(u.ok)o("Assembly checks updated successfully","success"),e();else{const e=await Ae(u,"Error when updating assembly checks");s(e)}}},ae.default.createElement(m.DialogContent,null,u.length>1?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogContentText,null,"Select account"),ae.default.createElement(m.Select,{value:d.internetAccountId,onChange:function(e){c(!1);const t=u.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);f(t)},disabled:l&&!r},n.map((e=>ae.default.createElement(m.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,ae.default.createElement(m.DialogContentText,null,"Select assembly"),ae.default.createElement(m.Select,{style:{width:300},labelId:"label",value:a?.name??"",onChange:function(e){const t=S.find((t=>t.name===e.target.value));o(t)},disabled:0===S.length},S.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),ae.default.createElement("br",null),ae.default.createElement("br",null),ae.default.createElement(m.TableContainer,{component:m.Paper},ae.default.createElement(m.Table,null,ae.default.createElement(m.TableHead,null,ae.default.createElement(m.TableRow,null,ae.default.createElement(m.TableCell,null,"Check name"),ae.default.createElement(m.TableCell,null,"Use check"))),ae.default.createElement(m.TableBody,null,g.map((e=>ae.default.createElement(m.TableRow,{key:e._id},ae.default.createElement(m.TableCell,null,e.name),ae.default.createElement(m.TableCell,null,ae.default.createElement(m.Checkbox,{value:e._id,checked:h.includes(e._id),onChange:v}))))))))),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit"},"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),r?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},r)):null)}function mt({changeManager:e,handleClose:n,session:a}){const{internetAccounts:o}=i.getRoot(a),r=o.filter((e=>"ApolloInternetAccount"===e.type&&e.role?.includes("admin")));if(0===r.length)throw new Error("No Apollo internet account found");const[s,l]=y.useState(""),[c,u]=y.useState(r[0]),[d,f]=y.useState([]),g=y.useCallback((async()=>{const{baseURL:e}=c,t=new URL("/users",e).href,n=c?.getFetcher({locationType:"UriLocation",uri:t});if(n){const e=await n(t,{method:"GET"});if(!e.ok){const t=await Ae(e,"Error when getting user data from db");return void l(t)}const a=await e.json();f(a.map((e=>void 0===e.role?{...e,role:""}:e)))}}),[c]);function p(e){return e===c.getUserId()}y.useEffect((()=>{g().catch((e=>l(String(e))))}),[g]);const h=[{field:"username",headerName:"User",width:140},{field:"email",headerName:"Email",width:160},{field:"role",headerName:"Role",width:140,type:"singleSelect",valueOptions:["","readOnly","user","admin"],editable:!0},{field:"actions",type:"actions",getActions:n=>[ae.default.createElement(M.GridActionsCellItem,{key:`delete-${n.id}`,icon:ae.default.createElement(ue.default,null),onClick:async()=>{window.confirm("Delete this user?")&&await async function(n){const a=new t.DeleteUserChange({typeName:"DeleteUserChange",userId:n});await e.submit(a,{internetAccountId:c.internetAccountId}),f((e=>e.filter((e=>e._id!==n))))}(n.id)},disabled:p(n.id),label:"Delete"})]}];return ae.default.createElement(ke,{open:!0,fullScreen:!0,title:"Manage users",handleClose:n,"data-testid":"manage-users"},ae.default.createElement(m.DialogContent,null,r.length>1?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogContentText,null,"Select account"),ae.default.createElement(m.Select,{value:c.internetAccountId,onChange:function(e){const t=r.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);u(t)},disabled:!s},o.map((e=>ae.default.createElement(m.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,ae.default.createElement("div",{style:{height:"100%",width:"100%"}},ae.default.createElement(M.DataGrid,{pagination:!0,rows:d,columns:h,getRowId:e=>e._id,slots:{toolbar:M.GridToolbar},getRowHeight:()=>"auto",isCellEditable:e=>!p(e.id),processRowUpdate:async function(n){const a=new t.UserChange({typeName:"UserChange",role:n.role,userId:n._id});return await e.submit(a,{internetAccountId:c.internetAccountId}),n},onProcessRowUpdateError:e=>l(String(e))}))),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Close")),s?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},s)):null)}function gt({getTagProps:e,index:t,ontology:n,termId:a}){const o=i.getParent(n,2),[r,s]=oe.useState(""),[l,c]=oe.useState("");return oe.useEffect((()=>{const e=new AbortController,{signal:t}=e;return async function(){const e=o.expandPrefixes(a),r=await(n.dataStore?.db);if(!r||t.aborted)return;const l=await r.transaction("nodes").objectStore("nodes").get(e);l&&l.lbl&&!t.aborted&&s(l.lbl||"no label")}().catch((e=>{t.aborted||c(String(e))})),()=>{e.abort()}}),[a,n,o]),oe.createElement(m.Tooltip,{title:r},oe.createElement("div",null,oe.createElement(m.Chip,{label:l||o.applyPrefixes(a),color:l?"error":"default",size:"small",...e({index:t})})))}function pt({includeDeprecated:e,onChange:t,ontologyName:n,ontologyVersion:a,session:o,value:s}){const l=o.apolloDataStore.ontologyManager,i=l.findOntology(n,a),[c,u]=oe.useState(s.map((e=>({term:{id:e,type:"CLASS"}})))),[d,f]=oe.useState(""),[g,p]=oe.useState([]),[h,y]=oe.useState(!1),[b,w]=oe.useState(""),S=oe.useMemo((()=>T.debounce((async(t,n)=>{if(!i)return;const{dataStore:a}=i;if(!a)return;const{input:o,signal:s}=t;try{const t=await a.getTermsByFulltext(o,void 0,s),r=new Map,l=[];for(const n of t){if(!et(n.term)||!e&&Ge(n.term))continue;let t=r.get(n.term.id);t||(t={term:n.term,matches:[]},r.set(n.term.id,t),l.push(t)),t.matches.push(n)}n(l)}catch(e){r.isAbortException(e)||w(String(e))}}),400)),[e,i]);if(oe.useEffect((()=>{const e=new AbortController,{signal:t}=e;if(""!==d)return y(!0),S({input:d,signal:t},(e=>{let t=[];c.length>0&&(t=c),e&&(t=[...t,...e]),p(t),y(!1)})),()=>{e.abort()};p([])}),[S,i,e,d,c]),!i)return null;const v={};return b&&(v.error=!0,v.helperText=b),oe.createElement(m.Autocomplete,{getOptionLabel:e=>l.applyPrefixes(e.term.id),filterOptions:e=>e.filter((e=>et(e.term))),options:g,autoComplete:!0,includeInputInList:!0,filterSelectedOptions:!0,value:c,loading:h,isOptionEqualToValue:(e,t)=>l.applyPrefixes(e.term.id)===l.applyPrefixes(t.term.id),noOptionsText:d?"No matches":"Start typing to search",onChange:(e,n)=>{p(n?[...n,...g]:g),t(n.map((e=>l.applyPrefixes(e.term.id)))),u(n)},onInputChange:(e,t)=>{t&&y(!0),p([]),f(t)},multiple:!0,renderInput:e=>oe.createElement(m.TextField,{...e,...v,variant:"outlined",fullWidth:!0}),renderOption:(e,t)=>oe.createElement(yt,{...e,ontologyManager:l,option:t,inputValue:d}),renderTags:(e,t)=>e.map(((e,n)=>oe.createElement(gt,{termId:e.term.id,index:n,ontology:i,getTagProps:t,key:e.term.id})))})}function ht(e){const{search:t,str:n}=e,a=de.default(n,t,{insideWords:!0,findAllOccurrences:!0}),o=fe.default(n,a);return oe.createElement(oe.Fragment,null,o.map(((e,t)=>oe.createElement(m.Typography,{key:t,component:"span",sx:{fontWeight:e.highlight?"bold":"regular"},variant:"body2",color:"text.secondary"},e.text))))}function yt(e){const{inputValue:t,ontologyManager:n,option:a,...o}=e,r=(a.matches??[]).filter((e=>"$.lbl"!==e.field.jsonPath)).map((e=>oe.createElement(oe.Fragment,{key:`option-${e.term.id}-${e.str}`},oe.createElement(m.Typography,{component:"dt",variant:"body2",color:"text.secondary"},e.field.displayName),oe.createElement("dd",null,oe.createElement(ht,{str:e.str,search:t})))));return oe.createElement("li",{...o},oe.createElement(m.Grid,{container:!0},oe.createElement(m.Grid,{item:!0},oe.createElement(m.Typography,{component:"span"},n.applyPrefixes(a.term.id))," ",oe.createElement(ht,{str:a.term.lbl??"(no label)",search:t})," ",oe.createElement("dl",null,r))))}!function(e){e[e.zero=0]="zero",e[e.one=1]="one",e[e.two=2]="two"}(ot||(ot={}));const bt=new Map([["Gene Ontology",e=>ae.default.createElement(pt,{...e,ontologyName:"Gene Ontology"})],["Sequence Ontology",e=>ae.default.createElement(pt,{...e,ontologyName:"Sequence Ontology"})]]),wt=v.makeStyles()((e=>({attributeInput:{maxWidth:600},newAttributePaper:{padding:e.spacing(2)},attributeName:{background:e.palette.secondary.main,color:e.palette.secondary.contrastText,padding:e.spacing(1)}}))),St=["ID","Name","Alias","Target","Gap","Derives_from","Note","Dbxref","Ontology","Is_Circular"];function vt(e){const{onChange:t,value:n}=e;return ae.default.createElement(m.TextField,{type:"text",value:n,onChange:e=>{t(e.target.value.split(","))},variant:"outlined",fullWidth:!0,helperText:"Separate multiple values for the attribute with commas"})}function Et({changeManager:e,handleClose:n,session:a,sourceAssemblyId:o,sourceFeature:r}){const{notify:s}=a,{internetAccounts:l}=i.getRoot(a),c=y.useMemo((()=>l.find((e=>"ApolloInternetAccount"===e.type))),[l]),u=["admin","user"].includes((c?c.role:"admin")??""),[d,f]=y.useState(""),[g,p]=y.useState(Object.fromEntries([...r.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]})))),[h,b]=y.useState(!1),[w,S]=y.useState(""),{classes:v}=wt(),E=Object.values(g).some((e=>0===e.length||e.includes("")));return ae.default.createElement(ke,{open:!0,title:"Feature attributes",handleClose:n,maxWidth:!1,"data-testid":"modify-feature-attribute"},ae.default.createElement("form",{onSubmit:async function(a){a.preventDefault(),f("");const l={};if(g)for(const[e,t]of Object.entries(g))if(t&&"parent"!==e.toLowerCase())if([...bt.keys()].includes(e))l[e]=t;else switch(e){case"ID":l._id=t;break;case"Name":l.gff_name=t;break;case"Alias":l.gff_alias=t;break;case"Target":l.gff_target=t;break;case"Gap":l.gff_gap=t;break;case"Derives_from":l.gff_derives_from=t;break;case"Note":l.gff_note=t;break;case"Dbxref":l.gff_dbxref=t;break;case"Ontology_term":l.gff_ontology_term=t;break;case"Is_circular":l.gff_is_circular=t;break;default:l[e.toLowerCase()]=t}const i=new t.FeatureAttributeChange({changedIds:[r._id],typeName:"FeatureAttributeChange",assembly:o,featureId:r._id,attributes:l});await(e.submit?.(i)),s("Feature attributes modified successfully","success"),n(),a.preventDefault()}},ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.Grid,{container:!0,direction:"column",spacing:1},Object.entries(g).map((([e,t])=>{const n=bt.get(e)??vt;return ae.default.createElement(m.Grid,{container:!0,item:!0,spacing:3,alignItems:"center",key:e},ae.default.createElement(m.Grid,{item:!0,xs:"auto"},ae.default.createElement(m.Paper,{variant:"outlined",className:v.attributeName},ae.default.createElement(m.Typography,null,e))),ae.default.createElement(m.Grid,{item:!0,flexGrow:1},ae.default.createElement(n,{session:a,value:t,onChange:(o=e,e=>{p({...g,[o]:e})})})),ae.default.createElement(m.Grid,{item:!0,xs:1},ae.default.createElement(m.IconButton,{"aria-label":"delete",size:"medium",disabled:!u,onClick:()=>{!function(e){f("");const{[e]:t,...n}=g;p(n)}(e)}},ae.default.createElement(ue.default,{fontSize:"medium",key:e}))));var o})),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Button,{color:"primary",variant:"contained",disabled:h||!u,onClick:()=>{b(!0)}},"Add new")),h?ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Paper,{elevation:8,className:v.newAttributePaper},ae.default.createElement(m.Grid,{container:!0,direction:"column"},ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.FormControl,null,ae.default.createElement(m.FormLabel,{id:"attribute-radio-button-group"},"Select attribute type"),ae.default.createElement(m.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:"custom",name:"radio-buttons-group",onChange:function(e,t){"custom"===t?S(""):bt.has(t)?S(t):f("Unknown attribute type")}},ae.default.createElement(m.FormControlLabel,{value:"custom",control:ae.default.createElement(m.Radio,null),disableTypography:!0,label:ae.default.createElement(m.Grid,{container:!0,spacing:1,alignItems:"center"},ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Typography,null,"Custom")),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.TextField,{label:"Custom attribute key",variant:"outlined",value:bt.has(w)?"":w,disabled:bt.has(w),onChange:e=>{S(e.target.value)}})))}),[...bt.keys()].map((e=>ae.default.createElement(m.FormControlLabel,{key:e,value:e,control:ae.default.createElement(m.Radio,null),label:e})))))),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{key:"addButton",color:"primary",variant:"contained",style:{margin:2},onClick:function(){f(""),0!==w.trim().length?"Parent"!==w?w in g?f(`Attribute "${w}" already exists`):!/^[A-Z]/.test(w)||St.includes(w)||[...bt.keys()].includes(w)?(p({...g,[w]:[]}),b(!1),S("")):f(`Key cannot starts with uppercase letter unless key is one of these: ${St.join(", ")}`):f('"Parent" -key is handled internally and it cannot be modified manually'):f("Attribute key is mandatory")},disabled:!w},"Add"),ae.default.createElement(m.Button,{key:"cancelAddButton",variant:"outlined",type:"submit",onClick:()=>{b(!1),S(""),f("")}},"Cancel")))))):null),d?ae.default.createElement(m.DialogContentText,{color:"error"},d):null),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit",disabled:h||E||!u},"Submit changes"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",disabled:h,onClick:n},"Cancel"))))}function Ct({handleClose:e,session:t}){const{addApolloTrackConfig:n,apolloDataStore:a}=t,{addAssembly:o,addSessionAssembly:s,assemblyManager:l,notify:i}=t,[c,u]=y.useState(null),[f,g]=y.useState(""),[p,h]=y.useState(""),[b,w]=y.useState(!1),S=m.useTheme();return ae.default.createElement(ke,{open:!0,title:"Open local GFF3 file",handleClose:e,maxWidth:!1,"data-testid":"open-local-file"},ae.default.createElement("form",{onSubmit:async function(t){if(t.preventDefault(),h(""),w(!0),!c)throw new Error("No file selected");const u=await new Response(c).text(),m=`${f}-${c.name}-${d.nanoid(8)}`;try{await Ce(m,u,a)}catch(e){h(String(e)),w(!1)}const g={name:m,aliases:[f],displayName:f,sequence:{trackId:`sequenceConfigId-${f}`,type:"ReferenceSequenceTrack",adapter:{type:"ApolloSequenceAdapter",assemblyId:m},metadata:{apollo:!0,...r.isElectron?{file:c.path}:{}}}};await(s||o)(g);const p=await l.waitForAssembly(g.name);p?(n(p),i(`Loaded GFF3 ${c?.name}`,"success")):i(`Error loading GFF3 ${c?.name}`,"error"),e()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.FormControl,null,ae.default.createElement("div",{style:{flexDirection:"row"}},ae.default.createElement(m.Button,{variant:"contained",component:"label",style:{marginRight:S.spacing()}},"Choose File",ae.default.createElement("input",{type:"file",required:!0,hidden:!0,onChange:async function(e){const t=e.target.files?.item(0);if(t&&(h(""),u(t),!f)){const e=t.name,n=e.lastIndexOf(".");g(-1===n?e:e.slice(0,n))}}})),c?c.name:"No file chosen"),ae.default.createElement(m.FormHelperText,null,"Make sure your GFF3 has an embedded FASTA section")),ae.default.createElement(m.TextField,{required:!0,label:"Assembly name",value:f,onChange:function(e){g(e.target.value)}})),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!1,variant:"contained",type:"submit"},b?"Submitting...":"Submit"),ae.default.createElement(m.Button,{disabled:b,variant:"outlined",type:"submit",onClick:e},"Cancel"))),p?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},p)):null)}const xt=v.makeStyles()((e=>({changeTextarea:{fontFamily:"monospace",width:600,resize:"none",border:`1px solid ${e.palette.divider}`,borderRadius:e.shape.borderRadius}})));function Ft({handleClose:t,session:n}){const{internetAccounts:a}=i.getRoot(n),o=a.find((e=>"ApolloInternetAccount"===e.type));if(!o)throw new Error("No Apollo internet account found");const{baseURL:r}=o,{classes:s}=xt(),[l,c]=y.useState(),[u,d]=y.useState([]),[f,g]=y.useState(""),[p,h]=y.useState([]),b=[{field:"sequence"},{field:"typeName",headerName:"Change type",width:200,type:"singleSelect",valueOptions:[...e.changeRegistry.changes.keys()]},{field:"changes",headerName:"Change JSON",width:600,renderCell:({value:e})=>ae.default.createElement("textarea",{className:s.changeTextarea,value:JSON.stringify(e),readOnly:!0}),valueFormatter:({value:e})=>JSON.stringify(e)},{field:"user",headerName:"User",width:140},{field:"createdAt",headerName:"Time",width:160,type:"dateTime",valueGetter:e=>e&&new Date(e)}];return y.useEffect((()=>{(async function(){const e=new URL("/assemblies",r).href,t=o?.getFetcher({locationType:"UriLocation",uri:e});if(t){const n=await t(e,{method:"GET"});if(!n.ok){const e=await Ae(n,"Error when retrieving assemblies from server");return void c(e)}const a=await n.json();d(a)}})().catch((e=>c(String(e))))}),[o,r]),y.useEffect((()=>{!f&&u.length>0&&g(u[0]._id)}),[f,u]),y.useEffect((()=>{(async function(){if(!f)return;const e=new URL("changes",r),t=new URLSearchParams({assembly:f});e.search=t.toString();const n=e.toString(),a=o?.getFetcher({locationType:"UriLocation",uri:n});if(a){const e=await a(n,{headers:new Headers({"Content-Type":"application/json"})});if(!e.ok){const t=await Ae(e,"Error when retrieving changes");return void c(t)}const t=await e.json();h(t)}})().catch((e=>c(String(e))))}),[f,o,r]),ae.default.createElement(ke,{open:!0,fullScreen:!0,title:"View change log",handleClose:t,"data-testid":"view-changelog"},ae.default.createElement(m.Select,{style:{width:200,marginLeft:40},value:f,onChange:async function(e){g(e.target.value)}},u.map((e=>ae.default.createElement(m.MenuItem,{key:e._id,value:e._id},e.name)))),ae.default.createElement(m.DialogContent,null,ae.default.createElement(M.DataGrid,{pagination:!0,rows:p,columns:b,getRowId:e=>e._id,slots:{toolbar:M.GridToolbar},initialState:{sorting:{sortModel:[{field:"sequence",sort:"desc"}]},columns:{columnVisibilityModel:{sequence:!1}}}})),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:t},"Close")),l?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},l)):null)}function At(e){const{color:t}=e;return ae.default.createElement(m.SvgIcon,{viewBox:"0 0 18 18",style:{fontSize:18,marginRight:4},...e},"disabled"===t?ae.default.createElement("path",{d:"M9.001,10.71 l0,-3.348 l8.424,0 c0.126,0.567,0.225,1.098,0.225,1.845 c0,5.139,-3.447,8.793,-8.64,8.793 c-4.968,0,-9,-4.032,-9,-9 c0,-4.968,4.032,-9,9,-9 c2.43,0,4.464,0.891,6.021,2.349 l-2.556,2.484 c-0.648,-0.612,-1.782,-1.332,-3.465,-1.332 c-2.979,0,-5.409,2.475,-5.409,5.508 c0,3.033,2.43,5.508,5.409,5.508 c3.447,0,4.716,-2.385,4.95,-3.798 l-4.959,0 l0,-0.009 z"}):ae.default.createElement(ae.default.Fragment,null,ae.default.createElement("path",{d:"M17.64,9.20454545 c0,-0.638,-0.057,-1.252,-0.164,-1.841 l-8.476,0 l0,3.481 l4.844,0 c-0.209,1.125,-0.843,2.079,-1.796,2.717 l0,2.258 l2.908,0 c1.702,-1.567,2.684,-3.874,2.684,-6.615 l0,0 z",fill:"#4285F4"}),ae.default.createElement("path",{d:"M9,18 c2.43,0,4.467,-0.806,5.956,-2.18 l-2.908,-2.259 c-0.806,0.54,-1.837,0.859,-3.048,0.859 c-2.344,0,-4.328,-1.583,-5.036,-3.71 l-3.007,0 l0,2.332 c1.481,2.941,4.525,4.958,8.043,4.958 l0,0 z",fill:"#34A853"}),ae.default.createElement("path",{d:"M3.96409091,10.71 c-0.18,-0.54,-0.282,-1.117,-0.282,-1.71 c0,-0.593,0.102,-1.17,0.282,-1.71 l0,-2.332 l-3.007,0 c-0.609,1.215,-0.957,2.59,-0.957,4.042 c0,1.452,0.348,2.827,0.957,4.042 l3.007,-2.332 l0,0 z",fill:"#FBBC05"}),ae.default.createElement("path",{d:"M9,3.57954545 c1.321,0,2.508,0.454,3.44,1.346 l2.582,-2.581 c-1.559,-1.453,-3.596,-2.345,-6.022,-2.345 c-3.518,0,-6.562,2.017,-8.043,4.959 l3.007,2.331 c0.708,-2.127,2.692,-3.71,5.036,-3.71 l0,0 z",fill:"#EA4335"})))}function Dt(e){const{color:t}=e;return ae.default.createElement(m.SvgIcon,{viewBox:"0 0 21 21",style:{fontSize:21},...e},ae.default.createElement("rect",{x:"1",y:"1",width:"9",height:"9",fill:"disabled"===t?"#7B7B7B":"#F25022"}),ae.default.createElement("rect",{x:"1",y:"11",width:"9",height:"9",fill:"disabled"===t?"#7B7B7B":"#00A4EF"}),ae.default.createElement("rect",{x:"11",y:"1",width:"9",height:"9",fill:"disabled"===t?"#939393":"#7FBA00"}),ae.default.createElement("rect",{x:"11",y:"11",width:"9",height:"9",fill:"disabled"===t?"#B9B9B9":"#FFB900"}))}const kt=v.makeStyles()((e=>({loginButton:{marginBottom:e.spacing(1),width:"220px",height:"40px",fontSize:"16px",textTransform:"none",justifyContent:"left",padding:"3px 12px"}})));function Nt(e){const{classes:t}=kt(),{disabled:n}=e;return ae.default.createElement(m.Button,{className:t.loginButton,variant:"outlined",startIcon:ae.default.createElement(At,{color:n?"disabled":void 0}),...e},"Sign in with Google")}function Rt(e){const{classes:t}=kt(),{disabled:n}=e;return ae.default.createElement(m.Button,{className:t.loginButton,variant:"outlined",startIcon:ae.default.createElement(Dt,{color:n?"disabled":void 0}),...e},"Sign in with Microsoft")}function Mt(e){const{classes:t}=kt();return ae.default.createElement(m.Button,{className:t.loginButton,variant:"outlined",startIcon:ae.default.createElement(me.default,{fontSize:"small"}),...e},"Continue as Guest")}const Tt=v.makeStyles()((e=>({divider:{marginTop:e.spacing(4),marginBottom:e.spacing(5)}}))),Lt=({baseURL:e,handleClose:t,name:n})=>{const{classes:a}=Tt(),[o,s]=y.useState(""),[l,i]=y.useState([]);function c(e){t("google"===e?"google":"microsoft"===e?"microsoft":"guest")}y.useEffect((()=>{const t=new AbortController,{signal:n}=t;return async function(){const t=new URL("/auth/types",e).href,a=await fetch(t,{method:"GET",signal:n});if(!a.ok){const e=await Ae(a,"Error when retrieving auth types from server");return void s(e)}const o=await a.json();i(o)}().catch((e=>r.isAbortException(e)?"":s(String(e)))),()=>{t.abort()}}),[e]);const u=l.includes("google"),d=l.includes("microsoft"),f=l.includes("guest");return ae.default.createElement(ke,{open:!0,title:`Log in to ${n}`,handleClose:t,maxWidth:!1,"data-testid":"login-apollo"},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column",paddingTop:8}},u?ae.default.createElement(Nt,{disabled:!u,onClick:()=>c("google")}):null,d?ae.default.createElement(Rt,{disabled:!d,onClick:()=>c("microsoft")}):null,f?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Divider,{className:a.divider}),ae.default.createElement(Mt,{onClick:()=>c("guest")})):null),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:()=>{t()}},"Cancel")),o?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},o)):null)},It="undefined"==typeof sessionStorage,Pt=o=>a.InternetAccount.named("ApolloInternetAccount").props({type:i.types.literal("ApolloInternetAccount"),configuration:n.ConfigurationReference(o)}).views((e=>({get baseURL(){return n.getConf(e,"baseURL")},getUserId(){const n=e.retrieveToken();if(n)return t.getDecodedToken(n).id}}))).volatile((()=>({role:void 0}))).actions((e=>{let n=!1;return{setRole(){const a=e.retrieveToken();if(!a)return void(e.role=void 0);const o=t.getDecodedToken(a),{role:r}=o;if(!r&&!n){const{session:t}=i.getRoot(e);t.notify("You have registered as a user but have not been given access. Ask your administrator to enable access for your account.","warning"),n=!0}e.role!==r&&(e.role=r)}}})).actions((e=>{let t;return{addMessageChannel(e,n){t=t=>{this.finishOAuthWindow(t,e,n)},window.addEventListener("message",t)},deleteMessageChannel(){window.removeEventListener("message",t)},async finishOAuthWindow(t,n,a){if(t.data.name!==`JBrowseAuthWindow-${e.internetAccountId}`)return this.deleteMessageChannel();const o=t.data.redirectUri.replace("#","?"),r=new URL(o),s=new URLSearchParams(r.search).get("access_token");return this.deleteMessageChannel(),s?(e.storeToken(s),e.setRole(),n(s)):a(new Error("Error with token endpoint"))},async openAuthWindow(t,n,a){const o=r.isElectron?"http://localhost/auth":window.location.origin+window.location.pathname,s=new URL("auth/login",e.baseURL),l=new URLSearchParams({type:t,redirect_uri:o});s.search=l.toString();const i=`JBrowseAuthWindow-${e.internetAccountId}`;if(r.isElectron){const{ipcRenderer:t}=window.require("electron"),r=await t.invoke("openAuthWindow",{internetAccountId:e.internetAccountId,data:{redirect_uri:o},url:s.toString()}),l=new MessageEvent("message",{data:{name:i,redirectUri:r}});this.finishOAuthWindow(l,n,a)}else this.addMessageChannel(n,a),window.open(s,i,"width=500,height=600")}}})).actions((e=>({async getTokenFromUser(t,n){const{baseURL:a}=e,o=await new Promise(((t,n)=>{const{session:a}=i.getRoot(e),{baseURL:o,name:r}=e;a.queueDialog((e=>[Lt,{name:r,handleClose:a=>{a?a instanceof Error?n(a):t(a):n(new Error("user cancelled entry")),e()},baseURL:o}]))}));if("guest"!==o)return void e.openAuthWindow(o,t,n);const r=new URL("auth/login",a),s=new URLSearchParams({type:o});r.search=s.toString();const l=r.toString(),c=await fetch(l);if(!c.ok){const e=await Ae(c,"Error when logging in");return n(new Error(e))}const{token:u}=await c.json();t(u)}}))).volatile((()=>({lastChangeSequenceNumber:void 0}))).actions((e=>({setLastChangeSequenceNumber(t){e.lastChangeSequenceNumber=t}}))).actions((t=>({updateLastChangeSequenceNumber:i.flow((function*(){const{baseURL:e}=t,n=new URL("changes",e),a=new URLSearchParams({limit:"1"});n.search=a.toString();const o=n.toString(),r=t.getFetcher({locationType:"UriLocation",uri:o}),s=yield r(o,{method:"GET"});if(!s.ok){const e=yield Ae(s,"Error when fetching server LastChangeSequence");throw new Error(e)}const l=yield s.json();t.setLastChangeSequenceNumber(l.length>0?l[0].sequence:0)})),getMissingChanges:i.flow((function*(){const{session:n}=i.getRoot(t),{changeManager:a}=n.apolloDataStore;if(!t.lastChangeSequenceNumber)throw new Error("No LastChangeSequence stored in session. Please, refresh you browser to get last updates from server");const{baseURL:o,lastChangeSequenceNumber:r}=t,s=new URL("changes",o),l=new URLSearchParams({since:String(r),sort:"1"});s.search=l.toString();const c=s.toString(),u=t.getFetcher({locationType:"UriLocation",uri:c}),d=yield u(c,{method:"GET"});if(!d.ok)return void console.error(`Error when fetching the last updates to recover socket connection — ${d.status}`);const f=yield d.json();for(const t of f){const n=e.Change.fromJSON(t);a?.submit(n,{submitToBackend:!1})}}))}))).volatile((e=>({socket:c.io(e.baseURL)}))).actions((n=>({addSocketListeners(){const{session:a}=i.getRoot(n),{notify:o}=a,r=n.retrieveToken();if(!r)throw new Error("No Token found");const{socket:s}=n,{addCheckResult:l,changeManager:c,deleteCheckResult:u}=a.apolloDataStore;s.on("connect",(async()=>{await n.getMissingChanges()})),s.on("connect_error",(()=>{o("Could not connect to the Apollo server.","error")})),s.on("COMMON",(t=>{if("checkResult"in t)return void(t.deleted?u(t.checkResult._id.toString()):l(t.checkResult));if(sessionStorage.setItem("LastChangeSequence",String(t.changeSequence)),t.userSessionId===r)return;const n=e.Change.fromJSON(t.changeInfo);c?.submit(n,{submitToBackend:!1})})),s.on("USER_LOCATION",(e=>{const{channel:n,locations:o,userName:s,userSessionId:l}=e,i=t.getDecodedToken(r),c=t.makeUserSessionId(i);"USER_LOCATION"===n&&l!==c&&a.addOrUpdateCollaborator({name:s,id:l,locations:o})})),s.on("REQUEST_INFORMATION",(e=>{const{channel:t,reqType:n,userSessionId:o}=e;"REQUEST_INFORMATION"===t&&o!==r&&"CURRENT_LOCATION"===n&&a.broadcastLocations()}))}}))).actions((e=>({postUserLocation:(t=>{let n;return t=>{clearTimeout(n),n=setTimeout((()=>async function(t){const{baseURL:n}=e,a=new URL("users/userLocation",n).href,o=new URLSearchParams(JSON.stringify(t)),r=e.getFetcher({locationType:"UriLocation",uri:a});try{if(!(await r(a,{method:"POST",body:o})).ok)throw new Error("ignore")}catch{console.error("Broadcasting user location failed")}}(t)),300)}})()}))).actions((e=>({initialize:i.flow((function*(t){if("admin"===t){const t=i.getRoot(e);r.isAbstractMenuManager(t)&&function(e){e.appendToMenu("Apollo",{label:"Add Assembly",onClick:e=>{e.queueDialog((t=>[Re,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Delete Assembly",onClick:e=>{e.queueDialog((t=>[it,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Import Features",onClick:e=>{e.queueDialog((t=>[dt,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Manage Users",onClick:e=>{e.queueDialog((t=>[mt,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Undo",onClick:e=>{const{apolloDataStore:t}=e,{notify:n}=e;t.changeManager.recentChanges.length>0?t.changeManager.revertLastChange():n("No changes to undo","info")}})}(t)}yield e.updateLastChangeSequenceNumber(),e.addSocketListeners();const{baseURL:n}=e,a=new URL("/users/locations",n).href,o=e.getFetcher({locationType:"UriLocation",uri:a});yield o(a,{method:"GET"}),window.addEventListener("beforeunload",(()=>{e.postUserLocation([])})),document.addEventListener("visibilitychange",(()=>{if("hidden"===document.visibilityState&&e.postUserLocation([]),"visible"===document.visibilityState){const{session:t}=i.getRoot(e);t.broadcastLocations()}}))}))}))).actions((e=>({afterAttach(){e.setRole(),l.autorun((async t=>{It||e.role&&(await e.initialize(e.role),t.dispose())}),{name:"ApolloInternetAccount"})}})));function qt(e){return"object"==typeof e&&null!==e&&"apollo"in e&&!0===e.apollo}const _t="undefined"==typeof sessionStorage;class Ut extends _.BaseSequenceAdapter{regions;async getRefNames(e){return(await this.getRegions(e)).map((e=>e.refName))}async getRegions(e){if(this.regions)return this.regions;const t=n.readConfObject(this.config,"assemblyId");if(!_t){const e=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!e)throw new Error("No Apollo data store found");const n=e.getBackendDriver(t),a=await n.getRegions(t);return this.regions=a,a}const a=await new Promise(((n,a)=>{const o=setTimeout((()=>{a("timeout")}),2e4),r=d.nanoid(),s=e=>{const{data:t}=e;qt(t)&&t.messageId===r&&(clearTimeout(o),removeEventListener("message",s),n(t.regions))};addEventListener("message",s,e),globalThis.rpcServer.emit("apollo",{apollo:!0,method:"getRegions",assembly:t,messageId:r})}));return this.regions=a,a}getFeatures(e,t){const{end:a,refName:o,start:r}=e,s=n.readConfObject(this.config,"assemblyId"),l={...e,assemblyName:s};return U.ObservableCreate((async e=>{if(!_t){const t=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!t)return void e.error("No Apollo data store found");const n=t.getBackendDriver(s),{seq:i}=await n.getSequence(l);return e.next(new pe.default({id:`${o} ${r}-${a}`,data:{refName:o,start:r,end:a,seq:i}})),void e.complete()}const n=await new Promise(((e,n)=>{const a=setTimeout((()=>{n("timeout")}),2e4),o=d.nanoid(),r=t=>{const{data:n}=t;qt(n)&&n.messageId===o&&(clearTimeout(a),removeEventListener("message",r),e(n.sequence))};addEventListener("message",r,t),globalThis.rpcServer.emit("apollo",{apollo:!0,method:"getSequence",region:l,messageId:o})}));e.next(new pe.default({id:`${o} ${r}-${a}`,data:{refName:o,start:r,end:a,seq:n}})),e.complete()}))}freeResources(){}}var Ot=n.ConfigurationSchema("ApolloSequenceAdapter",{assemblyId:{type:"string",defaultValue:""}},{explicitlyTyped:!0});function Bt(e,t,n,a,o,r){const s=a/o;e.fillStyle="black",e.fillRect(t,n,s,r),s>2&&(e.clearRect(t+1,n+1,s-2,r-2),e.fillStyle="rgba(255,255,255,0.75)",e.fillRect(t+1,n+1,s-2,r-2))}var jt=S.observer((function(e){const[a,o]=y.useState(),[s,c]=y.useState(),u=y.useRef(null),d=y.useRef(null),f=y.useRef(null),[g,p]=y.useState(!1),[h,b]=y.useState(!0),[w,S]=y.useState(),[v,E]=y.useState(!1),[C,x]=y.useState([]),{bpPerPx:F,displayModel:A,regions:D}=e,{session:k}=A,{collaborators:N}=k;y.useEffect((()=>l.autorun((()=>x(l.toJS(N))))),[]);const[R]=D,M=(R.end-R.start)/F,{apolloFeatureUnderMouse:T,apolloRowHeight:L,apolloRowUnderMouse:I,changeManager:P,codonLayout:q,featureLayout:_,features:U,featuresHeight:O,getAssemblyId:B,selectedFeature:j,setApolloFeatureUnderMouse:$,setApolloRowUnderMouse:G,setSelectedFeature:W,showIntronLines:H,showStartCodons:z,showStopCodons:V}=A,J=[...U.values()].map((e=>[...e.values()].map((e=>i.getSnapshot(e))))),X=y.useMemo((()=>{const{internetAccounts:e}=i.getRoot(k),{assemblyName:t}=R,{assemblyManager:a}=r.getSession(A),o=a.get(t);if(!o)throw new Error(`No assembly found with name ${t}`);const{internetAccountConfigId:s}=n.getConf(o,["sequence","metadata"]),l=e.find((e=>n.getConf(e,"internetAccountId")===s));if(!l)throw new Error(`No InternetAccount found with config id ${s}`);return l}),[A,R,k]),{role:Y}=X;return y.useEffect((()=>{Y?.includes("admin")&&p(!0),(Y?.includes("admin")??Y?.includes("user"))&&b(!1)}),[Y]),y.useEffect((()=>{const e=u.current;if(!e)return;const t=e.getContext("2d");if(!t)return;const n={};t.clearRect(0,0,M,O);for(const[e,a]of _)for(const[o,r]of a){const a=R.reversed?R.end-r.end:r.start-R.start-1,s=r.end-R.start-1,l=a/F,i=s/F;Bt(t,l,e*L,s-a,F,L);const c=e*L+L/2;n[o]||(n[o]=[]),n[o].some((e=>e[0]===l&&e[1]===c))||n[o].push([l,c]),n[o].some((e=>e[0]===i&&e[1]===c))||n[o].push([i,c])}if(H){let e=-Math.floor(Object.keys(n).length/2);for(const a in n){t.strokeStyle=`hsl(${e*(180*(3-Math.sqrt(5)))+60},100%,50%)`;const o=n[a].sort(((e,t)=>e[0]-t[0]));let[r]=o;for(const[n,a]of o.entries())if(0!==n){if(n%2==0){const n=[(a[0]-r[0])/2+r[0],Math.max(1,Math.min(r[1],a[1])-L/2+2*e)];t.beginPath(),t.moveTo(r[0],r[1]+2*e),t.lineTo(...n),t.stroke(),t.moveTo(...n),t.lineTo(a[0],a[1]+2*e),t.stroke()}r=a}e+=1}}}),[H,R,F,R.start,R.end,R.reversed,M,_,O,U,L,J]),y.useEffect((()=>{const e=f.current;if(!e)return;const t=e.getContext("2d");if(t){t.clearRect(0,0,M,O);for(const[e,{starts:n,stops:a}]of q){const o=F;for(const a of n){const n=a/o;R.start/o<=n&&n<=R.end/o&&(t.fillStyle="rgba(255,0,255,1)",z?t.fillRect(Math.round(n-.5-R.start/o),e*L,1,L):t.clearRect(Math.round(n-.5-R.start/o),e*L,1,L))}for(const n of a){const a=n/o;R.start/o<=a&&a<=R.end/o&&(t.fillStyle="black",V?t.fillRect(Math.round(a-.5-R.start/o),e*L,1,L):t.clearRect(Math.round(a-.5-R.start/o),e*L,1,L))}}}}),[z,V,q,M,O,F,L,R,R.start,R.end]),y.useEffect((()=>{const e=d.current;if(!e)return;const t=e.getContext("2d");if(t){t.clearRect(0,0,M,O);for(const e of C){const{locations:n}=e;if(0===n.length)return;for(const a of n){const{end:n,start:o}=a,r=(R.reversed?R.end-o:o-R.start)/F,s=(n-o)/F;t.fillStyle="rgba(0,255,0,.2)",t.fillRect(r,1,s,100),t.fillStyle="black",t.fillText(e.name,r+1,11,s-2)}}}}),[T,I,F,O,M,R,R.start,R.end,R.reversed,w,L,C]),ae.default.createElement("div",{style:{position:"relative",width:M,height:O}},ae.default.createElement(m.Menu,{open:Boolean(s),anchorReference:"anchorPosition",anchorPosition:a?{left:a[0],top:a[1]}:void 0,"data-testid":"base_linear_display_context_menu",onClose:()=>{c(void 0)}},ae.default.createElement(m.MenuItem,{disabled:h,key:1,value:1,onClick:()=>{if(!s)return;const e=B(R.assemblyName);k.queueDialog((t=>[rt,{session:k,handleClose:()=>{t(),c(void 0)},changeManager:P,sourceFeature:s,sourceAssemblyId:e,internetAccount:X}]))}},"Add child feature"),ae.default.createElement(m.MenuItem,{disabled:h,key:2,value:2,onClick:()=>{if(!s)return;const e=B(R.assemblyName);k.queueDialog((t=>[lt,{session:k,handleClose:()=>{t(),c(void 0)},changeManager:P,sourceFeature:s,sourceAssemblyId:e}]))}},"Copy features and annotations"),ae.default.createElement(m.MenuItem,{disabled:!g,key:3,value:3,onClick:()=>{if(!s)return;const e=B(R.assemblyName);k.queueDialog((t=>[ct,{session:k,handleClose:()=>{t(),c(void 0)},changeManager:P,sourceFeature:s,sourceAssemblyId:e,selectedFeature:j,setSelectedFeature:W}]))}},"Delete feature")),ae.default.createElement("canvas",{ref:u,width:M,height:O,style:{position:"absolute",left:0,top:0}}),ae.default.createElement("canvas",{ref:d,width:M,height:O,onMouseLeave:function(){$(),G()},onMouseUp:async function(){if(v){if(w){const e=B(R.assemblyName),{bp:n,edge:a,feature:o}=w;let r;if("end"===a){const a=o._id,s=o.end,l=Math.round(n);r=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[a],featureId:a,oldEnd:s,newEnd:l,assembly:e})}else{const a=o._id,s=o.start,l=Math.round(n);r=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[a],featureId:a,oldStart:s,newStart:l,assembly:e})}await(P?.submit(r))}}else T&&W(T);S(void 0),E(!1)},onContextMenu:function(e){e.preventDefault(),c(T),o([e.pageX,e.pageY])},style:{position:"absolute",left:0,top:0}}),ae.default.createElement("canvas",{ref:f,width:M,height:6*L,style:{position:"absolute",left:0,top:0}}))})),$t=n.ConfigurationSchema("ApolloSixFrameRenderer",{},{explicitlyTyped:!0});class Gt extends a.RendererType{async renderInClient(e,t){return this.render(t)}async freeResourcesInClient(e,t){return 0}}class Wt extends _.BaseAdapter{get baseURL(){return n.readConfObject(this.config,"baseURL").uri}get trackId(){return n.readConfObject(this.config,"trackId")}get assemblyNames(){return n.readConfObject(this.config,"assemblyNames")}mapBaseResult(e,t){return e.map((e=>new he.default({label:t,trackId:this.trackId,locString:`${e.refSeq?.name}:${e.start+1}..${e.end}`})))}async searchIndex(e){const t=[];for(const n of this.assemblyNames){const a=this.pluginManager?.rootModel?.session,o=a?.apolloDataStore.getBackendDriver(n),r=await o.searchFeatures(e.queryString,[n]);t.push(...r)}return this.mapBaseResult(t,e.queryString)}freeResources(){}}var Ht,zt=n.ConfigurationSchema("ApolloTextSearchAdapter",{assemblyNames:{type:"stringArray",defaultValue:[],description:"List of assemblies covered by text search adapter"},trackId:{type:"string",defaultValue:""},baseURL:{type:"fileLocation",defaultValue:{uri:"",locationType:"UriLocation"}}},{explicitlyTyped:!0,explicitIdentifier:"textSearchAdapterId"});function Vt({changeManager:e,handleClose:n,region:a,session:o}){const{notify:r}=o,[s,l]=y.useState(String(a.end)),[i,c]=y.useState(String(a.start+1)),[u,d]=y.useState(""),[f,g]=y.useState(""),[p,h]=y.useState(),[b,w]=y.useState(),[S,v]=y.useState(!1),[E,C]=y.useState(""),x=Number(s)<=Number(i);return ae.default.createElement(ke,{open:!0,title:"Add new feature",handleClose:n,maxWidth:!1,"data-testid":"add-feature-dialog"},ae.default.createElement("form",{onSubmit:async function(l){if(l.preventDefault(),C(""),S&&""===f)return void C("The phase is REQUIRED for all CDS features.");let c;for(const[,e]of o.apolloDataStore.assemblies??new Map)if(e._id===a.assemblyName)for(const[,t]of e.refSeqs??new Map)t.name===a.refName&&(c=t._id);if(!c)return void C("Invalid refseq id");const d=(new ne.default).toHexString(),m=new t.AddFeatureChange({changedIds:[d],typeName:"AddFeatureChange",assembly:a.assemblyName,addedFeature:{_id:d,gffId:"",refSeq:c,start:Number(i)-1,end:Number(s),type:u,phase:b,strand:p}});await(e.submit?.(m)),r("Feature added successfully","success"),n(),l.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.TextField,{margin:"dense",id:"start",label:"Start",type:"number",fullWidth:!0,variant:"outlined",value:Number(i),onChange:e=>c(e.target.value)}),ae.default.createElement(m.TextField,{margin:"dense",id:"end",label:"End",type:"number",fullWidth:!0,variant:"outlined",value:s,onChange:e=>l(e.target.value),error:x,helperText:x?'"End" must be greater than "Start"':null}),ae.default.createElement(at,{session:o,ontologyName:"Sequence Ontology",style:{width:170},value:u,filterTerms:et,renderInput:e=>ae.default.createElement(m.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0}),onChange:(e,t)=>{var n;t&&(n=t,C(""),d(n),n.startsWith("CDS")?(v(!0),g("")):v(!1))}}),ae.default.createElement(m.FormControl,null,ae.default.createElement(m.InputLabel,{id:"demo-simple-select-label"},"Strand"),ae.default.createElement(m.Select,{labelId:"demo-simple-select-label",id:"demo-simple-select",label:"Strand",value:p?.toString(),onChange:function(e){switch(C(""),Number(e.target.value)){case 1:h(1);break;case-1:h(-1);break;default:h(void 0)}}},ae.default.createElement(m.MenuItem,{value:void 0}),ae.default.createElement(m.MenuItem,{value:1},"+"),ae.default.createElement(m.MenuItem,{value:-1},"-"))),S?ae.default.createElement(m.FormControl,null,ae.default.createElement(m.InputLabel,null,"Phase"),ae.default.createElement(m.Select,{value:f,onChange:async function(e){switch(C(""),g(e.target.value),Number(e.target.value)){case 0:w(Ht.zero);break;case 1:w(Ht.one);break;case 2:w(Ht.two);break;default:w(void 0)}}},ae.default.createElement(m.MenuItem,{value:0},"0"),ae.default.createElement(m.MenuItem,{value:1},"1"),ae.default.createElement(m.MenuItem,{value:2},"2"))):null),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit",disabled:x||!(i&&s&&u)},"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),E?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},E)):null)}function Jt({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),{collaborationServerDriver:a}=t.apolloDataStore,o=n.find((e=>"ApolloInternetAccount"===e.type));if(!o)throw new Error("No Apollo internet account found");const{baseURL:r}=o,[s,l]=y.useState(),[c,u]=y.useState(),[d,f]=y.useState([]),g=a.getAssemblies();return y.useEffect((()=>{!c&&g.length>0&&u(g[0])}),[g,c]),y.useEffect((()=>{(async function(){const e=c?.name;if(!e)return;const t=new URL("checks",r),n=new URLSearchParams({assembly:e});t.search=n.toString();const a=t.toString(),s=o?.getFetcher({locationType:"UriLocation",uri:a});if(s){const e=await s(a,{headers:new Headers({"Content-Type":"application/json"})});if(!e.ok){const t=await Ae(e,"Error when retrieving checks");return void l(t)}const t=await e.json();f(t)}})().catch((e=>l(String(e))))}),[c,o,r]),ae.default.createElement(ke,{open:!0,fullScreen:!0,title:"View check results",handleClose:e,"data-testid":"view-check-results"},ae.default.createElement(m.Select,{style:{width:200,marginLeft:40},value:c?.name??"",onChange:function(e){const t=g.find((t=>t.name===e.target.value));u(t)},disabled:0===g.length},g.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),ae.default.createElement(m.DialogContent,null,ae.default.createElement(M.DataGrid,{pagination:!0,rows:d,columns:[{field:"_id",headerName:"id",width:50},{field:"name",headerName:"Check name",width:200},{field:"refSeq",headerName:"Reference sequence ID",width:200},{field:"ids",headerName:"Feature IDs",width:200},{field:"message",headerName:"Message",flex:1}],getRowId:e=>e._id,slots:{toolbar:M.GridToolbar},initialState:{sorting:{sortModel:[{field:"name",sort:"asc"}]},columns:{columnVisibilityModel:{name:!0}}}})),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:e},"Close")),s?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},s)):null)}!function(e){e[e.zero=0]="zero",e[e.one=1]="one",e[e.two=2]="two"}(Ht||(Ht={}));const Xt=n.ConfigurationSchema("ApolloPlugin",{ontologies:i.types.array(Qe)});function Yt(e){if("LinearPileupDisplay"!==e.name)return e;const{stateModel:n}=e,a=n.views((e=>({getFirstRegion:()=>r.getContainingView(e).dynamicBlocks.contentBlocks[0],getAssembly(){const t=e.getFirstRegion(),n=r.getSession(e),{assemblyManager:a}=n,{assemblyName:o}=t,s=a.get(o);if(!s)throw new Error(`Could not find assembly named ${o}`);return s},getRefSeqId(t){const n=e.getFirstRegion(),{refName:a}=n,{refNameAliases:o}=t;if(!o)throw new Error(`Could not find aliases for ${t.name}`);const r=[...Object.entries(o)].filter((([e,t])=>e!==t)).map((([e,t])=>({_id:e,name:t??""}))),s=r.find((e=>e.name===a))?._id;if(!s)throw new Error(`Could not find refSeqId named ${a}`);return s},createFeature(){const t=e.contextMenuFeature,n=e.getAssembly(),a=e.getRefSeqId(n),o=(t.get("CIGAR").toUpperCase().match(/\d+\D/g)??[]).map((e=>[(e.match(/\D/)??[])[0],Number.parseInt(e,10)]));let r=0;const s=t.get("start");let l;const i=[];for(const[e,t]of o)"M"===e||"="===e?void 0===l&&(l=r+s):"N"===e&&void 0!==l&&(i.push({start:l,end:r+l}),l=void 0),"I"!==e&&(r+=t);void 0!==l&&i.push({start:l,end:r+s});const c={_id:ne.default().toHexString(),gffId:"",refSeq:a,start:t.get("start"),end:t.get("end"),type:"mRNA",strand:t.get("strand")};if(0===i.length)return c;c.children={};const[u]=i,d={_id:ne.default().toHexString(),gffId:"",refSeq:a,start:u.start,end:u.end,type:"CDS",strand:t.get("strand"),phase:0};if(c.children[d._id]=d,1===i.length){const e={_id:ne.default().toHexString(),gffId:"",refSeq:a,start:u.start,end:u.end,type:"exon",strand:t.get("strand")};return c.children[e._id]=e,c}const f=[];let m=0;for(const e of i){d.start=Math.min(d.start,e.start),d.end=Math.max(d.end,e.end);const{end:n,start:o}=e;f?.push({start:o,end:n,phase:m}),m=(m+(n-o)%3)%3;const r={_id:ne.default().toHexString(),gffId:"",refSeq:a,start:o,end:n,type:"exon",strand:t.get("strand")};c.children[r._id]=r}return d.discontinuousLocations=f,c},async onPileupFeatureContext(){const n=e.createFeature(),a=e.getAssembly(),o=new t.AddFeatureChange({changedIds:[n._id],typeName:"AddFeatureChange",assembly:a.name,addedFeature:n}),s=r.getSession(e);await(s.apolloDataStore.changeManager.submit?.(o)),s.notify("Annotation added successfully","success")}}))).views((e=>{const t=e.contextMenuItems;return{contextMenuItems:()=>e.contextMenuFeature?[...t(),{label:"Create Apollo annotation",icon:K.default,onClick:e.onPileupFeatureContext}]:t()}}));return e.stateModel=a,e}const Kt=S.observer((function({onChangeCommitted:e,value:t,...n}){const[a,o]=y.useState(String(t)),[r,s]=y.useState(!1),[l,i]=y.useState(null);return y.useEffect((()=>{o(String(t))}),[t]),y.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]),ae.default.createElement(m.TextField,{...n,type:"text",onChange:function(e){o(e.target.value)},value:a,onKeyDown:e=>{"Enter"===e.key?l?.blur():"Escape"===e.key&&(o(String(t)),s(!0))},onBlur:()=>{a!==String(t)&&e(a)},inputRef:e=>i(e)})})),Zt=new Map([["Gene Ontology",e=>ae.default.createElement(pt,{...e,ontologyName:"Gene Ontology"})],["Sequence Ontology",e=>ae.default.createElement(pt,{...e,ontologyName:"Sequence Ontology"})]]),Qt=["ID","Name","Alias","Target","Gap","Derives_from","Note","Dbxref","Ontology","Is_Circular"],en=v.makeStyles()((e=>({newAttributePaper:{padding:e.spacing(2)},attributeName:{background:e.palette.secondary.main,color:e.palette.secondary.contrastText,padding:e.spacing(1)}})));function tn(e){const{onChange:t,value:n}=e;return ae.default.createElement(Kt,{value:n,onChangeCommitted:e=>{t(e.split(","))},variant:"outlined",fullWidth:!0,helperText:"Separate multiple values for the attribute with commas"})}const nn=S.observer((function({assembly:e,editable:n,feature:a,session:o}){const[r,s]=y.useState(""),[l,c]=y.useState(!1),{classes:u}=en(),[d,f]=y.useState(""),g=Object.fromEntries([...a.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]}))),{notify:p}=o,{changeManager:h}=o.apolloDataStore;async function b(n,o){s("");const r={};if(g){const e=Object.entries({...g,[n]:o});for(const[t,n]of e)if(n&&"parent"!==t.toLowerCase())if([...Zt.keys()].includes(t))r[t]=n;else switch(t){case"ID":r._id=n;break;case"Name":r.gff_name=n;break;case"Alias":r.gff_alias=n;break;case"Target":r.gff_target=n;break;case"Gap":r.gff_gap=n;break;case"Derives_from":r.gff_derives_from=n;break;case"Note":r.gff_note=n;break;case"Dbxref":r.gff_dbxref=n;break;case"Ontology_term":r.gff_ontology_term=n;break;case"Is_circular":r.gff_is_circular=n;break;default:r[t.toLowerCase()]=n}}const l=new t.FeatureAttributeChange({changedIds:[a._id],typeName:"FeatureAttributeChange",assembly:e,featureId:a._id,attributes:r});await(h.submit?.(l)),p("Feature attributes modified successfully","success")}return ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h4"},"Attributes"),ae.default.createElement(m.Grid,{container:!0,direction:"column",spacing:1},Object.entries(g).map((([e,t])=>{const a=Zt.get(e)??tn;return ae.default.createElement(m.Grid,{container:!0,item:!0,spacing:3,alignItems:"center",key:e},ae.default.createElement(m.Grid,{item:!0,xs:"auto"},ae.default.createElement(m.Paper,{variant:"outlined",className:u.attributeName},ae.default.createElement(m.Typography,null,e))),ae.default.createElement(m.Grid,{item:!0,flexGrow:1},ae.default.createElement(a,{session:o,value:t,onChange:t=>b(e,t)})),ae.default.createElement(m.Grid,{item:!0,xs:1},ae.default.createElement(m.IconButton,{"aria-label":"delete",size:"medium",disabled:!n,onClick:()=>b(e)},ae.default.createElement(ue.default,{fontSize:"medium",key:e}))))})),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Button,{color:"primary",variant:"contained",disabled:l||!n,onClick:()=>{c(!0)}},"Add new")),l?ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Paper,{elevation:8,className:u.newAttributePaper},ae.default.createElement(m.Grid,{container:!0,direction:"column"},ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.FormControl,null,ae.default.createElement(m.FormLabel,{id:"attribute-radio-button-group"},"Select attribute type"),ae.default.createElement(m.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:"custom",name:"radio-buttons-group",onChange:function(e,t){"custom"===t?f(""):Zt.has(t)?f(t):s("Unknown attribute type")}},ae.default.createElement(m.FormControlLabel,{value:"custom",control:ae.default.createElement(m.Radio,null),disableTypography:!0,label:ae.default.createElement(m.Grid,{container:!0,spacing:1,alignItems:"center"},ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Typography,null,"Custom")),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.TextField,{label:"Custom attribute key",variant:"outlined",value:Zt.has(d)?"":d,disabled:Zt.has(d),onChange:e=>{f(e.target.value)}})))}),[...Zt.keys()].map((e=>ae.default.createElement(m.FormControlLabel,{key:e,value:e,control:ae.default.createElement(m.Radio,null),label:e})))))),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{key:"addButton",color:"primary",variant:"contained",onClick:function(){s(""),0!==d.trim().length?"Parent"!==d?d in g?s(`Attribute "${d}" already exists`):!/^[A-Z]/.test(d)||Qt.includes(d)||[...Zt.keys()].includes(d)?b(d,[]):s(`Key cannot starts with uppercase letter unless key is one of these: ${Qt.join(", ")}`):s('"Parent" -key is handled internally and it cannot be modified manually'):s("Attribute key is mandatory")},disabled:!d},"Add"),ae.default.createElement(m.Button,{key:"cancelAddButton",variant:"outlined",type:"submit",onClick:()=>{c(!1),f(""),s("")}},"Cancel")))))):null),r?ae.default.createElement(m.Typography,{color:"error"},r):null)})),an=S.observer((function({onChangeCommitted:e,value:t,...n}){const[a,o]=y.useState(String(t)),[r,s]=y.useState(!1),[l,i]=y.useState(null);y.useEffect((()=>{o(String(t))}),[t]),y.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]);const c=Number.isNaN(Number(a));return ae.default.createElement(m.TextField,{...n,type:"text",onChange:function(e){o(e.target.value)},value:a,onKeyDown:e=>{"Enter"===e.key?l?.blur():"Escape"===e.key&&(o(String(t)),s(!0))},onBlur:()=>{const n=Number(a);a!==String(t)&&(Number.isNaN(n)?o(String(t)):e(n))},inputRef:e=>i(e),error:c,helperText:c?"Not a valid number":void 0})})),on=S.observer((function({assembly:e,feature:n,session:a}){const[o,r]=y.useState(""),[s,l]=y.useState(""),{_id:i,assemblyId:c,end:u,start:d,strand:f,type:g}=n,p=e=>a.notify(e.message,"error"),{changeManager:h}=a.apolloDataStore;return ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h4"},"Basic information"),ae.default.createElement(an,{margin:"dense",id:"start",label:"Start",fullWidth:!0,variant:"outlined",value:d+1,onChangeCommitted:function(n){n--;const a=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[i],featureId:i,oldStart:d,newStart:n,assembly:e});return h.submit(a)}}),ae.default.createElement(an,{margin:"dense",id:"end",label:"End",fullWidth:!0,variant:"outlined",value:u,onChangeCommitted:function(n){const a=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[i],featureId:i,oldEnd:u,newEnd:n,assembly:e});return h.submit(a)}}),ae.default.createElement(at,{session:a,ontologyName:"Sequence Ontology",value:g,filterTerms:et,fetchValidTerms:async function(e,t,n){const a=await nt(e,t);if(a)return a;l(`Type "${e?.type}" does not have any children in the ontology`)}.bind(null,n),renderInput:e=>ae.default.createElement(m.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0,error:Boolean(s),helperText:s}),onChange:(e,n)=>{n&&function(e){r("");const n=new t.TypeChange({typeName:"TypeChange",changedIds:[i],featureId:i,oldType:g,newType:e,assembly:c});return h.submit(n)}(n).catch(p)}}),ae.default.createElement(m.FormControl,null,ae.default.createElement(m.FormLabel,null,"Strand"),ae.default.createElement(m.RadioGroup,{row:!0,value:f??"",onChange:function(n){const{value:a}=n.target,o=a?Number(a):void 0,r=new t.StrandChange({typeName:"StrandChange",changedIds:[i],featureId:i,oldStrand:f,newStrand:o,assembly:e});return h.submit(r)}},ae.default.createElement(m.FormControlLabel,{value:"1",control:ae.default.createElement(m.Radio,null),label:"Forward (+)"}),ae.default.createElement(m.FormControlLabel,{value:"-1",control:ae.default.createElement(m.Radio,null),label:"Reverse (-)"}),ae.default.createElement(m.FormControlLabel,{value:"",control:ae.default.createElement(m.Radio,null),label:"None"}))),o?ae.default.createElement(m.Typography,{color:"error"},o):null)})),rn=v.makeStyles()((e=>({paper:{margin:e.spacing(2),padding:e.spacing(2),display:"flex",flexDirection:"column"}}))),sn=S.observer((function({assembly:e,feature:t,refName:n,session:a}){const{classes:o}=rn(),{parent:r}=t,{children:s}=t,l=t=>{if(r){const o=a.addWidget("ApolloFeatureDetailsWidget","apolloFeatureDetailsWidget",{feature:t,assembly:e,refName:n});a.showWidget?.(o)}};return r||s&&s.size>0?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h4"},"Related features"),r&&ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h5"},"Parent"),ae.default.createElement(m.Paper,{elevation:6,className:o.paper},`Start: ${r.start}, End: ${r.end}, Type: ${r.type}`,ae.default.createElement(m.Button,{variant:"contained",onClick:()=>l(r)},"Go to parent"))),s&&s.size>0&&ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h5"},"Children"),[...s.values()].map((e=>ae.default.createElement(m.Paper,{elevation:6,className:o.paper,key:e._id},`Start: ${e.start}, End: ${e.end}, Type: ${e.type}`,ae.default.createElement(m.Button,{variant:"contained",onClick:()=>l(e)},"Go to child")))))):null})),ln=v.makeStyles()({sequence:{width:"100%",resize:"vertical"}}),cn=S.observer((function({assembly:e,feature:t,refName:n,session:a}){const o=a.apolloDataStore.assemblies.get(e),[r,s]=y.useState(!1),{classes:l}=ln();if(!t||!o)return null;const i=o.getByRefName(n);if(!i)return null;const{end:c,start:u}=t;let d="";return r&&(d=i.getSequence(u,c),d?d=function(e,t,n,a,o){return`>${t}:${n+1}–${a}\n${e}`}(d,n,u,c):a.apolloDataStore.loadRefSeq([{assemblyName:e,refName:n,start:u,end:c}])),ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h4"},"Sequence"),ae.default.createElement(m.Button,{variant:"contained",onClick:()=>{s(!r)}},r?"Hide sequence":"Show sequence"),ae.default.createElement("div",null,r&&ae.default.createElement("textarea",{readOnly:!0,rows:20,className:l.sequence,value:d})))})),un=v.makeStyles()((e=>({root:{padding:e.spacing(2)}}))),dn=S.observer((function(e){const{model:t}=e,{assembly:n,feature:a,refName:o}=t,s=r.getSession(t),l=s.apolloDataStore.assemblies.get(n),{classes:c}=un(),{internetAccounts:u}=i.getRoot(s),d=y.useMemo((()=>u.find((e=>"ApolloInternetAccount"===e.type))),[u]),f=["admin","user"].includes((d?d.role:"admin")??"");if(!a||!l)return null;const m=l.getByRefName(o);if(!m)return null;const{end:g,start:p}=a;return m.getSequence(p,g)||s.apolloDataStore.loadRefSeq([{assemblyName:n,refName:o,start:p,end:g}]),ae.default.createElement("div",{className:c.root},ae.default.createElement(on,{feature:a,session:s,assembly:l._id}),ae.default.createElement("hr",null),ae.default.createElement(nn,{feature:a,session:s,assembly:l._id,editable:f}),ae.default.createElement("hr",null),ae.default.createElement(cn,{feature:a,session:s,assembly:l._id,refName:o}),ae.default.createElement("hr",null),ae.default.createElement(sn,{feature:a,refName:o,session:s,assembly:l._id}))})),fn=i.types.model("ApolloFeatureDetailsWidget",{id:E.ElementId,type:i.types.literal("ApolloFeatureDetailsWidget"),feature:i.types.maybe(i.types.reference(j.AnnotationFeature,{onInvalidated(e){e.parent.setTryReload(e.invalidId),e.removeRef()}})),assembly:i.types.string,refName:i.types.string}).volatile((()=>({tryReload:void 0}))).actions((e=>({setFeature(t){e.feature=t},setTryReload(t){e.tryReload=t}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((t=>{if(!e.tryReload)return;const n=r.getSession(e),{apolloDataStore:a}=n;if(!a)return;const o=a.getFeature(e.tryReload);o&&(e.setFeature(o),e.setTryReload(),t.dispose())})))}})));function mn(e,n,a,o,r){const s=n._id,l=void 0===r?new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[s],featureId:s,oldStart:a,newStart:o,assembly:n.assemblyId}):new t.DiscontinuousLocationStartChange({typeName:"DiscontinuousLocationStartChange",changedIds:[s],featureId:s,oldStart:a,newStart:o,assembly:n.assemblyId,index:r});return e.submit(l)}function gn(e,n,a,o,r){const s=n._id,l=void 0===r?new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[s],featureId:s,oldEnd:a,newEnd:o,assembly:n.assemblyId}):new t.DiscontinuousLocationEndChange({typeName:"DiscontinuousLocationEndChange",changedIds:[s],featureId:s,oldEnd:a,newEnd:o,assembly:n.assemblyId,index:r});return e.submit(l)}const pn=v.makeStyles()({highlighted:{background:"orange"}}),hn=({highlight:e,text:t})=>{const{classes:n}=pn();if(!e)return ae.default.createElement(ae.default.Fragment,null,t);const a=t.split(e);if(1===a.length)return ae.default.createElement(ae.default.Fragment,null,t);const o=[];for(let t=0;t<a.length-1;t++)o.push(a[t],ae.default.createElement("span",{className:n.highlighted},e));return ae.default.createElement(ae.default.Fragment,null,o,a.at(-1))},yn=S.observer((function({feature:e,filterText:t}){const n=[...e.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]})).map((([e,t])=>`${e}=${Array.isArray(t)?t.join(", "):t}`)).join(", ");return ae.default.createElement(hn,{text:n,highlight:t})})),bn=v.makeStyles()((e=>({inputWrapper:{position:"relative"},hiddenWidthSpan:{padding:e.spacing(.5),color:"transparent"},numberTextInput:{border:"none",background:"inherit",font:"inherit",position:"absolute",width:"100%",left:0}}))),wn=S.observer((function({initialValue:e,notifyError:t,onChangeCommitted:n}){const[a,o]=y.useState(e),[r,s]=y.useState(!1),[l,i]=y.useState(null),{classes:c}=bn();return y.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]),ae.default.createElement("span",{className:c.inputWrapper},ae.default.createElement("span",{className:c.hiddenWidthSpan,"aria-hidden":!0},a),ae.default.createElement("input",{type:"text",value:a,className:c.numberTextInput,onChange:function(e){const t=Number(e.target.value);Number.isNaN(t)||o(t)},onKeyDown:t=>{"Enter"===t.key?l?.blur():"Escape"===t.key&&(o(e),s(!0))},onBlur:()=>{a!==e&&n(a).catch(t)},ref:e=>i(e)}))})),Sn=v.makeStyles()((e=>({typeContent:{display:"inline-block",width:"174px",height:"100%",cursor:"text"},feature:{td:{position:"relative",verticalAlign:"top",paddingLeft:"0.5em"}},arrow:{display:"inline-block",width:"1.6em",textAlign:"center",cursor:"pointer"},arrowExpanded:{transform:"rotate(90deg)"},hoveredFeature:{backgroundColor:e.palette.action.hover},typeInputElement:{border:"none",background:"none"},typeErrorMessage:{color:"red"}})));function vn(e,t){const{changeManager:n,getAssemblyId:a,regions:o,selectedFeature:r,session:s,setSelectedFeature:l}=e;return function(e,t,n,a,o,r,s){const l=function(e){const{internetAccounts:t}=i.getParent(e);return t.find((e=>"ApolloInternetAccount"===e.type))}(r),c=l?l.role:"admin",u="admin"===c,d=!(c&&["admin","user"].includes(c)),f=[];if(e){const i=n(t.assemblyName),c=n(t.assemblyName);f.push({label:"Add child feature",disabled:d,onClick:()=>{r.queueDialog((t=>[rt,{session:r,handleClose:()=>{t()},changeManager:s,sourceFeature:e,sourceAssemblyId:i,internetAccount:l}]))}},{label:"Copy features and annotations",disabled:d,onClick:()=>{r.queueDialog((t=>[lt,{session:r,handleClose:()=>{t()},changeManager:s,sourceFeature:e,sourceAssemblyId:c}]))}},{label:"Delete feature",disabled:!u,onClick:()=>{r.queueDialog((t=>[ct,{session:r,handleClose:()=>{t()},changeManager:s,sourceFeature:e,sourceAssemblyId:c,selectedFeature:a,setSelectedFeature:o}]))}},{label:"Edit attributes",disabled:d,onClick:()=>{r.queueDialog((t=>[Et,{session:r,handleClose:()=>{t()},changeManager:s,sourceFeature:e,sourceAssemblyId:c}]))}})}return f}(t,o[0],a,r,l,s,n)}function En(e){let t=e;for(;t.parent;)t=t.parent;return t}const Cn=S.observer((function e({depth:n,feature:a,isHovered:o,isSelected:r,model:s,selectedFeatureClass:l,setContextMenu:i}){const{classes:c}=Sn(),{apolloHover:u,changeManager:d,selectedFeature:f,session:m,tabularEditor:g}=s,{featureCollapsed:p,filterText:h}=g,{_id:y,children:b,discontinuousLocations:w,end:S,phase:v,start:E,strand:C,type:x}=a,F=!p.get(y),A=e=>m.notify(e.message,"error");return ae.default.createElement(ae.default.Fragment,null,ae.default.createElement("tr",{onMouseEnter:e=>{s.setApolloHover({feature:a,topLevelFeature:En(a)})},className:c.feature+(r?` ${l}`:o?` ${c.hoveredFeature}`:""),onClick:e=>{e.stopPropagation(),s.setSelectedFeature(a)},onContextMenu:e=>(e.preventDefault(),i({position:{left:e.clientX+2,top:e.clientY-6},items:vn(s,a)}),!1)},ae.default.createElement("td",{style:{whiteSpace:"nowrap",borderLeft:2*n+"em solid transparent"}},b?.size?ae.default.createElement("div",{onClick:e=>{e.stopPropagation(),g.setFeatureCollapsed(y,F)},className:c.arrow+(F?` ${c.arrowExpanded}`:"")},"❯"):null,ae.default.createElement("div",{className:c.typeContent},ae.default.createElement(at,{session:m,ontologyName:"Sequence Ontology",style:{width:170},value:x,filterTerms:et,fetchValidTerms:xn.bind(null,a),renderInput:e=>ae.default.createElement("div",{ref:e.InputProps.ref},ae.default.createElement("input",{type:"text",...e.inputProps,className:c.typeInputElement,style:{width:170}}),e.error?ae.default.createElement("div",{className:c.typeErrorMessage},e.errorMessage??"unknown error"):null),onChange:(e,n)=>{n&&function(e,n,a,o){const r=n._id,s=new t.TypeChange({typeName:"TypeChange",changedIds:[r],featureId:r,oldType:String(a),newType:String(o),assembly:n.assemblyId});return e.submit(s)}(d,a,e,n).catch(A)}}))),ae.default.createElement("td",null,w&&w.length>0?ae.default.createElement("div",{style:{display:"flex",flexDirection:"column"}},w.map(((e,t)=>ae.default.createElement(wn,{key:`${y}:${e.start},${e.phase}`,initialValue:e.start+1,notifyError:A,onChangeCommitted:e=>mn(d,a,w[t].start,e-1,t)})))):ae.default.createElement(wn,{initialValue:E+1,notifyError:A,onChangeCommitted:e=>mn(d,a,E,e-1)})),ae.default.createElement("td",null,w&&w.length>0?ae.default.createElement("div",{style:{display:"flex",flexDirection:"column"}},w.map(((e,t)=>ae.default.createElement(wn,{key:`${y}:${e.end},${e.phase}`,initialValue:e.end,notifyError:A,onChangeCommitted:e=>gn(d,a,w[t].end,e,t)})))):ae.default.createElement(wn,{initialValue:S,notifyError:A,onChangeCommitted:e=>gn(d,a,S,e)})),ae.default.createElement("td",null,1===C?"+":-1===C?"-":void 0),ae.default.createElement("td",null,v),ae.default.createElement("td",null,ae.default.createElement(yn,{filterText:h,feature:a}))),F&&b?[...b.entries()].filter((e=>{if(!h)return!0;const[,t]=e;return JSON.stringify(t).includes(h)})).map((([t,a])=>ae.default.createElement(e,{isHovered:u?.feature?._id===a._id,isSelected:f?._id===a._id,selectedFeatureClass:l,key:t,depth:(n||0)+1,feature:a,model:s,setContextMenu:i}))):null)}));async function xn(e,t,n){const{parent:a}=e;if(a){const e=(await t.getTermsWithLabelOrSynonym(a.type,{includeSubclasses:!1})).filter(et);if(e.length>0)return await t.getClassesThat("part_of",e)}}const Fn=v.makeStyles()((e=>({scrollableTable:{width:"100%",height:"100%",th:{position:"sticky",top:0,zIndex:2,textAlign:"left",background:e.palette.background.paper,paddingTop:"3.2em"},td:{whiteSpace:"normal"}},selectedFeature:{backgroundColor:e.palette.action.selected}}))),An=S.observer((function({model:e}){const{apolloHover:t,seenFeatures:n,selectedFeature:a,tabularEditor:o}=e,r=m.useTheme(),{classes:s}=Fn(),l=y.useRef(null),[i,c]=y.useState(null),{filterText:u}=o;return y.useEffect((()=>{const e=l.current;if(e&&a){const t=e.querySelector(`.${s.selectedFeature}`);if(t){const n=e.scrollTop,a=t.offsetTop-25;a>n&&a<n+e.offsetHeight||e.scroll({top:a-40,behavior:"smooth"})}}}),[a,n,s.selectedFeature]),ae.default.createElement("div",{ref:l,style:{width:"100%",overflowY:"auto",height:"100%"}},ae.default.createElement("table",{className:s.scrollableTable},ae.default.createElement("thead",null,ae.default.createElement("tr",null,ae.default.createElement("th",null,"Type"),ae.default.createElement("th",null,"Start"),ae.default.createElement("th",null,"End"),ae.default.createElement("th",null,"Strand"),ae.default.createElement("th",null,"Phase"),ae.default.createElement("th",null,"Attributes"))),ae.default.createElement("tbody",null,[...n.entries()].filter((e=>{if(!u)return!0;const[,t]=e;return JSON.stringify(t).includes(u)})).sort(((e,t)=>e[1].start-t[1].start)).map((([n,o])=>ae.default.createElement(Cn,{key:n,isSelected:a?._id===n,isHovered:t?.feature?._id===n,selectedFeatureClass:s.selectedFeature,feature:o,model:e,depth:0,setContextMenu:c}))))),ae.default.createElement(b.Menu,{open:Boolean(i),onMenuItemClick:(e,t)=>{t(),c(null)},onClose:()=>{c(null)},TransitionProps:{onExit:()=>{c(null)}},style:{zIndex:r.zIndex.tooltip},menuItems:i?.items??[],anchorReference:"anchorPosition",anchorPosition:i?.position}))})),Dn=v.makeStyles()({toolbar:{width:"100%",display:"flex",paddingRight:"2em",flexDirection:"row",justifyContent:"space-between",position:"absolute",zIndex:4},filterText:{}}),kn=S.observer((function({model:e}){const t=e.tabularEditor,{classes:n}=Dn();return ae.default.createElement("div",{className:n.toolbar},ae.default.createElement(m.Tooltip,{title:"Collapse all"},ae.default.createElement(m.IconButton,{"aria-label":"collapse",sx:{marginTop:0},onClick:t.collapseAllFeatures},ae.default.createElement(be.default,null))),ae.default.createElement(m.TextField,{className:n.filterText,label:"Filter features",value:t.filterText,sx:{marginTop:0},variant:"outlined",onChange:e=>t.setFilterText(e.target.value),InputProps:{endAdornment:ae.default.createElement(m.InputAdornment,{position:"end"},ae.default.createElement(m.IconButton,{onClick:()=>t.clearFilterText()},ae.default.createElement(ye.default,null)))}}))}));function Nn(e){e.stopPropagation()}const Rn=S.observer((function({model:e}){return e.tabularEditor.isShown?ae.default.createElement("div",{onMouseDown:Nn,onClick:Nn,style:{width:"100%",height:"100%",position:"relative"}},ae.default.createElement(kn,{model:e}),ae.default.createElement(An,{model:e})):null})),Mn=i.types.model("TabularEditor",{isShown:!0,featureCollapsed:i.types.map(i.types.boolean),filterText:""}).actions((e=>({setFeatureCollapsed(t,n){e.featureCollapsed.set(t,n)},setFilterText(t){e.filterText=t},clearFilterText(){e.filterText=""},collapseAllFeatures(){const t=i.getParent(e);for(const[n]of t.seenFeatures.entries())e.featureCollapsed.set(n,!0)},togglePane(){e.isShown=!e.isShown},hidePane(){e.isShown=!1},showPane(){e.isShown=!0}})));class Tn{drawHover(e,t,n,a,o){}drawDragPreview(e,t){}startDrag(e,t){return!1}executeDrag(e,t){}onMouseDown(e,t){}onMouseMove(e,t){}onMouseLeave(e,t){}onMouseUp(e,t){}onContextMenu(e,t){}drawTooltip(e,t){const{apolloHover:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e;if(!n)return;const{feature:l,mousePosition:i}=n;if(!l||!i)return;const{regionNumber:c,y:u}=i,d=o[c],{refName:f,reversed:g}=d,{bpPerPx:p,bpToPx:h,offsetPx:y}=r,{discontinuousLocations:b}=l;let w,S,v,E="Loc: ";if(b&&b.length>0){const e=b.at(-1);if(!e)return;if(({start:w}=e),({end:S}=e),v=e.end-e.start,b.length<=2)for(const[e,t]of b.entries())E+=`${t.start+1}–${t.end}`,e!==b.length-1&&(E+=",");else{const[t]=b;E+=`${t.start+1}–${t.end},…,${e.start+1}–${e.end}`}}else({end:S,length:v,start:w}=l),E+=`${w+1}–${S}`;let C=(h({refName:f,coord:g?S:w,regionNumber:c})?.offsetPx??0)-y;const x=Math.floor(u/a)*a,F=v/p,A=`Type: ${l.type}`,{attributes:D}=l,k=D.get("gff_name")?.find((e=>""!==e)),N=[t.measureText(A).width,t.measureText(E).width];k&&N.push(t.measureText(`Name: ${k}`).width);const R=Math.max(...N);C=C+F+5,t.fillStyle=m.alpha(s?.palette.text.primary??"rgb(1, 1, 1)",.7),t.fillRect(C,x,R+4,3===N.length?45:35),t.beginPath(),t.moveTo(C,x),t.lineTo(C-5,x+5),t.lineTo(C,x+10),t.fill(),t.fillStyle=s?.palette.background.default??"rgba(255, 255, 255)";let M=x+12;t.fillText(A,C+2,M),k&&(M+=12,t.fillText(`Name: ${k}`,C+2,M)),M+=12,t.fillText(E,C+2,M)}getAdjacentFeatures(e,t){let n,a,o=0;if(!e||!t||!t.children)return{prevFeature:n,nextFeature:a};for(const[,n]of t.children){if(n._id===e._id)break;o++}const r=[...t.children.keys()];return o>0&&(n=t.children.get(r[o-1])),o<r.length-1&&(a=t.children.get(r[o+1])),{prevFeature:n,nextFeature:a}}getParentFeature(e,t){let n;if(!e||!t||!t.children)return n;for(const[,a]of t.children){if(a._id===e._id){n=t;break}if(a?.children){for(const[,t]of a.children)if(t._id===e._id){n=a;break}if(n)break}}return n}getContextMenuItems(e){const{apolloHover:t,apolloInternetAccount:n,changeManager:a,getAssemblyId:o,regions:r,selectedFeature:s,session:l,setSelectedFeature:i}=e,{feature:c}=t??{},u=n?n.role:"admin",d="admin"===u,f=!(u&&["admin","user"].includes(u)),m=[];if(c){const[e]=r,t=o(e.assemblyName),u=o(e.assemblyName);m.push({label:"Add child feature",disabled:f,onClick:()=>{l.queueDialog((e=>[rt,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:t,internetAccount:n}]))}},{label:"Copy features and annotations",disabled:f,onClick:()=>{l.queueDialog((e=>[lt,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:u}]))}},{label:"Delete feature",disabled:!d,onClick:()=>{l.queueDialog((e=>[ct,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:u,selectedFeature:s,setSelectedFeature:i}]))}},{label:"Modify feature attribute",disabled:f,onClick:()=>{l.queueDialog((e=>[Et,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:u}]))}},{label:"Edit feature details",onClick:()=>{const t=l.addWidget("ApolloFeatureDetailsWidget","apolloFeatureDetailsWidget",{feature:c,assembly:u,refName:e.refName});l.showWidget?.(t)}})}return m}}class Ln extends Tn{getRowCount(e){return 1}getIsSelectedFeature(e,t){return Boolean(t&&e._id===t._id)}getBackgroundColor(e,t){return t?e?.palette.text.primary??"black":e?.palette.background.default??"white"}getTextColor(e,t){return t?e?.palette.getContrastText(this.getBackgroundColor(e,t))??"white":e?.palette.text.primary??"black"}drawBox(e,t,n,a,o,r){e.fillStyle=r,e.fillRect(t,n,a,o)}drawBoxOutline(e,t,n,a,o,r){this.drawBox(e,t,n,a,o,r),e.clearRect(t+1,n+1,a-2,o-2)}drawBoxFill(e,t,n,a,o,r){this.drawBox(e,t+1,n+1,a-2,o-2,r)}drawBoxText(e,t,n,a,o,r){e.fillStyle=o;const s=Math.max(t+1,0);e.fillText(r,s,n+11,t-1+a-s)}draw(e,t,n,a,o,r){const{apolloRowHeight:s,lgv:l,session:i,theme:c}=e,{bpPerPx:u}=l,{apolloSelectedFeature:d}=i,f=(n.start-n.min)/u,m=n.length/u,g=r?a-f-m:a+f,p=o*s,h=this.getIsSelectedFeature(n,d),y=this.getBackgroundColor(c,h),b=this.getTextColor(c,h),w=h?"rgba(130,0,0,0.45)":"rgba(255,0,0,0.25)",S=[g,p,m,s];if(this.drawBoxOutline(t,...S,b),m<=2)return;let v=[n];if(n.discontinuousLocations&&n.discontinuousLocations.length>0&&(v=n.discontinuousLocations.map((e=>({start:e.start,end:e.end,type:n.type})))),v.length>1){this.drawBoxFill(t,...S,w);for(const e of v){const o=(e.start-n.min)/u,l=(e.end-e.start)/u;this.drawBoxOutline(t,r?a-o-l:a+o,p,l,s,b)}}for(const e of v){const o=(e.start-n.min)/u,l=(e.end-e.start)/u,i=r?a-o-l:a+o;this.drawBoxFill(t,i,p,l,s,y),this.drawBoxText(t,i,p,l,b,e.type)}}getFeatureFromLayout(e,t,n){return e}getRowForFeature(e,t){return 0}isMouseOnFeatureEdge(e,t,n){if(!e)return;const{refName:a,regionNumber:o,x:r}=e,{lgv:s}=n,{bpToPx:l,offsetPx:i}=s,c=l({refName:a,coord:t.start,regionNumber:o}),u=l({refName:a,coord:t.end,regionNumber:o});if(void 0!==c&&void 0!==u){const e=c.offsetPx-i,t=u.offsetPx-i;if(Math.abs(t-e)<8)return;if(Math.abs(e-r)<4)return"start";if(Math.abs(t-r)<4)return"end"}}drawHover(e,t){const{apolloHover:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e;if(!n)return;const{feature:l,mousePosition:i}=n;if(!l||!i)return;const{bpPerPx:c,bpToPx:u,offsetPx:d}=r,f=o[i.regionNumber],{refName:m,reversed:g}=f,{end:p,length:h,start:y}=l,{regionNumber:b,y:w}=i,S=(u({refName:m,coord:g?p:y,regionNumber:b})?.offsetPx??0)-d,v=Math.floor(w/a)*a,E=h/c;t.fillStyle=s?.palette.action.focus??"rgba(0,0,0,0.04)",t.fillRect(S,v,E,a)}drawDragPreview(e,t){const{apolloDragging:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e,{bpPerPx:l,offsetPx:i}=r;if(!n)return;const{feature:c,glyph:u,mousePosition:d}=n.start;if(!c)throw new Error("no feature for drag preview??");if(u!==this)throw new Error("drawDragPreview() called on wrong glyph?");const{mousePosition:f}=n.current,g=this.isMouseOnFeatureEdge(d,c,e);if(!g)return;const p=Math.floor(d.y/a),h=o[d.regionNumber],y=this.getRowCount(c),b=(h.reversed?h.end-c[g]:c[g]-h.start)/l-i,w=Math.min(f.x,b),S=p*a,v=Math.abs(f.x-b),E=a*y;t.strokeStyle=s?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(w,S,v,E),t.fillStyle=m.alpha(s?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(w,S,v,E)}onMouseMove(e,t){const{feature:n,mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);e.apolloDragging?e.setCursor("col-resize"):n&&a&&(this.isMouseOnFeatureEdge(a,n,e)?e.setCursor("col-resize"):e.setCursor())}onMouseDown(e,t){const{feature:n,mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);n&&a&&this.isMouseOnFeatureEdge(a,n,e)&&t.stopPropagation()}onMouseUp(e,t){if(e.apolloDragging??0!==t.button)return;const{feature:n}=e.getFeatureAndGlyphUnderMouse(t);n&&e.setSelectedFeature(n)}startDrag(e){const{feature:t,mousePosition:n}=e.apolloDragging?.start??{};return!!(t&&n&&this.isMouseOnFeatureEdge(n,t,e))}continueDrag(e,t){const{feature:n,glyph:a,mousePosition:o,topLevelFeature:r}=e.apolloDragging?.start??{};t&&o&&e.setDragging({start:{feature:n,topLevelFeature:r,glyph:a,mousePosition:o},current:{feature:n,topLevelFeature:r,glyph:a,mousePosition:t}})}executeDrag(e){const{apolloDragging:n,changeManager:a,displayedRegions:o,getAssemblyId:r,setCursor:s}=e;if(!n)return;const{feature:l,glyph:i,mousePosition:c}=n.start;if(!l)throw new Error("no feature for drag preview??");if(i!==this)throw new Error("drawDragPreview() called on wrong glyph?");const u=this.isMouseOnFeatureEdge(c,l,e);if(!u)return;const{mousePosition:d}=n.current,f=d.bp,m=r(o[c.regionNumber].assemblyName);let g;if("end"===u){const e=l._id;g=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[e],featureId:e,oldEnd:l.end,newEnd:f,assembly:m})}else{const e=l._id;g=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[e],featureId:e,oldStart:l.start,newStart:f,assembly:m})}if(!a)throw new Error("no change manager");a.submit(g),s()}}const In=i.types.model({heightPreConfig:i.types.maybe(i.types.refinement("displayHeight",i.types.number,(e=>e>=20)))}).volatile((()=>({scrollTop:0}))).views((e=>({get height(){return e.heightPreConfig??n.getConf(e,"height")}}))).actions((e=>({setScrollTop(t){e.scrollTop=t},setHeight:t=>(e.heightPreConfig=Math.max(t,20),e.height),resizeHeight(t){const n=e.height;return this.setHeight(e.height+t)-n}})));function Pn(e,t,n,a){return 1===n?(e+a)%3+1:(t-a)%3*-1-1}const qn=[null,"#FF8080","#80FF80","#8080FF","#8080FF","#80FF80","#FF8080"];function _n(e,t){return t?.palette.bases[e.toUpperCase()].main.toString()??"lightgray"}function Un(e,t,n,a,o){const r=Math.min(n,10);e.fillStyle="#000",e.font=`${r}px`;const s=e.measureText(a).width;e.fillText(a,t+(n-s)/2,o+10)}function On(e,t,n,a,o,s,l,i,c,u){let d=l.slice(i,i+3).toUpperCase();c&&(d=function(e){return[...e].map((e=>r.revcom(e))).reverse().join("")}(d));const f=r.defaultCodonTable[d];f&&(e.beginPath(),e.fillStyle=function(e,t,n){const a={M:"#33ee33","*":"#f44336"};return void 0!==a[e?.toUpperCase()]?a[e?.toUpperCase()]:n<=.1?t:"lightgray"}(f,u,t),e.rect(n,a,o,s),e.fill(),t<=.1&&(e.stroke(),Un(e,n,o,f,a)))}let Bn=null,jn=null;if("document"in window)for(const e of["forward","backward"]){const t=document.createElement("canvas"),n=10;t.width=t.height=n;const a=t.getContext("2d");if(a){const o="rgba(0,0,0,0)",r="rgba(255,255,255,0.25)",s="forward"===e?a.createLinearGradient(0,n,n,0):a.createLinearGradient(0,0,n,n);s.addColorStop(0,o),s.addColorStop(.25,o),s.addColorStop(.25,r),s.addColorStop(.5,r),s.addColorStop(.5,o),s.addColorStop(.75,o),s.addColorStop(.75,r),s.addColorStop(1,r),a.fillStyle=s,a.fillRect(0,0,10,10),"forward"===e?Bn=a.createPattern(t,"repeat"):jn=a.createPattern(t,"repeat")}}let $n=null,Gn=null;if("document"in window)for(const e of["forward","backward"]){const t=document.createElement("canvas"),n=10;t.width=t.height=n;const a=t.getContext("2d");if(a){const o="rgba(0,0,0,0)",r="rgba(255,255,255,0.25)",s="forward"===e?a.createLinearGradient(0,n,n,0):a.createLinearGradient(0,0,n,n);s.addColorStop(0,o),s.addColorStop(.25,o),s.addColorStop(.25,r),s.addColorStop(.5,r),s.addColorStop(.5,o),s.addColorStop(.75,o),s.addColorStop(.75,r),s.addColorStop(1,r),a.fillStyle=s,a.fillRect(0,0,10,10),"forward"===e?$n=a.createPattern(t,"repeat"):Gn=a.createPattern(t,"repeat")}}const Wn=new Ln,Hn=new class extends Tn{featuresForRow(e){const t=[];for(const[,n]of e.children??new Map)for(const[,e]of n.children??new Map)"CDS"===e.type&&t.push({parent:n,cds:e});const n=[];for(const e of t){const t=[];for(const[,n]of e.parent.children??new Map)if("CDS"!==n.type||n._id===e.cds._id)if(n.discontinuousLocations&&n.discontinuousLocations.length>0)for(const a of n.discontinuousLocations)t.push({annotationFeature:n,parent:e.parent,start:a.start,end:a.end,phase:a.phase});else t.push({annotationFeature:n,parent:e.parent});t.push({annotationFeature:e.parent}),n.push(t)}return n}getRowCount(e,t){let n=0;for(const[,t]of e.children??new Map)for(const[,e]of t.children??new Map)"CDS"===e.type&&(n+=1);return n}draw(e,t,n,a,o,r){const{apolloRowHeight:s,lgv:l,session:i,theme:c}=e,{bpPerPx:u}=l,d=s,f=Math.round(.6*d),m=Math.round(.9*d),{_id:g,children:p,min:h,strand:y}=n,{apolloSelectedFeature:b}=i;let w=0;for(const[,e]of p??new Map)if("mRNA"===e.type)for(const[,n]of e.children??new Map){if("CDS"!==n.type)continue;const s=(e.start-h)/u,l=e.length/u,i=r?a-s-l:a+s,f=Math.round((w+.5)*d)+o*d;t.strokeStyle=c?.palette.text.primary??"black",t.beginPath(),t.moveTo(i,f),t.lineTo(i+l,f),t.stroke(),w+=1}w=0;for(const[,e]of p??new Map){if("mRNA"!==e.type)continue;const n=[...e.children??[]].filter((([,e])=>"CDS"===e.type)).length;for(let s=0;s<n;s++){for(const[,n]of e.children??new Map){if("exon"!==n.type)continue;const e=(n.start-h)/u,s=n.length/u,l=r?a-e-s:a+e,i=(o+w)*d+(d-f)/2;if(t.fillStyle=c?.palette.text.primary??"black",t.fillRect(l,i,s,f),s>2&&(t.clearRect(l+1,i+1,s-2,f-2),t.fillStyle=b&&n._id===b._id?"rgb(0,0,0)":"rgb(211,211,211)",t.fillRect(l+1,i+1,s-2,f-2),Bn&&jn&&y)){const e=r?-1:1,[n,a]=y*e==1?[Bn,jn]:[jn,Bn];t.fillStyle=n,t.fillRect(l+1,i+1,s-2,(f-2)/2),t.fillStyle=a,t.fillRect(l+1,i+1+(f-2)/2,s-2,(f-2)/2)}}w+=1}}w=0;for(const[,e]of p??new Map)if("mRNA"===e.type)for(const[,n]of e.children??new Map)if("CDS"===n.type){if(n.discontinuousLocations)for(const e of n.discontinuousLocations){const s=(e.start-h)/u,l=(e.end-e.start)/u,i=r?a-s-l:a+s;t.fillStyle=c?.palette.text.primary??"black";const f=(o+w)*d+(d-m)/2;if(t.fillRect(i,f,l,m),l>2){t.clearRect(i+1,f+1,l-2,m-2);const a=Pn(e.start,e.end,e.strand,e.phase),o=qn.at(a)??"rgb(171,71,188)";if(t.fillStyle=b&&n._id===b._id?"rgb(0,0,0)":o,t.fillRect(i+1,f+1,l-2,m-2),Bn&&jn&&y){const e=r?-1:1,[n,a]=y*e==1?[Bn,jn]:[jn,Bn];t.fillStyle=n,t.fillRect(i+1,f+1,l-2,(m-2)/2),t.fillStyle=a,t.fillRect(i+1,f+(m-2)/2,l-2,(m-2)/2)}}}w+=1}if(b)if(g===b._id){const e=n.length/u,s=r?a-e:a,l=o*d,i=this.getRowCount(n)*d;t.fillStyle=c?.palette.action.selected??"rgba(0,0,0,0.08)",t.fillRect(s,l,e,i)}else{let e,n,s=0;for(const[,t]of p??new Map)t._id===b?._id&&(e=t,n=s),s++;if(void 0===e||void 0===n)return;const l=this.cdsCount(e);let i=d;l>1&&(i*=l);const f=e.length/u,m=r?a-f:a+(e.start-h)/u,g=(o+n)*d;t.fillStyle=c?.palette.action.selected??"rgba(0,0,0,08)",t.fillRect(m,g,f,i)}}cdsCount(e){let t=0;for(const[,n]of e?.children??new Map)"CDS"===n.type&&n.discontinuousLocations&&n.discontinuousLocations.length>0&&t++;return t}drawHover(e,t,n,a,o){const{apolloHover:r}=e;if(!r)return;const{feature:s}=r;if(s)if(s.discontinuousLocations&&s.discontinuousLocations.length>0)for(const n of s.discontinuousLocations)this.drawShadeForFeature(e,t,n.start,n.end,n.end-n.start);else this.drawShadeForFeature(e,t,s.start,s.end,s.length,n,a,o)}drawShadeForFeature(e,t,n,a,o,r,s,l){const{apolloHover:i,apolloRowHeight:c,displayedRegions:u,lgv:d,theme:f}=e,{bpPerPx:m,bpToPx:g,offsetPx:p}=d;if(!i)return;const{feature:h,topLevelFeature:y}=i;if(!h||!y)return;let b,w,S,v=0;for(const[,e]of y.children??new Map){e._id===h?._id&&(b=e,S=v);for(const[,t]of e.children??new Map)t._id===h._id&&(w=t,b=e,S=v);v++}const E=this.cdsCount(b);if(E>1&&r&&s){if(void 0===b||void 0===S)return;const e=w?w.length/m:b.length/m,n=l?s-e:s+(w?(w.start-h.min)/m:(b.start-h.min)/m),a=(r+S)*c;t.fillStyle=f?.palette.action.selected??"rgba(0,0,0,04)",t.fillRect(n,a,e,c*E)}else{const{mousePosition:e}=i;if(!e)return;const r=c,{regionNumber:s,y:l}=e,d=Math.floor(l/r),h=u[s],{refName:y,reversed:b}=h,w=(g({refName:y,coord:b?a:n,regionNumber:s})?.offsetPx??0)-p,S=d*r,v=o/m;t.fillStyle=f?.palette.action.focus??"rgba(0,0,0,0.04)",t.fillRect(w,S,v,r)}}drawDragPreview(e,t){const{apolloDragging:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e,{bpPerPx:l,offsetPx:i}=r;if(!n)return;const{discontinuousLocation:c,feature:u,glyph:d,mousePosition:f}=n.start;if(!u)throw new Error("no feature for drag preview??");if(d!==this)throw new Error("drawDragPreview() called on wrong glyph?");const{mousePosition:g}=n.current,p=this.isMouseOnFeatureEdge(f,u,e);if(!p)return;const h=Math.floor(f.y/a),y=o[f.regionNumber];let b;b=c?y.reversed?y.end-c[p]:c[p]-y.start:y.reversed?y.end-u[p]:u[p]-y.start;const w=b/l-i,S=Math.min(g.x,w),v=h*a,E=Math.abs(g.x-w),C=1*a;t.strokeStyle=s?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(S,v,E,C),t.fillStyle=m.alpha(s?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(S,v,E,C)}isMouseOnFeatureEdge(e,t,n,a){if(!e)return;const{bp:o,refName:r,regionNumber:s,x:l}=e,{lgv:i}=n,{bpToPx:c,offsetPx:u}=i;let d,f;if(t.discontinuousLocations&&t.discontinuousLocations.length>0){let e;for(const n of t.discontinuousLocations)if(o>=n.start&&o<=n.end){e=n;break}if(!e)return;d=c({refName:r,coord:e.start,regionNumber:s}),f=c({refName:r,coord:e.end,regionNumber:s})}else d=c({refName:r,coord:t.start,regionNumber:s}),f=c({refName:r,coord:t.end,regionNumber:s});if(void 0!==d&&void 0!==f){const e=d.offsetPx-u,n=f.offsetPx-u;if(Math.abs(n-e)<8)return;const o=this.getParentFeature(t,a);if(o){if("gene"===o.type)return;if(t.start<=o.start&&Math.abs(e-l)<4)return;if(t.end>=o.end&&Math.abs(n-l)<4)return}if(Math.abs(e-l)<4)return"start";if(Math.abs(n-l)<4)return"end"}}onMouseMove(e,t){const{feature:n,mousePosition:a,topLevelFeature:o}=e.getFeatureAndGlyphUnderMouse(t);e.apolloDragging?e.setCursor("col-resize"):n&&a&&(this.isMouseOnFeatureEdge(a,n,e,o)?e.setCursor("col-resize"):e.setCursor())}onMouseDown(e,t){const{feature:n,mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);n&&a&&this.isMouseOnFeatureEdge(a,n,e)&&t.stopPropagation()}onMouseUp(e,t){if(e.apolloDragging??0!==t.button)return;const{feature:n}=e.getFeatureAndGlyphUnderMouse(t);n&&e.setSelectedFeature(n)}startDrag(e){const{feature:t,mousePosition:n,topLevelFeature:a}=e.apolloDragging?.start??{},{mousePosition:o}=e.apolloDragging?.current??{};return!!(t&&n&&o&&this.isMouseOnFeatureEdge(n,t,e,a))}adjacentExonsOfCdsDL(e,t){let n,a,o,r;if(t){for(const[n,a]of t.entries()){const t=a.cdsDL;if(e.start===t?.start&&e.end===t.end&&e.phase===t.phase){r=n;break}}if(void 0!==r){const{exon:e}=t[r];o=e}void 0!==r&&r>0&&(n=t[r-1].exon),void 0!==r&&r<t.length-1&&(a=t[r+1].exon)}return{prevExon:n,matchingExon:o,nextExon:a}}exonCDSRelation(e,t){const n=[];if(!e)return n;const a=this.getParentFeature(e,t);if(!a?.children)return n;for(const[,t]of a.children)if("exon"===t.type){const a=this.cdsDLForExon(t,e);n.push({exon:t,cdsDL:a?{start:a.start,end:a.end,phase:a.phase}:void 0})}return n}cdsDLForExon(e,t){let n;if(t.discontinuousLocations&&t.discontinuousLocations.length>0)for(const a of t.discontinuousLocations)if(a.start>=e.start&&a.end<=e.end){n=a;break}return n}cdsDlsForExon(e,t){const n=[],a=this.getParentFeature(e,t);if(!a?.children||!t)return n;const o=[];for(const[,e]of a.children)"CDS"===e.type&&o.push(e);for(const t of o)for(const[,o]of a.children)if("exon"===o.type&&o._id===e._id){const e=this.cdsDLForExon(o,t);e&&n.push(e)}return n}adjacentExonsOfExon(e,t){const n=this.getParentFeature(e,t);if(!n||!n.children)return;let a,o,r=0;for(const[,t]of n.children){if(t._id===e._id)break;r++}const s=[...n.children.keys()];if(r>0){const e=n.children.get(s[r-1]);e&&"exon"===e.type&&(a=e)}if(r<s.length-1){const e=n.children.get(s[r+1]);e&&"exon"===e.type&&(o=e)}return{prevExon:a,nextExon:o}}continueDrag(e,t){const{discontinuousLocation:n,feature:a,glyph:o,mousePosition:r,topLevelFeature:s}=e.apolloDragging?.start??{};if(!t||!r)return;const{bp:l}=t;if(!a||!t)return;const i=this.isMouseOnFeatureEdge(r,a,e,s);if("CDS"===a.type&&a.discontinuousLocations&&a.discontinuousLocations.length>0&&n){const e=this.exonCDSRelation(a,s),{matchingExon:t,nextExon:o,prevExon:r}=this.adjacentExonsOfCdsDL(n,e);if(o&&l>=o.start-1)return;if(r&&l<=r.end+1)return;if(!r&&o&&t&&l<t.start)return;if(r&&!o&&t&&l>t.end)return;if(i&&("start"===i&&l>=n.end-1||"end"===i&&l<=n.start+1))return}if("CDS"!==a.type){const e=this.adjacentExonsOfExon(a,s);if(e?.nextExon&&l>=e?.nextExon.start-1)return;if(e?.prevExon&&l<=e?.prevExon.end+1)return;const t=this.cdsDlsForExon(a,s);if(t&&t.length>0){let e;for(const n of t)if(i&&("start"===i&&l>=n.start-1||"end"===i&&l<=n.end+1)){e=!0;break}if(e)return}else if(i&&("start"===i&&l>=a.end-1||"end"===i&&l<=a.start+1))return}e.setDragging({start:{feature:a,topLevelFeature:s,glyph:o,discontinuousLocation:n,mousePosition:r},current:{feature:a,topLevelFeature:s,glyph:o,mousePosition:t}})}getFeatureFromLayout(e,t,n){const a=this.featuresForRow(e)[n];let o;for(const e of a)void 0!==e.start&&void 0!==e.end&&void 0!==e.phase?t>=e.start&&t<=e.end&&e.parent&&(o=e.annotationFeature):t>=e.annotationFeature.start&&t<=e.annotationFeature.end&&e.parent&&(o=e.annotationFeature);return o||(o=a.at(-1)?.annotationFeature),o}getRowForFeature(e,t){const n=this.featuresForRow(e);for(const[e,a]of n.entries())if(a.some((e=>e.annotationFeature._id===t._id)))return e}async executeDrag(e){const{apolloDragging:t,changeManager:n,displayedRegions:a,getAssemblyId:o,setCursor:r}=e;if(!t)return;const{discontinuousLocation:s,feature:l,glyph:i,mousePosition:c,topLevelFeature:u}=t.start;if(!l)throw new Error("no feature for drag preview??");if(i!==this)throw new Error("drawDragPreview() called on wrong glyph?");const d=this.isMouseOnFeatureEdge(c,l,e);if(!d)return;const{mousePosition:f}=t.current,m=f.bp,g=o(a[c.regionNumber].assemblyName),p=[];if("start"===d)if(void 0!==s?.idx&&l.discontinuousLocations&&l.discontinuousLocations.length>0){this.addDiscontinuousLocStartChange(p,l,m,l.discontinuousLocations[s.idx].start,g,s.idx);const e=this.exonCDSRelation(l,u),t=this.adjacentExonsOfCdsDL(s,e);t&&t.matchingExon&&m<t.matchingExon.start&&this.addStartLocationChange(p,t.matchingExon,m,g)}else this.addStartLocationChange(p,l,m,g);else if(void 0!==s?.idx&&l.discontinuousLocations&&l.discontinuousLocations.length>0){this.addDiscontinuousLocEndChange(p,l,m,l.discontinuousLocations[s.idx].end,g,s.idx);const e=this.exonCDSRelation(l,u),t=this.adjacentExonsOfCdsDL(s,e);t&&t.matchingExon&&m>t.matchingExon.end&&this.addEndLocationChange(p,t.matchingExon,m,g)}else this.addEndLocationChange(p,l,m,g);if(!n)throw new Error("no change manager");for(const e of p)await n.submit(e);r()}addDiscontinuousLocStartChange(e,n,a,o,r,s){e.push(new t.DiscontinuousLocationStartChange({typeName:"DiscontinuousLocationStartChange",changedIds:[n._id],featureId:n._id,newStart:a,oldStart:o,index:s,assembly:r}))}addDiscontinuousLocEndChange(e,n,a,o,r,s){e.push(new t.DiscontinuousLocationEndChange({typeName:"DiscontinuousLocationEndChange",changedIds:[n._id],featureId:n._id,newEnd:a,oldEnd:o,index:s,assembly:r}))}addEndLocationChange(e,n,a,o){const r=n._id;e.push(new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[r],featureId:r,oldEnd:n.end,newEnd:a,assembly:o}))}addStartLocationChange(e,n,a,o){const r=n._id;e.push(new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[r],featureId:r,oldStart:n.start,newStart:a,assembly:o}))}},zn=new class extends Ln{featuresForRow(e){const t=[[e]];if(e.children)for(const[,n]of e.children??new Map)t.push(...this.featuresForRow(n));return t}getRowCount(e){return this.featuresForRow(e).length}draw(e,t,n,a,o,r){for(let s=0;s<this.getRowCount(n);s++)this.drawRow(e,t,n,a,o+s,o,r)}drawRow(e,t,n,a,o,r,s){const l=this.featuresForRow(n)[o-r];for(const r of l)this.drawFeature(e,t,n,r,a,o,s)}drawFeature(e,t,n,a,o,r,s){const{apolloRowHeight:l,lgv:i,session:c}=e,{bpPerPx:u}=i,{apolloSelectedFeature:d}=c,f=(a.start-n.min)/u,m=a.length/u,g=s?o-f-m:o+f,p=r*l,h=this.getRowCount(a),y=this.getIsSelectedFeature(a,d);h>1&&this.drawBox(t,g,p,m,h*l,y?"rgba(130,0,0,0.45)":"rgba(255,0,0,0.25)"),super.draw(e,t,a,g,r,s)}drawHover(e,t){const{apolloHover:n,apolloRowHeight:a,displayedRegions:o,lgv:r}=e;if(!n)return;const{feature:s,mousePosition:l}=n;if(!s||!l)return;const{regionNumber:i,y:c}=l,u=o[i],{refName:d,reversed:f}=u,{bpPerPx:m,bpToPx:g,offsetPx:p}=r,{end:h,length:y,start:b}=s,w=(g({refName:d,coord:f?h:b,regionNumber:i})?.offsetPx??0)-p,S=Math.floor(c/a)*a,v=y/m;t.fillStyle="rgba(0,0,0,0.2)",t.fillRect(w,S,v,a*this.getRowCount(s))}onMouseUp(e,t){if(e.apolloDragging??0!==t.button)return;const{feature:n}=e.getFeatureAndGlyphUnderMouse(t);n&&e.setSelectedFeature(n)}continueDrag(e,t){}getFeatureFromLayout(e,t,n){const a=this.featuresForRow(e)[n];return a?.find((e=>t>=e.start&&t<=e.end))}getRowForFeature(e,t){const n=this.featuresForRow(e);for(const[e,a]of n.entries())if(a.some((e=>e._id===t._id)))return e}},Vn=new class extends Tn{featuresForRow(e){const t=[];for(const[,n]of e.children??new Map){const e=[];for(const[,t]of n.children??new Map)e.push(t);e.push(n),t.push(e)}return t}getRowCount(e){let t=0;for(const[,n]of e.children??new Map)"mRNA"===n.type&&(t+=1);return t}draw(e,t,n,a,o,r){const{apolloRowHeight:s,lgv:l,session:i,theme:c}=e,{bpPerPx:u}=l,d=s,f=Math.round(.6*d),m=Math.round(.9*d),{_id:g,children:p,min:h,strand:y}=n,{apolloSelectedFeature:b}=i;let w=0;for(const[,e]of p??new Map){if("mRNA"!==e.type)continue;const n=(e.start-h)/u,s=e.length/u,l=r?a-n-s:a+n,i=Math.round((w+.5)*d)+o*d;t.strokeStyle=c?.palette.text.primary??"black",t.beginPath(),t.moveTo(l,i),t.lineTo(l+s,i),t.stroke(),w+=1}w=0;for(const[,e]of p??new Map){if("mRNA"!==e.type)continue;const n=[...e.children??[]].filter((([,e])=>"CDS"===e.type)).length;for(let s=0;s<n;s++)for(const[,n]of e.children??new Map){const e="CDS"===n.type,s=n.type.endsWith("UTR");if(!e&&!s)continue;const l=(n.start-h)/u,i=n.length/u,g=r?a-l-i:a+l;t.fillStyle=c?.palette.text.primary??"black";const p=e?m:f,S=(o+w)*d+(d-p)/2;if(t.fillRect(g,S,i,p),i>2){t.clearRect(g+1,S+1,i-2,p-2);let a="rgb(211,211,211)";if(e){const e=Pn(n.start,n.end,n.strand,n.phase);a=qn.at(e)??"rgb(171,71,188)"}if(t.fillStyle=b&&n._id===b._id?"rgb(0,0,0)":a,t.fillRect(g+1,S+1,i-2,p-2),$n&&Gn&&y){const e=r?-1:1,[n,a]=y*e==1?[$n,Gn]:[Gn,$n];t.fillStyle=n,t.fillRect(g+1,S+1,i-2,(p-2)/2),t.fillStyle=a,t.fillRect(g+1,S+1+(p-2)/2,i-2,(p-2)/2)}}}w+=1}if(b)if(g===b._id){const e=n.length/u,s=r?a-e:a,l=o*d,i=this.getRowCount(n)*d;t.fillStyle=c?.palette.action.selected??"rgba(0,0,0,0.08)",t.fillRect(s,l,e,i)}else{let e,n,s=0;for(const[,t]of p??new Map)t._id===b?._id&&(e=t,n=s),s++;if(void 0===e||void 0===n)return;const l=e.length/u,i=r?a-l:a+(e.start-h)/u,f=(o+n)*d;t.fillStyle=c?.palette.action.selected??"rgba(0,0,0,08)",t.fillRect(i,f,l,d)}}drawHover(e,t){const{apolloHover:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e;if(!n)return;const{feature:l,mousePosition:i}=n;if(!l||!i)return;const{regionNumber:c,y:u}=i,{bpPerPx:d,bpToPx:f,offsetPx:m}=r,g=a,p=Math.floor(u/g),h=o[c],{refName:y,reversed:b}=h,w=(f({refName:y,coord:b?l.end:l.start,regionNumber:c})?.offsetPx??0)-m,S=p*g,v=l.length/d;t.fillStyle=s?.palette.action.focus??"rgba(0,0,0,0.04)",t.fillRect(w,S,v,g)}drawDragPreview(e,t){const{apolloDragging:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e,{bpPerPx:l,offsetPx:i}=r;if(!n)return;const{feature:c,glyph:u,mousePosition:d}=n.start;if(!c)throw new Error("no feature for drag preview??");if(u!==this)throw new Error("drawDragPreview() called on wrong glyph?");const{mousePosition:f}=n.current,g=this.isMouseOnFeatureEdge(d,c,e);if(!g)return;const p=Math.floor(d.y/a),h=o[d.regionNumber],y=(h.reversed?h.end-c[g]:c[g]-h.start)/l-i,b=Math.min(f.x,y),w=p*a,S=Math.abs(f.x-y),v=1*a;t.strokeStyle=s?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(b,w,S,v),t.fillStyle=m.alpha(s?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(b,w,S,v)}isMouseOnFeatureEdge(e,t,n,a){if(!e)return;const{refName:o,regionNumber:r,x:s}=e,{lgv:l}=n,{bpToPx:i,offsetPx:c}=l,u=i({refName:o,coord:t.start,regionNumber:r}),d=i({refName:o,coord:t.end,regionNumber:r});if(void 0!==u&&void 0!==d){const e=u.offsetPx-c,n=d.offsetPx-c;if(Math.abs(n-e)<8)return;const o=this.getParentFeature(t,a);if(o&&t.start<=o.start&&Math.abs(e-s)<4)return;if(o&&t.end>=o.end&&Math.abs(n-s)<4)return;if(Math.abs(e-s)<4)return"start";if(Math.abs(n-s)<4)return"end"}}onMouseMove(e,t){const{feature:n,mousePosition:a,topLevelFeature:o}=e.getFeatureAndGlyphUnderMouse(t);e.apolloDragging?e.setCursor("col-resize"):n&&a&&(this.isMouseOnFeatureEdge(a,n,e,o)?e.setCursor("col-resize"):e.setCursor())}onMouseDown(e,t){const{feature:n,mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);n&&a&&this.isMouseOnFeatureEdge(a,n,e)&&t.stopPropagation()}onMouseUp(e,t){if(e.apolloDragging??0!==t.button)return;const{feature:n}=e.getFeatureAndGlyphUnderMouse(t);n&&e.setSelectedFeature(n)}startDrag(e){const{feature:t,mousePosition:n,topLevelFeature:a}=e.apolloDragging?.start??{},{mousePosition:o}=e.apolloDragging?.current??{};return!!(t&&n&&o&&this.isMouseOnFeatureEdge(n,t,e,a))}continueDrag(e,t){const{feature:n,glyph:a,mousePosition:o,topLevelFeature:r}=e.apolloDragging?.start??{};if(!t||!o)return;const s=this.getParentFeature(n,r),l=this.getAdjacentFeatures(n,s);if(!n||!t)return;const{bp:i}=t,c=this.isMouseOnFeatureEdge(o,n,e,r);if(!c||!("start"===c&&i>=n.end-1||"end"===c&&i<=n.start+1)){if("CDS"!==n.type){if(l.prevFeature&&!l.nextFeature){if("CDS"===l.prevFeature.type&&i<=l.prevFeature.start+1)return;if("CDS"!==l.prevFeature.type&&i<=l.prevFeature.end+1)return}if(!l.prevFeature&&l.nextFeature){if("CDS"===l.nextFeature.type&&i>=l.nextFeature.end-1)return;if("CDS"!==l.nextFeature.type&&i>=l.nextFeature.start-1)return}}if(l.prevFeature&&l.nextFeature)if("CDS"===n.type){if("CDS"!==l.nextFeature.type&&i>=l.nextFeature.end-1)return;if("CDS"===l.nextFeature.type&&i>=l.nextFeature.start-1)return;if("CDS"!==l.prevFeature.type&&i<=l.prevFeature.start+1)return;if("CDS"===l.prevFeature.type&&i<=l.prevFeature.end+1)return}else{if("CDS"===l.prevFeature.type&&i<=l.prevFeature.start+1)return;if("CDS"!==l.prevFeature.type&&i<=l.prevFeature.end+1)return;if("CDS"!==l.nextFeature.type&&i>=l.nextFeature.start-1)return;if("CDS"===l.nextFeature.type&&i>=l.nextFeature.end-1)return}e.setDragging({start:{feature:n,topLevelFeature:r,glyph:a,mousePosition:o},current:{feature:n,topLevelFeature:r,glyph:a,mousePosition:t}})}}getFeatureFromLayout(e,t,n){const a=this.featuresForRow(e)[n];return a?.find((e=>t>=e.start&&t<=e.end))}getRowForFeature(e,t){const n=this.featuresForRow(e);for(const[e,a]of n.entries())if(a.some((e=>e._id===t._id)))return e}async executeDrag(e){const{apolloDragging:t,changeManager:n,displayedRegions:a,getAssemblyId:o,setCursor:r}=e;if(!t)return;const{feature:s,glyph:l,mousePosition:i,topLevelFeature:c}=t.start;if(!s)throw new Error("no feature for drag preview??");if(l!==this)throw new Error("drawDragPreview() called on wrong glyph?");const u=this.isMouseOnFeatureEdge(i,s,e);if(!u)return;const{mousePosition:d}=t.current,f=d.bp,m=o(a[i.regionNumber].assemblyName),g=this.getParentFeature(s,c),p=this.getAdjacentFeatures(s,g),h=[];if("end"===u){this.addEndLocation(h,s,f,m);const{nextFeature:e}=p;if(!e)return;("CDS"!==s.type&&"CDS"===e.type||"CDS"===s.type&&"CDS"!==e.type)&&this.addStartLocation(h,e,f+1,m)}else{this.addStartLocation(h,s,f,m);const{prevFeature:e}=p;if(!e)return;("CDS"!==s.type&&"CDS"===e.type||"CDS"===s.type&&"CDS"!==e.type)&&this.addEndLocation(h,e,f-1,m)}if(!n)throw new Error("no change manager");for(const e of h)await n.submit(e);r()}getAdjacentFeatures(e,t){let n,a,o=0;if(!e||!t||!t.children)return{prevFeature:n,nextFeature:a};for(const[,n]of t.children){if(n._id===e._id)break;o++}const r=[...t.children.keys()];return o>0&&(n=t.children.get(r[o-1])),o<r.length-1&&(a=t.children.get(r[o+1])),{prevFeature:n,nextFeature:a}}addEndLocation(e=[],n,a,o){const r=n._id;e.push(new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[r],featureId:r,oldEnd:n.end,newEnd:a,assembly:o}))}addStartLocation(e=[],n,a,o){const r=n._id;e.push(new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[r],featureId:r,oldStart:n.start,newStart:a,assembly:o}))}};function Jn(e,t){if("gene"===e.type){let t=!1;for(const[,n]of e.children??new Map)if("mRNA"===n.type)for(const[,e]of n.children??new Map)"exon"===e.type&&(t=!0);return t?Hn:Vn}return e.children?.size?zn:Wn}function Xn(e,t){return"CDS"===e.type&&void 0!==e.phase?-1===e.strand?(e.end-e.phase)%3+(t<=1?5:3):Math.abs((e.start+e.phase)%3-2):t<=1?-1===e.strand?4:3:void 0}function Yn(e,t,n,a,o,r){void 0!==o&&(e.fillStyle=t?.palette.action.focus??"rgba(0,0,0,0.04)",e.fillRect(n,a*o,r,a))}function Kn(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return i.types.compose(a.BaseDisplay,In).named("BaseLinearApolloDisplay").props({type:i.types.literal("LinearApolloDisplay"),configuration:n.ConfigurationReference(t)}).volatile((e=>({lgv:r.getContainingView(e)}))).views((e=>{const{configuration:t,renderProps:n}=e;return{renderProps:()=>({...n(),...W.getParentRenderProps(e),config:t.renderer})}})).views((e=>({get rendererTypeName(){return e.configuration.renderer.type},get session(){return r.getSession(e)},get regions(){return e.lgv.dynamicBlocks.contentBlocks.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:Math.round(a),end:Math.round(t)})))},get displayedRegions(){return e.lgv.displayedRegions},regionCannotBeRendered(){if(e.lgv&&e.lgv.bpPerPx>=200)return"Zoom in to see annotations"}}))).views((e=>({get apolloInternetAccount(){const[t]=e.regions,{internetAccounts:a}=i.getRoot(e),{assemblyName:o}=t,{assemblyManager:r}=e.session,s=r.get(o);if(!s)throw new Error(`No assembly found with name ${o}`);const{internetAccountConfigId:l}=n.getConf(s,["sequence","metadata"]);return a.find((e=>n.getConf(e,"internetAccountId")===l))},get changeManager(){return e.session.apolloDataStore?.changeManager},getAssemblyId(t){const{assemblyManager:n}=e.session,a=n.get(t);if(!a)throw new Error(`Could not find assembly named ${t}`);return a.name},get selectedFeature(){return e.session.apolloSelectedFeature}}))).actions((e=>({setSelectedFeature:t=>e.session.apolloSetSelectedFeature(t),afterAttach(){i.addDisposer(e,l.autorun((()=>{e.lgv.initialized&&!e.regionCannotBeRendered()&&(e.session.apolloDataStore.loadFeatures(e.regions),e.session.apolloDataStore.loadRefSeq(e.regions))}),{name:"LinearApolloDisplayLoadFeatures",delay:1e3}))}})))}(0,t);return o.named("LinearApolloDisplayLayouts").props({featuresMinMaxLimit:5e5}).volatile((()=>({seenFeatures:l.observable.map()}))).views((e=>({get featuresMinMax(){const{assemblyManager:t}=e.session;return e.displayedRegions.map((n=>{const a=t.get(n.assemblyName);let o,s;const{end:l,refName:i,start:c}=n;for(const[,t]of e.seenFeatures)i!==a?.getCanonicalRefName(t.refSeq)||!r.doesIntersect2(c,l,t.min,t.max)||t.length>e.featuresMinMaxLimit||(void 0===o&&({min:o}=t),void 0===s&&({max:s}=t),t.min<o&&({min:o}=t),t.end>s&&({max:s}=t));if(void 0!==o&&void 0!==s)return[o,s]}))}}))).actions((e=>({addSeenFeature(t){e.seenFeatures.set(t._id,t)},deleteSeenFeature(t){e.seenFeatures.delete(t)}}))).views((e=>({get featureLayouts(){const{assemblyManager:t}=e.session;return e.displayedRegions.map(((n,a)=>{const o=t.get(n.assemblyName),s=new Map,l=e.featuresMinMax[a];if(!l)return s;const[c,u]=l,d=[],{end:f,refName:m,start:g}=n;for(const[t,n]of e.seenFeatures.entries()){if(!i.isAlive(n)){e.deleteSeenFeature(t);continue}if(m!==o?.getCanonicalRefName(n.refSeq)||!r.doesIntersect2(g,f,n.min,n.max))continue;const a=Jn(n).getRowCount(n,e.lgv.bpPerPx);let l=0,p=!1;for(;!p;){let e=d.slice(l,l+a);if(e.length<a){for(let t=0;t<a-e.length;t++){const e=d.length;d[e]=Array.from({length:u-c}),s.set(e,[])}e=d.slice(l,l+a)}if(e.map((e=>{const t=n.max-n.min==0?n.min+1:n.max;let a=n.min-c,o=t-c;return n.min-c<0&&(a=0,o=t-n.min),e.slice(a,o).some(Boolean)})).some(Boolean))l+=1;else{for(let e=l;e<l+a;e++){let t=n.min-c,a=n.max-c;n.min-c<0&&(t=0,a=n.max-n.min),d[e].fill(!0,t,a);const o=s.get(e);o?.push([e-l,n])}p=!0}}}return s}))},getFeatureLayoutPosition(e){const{featureLayouts:t}=this;for(const n of t)for(const[t,a]of n)for(const[n,o]of a)if(0===n){if(e._id===o._id)return{layoutRow:t,featureRow:n};if(o.hasDescendant(e._id)){const n=Jn(o).getRowForFeature(o,e);if(void 0!==n)return{layoutRow:t,featureRow:n}}}}}))).views((e=>({get highestRow(){return Math.max(0,...e.featureLayouts.map((e=>Math.max(...e.keys()))))}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(e.lgv.initialized&&!e.regionCannotBeRendered())for(const t of e.regions){const n=e.session.apolloDataStore.assemblies.get(t.assemblyName),a=n?.getByRefName(t.refName);for(const[,n]of a?.features??new Map)r.doesIntersect2(t.start,t.end,n.start,n.end)&&!e.seenFeatures.has(n._id)&&e.addSeenFeature(n)}}),{name:"LinearApolloDisplaySetSeenFeatures",delay:1e3}))}})))}(0,t).named("LinearApolloDisplayRendering").props({sequenceRowHeight:15,apolloRowHeight:20,detailsMinHeight:200,detailsHeight:200,lastRowTooltipBufferHeight:40,isShown:!0}).volatile((()=>({canvas:null,overlayCanvas:null,collaboratorCanvas:null,seqTrackCanvas:null,seqTrackOverlayCanvas:null,theme:void 0}))).views((e=>({get featuresHeight(){return(e.highestRow+1)*e.apolloRowHeight+e.lastRowTooltipBufferHeight}}))).actions((e=>({toggleShown(){e.isShown=!e.isShown},setDetailsHeight(t){e.detailsHeight=e.isShown?Math.max(Math.min(t,e.height-100),Math.min(e.height,e.detailsMinHeight)):t},setCanvas(t){e.canvas=t},setOverlayCanvas(t){e.overlayCanvas=t},setCollaboratorCanvas(t){e.collaboratorCanvas=t},setSeqTrackCanvas(t){e.seqTrackCanvas=t},setSeqTrackOverlayCanvas(t){e.seqTrackOverlayCanvas=t},setTheme(t){e.theme=t},afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.collaboratorCanvas?.getContext("2d");if(t){t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);for(const n of e.session.collaborators){const{locations:a}=n;if(0===a.length)continue;let o=0;for(const r of e.lgv.displayedRegions){for(const s of a){if(s.refSeq!==r.refName)continue;const{end:a,refSeq:l,start:i}=s,c=e.lgv.bpToPx({refName:l,coord:i,regionNumber:o});if(!c)continue;const u=c.offsetPx-e.lgv.offsetPx,d=(a-i)/e.lgv.bpPerPx;t.fillStyle="rgba(0,255,0,.2)",t.fillRect(u,1,d,100),t.fillStyle="black",t.fillText(n.name,u+1,11,d-2)}o++}}}}),{name:"LinearApolloDisplayRenderCollaborators"}))}})))}(0,t);return o.actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((async()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;if(e.lgv.bpPerPx>3)return;const t=e.seqTrackCanvas?.getContext("2d");if(t){t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.lgv.bpPerPx<=1?125:95);for(const[n,a]of e.regions.entries()){const o=e.session.apolloDataStore.getBackendDriver(a.assemblyName);if(!o)throw new Error("Failed to get the backend driver");const{seq:s}=await o.getSequence(a);if(!s)return;for(const[o,l]of[...s].entries()){const i=(e.lgv.bpToPx({refName:a.refName,coord:a.start+o,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx,c=3/e.lgv.bpPerPx,u=e.displayedRegions[n].reversed?i-c:i;for(let n=2;n>=0;n--){const r=qn.at(n+1)??"#ffffff";(a.start+o)%3===n&&On(t,e.lgv.bpPerPx,u,e.sequenceRowHeight*(2-n),c,e.sequenceRowHeight,s,o,!1,r)}if(e.lgv.bpPerPx<=1){const s=(e.lgv.bpToPx({refName:a.refName,coord:a.start+o,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx,i=1/e.lgv.bpPerPx,c=e.displayedRegions[n].reversed?s-i:s;t.beginPath(),t.fillStyle=_n(l,e.theme),t.rect(c,3*e.sequenceRowHeight,i,e.sequenceRowHeight),t.fill(),e.lgv.bpPerPx<=.1&&(t.stroke(),Un(t,c,i,l,3*e.sequenceRowHeight));const u=r.revcom(l);t.beginPath(),t.fillStyle=_n(u,e.theme),t.rect(c,4*e.sequenceRowHeight,i,e.sequenceRowHeight),t.fill(),e.lgv.bpPerPx<=.1&&(t.stroke(),Un(t,c,i,u,4*e.sequenceRowHeight))}for(let n=0;n<=2;n++){const r=qn.at(-(n+1))??"#ffffff";(a.start+o)%3===n&&On(t,e.lgv.bpPerPx,u,e.sequenceRowHeight*((e.lgv.bpPerPx<=1?5:3)+n),c,e.sequenceRowHeight,s,o,!0,r)}}}}}),{name:"LinearApolloDisplayRenderSequence"}))}})))}(0,t).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.canvas?.getContext("2d");if(t){t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);for(const[n,a]of e.featureLayouts.entries()){const o=e.displayedRegions[n];for(const[s,l]of a.entries())for(const[a,i]of l){if(a>0)continue;if(!r.doesIntersect2(o.start,o.end,i.min,i.max))continue;const l=(e.lgv.bpToPx({refName:o.refName,coord:i.min,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx;Jn(i).draw(e,t,i,l,s,o.reversed)}}}}),{name:"LinearApolloDisplayRenderFeatures"}))}})))}(0,t);return o.named("LinearApolloDisplayMouseEvents").volatile((()=>({apolloDragging:null,cursor:void 0,apolloHover:null}))).views((e=>({getFeatureAndGlyphUnderMouse(t){const n=function(e,t){const n=e.currentTarget,{clientX:a,clientY:o}=e,{left:r,top:s}=n.getBoundingClientRect()||{left:0,top:0},l=a-r,i=o-s,{coord:c,index:u,refName:d}=t.pxToBp(l);return{x:l,y:i,refName:d,bp:c,regionNumber:u}}(t,e.lgv),{bp:a,regionNumber:o,y:r}=n,s=Math.floor(r/e.apolloRowHeight),l=e.featureLayouts[o].get(s);if(!l)return{mousePosition:n};const i=l.find((e=>a>=e[1].min&&a<=e[1].max));if(!i)return{mousePosition:n};const[c,u]=i,d=Jn(u);return{feature:d.getFeatureFromLayout(u,a,c),topLevelFeature:u,glyph:d,mousePosition:n}}}))).actions((e=>({continueDrag(t){if(!e.apolloDragging)throw new Error("continueDrag() called with no current drag in progress");t.stopPropagation();const{glyph:n}=e.apolloDragging.start,{mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);a&&n&&n.continueDrag(e,a)},setDragging(t){e.apolloDragging=t??null}}))).actions((e=>({setApolloHover(t){e.apolloHover=t},setCursor(t){e.cursor!==t&&(e.cursor=t)}}))).actions((()=>({onClick(){}})))}(0,t).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((async()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.seqTrackOverlayCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.lgv.bpPerPx<=1?125:95);const{apolloHover:n,displayedRegions:a,lgv:o,regions:r,sequenceRowHeight:s,theme:l}=e;if(!n)return;const{feature:i,mousePosition:c}=n;if(i&&c)for(const[e,n]of r.entries()){const r=Xn(i,o.bpPerPx);if(i.discontinuousLocations&&i.discontinuousLocations.length>0)for(const c of i.discontinuousLocations){const i=(o.bpToPx({refName:n.refName,coord:c.start,regionNumber:e})?.offsetPx??0)-o.offsetPx,u=(c.end-c.start)/o.bpPerPx;Yn(t,l,a[e].reversed?i-u:i,s,r,u)}else{const c=(o.bpToPx({refName:n.refName,coord:i.start,regionNumber:e})?.offsetPx??0)-o.offsetPx,u=i.length/o.bpPerPx;Yn(t,l,a[e].reversed?c-u:c,s,r,u)}}}),{name:"LinearApolloDisplayRenderSeqHighlight"}))}})))}(0,t);return o.views((e=>({contextMenuItems(t){const{apolloHover:n}=e,{topLevelFeature:a}=n??{};return a&&t?Jn(a).getContextMenuItems(e):[]}}))).actions((e=>({startDrag(t){const{feature:n,glyph:a,mousePosition:o,topLevelFeature:r}=e.getFeatureAndGlyphUnderMouse(t);if(n&&r&&a&&o){let s,l;if(n.discontinuousLocations&&n.discontinuousLocations.length>0)for(let e=0;e<n.discontinuousLocations.length;e++)if(o.bp>=n.discontinuousLocations[e].start&&o.bp<=n.discontinuousLocations[e].end){l=e,s=n.discontinuousLocations[l];break}e.apolloDragging={start:{glyph:a,feature:n,topLevelFeature:r,discontinuousLocation:s?{start:s.start,end:s.end,phase:s.phase,idx:l}:void 0,mousePosition:o},current:{glyph:a,feature:n,topLevelFeature:r,mousePosition:o}},a.startDrag(e,t)||(e.apolloDragging=null)}},endDrag(t){e.continueDrag(t),e.apolloDragging?.start.glyph?.executeDrag(e,t),e.setDragging()}}))).actions((e=>({onMouseDown(t){const{feature:n,glyph:a,topLevelFeature:o}=e.getFeatureAndGlyphUnderMouse(t);a&&n&&o&&a.onMouseDown(e,t)},onMouseMove(t){const{buttons:n}=t,a=e.getFeatureAndGlyphUnderMouse(t),{glyph:o}=a;if(o&&o.onMouseMove(e,t),n)1===n&&(e.apolloDragging?e.continueDrag(t):e.startDrag(t));else{const{feature:t,topLevelFeature:n}=a;t&&o&&n?e.setApolloHover(a):(e.setApolloHover(null),e.setCursor())}},onMouseLeave(t){e.setDragging();const{glyph:n}=e.getFeatureAndGlyphUnderMouse(t);n&&n.onMouseLeave(e,t)},onMouseUp(t){const{glyph:n}=e.getFeatureAndGlyphUnderMouse(t);n&&n.onMouseUp(e,t),e.apolloDragging&&e.endDrag(t)}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.overlayCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);const{apolloDragging:n,apolloHover:a,displayedRegions:o,featureLayouts:r,lgv:s}=e;if(!a)return;const{feature:l,glyph:i}=a;if(!l)return;let c=0,u=0,d=!1;for(const[e,t]of r.entries()){const n=o[e];for(const[a,o]of t.entries())if(0===c)for(const[,t]of o)for(const[,o]of t.children??new Map)if(0===c)if(u=(s.bpToPx({refName:n.refName,coord:l.min,regionNumber:e})?.offsetPx??0)-s.offsetPx,({reversed:d}=n),o._id!==l._id)for(const[,e]of o.children??new Map)0===c&&(e._id!==l._id||(c=a));else c=a}i?.drawHover(e,t,c,u,d),i?.drawTooltip(e,t),n&&n.start.glyph?.drawDragPreview(e,t)}),{name:"LinearApolloDisplayRenderMouseoverAndDrag"}))}})))}(0,t).props({tabularEditor:i.types.optional(Mn,{})}).named("LinearApolloDisplay")}const Zn=v.makeStyles()((e=>({canvasContainer:{position:"relative",left:0},canvas:{position:"absolute",left:0},ellipses:{textOverflow:"ellipsis",overflow:"hidden"},avatar:{position:"absolute",color:e.palette.warning.light,backgroundColor:e.palette.warning.contrastText}}))),Qn=S.observer((function(e){const t=m.useTheme(),{model:n}=e,{apolloRowHeight:a,contextMenuItems:o,cursor:s,featuresHeight:l,isShown:i,onMouseDown:c,onMouseLeave:u,onMouseMove:d,onMouseUp:f,regionCannotBeRendered:g,session:p,setCanvas:h,setCollaboratorCanvas:w,setOverlayCanvas:S,setSeqTrackCanvas:v,setSeqTrackOverlayCanvas:E,setTheme:C,tabularEditor:x}=n,{classes:F}=Zn(),A=r.getContainingView(n);y.useEffect((()=>C(t)),[t,C]);const[D,k]=y.useState(),[N,R]=y.useState([]),M=g();if(!i)return null;const{assemblyManager:T}=p;return ae.default.createElement(ae.default.Fragment,null,A.bpPerPx<=3?ae.default.createElement("div",{className:F.canvasContainer,style:{width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95}},ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),v(e)},width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95,className:F.canvas,"data-testid":"seqTrackCanvas"}),ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),E(e)},width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95,className:F.canvas,"data-testid":"seqTrackOverlayCanvas"})):null,ae.default.createElement("div",{className:F.canvasContainer,style:{width:A.dynamicBlocks.totalWidthPx,height:l},onContextMenu:e=>{if(e.preventDefault(),N.length>0)R([]);else{const t=[e.clientX,e.clientY];k(t),R(o(t))}}},M?ae.default.createElement(m.Alert,{severity:"warning",classes:{message:F.ellipses}},ae.default.createElement(m.Tooltip,{title:M},ae.default.createElement("div",null,M))):ae.default.createElement(ae.default.Fragment,null,ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),w(e)},width:A.dynamicBlocks.totalWidthPx,height:l,className:F.canvas,"data-testid":"collaboratorCanvas"}),ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),h(e)},width:A.dynamicBlocks.totalWidthPx,height:l,className:F.canvas,"data-testid":"canvas"}),ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),S(e)},width:A.dynamicBlocks.totalWidthPx,height:l,onMouseMove:d,onMouseLeave:u,onMouseDown:c,onMouseUp:f,onClick:()=>{x.showPane()},className:F.canvas,style:{cursor:s??"default"},"data-testid":"overlayCanvas"}),A.displayedRegions.flatMap(((e,t)=>{const o=T.get(e.assemblyName);return[...p.apolloDataStore.checkResults.values()].filter((t=>o?.isValidRefName(t.refSeq)&&o?.getCanonicalRefName(t.refSeq)===e.refName&&r.doesIntersect2(e.start,e.end,t.start,t.end))).map((o=>{const r=(A.bpToPx({refName:e.refName,coord:o.start,regionNumber:t})?.offsetPx??0)-A.offsetPx,[s]=o.ids;if(!s)return null;const{topLevelFeature:l}=s,i=parent?n.getFeatureLayoutPosition(l)?.layoutRow??0:0;return ae.default.createElement(m.Tooltip,{key:o._id,title:o.message},ae.default.createElement(m.Avatar,{className:F.avatar,style:{top:i*a,left:r,height:a,width:a}},ae.default.createElement(ve.default,null)))}))})),ae.default.createElement(b.Menu,{open:N.length>0,onMenuItemClick:(e,t)=>{t(),R([])},onClose:()=>{R([])},TransitionProps:{onExit:()=>{R([])}},anchorReference:"anchorPosition",anchorPosition:D?{top:D[1],left:D[0]}:void 0,style:{zIndex:t.zIndex.tooltip},menuItems:N}))))})),ea=S.observer((function({model:e}){const{height:t}=e;return ae.default.createElement("div",{style:{position:"absolute",left:0,top:t/2,width:"100%"}},ae.default.createElement("hr",{style:{margin:0,top:0,color:"black"}}))})),ta=v.makeStyles()((e=>({shading:{background:m.alpha(e.palette.primary.main,.2),overflowY:"scroll",overflowX:"hidden"},details:{background:e.palette.background.paper},accordionControl:{height:12,width:"100%","&:hover":{background:e.palette.action.hover},display:"flex",alignItems:"center",justifyContent:"center"},accordionRoot:{background:e.palette.divider},resizeHandle:{width:"100%",height:4,position:"absolute",cursor:"row-resize",zIndex:100},expandIcon:{},title:{userSelect:"none"}}))),na=({onResize:e})=>{const{classes:t}=ta(),n=y.useCallback((t=>{t.stopPropagation(),t.preventDefault(),e(t.movementY)}),[e]),a=y.useCallback((e=>{e.stopPropagation(),e.preventDefault(),window.removeEventListener("mousemove",n),window.removeEventListener("mouseup",a),window.removeEventListener("mouseleave",a)}),[n]);return ae.default.createElement("div",{onMouseDown:e=>{e.stopPropagation(),window.addEventListener("mousemove",n),window.addEventListener("mouseup",a),window.addEventListener("mouseleave",a)},onClick:e=>{e.stopPropagation(),e.preventDefault()},className:t.resizeHandle})},aa=S.observer((function({onClick:e,onResize:t,open:n,title:a}){const{classes:o}=ta();return ae.default.createElement("div",{className:o.accordionRoot},n&&t?ae.default.createElement(na,{onResize:t}):null,ae.default.createElement("div",{className:o.accordionControl,onClick:e},ae.default.createElement(n?we.default:Se.default,{className:o.expandIcon}),a?ae.default.createElement(m.Typography,{className:o.title,variant:"caption",component:"span"},a):null))})),oa=S.observer((function({model:e,...t}){const{classes:n}=ta(),{height:a,isShown:o,selectedFeature:r,tabularEditor:s,toggleShown:l}=e,i=s.isShown?e.detailsHeight:0,c=o?a-i-24:0,u=y.useRef(null);return y.useEffect((()=>function(e,t){const{apolloRowHeight:n,selectedFeature:a}=e;if(t.current&&a){const o=e.getFeatureLayoutPosition(a);o&&t.current.scroll({top:(o.layoutRow+o.featureRow)*n,behavior:"smooth"})}}(e,u)),[e,r]),ae.default.createElement("div",{className:n.details,style:{height:a}},ae.default.createElement(aa,{open:o,title:"Graphical",onClick:l}),ae.default.createElement("div",{className:n.shading,ref:u,style:{height:c}},ae.default.createElement(Qn,{model:e,...t})),ae.default.createElement(aa,{title:"Table",open:s.isShown,onClick:s.togglePane,onResize:t=>{e.setDetailsHeight(e.detailsHeight-t)}}),ae.default.createElement("div",{style:{height:i}},ae.default.createElement(Rn,{model:e})))})),ra=i.types.model("JobsManager",{}).views((e=>({get jobStatusWidget(){const{widgets:t}=r.getSession(e);let n=t.get("JobsList");return n||(n=r.getSession(e).addWidget("JobsListWidget","JobsList")),n}}))).actions((e=>({update(t,n,a){e.jobStatusWidget.updateJobStatusMessage(t,n),a&&e.jobStatusWidget.updateJobProgressPct(t,a)},abortJob(t,n){const a=r.getSession(e);if(r.isSessionModelWithWidgets(a)){a.showWidget(e.jobStatusWidget),e.jobStatusWidget.updateJobStatusMessage(t,n??"Aborted unexpectedly");const o=e.jobStatusWidget.jobs.findIndex((e=>e.name===t));e.jobStatusWidget.addAbortedJob({...e.jobStatusWidget.jobs[o]}),e.jobStatusWidget.removeJob(t),a.notify("Job aborted","info")}},runJob(t){const n=r.getSession(e);r.isSessionModelWithWidgets(n)&&(n.showWidget(e.jobStatusWidget),e.jobStatusWidget.addJob(t))},done(t){const n=r.getSession(e);r.isSessionModelWithWidgets(n)&&(n.showWidget(e.jobStatusWidget),e.jobStatusWidget.removeJob(t.name),e.jobStatusWidget.addFinishedJob({name:t.name,statusMessage:"All operations successful",progressPct:100,cancelCallback:t.cancelCallback}))}})));class sa{clientStore;constructor(e){this.clientStore=e}}class la{dataStore;constructor(e){this.dataStore=e}recentChanges=[];async submit(n,a={}){const{addToRecents:o=!0,submitToBackend:s=!0,updateJobsManager:l=!1}=a,i=r.getSession(this.dataStore),c=new AbortController,{jobsManager:u}=r.getSession(this.dataStore),d={name:`${n.typeName}`,statusMessage:"Pre-validating",progressPct:0,cancelCallback:()=>{c.abort()}};l&&u.runJob(d);const f=await t.validationRegistry.frontendPreValidate(n);if(!f.ok){const e=`Pre-validation failed: "${f.resultsMessages}"`;return l&&u.abortJob(d.name,e),void i.notify(e,"error")}try{await n.execute(this.dataStore)}catch(e){return l&&u.abortJob(d.name,String(e)),console.error(e),void i.notify(String(e),"error")}if((await t.validationRegistry.frontendPostValidate(n,this.dataStore)).ok||await this.revert(n),s){l&&u.update(d.name,"Submitting to driver");const{collaborationServerDriver:t,getBackendDriver:o}=this.dataStore,r=e.isAssemblySpecificChange(n)?o(n.assembly):t;let s;try{s=await r.submitChange(n,a)}catch(e){return l&&u.abortJob(d.name,String(e)),console.error(e),i.notify(String(e),"error"),void await this.revert(n,!1)}if(!s.ok){const e=`Post-validation failed: "${f.resultsMessages}"`;return l&&u.abortJob(d.name,e),i.notify(e,"error"),void await this.revert(n,!1)}n.notification&&i.notify(n.notification,"success")}o&&this.recentChanges.push(n),l&&u.done(d)}async revert(e,t=!0){const n=e.getInverse();return this.submit(n,{submitToBackend:t,addToRecents:!1})}async revertLastChange(){const e=this.recentChanges.pop();if(e)return this.revert(e);r.getSession(this.dataStore).notify("No changes to undo!","warning")}}class ia extends sa{inFlight=new Map;async fetch(e,t,n){return e.getFetcher({locationType:"UriLocation",uri:t.toString()})(t,n)}async searchFeatures(e,t){const n=this.clientStore.getInternetAccount(t[0]),{baseURL:a}=n,o=new URL("features/searchFeatures",a),r=new URLSearchParams({assemblies:t.join(","),term:e});o.search=r.toString();const s=o.toString(),l=await this.fetch(n,s);if(!l.ok){const e=await Ae(l,"searchFeatures failed");throw new Error(e)}return l.json()}async getFeatures(e){const{assemblyName:t,end:a,refName:o,start:s}=e,{assemblyManager:l}=r.getSession(this.clientStore),i=l.get(t);if(!i)throw new Error(`Could not find assembly with name "${t}"`);const{ids:c}=n.getConf(i,["sequence","metadata"]),u=c[o];if(!u)throw new Error(`Could not find refSeq "${o}"`);const d=this.clientStore.getInternetAccount(t),{baseURL:f}=d,m=new URL("features/getFeatures",f),g=new URLSearchParams({refSeq:u,start:String(s),end:String(a)});m.search=g.toString();const p=m.toString(),h=await this.fetch(d,p);if(!h.ok){const e=await Ae(h,"getFeatures failed");throw new Error(e)}return await this.checkSocket(t,o,d),h.json()}async checkSocket(t,n,a){const{socket:o}=a,r=a.retrieveToken(),s=`${t}-${n}`,l=new la(this.clientStore);o.hasListeners(s)||o.on(s,(async t=>{if(a.setLastChangeSequenceNumber(Number(t.changeSequence)),t.userSessionId!==r&&t.channel===s){const n=e.Change.fromJSON(t.changeInfo);await l.submit(n,{submitToBackend:!1})}}))}async getSequence(e){const t=`${e.refName}:${e.start}-${e.end}`,a=this.inFlight.get(t),{assemblyName:o,end:s,refName:l,start:i}=e,{assemblyManager:c}=r.getSession(this.clientStore),u=c.get(o);if(!u)throw new Error(`Could not find assembly with name "${o}"`);const{ids:d}=n.getConf(u,["sequence","metadata"]),f=d[l];if(!f)throw new Error(`Could not find refSeq "${l}"`);if(a)return{seq:await a,refSeq:f};let m=this.clientStore.assemblies.get(o);m||(m=this.clientStore.addAssembly(o));let g=m?.refSeqs.get(f);g||(g=m.addRefSeq(f,l));const p=g.getSequence(i,s);if(p.length===s-i)return{seq:p,refSeq:f};const h=this.clientStore.getInternetAccount(o),{baseURL:y}=h,b=new URL("sequence",y),w=new URLSearchParams({refSeq:f,start:String(i),end:String(s)});b.search=w.toString();const S=b.toString(),v=this.getSeqFromServer(h,S,g,i,s);this.inFlight.set(t,v);const E=await v;return await this.checkSocket(o,l,h),this.inFlight.delete(t),{seq:E,refSeq:f}}async getSeqFromServer(e,t,n,a,o){const r=await this.fetch(e,t);if(!r.ok){let e;try{e=await r.text()}catch{e=""}throw new Error(`getSequence failed: ${r.status} (${r.statusText})${e?` (${e})`:""}`)}const s=await r.text();return n.addSequence({sequence:s,start:a,stop:o}),s}async getRegions(e){const{assemblyManager:t}=r.getSession(this.clientStore);if(!t.get(e))throw new Error(`Could not find assembly with name "${e}"`);const n=this.clientStore.getInternetAccount(e),{baseURL:a}=n,o=new URL("refSeqs",a),s=new URLSearchParams({assembly:e});o.search=s.toString();const l=o.toString(),i=await this.fetch(n,l);if(!i.ok){let e;try{e=await i.text()}catch{e=""}throw new Error(`getRegions failed: ${i.status} (${i.statusText})${e?` (${e})`:""}`)}return(await i.json()).map((e=>({refName:e.name,start:0,end:e.length})))}getAssemblies(e){const{assemblyManager:t}=r.getSession(this.clientStore);return t.assemblies.filter((t=>{const a=n.getConf(t,["sequence","metadata"]);return!(!(a&&a.apollo&&a.internetAccountConfigId)||e&&a.internetAccountConfigId!==e)}))}async submitChange(e,n={}){const{internetAccountId:a}=n,o=this.clientStore.getInternetAccount("assembly"in e?e.assembly:void 0,a),{baseURL:r}=o,s=new URL("changes",r).href,l=await this.fetch(o,s,{method:"POST",body:JSON.stringify(e.toJSON()),headers:{"Content-Type":"application/json"}});if(!l.ok){const e=await Ae(l,"submitChange failed");throw new Error(e)}const i=new t.ValidationResultSet;return l.ok||(i.ok=!1),i}}class ca extends sa{async getFeatures(){return[[],[]]}async getSequence(e){const{assemblyName:t,end:n,refName:a,start:o}=e,r=this.clientStore.assemblies.get(t);if(!r)return{seq:"",refSeq:a};const s=r.refSeqs.get(a);return s?{seq:s.getSequence(o,n),refSeq:a}:{seq:"",refSeq:a}}async getRegions(e){const t=this.clientStore.assemblies.get(e);if(!t)return[];const n=[];for(const[,a]of t.refSeqs)n.push({assemblyName:e,refName:a.name,start:a.sequence[0].start,end:a.sequence[0].stop});return n}getAssemblies(){const{assemblyManager:e}=r.getSession(this.clientStore);return e.assemblies.filter((e=>{const t=n.getConf(e,["sequence","metadata"]);return Boolean(t&&t.apollo&&!t.file&&!t.internetAccountConfigId)}))}async submitChange(e,n={}){return new t.ValidationResultSet}async searchFeatures(e,t){return[]}}class ua extends sa{async loadAssembly(e){const{assemblyManager:t}=r.getSession(this.clientStore),a=t.get(e);if(!a)throw new Error(`Assembly ${e} not found`);const{file:o}=n.getConf(a,["sequence","metadata"]),s=require("node:fs");return Ce(e,await s.promises.readFile(o,"utf8"),this.clientStore)}async getAssembly(e){let t=this.clientStore.assemblies.get(e);return t||(t=await this.loadAssembly(e)),t}async getFeatures(e){return await this.getAssembly(e.assemblyName),[[],[]]}async getSequence(e){const{assemblyName:t,end:n,refName:a,start:o}=e,r=(await this.getAssembly(t)).refSeqs.get(a);if(!r)throw new Error(`refSeq ${a} not found in client data store`);return{seq:r.getSequence(o,n),refSeq:a}}async getRegions(e){const t=await this.getAssembly(e),n=[];for(const[,a]of t.refSeqs)n.push({assemblyName:e,refName:a.name,start:a.sequence[0].start,end:a.sequence[0].stop});return n}getAssemblies(){const{assemblyManager:e}=r.getSession(this.clientStore);return e.assemblies.filter((e=>{const t=n.getConf(e,["sequence","metadata"]);return Boolean(t&&t.apollo&&!t.internetAccountConfigId&&t.file)}))}async submitChange(a){if(!e.isAssemblySpecificChange(a))throw new Error(`Cannot use this type of change with local file: "${a.typeName}"`);const{assemblyManager:o}=r.getSession(this.clientStore),s=o.get(a.assembly);if(!s)throw new Error(`Could not find assembly with name "${a.assembly}"`);const{file:l}=n.getConf(s,["sequence","metadata"]),c=this.clientStore.assemblies.get(a.assembly);if(!c)throw new Error(`Could not find assembly in client with name "${a.assembly}"`);const u=new Set(...c.refSeqs.keys()),{checkResults:d}=this.clientStore;for(const e of d.values())u.has(e.refSeq)&&d.delete(e._id);const f=await xe(c);this.clientStore.addCheckResults(f);const m=[{directive:"gff-version",value:"3"}];for(const[,e]of c.refSeqs)m.push({directive:"sequence-region",value:`${e.name} 1 ${e.sequence[0].stop}`});for(const e of c.comments)m.push({comment:e});for(const[,e]of c.refSeqs){const{features:n}=e;for(const[,e]of n)m.push(t.makeGFF3Feature(i.getSnapshot(e)))}for(const[,e]of c.refSeqs){const[n]=e.sequence,a=t.splitStringIntoChunks(n.sequence,80).join("\n");m.push({id:e.name,description:e.description,sequence:a})}const g=Z.default.formatSync(m),p=require("node:fs");return await p.promises.writeFile(l,g,"utf8"),new t.ValidationResultSet}async searchFeatures(e,t){return[]}}function da(e,t){const a=new AbortController,{signal:o}=a,s=e.evaluateExtensionPoint("Apollo-extendAnnotationFeature",j.AnnotationFeature),c=function(e){const t=i.types.model("ClientDataStore",{typeName:i.types.optional(i.types.literal("Client"),"Client"),assemblies:i.types.map(j.ApolloAssembly),checkResults:i.types.map(j.CheckResult)}).views((t=>({get internetAccounts(){return i.getRoot(t).internetAccounts},get pluginConfiguration(){return i.getRoot(t).jbrowse.configuration.ApolloPlugin},getFeature:n=>i.resolveIdentifier(e,t.assemblies,n)}))).actions((e=>({addAssembly:t=>e.assemblies.put({_id:t,refSeqs:{}}),addFeature(t,n){const a=e.assemblies.get(t);if(!a)throw new Error(`Could not find assembly "${t}" to add feature "${n._id}"`);const o=a.refSeqs.get(n.refSeq);if(!o)throw new Error(`Could not find refSeq "${n.refSeq}" to add feature "${n._id}"`);o.features.put(n)},deleteFeature(t){const n=e.getFeature(t);if(!n)throw new Error(`Could not find feature "${t}" to delete`);const{_id:a,parent:o}=n;o?o.deleteChild(t):i.getParentOfType(n,j.ApolloRefSeq).deleteFeature(a)},deleteAssembly(t){e.assemblies.delete(t)},addCheckResult(t){e.checkResults.put(t)},addCheckResults(t){for(const n of t)e.checkResults.has(n._id)||e.checkResults.put(n)},deleteCheckResult(t){e.checkResults.delete(t)}}))).volatile((e=>({changeManager:new la(e),collaborationServerDriver:new ia(e),inMemoryFileDriver:new ca(e),desktopFileDriver:r.isElectron?new ua(e):void 0,ontologyManager:Ke.create()}))).actions((e=>({afterCreate(){const{ontologyManager:t,pluginConfiguration:a}=e,o=a.ontologies;for(const e of o||[]){const[a,o,r,s]=[n.readConfObject(e,"name"),n.readConfObject(e,"version"),n.readConfObject(e,"source"),n.readConfObject(e,"textIndexFields")];t.findOntology(a)||t.addOntology(a,o,r,{textIndexing:{indexFields:s}})}}}))).views((e=>({getBackendDriver(t){if(!t)return e.collaborationServerDriver;const a=r.getSession(e),{assemblyManager:o}=a,s=o.get(t);if(!s)return e.collaborationServerDriver;const{file:l,internetAccountConfigId:i}=n.getConf(s,["sequence","metadata"]);return r.isElectron&&l?e.desktopFileDriver:i?e.collaborationServerDriver:e.inMemoryFileDriver},getInternetAccount(t,a){if(!(t??a))throw new Error("Must provide either assemblyName or internetAccountId");let o=a;if(t&&!o){const{assemblyManager:a}=r.getSession(e),s=a.get(t);if(!s)throw new Error(`No assembly found with name ${t}`);({internetAccountConfigId:o}=n.getConf(s,["sequence","metadata"]))}const{internetAccounts:s}=e,l=s.find((e=>e.internetAccountId===o));if(!l)throw new Error(`No InternetAccount found with config id ${a}`);return l}}))).actions((e=>({loadFeatures:i.flow((function*(t){for(const n of t){const t=e.getBackendDriver(n.assemblyName);if(!t)return;const[a,o]=yield t.getFeatures(n);if(0===a.length)continue;const{assemblyName:r,refName:s}=n;let l=e.assemblies.get(r);l||(l=e.assemblies.put({_id:r,refSeqs:{}}));const[i]=a;let c=l.refSeqs.get(i.refSeq);c||(c=l.refSeqs.put({_id:i.refSeq,name:s,features:{}}));for(const e of a)c.features.has(e._id)||c.features.put(e);e.addCheckResults(o)}})),loadRefSeq:i.flow((function*(t){for(const n of t){const t=e.getBackendDriver(n.assemblyName);if(!t)return;const{refSeq:a,seq:o}=yield t.getSequence(n),{assemblyName:r,end:s,refName:l,start:i}=n;let c=e.assemblies.get(r);c||(c=e.assemblies.put({_id:r,refSeqs:{}}));let u=c.refSeqs.get(a);u||(u=c.refSeqs.put({_id:a,name:l,sequence:[]})),u.addSequence({start:i,stop:s,sequence:o})}}))})));return i.types.snapshotProcessor(t,{postProcessor:e=>(e.assemblies={},e.checkResults={},e)})}(s);return t.props({apolloDataStore:i.types.optional(c,{typeName:"Client"}),apolloSelectedFeature:i.types.safeReference(s),jobsManager:i.types.optional(ra,{})}).extend((()=>{const e=l.observable.array([]);return{views:{get collaborators(){return e}},actions:{addOrUpdateCollaborator(t){const n=e.find((e=>e.id===t.id));n?n.locations=t.locations:e.push(t)}}}})).actions((e=>({apolloSetSelectedFeature(t){e.apolloSelectedFeature=t},addApolloTrackConfig(t,a){const o=`apollo_track_${t.name}`;e.tracks.some((e=>e.trackId===o))||e.addTrackConf({type:"ApolloTrack",trackId:o,name:`Annotations (${n.getConf(t,"displayName")||t.name})`,assemblyNames:[t.name],textSearching:{textSearchAdapter:{type:"ApolloTextSearchAdapter",trackId:o,assemblyNames:[t.name],textSearchAdapterId:`apollo_search_${t.name}`,...a?{baseURL:{uri:a,locationType:"UriLocation"}}:{}}},displays:[{type:"LinearApolloDisplay",displayId:`${o}-LinearApolloDisplay`},{type:"SixFrameFeatureDisplay",displayId:`${o}-SixFrameFeatureDisplay`}]})},broadcastLocations(){const{internetAccounts:t}=i.getRoot(e),n=[];for(const t of e.views){if("LinearGenomeView"!==t.type)return;const e=t;if(e.initialized){const{dynamicBlocks:t}=e;t.forEach((e=>{if(void 0!==e.regionNumber){const{assemblyName:t,end:a,refName:o,start:r}=e;n.push({assemblyName:t,refName:o,start:r,end:a})}}))}}if(0===n.length){for(const e of t)"baseURL"in e&&e.postUserLocation([]);return}const a=[];for(const e of t)if("baseURL"in e){for(const e of n)a.push({assemblyId:e.assemblyName,refSeq:e.refName,start:e.start,end:e.end});e.postUserLocation(a)}}}))).actions((e=>({afterCreate:i.flow((function*(){const{internetAccounts:t}=i.getRoot(e);l.autorun((()=>{const n=[];for(const t of e.views){if("LinearGenomeView"!==t.type)return;const e=t;if(e.initialized){const{dynamicBlocks:t}=e;t.forEach((e=>{if(void 0!==e.regionNumber){const{assemblyName:t,end:a,refName:o,start:r}=e;n.push({assemblyName:t,refName:o,start:r,end:a})}}))}}if(0===n.length){for(const e of t)"baseURL"in e&&e.postUserLocation([]);return}const a=[];for(const e of t)if("baseURL"in e){for(const e of n)a.push({assemblyId:e.assemblyName,refSeq:e.refName,start:e.start,end:e.end});e.postUserLocation(a)}}),{name:"ApolloSession"});for(const n of t){if("ApolloInternetAccount"!==n.type)continue;const{baseURL:t,configuration:a}=n,r=new URL("assemblies",t).href,s=n.getFetcher({locationType:"UriLocation",uri:r});let l,i;try{l=yield s(r,{signal:o})}catch(e){console.error(e);continue}if(l.ok){try{i=yield l.json()}catch(e){console.error(e);continue}for(const r of i){const{addAssembly:s,addSessionAssembly:l,assemblyManager:i}=e,c=i.get(r.name);if(c){e.addApolloTrackConfig(c,t);continue}const u=new URL("refSeqs",t),d=new URLSearchParams({assembly:r._id});u.search=d.toString();const f=u.toString(),m=n.getFetcher({locationType:"UriLocation",uri:f}),g=yield m(f,{signal:o});if(!g.ok){let e;try{e=yield g.text()}catch{e=""}throw new Error(`Failed to fetch fasta info — ${g.status} (${g.statusText})${e?` (${e})`:""}`)}const p=yield g.json(),h={},y=p.map((e=>(h[e.name]=e._id,{refName:e.name,aliases:[e._id],uniqueId:`alias-${e._id}`}))),b={name:r._id,aliases:[r.name,...r.aliases??[]],displayName:r.displayName??r.name,sequence:{trackId:`sequenceConfigId-${r.name}`,type:"ReferenceSequenceTrack",adapter:{type:"ApolloSequenceAdapter",assemblyId:r._id,baseURL:{uri:t,locationType:"UriLocation"}},metadata:{apollo:!0,internetAccountConfigId:a.internetAccountId,ids:h}},refNameAliases:{adapter:{type:"FromConfigAdapter",features:y}}};(l||s)(b);const w=yield i.waitForAssembly(b.name);e.addApolloTrackConfig(w,t)}}else{const e=yield Ae(l,"Failed to fetch assemblies");console.error(e)}}})),beforeDestroy(){a.abort()}})))}const fa={0:2,1:1,2:0},ma={3:0,4:1,5:2};function ga(e,t){const a=e.getPlugin("LinearGenomeViewPlugin"),{BaseLinearDisplay:o}=a.exports;return o.named("SixFrameFeatureDisplay").props({type:i.types.literal("SixFrameFeatureDisplay"),configuration:n.ConfigurationReference(t),apolloRowHeight:20,detailsMinHeight:200,showStartCodons:!1,showStopCodons:!0,showIntronLines:!0}).volatile((()=>({apolloFeatureUnderMouse:void 0,apolloRowUnderMouse:void 0}))).views((e=>{const{configuration:t,renderProps:n}=e;return{renderProps:()=>({...n(),...W.getParentRenderProps(e),config:t.renderer})}})).views((e=>({get regions(){let t;try{({blockDefinitions:t}=e)}catch{return[]}return t.contentBlocks.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))},regionCannotBeRendered(){const t=r.getContainingView(e);if(t&&t.bpPerPx>=200)return"Zoom in to see annotations"},get session(){return r.getSession(e)}}))).actions((e=>{let t=[];return{afterAttach(){i.addDisposer(e,l.autorun((()=>{const n=r.getSession(e);if(r.getContainingView(e).initialized){if(e.regionCannotBeRendered())return;const a=[],o=[];for(const n of e.blockDefinitions.contentBlocks)a.push(n.key),t.includes(n.key)||o.push(n);n.apolloDataStore.loadFeatures(o.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))),n.apolloDataStore.loadRefSeq(o.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))),t=a}}),{name:"SixFrameFeatureDisplay"}))}}})).views((e=>({get rendererTypeName(){return e.configuration.renderer.type},get changeManager(){const t=r.getSession(e);return t.apolloDataStore?.changeManager},get sequence(){const{regions:t}=e,n=r.getSession(e),a=new Map;for(const e of t){const t=n.apolloDataStore.assemblies.get(e.assemblyName),o=t?.getByRefName(e.refName),r=o?.getSequence(e.start,e.end);a.set(e.start,r??"")}return a},get features(){const{regions:t}=e,n=r.getSession(e),a=new Map;for(const e of t){const t=n.apolloDataStore.assemblies.get(e.assemblyName),o=t?.getByRefName(e.refName);let r=a.get(e.refName);r||(r=new Map,a.set(e.refName,r));for(const[t,n]of o?.features.entries()??new Map)e.start<n.end&&e.end>n.start&&r.set(t,n)}return a},get featuresMinMax(){const e={};for(const[t,n]of this.features||[]){let a,o;for(const[,e]of n)void 0===a&&({min:a}=e),void 0===o&&({max:o}=e),e.min<a&&({min:a}=e),e.end>o&&({max:o}=e);void 0!==a&&void 0!==o&&(e[t]=[a,o])}return e},get codonLayout(){const e=new Map;let t="",n=0;for(const[e,a]of this.sequence||[])a&&(t||(n=e),t+=a);for(let a=0;a<6;a++){const o=[],s=[],l=a in ma;let i,c,u;l?(i=(t.length+n)%3,c=(ma[a]+i+3)%3,u=r.reverse(t).slice(c)):(i=3-n%3,c=(fa[a]+i+3)%3,u=t.slice(c));for(let e=0;e<u.length;e+=3){const t=u.slice(e,e+3),a=l?r.reverse(r.revcom(t)):t,i=l?n+u.length-(3+e):n+e+c;r.defaultStarts.includes(a.toUpperCase())?o.push(i):r.defaultStops.includes(a.toUpperCase())&&s.push(i)}e.set(a,{starts:o,stops:s})}return e},get featureLayout(){const e=new Map;for(const[t,n]of this.features||[]){if(!n)continue;const a=this.featuresMinMax[t];if(!a)continue;const[o,r]=a,s=[],l=6;for(let t=0;t<l;t++){const t=s.length;s[t]=Array.from({length:r-o}),e.set(t,[])}for(const t of[...n.values()].sort(((e,t)=>{const{max:n,min:a}=e,{max:o,min:r}=t;return a-r||n-o})))for(const[,n]of t.children??new Map)if("mRNA"===n.type)for(const[,a]of n.children||new Map){let o;if("CDS"===a.type){let r;a.discontinuousLocations.length>0?({discontinuousLocations:r}=a):r=[a];for(const a of r){const r=a.start+3,s=a.end-3;for(const[l,{stops:i}]of this.codonLayout)if((l<3&&1===t.strand||l>=3&&-1===t.strand)&&0===i.filter((e=>e>=r&&e<=s)).length){o=l;const t=e.get(o);t?.push([n.featureId,a]);break}}}}}return e},getAssemblyId(t){const{assemblyManager:n}=r.getSession(e),a=n.get(t);if(!a)throw new Error(`Could not find assembly named ${t}`);return a.name},get selectedFeature(){return r.getSession(e).apolloSelectedFeature},get setSelectedFeature(){return r.getSession(e).apolloSetSelectedFeature}}))).actions((e=>({setSelectedFeature:t=>r.getSession(e).apolloSetSelectedFeature(t),setApolloFeatureUnderMouse(t){e.apolloFeatureUnderMouse=t},setApolloRowUnderMouse(t){e.apolloRowUnderMouse=t},toggleShowStartCodons(){e.showStartCodons=!e.showStartCodons},toggleShowStopCodons(){e.showStopCodons=!e.showStopCodons},toggleShowIntronLines(){e.showIntronLines=!e.showIntronLines}}))).views((e=>({get highestRow(){return 0===e.featureLayout.size?0:Math.max(...e.featureLayout.keys())},get featuresHeight(){return(this.highestRow+1)*e.apolloRowHeight},get detailsHeight(){return Math.max(e.detailsMinHeight,e.height-this.featuresHeight)},trackMenuItems:()=>[{label:"Show start codons",type:"checkbox",checked:e.showStartCodons,onClick:()=>e.toggleShowStartCodons()},{label:"Show stop codons",type:"checkbox",checked:e.showStopCodons,onClick:()=>e.toggleShowStopCodons()},{label:"Show intron lines",type:"checkbox",checked:e.showIntronLines,onClick:()=>e.toggleShowIntronLines()}]})))}const pa="WorkerGlobalScope"in globalThis;for(const[n,a]of Object.entries(t.changes))e.changeRegistry.registerChange(n,a);const ha=new t.CDSCheck;e.checkRegistry.registerCheck(ha.name,ha),t.validationRegistry.registerValidation(new t.CoreValidation),t.validationRegistry.registerValidation(new t.ParentChildValidation),exports.default=class extends Y.default{name="ApolloPlugin";version="0.1.5";configurationSchema=Xt;install(e){!function(e){e.addAdapterType((()=>new ge.default({name:"ApolloSequenceAdapter",configSchema:Ot,adapterMetadata:{category:void 0,hiddenFromGUI:!0,description:void 0},AdapterClass:Ut})))}(e),function(e){e.addTextSearchAdapterType((()=>new a.TextSearchAdapterType({name:"ApolloTextSearchAdapter",displayName:"Apollo text search adapter",configSchema:zt,AdapterClass:Wt,description:"Apollo Text Search adapter"})))}(e),e.addWidgetType((()=>{const e=n.ConfigurationSchema("ApolloFeatureDetailsWidget",{});return new a.WidgetType({name:"ApolloFeatureDetailsWidget",heading:"Apollo feature details",configSchema:e,stateModel:fn,ReactComponent:dn})})),e.addTrackType((()=>{const t=n.ConfigurationSchema("ApolloTrack",{adapter:""},{baseConfiguration:a.createBaseTrackConfig(e),explicitIdentifier:"trackId"});return new a.TrackType({name:"ApolloTrack",configSchema:t,stateModel:a.createBaseTrackModel(e,"ApolloTrack",t)})})),e.addInternetAccountType((()=>new a.InternetAccountType({name:"ApolloInternetAccount",configSchema:Ee,stateModel:Pt(Ee)}))),e.addDisplayType((()=>{const t=function(e){const t=e.getPlugin("LinearGenomeViewPlugin"),{baseLinearDisplayConfigSchema:a}=t.exports;return n.ConfigurationSchema("LinearApolloDisplay",{height:{type:"number",defaultValue:500}},{baseConfiguration:a,explicitlyTyped:!0})}(e);return new a.DisplayType({name:"LinearApolloDisplay",configSchema:t,stateModel:Kn(0,t),trackType:"ApolloTrack",viewType:"LinearGenomeView",ReactComponent:oa})})),e.addDisplayType((()=>{const t=function(e){const t=e.getPlugin("LinearGenomeViewPlugin"),{baseLinearDisplayConfigSchema:a}=t.exports;return n.ConfigurationSchema("SixFrameFeatureDisplay",{renderer:$t,height:{type:"number",defaultValue:120}},{baseConfiguration:a,explicitlyTyped:!0})}(e),o=function(e){const t=e.getPlugin("LinearGenomeViewPlugin");if(!t)throw new Error("LinearGenomeView plugin not found");const{BaseLinearDisplayComponent:n}=t.exports;return S.observer((function({model:e,...t}){const{classes:a}=ta(),{height:o,selectedFeature:r}=e;let{detailsHeight:s}=e;return r||(s=0),ae.default.createElement("div",{style:{height:e.height}},ae.default.createElement("div",{className:a.shading,style:{height:o-s}},ae.default.createElement(n,{model:e,...t})),ae.default.createElement("div",{className:"testTrackLines"},ae.default.createElement(ea,{model:e})))}))}(e);return new a.DisplayType({name:"SixFrameFeatureDisplay",configSchema:t,stateModel:ga(e,t),trackType:"ApolloTrack",viewType:"LinearGenomeView",ReactComponent:o})})),e.addRendererType((()=>new Gt({name:"ApolloSixFrameRenderer",ReactComponent:jt,configSchema:$t,pluginManager:e}))),e.addToExtensionPoint("Core-extendSession",da.bind(this,e)),e.addToExtensionPoint("Core-extendPluggableElement",(e=>{if("LinearGenomeView"===e.name){const{stateModel:t}=e,n=t.views((e=>{const t=e.rubberBandMenuItems;return{rubberBandMenuItems:()=>[...t(),{label:"Add new feature",icon:K.default,onClick:()=>{const t=r.getSession(e),{leftOffset:n,rightOffset:a}=e,o=e.getSelectedRegions(n,a);t.queueDialog((e=>[Vt,{session:t,handleClose:()=>{e()},region:o[0],changeManager:t.apolloDataStore.changeManager}]))}}]}}));e.stateModel=n}return e})),e.addToExtensionPoint("Core-extendPluggableElement",Yt),pa||e.addToExtensionPoint("Core-extendWorker",(t=>"on"in t&&t.on?(t.on("apollo",(async n=>{if("object"!=typeof(a=n)||null===a||!("apollo"in a)||!0!==a.apollo)return;var a;const{apollo:o,messageId:r,method:s}=n;switch(s){case"getSequence":{const{region:a}=n,{assemblyName:s}=a,l=e.rootModel?.session?.apolloDataStore;if(!l)break;const i=l.getBackendDriver(s),{seq:c}=await i.getSequence(a);t.workers[0].postMessage({apollo:o,messageId:r,sequence:c});break}case"getRegions":{const{assembly:a}=n,s=e.rootModel?.session?.apolloDataStore;if(!s)break;const l=s.getBackendDriver(a),i=await l.getRegions(a);t.workers[0].postMessage({apollo:o,messageId:r,regions:i});break}}})),t):t))}configure(e){r.isAbstractMenuManager(e.rootModel)&&(e.rootModel.appendToMenu("Apollo",{label:"Download GFF3",onClick:e=>{e.queueDialog((t=>[ut,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Manage Checks",onClick:e=>{e.queueDialog((t=>[ft,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"View Change Log",onClick:e=>{e.queueDialog((t=>[Ft,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Open local GFF3 file",onClick:e=>{e.queueDialog((t=>[Ct,{session:e,handleClose:()=>{t()},inMemoryFileDriver:e.apolloDataStore.inMemoryFileDriver}]))}}),e.rootModel.appendToMenu("Apollo",{label:"View check results",onClick:e=>{e.queueDialog((t=>[Jt,{session:e,handleClose:()=>{t()}}]))}}))}};
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@apollo-annotation/apollo-common"),t=require("@apollo-annotation/apollo-shared"),n=require("@jbrowse/core/configuration"),a=require("@jbrowse/core/pluggableElementTypes"),o=require("@jbrowse/core/Plugin"),r=require("@jbrowse/core/util"),s=require("@mui/icons-material/Add"),l=require("mobx"),i=require("mobx-state-tree"),c=require("socket.io-client"),u=require("@gmod/gff"),d=require("nanoid"),f=require("@mui/icons-material/Link"),m=require("@mui/material"),g=require("@mui/material/InputAdornment"),p=require("@mui/material/LinearProgress"),h=require("bson-objectid"),y=require("react"),b=require("@jbrowse/core/ui"),w=require("@mui/icons-material/Close"),S=require("mobx-react"),v=require("tss-react/mui"),E=require("@jbrowse/core/util/types/mst"),C=require("jsonpath"),x=require("@jbrowse/core/util/io"),F=require("fast-deep-equal/es6"),A=require("idb/with-async-ittr"),D=require("file-saver"),k=require("@mui/material/Checkbox"),N=require("@mui/material/FormControlLabel"),R=require("@mui/icons-material/Delete"),M=require("@mui/x-data-grid"),T=require("@mui/material/utils"),L=require("autosuggest-highlight/match"),I=require("autosuggest-highlight/parse"),P=require("@mui/icons-material/AccountCircle"),q=require("@jbrowse/core/pluggableElementTypes/AdapterType"),_=require("@jbrowse/core/data_adapters/BaseAdapter"),U=require("@jbrowse/core/util/rxjs"),O=require("@jbrowse/core/util/simpleFeature"),B=require("@jbrowse/core/TextSearch/BaseResults"),j=require("@apollo-annotation/apollo-mst"),$=require("@mui/icons-material/Clear"),G=require("@mui/icons-material/UnfoldLess"),W=require("@jbrowse/core/util/tracks"),H=require("@mui/icons-material/ExpandLess"),z=require("@mui/icons-material/ExpandMore"),V=require("@mui/icons-material/Error");function J(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function X(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var a=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,a.get?a:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,t}var Y=J(o),K=J(s),Z=J(u),Q=J(f),ee=J(g),te=J(p),ne=J(h),ae=J(y),oe=X(y),re=J(w),se=J(C),le=J(F),ie=J(k),ce=J(N),ue=J(R),de=J(L),fe=J(I),me=J(P),ge=J(q),pe=J(O),he=J(B),ye=J($),be=J(G),we=J(H),Se=J(z),ve=J(V);const Ee=n.ConfigurationSchema("ApolloInternetAccount",{baseURL:{description:"Location of Apollo server",type:"string",defaultValue:""},tokenType:{description:"A custom name for a token to include in the header",type:"string",defaultValue:"Bearer"}},{baseConfiguration:a.BaseInternetAccountConfig,explicitlyTyped:!0});async function Ce(e,t,n){const a=Z.default.parseStringSync(t,{parseSequences:!0,parseComments:!0,parseDirectives:!1,parseFeatures:!0});if(0===a.length)throw new Error("No features found in GFF3 file");let o=0,r=n.assemblies.get(e);r||(r=n.addAssembly(e));for(const e of a)if(Array.isArray(e)){const t=Fe(e),n=r.refSeqs.get(t.refSeq)??r.addRefSeq(t.refSeq,t.refSeq);n.features.has(t._id)||n.addFeature(t)}else if("comment"in e)r.addComment(e.comment);else{o++;let t=r.refSeqs.get(e.id);t||(t=r.addRefSeq(e.id,e.id,e.description)),e.description&&!t.description&&t.setDescription(e.description),t.addSequence({start:0,stop:e.sequence.length,sequence:e.sequence})}if(0===o)throw new Error("No embedded FASTA section found in GFF3");const s=await xe(r);return n.addCheckResults(s),r}async function xe(t){const n=[];for(const a of t.refSeqs.values())for(const t of a.features.values())for(const o of e.checkRegistry.getChecks().values()){const e=await o.checkFeature(i.getSnapshot(t),(async(e,t)=>a.getSequence(e,t)));n.push(...e)}return n}function Fe(e){const[t]=e,{attributes:n,child_features:a,end:o,phase:r,score:s,seq_id:l,source:i,start:c,strand:u,type:f}=t;if(!l)throw new Error(`feature does not have seq_id: ${JSON.stringify(t)}`);if(!f)throw new Error(`feature does not have type: ${JSON.stringify(t)}`);if(null===c)throw new Error(`feature does not have start: ${JSON.stringify(t)}`);if(null===o)throw new Error(`feature does not have end: ${JSON.stringify(t)}`);const m={_id:d.nanoid(),gffId:"",refSeq:l,type:f,start:c-1,end:o};if(e.length>1&&(m.discontinuousLocations=e.map((e=>{const{end:t,phase:n,start:a}=e;if(null===a||null===t)throw new Error(`feature does not have start and/or end: ${JSON.stringify(e)}`);let o;if(n)switch(n){case"0":o=0;break;case"1":o=1;break;case"2":o=2;break;default:throw new Error(`Unknown phase: "${n}"`)}return{start:a-1,end:t,phase:o}}))),u)if("+"===u)m.strand=1;else{if("-"!==u)throw new Error(`Unknown strand: "${u}"`);m.strand=-1}if(null!==s&&(m.score=s),r)switch(r){case"0":m.phase=0;break;case"1":m.phase=1;break;case"2":m.phase=2;break;default:throw new Error(`Unknown phase: "${r}"`)}if(a?.length){const e={};for(const t of a){const n=Fe(t);e[n._id]=n,n.gffId=n.attributes?._id?n.attributes?._id.toString():n._id}m.children=e}if(i??n){const e={};if(i&&(e.source=[i]),n)for(const[t,a]of Object.entries(n))if(a&&"parent"!==t.toLowerCase())switch(t){case"ID":e._id=a;break;case"Name":e.gff_name=a;break;case"Alias":e.gff_alias=a;break;case"Target":e.gff_target=a;break;case"Gap":e.gff_gap=a;break;case"Derives_from":e.gff_derives_from=a;break;case"Note":e.gff_note=a;break;case"Dbxref":e.gff_dbxref=a;break;case"Ontology_term":{const t=[],n=[];for(const e of a)e.startsWith("GO:")?t.push(e):n.push(e);t.length>0&&(e["Gene Ontology"]=t),n.length>0&&(e.gff_ontology_term=n);break}case"Is_circular":e.gff_is_circular=a;break;default:e[t.toLowerCase()]=a}m.attributes=e}return m}async function Ae(e,t){let n;try{n=await e.text()}catch{n=""}return`${t?`${t} — `:""}${e.status} ${e.statusText}${n?` (${n})`:""}`}const De=v.makeStyles()((e=>({dialogTitle:{background:e.palette.primary.main,color:e.palette.primary.contrastText,padding:e.spacing(2)},closeButton:{position:"absolute",right:e.spacing(1),top:e.spacing(1.5),color:e.palette.primary.contrastText}}))),ke=S.observer((function(e){const{classes:t}=De(),{handleClose:n,title:a,...o}=e;return ae.default.createElement(b.Dialog,{...o,header:ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogTitle,{className:t.dialogTitle},a),ae.default.createElement(m.IconButton,{"aria-label":"close",onClick:n,className:t.closeButton},ae.default.createElement(re.default,null)))})}));var Ne;function Re({changeManager:e,handleClose:a,session:o}){const{internetAccounts:r}=i.getRoot(o),{notify:s}=o,l=r.filter((e=>"ApolloInternetAccount"===e.type));if(0===l.length)throw new Error("No Apollo internet account found");const[c,u]=y.useState(""),[d,f]=y.useState(""),[g,p]=y.useState(!1),[h,b]=y.useState(null),[w,S]=y.useState(Ne.GFF3),[v,E]=y.useState(!0),[C,x]=y.useState(!1),[F,A]=y.useState(l[0]),[D,k]=y.useState(""),[N,R]=y.useState(""),[M,T]=y.useState(""),[L,I]=y.useState(!1);let P=!1;try{const e=new URL(D);"http:"!==e.protocol&&"https:"!==e.protocol||(P=!0)}catch{}let q=!1;try{const e=new URL(N);"http:"!==e.protocol&&"https:"!==e.protocol||(q=!0)}catch{}let _=!1;try{const e=new URL(M);"http:"!==e.protocol&&"https:"!==e.protocol||(_=!0)}catch{}return ae.default.createElement(ke,{open:!0,maxWidth:!1,"data-testid":"add-assembly-dialog",title:"Add new assembly",handleClose:a},L?ae.default.createElement(te.default,null):null,ae.default.createElement("form",{onSubmit:async function(n){n.preventDefault(),f(""),x(!0),I(!0),s(`Assembly "${c}" is being added`,"info"),a(),n.preventDefault();const{jobsManager:r}=o,l=new AbortController,i={name:`UploadAssemblyFile for ${c}`,statusMessage:"Pre-validating",progressPct:0,cancelCallback:()=>{l.abort(),r.abortJob(i.name)}};r.runJob(i);let u="";const{baseURL:d,getFetcher:m,internetAccountId:g}=F;if(w!==Ne.EXTERNAL&&h){const e=new URL("/files",d).href,t=new FormData;t.append("file",h),t.append("fileName",h.name),t.append("type",w);const n=m({locationType:"UriLocation",uri:e});if(n){r.update(i.name,"Uploading file, this may take awhile");const{signal:a}=l,o=await n(e,{method:"POST",body:t,signal:a});if(!o.ok){const e=await Ae(o,"Error when inserting new assembly (while uploading file)");return r.abortJob(i.name,e),void f(e)}u=(await o.json())._id}}let p;if(w===Ne.EXTERNAL)p=new t.AddAssemblyFromExternalChange({typeName:"AddAssemblyFromExternalChange",assembly:(new ne.default).toHexString(),assemblyName:c,externalLocation:{fa:D,fai:N,...M?{gzi:M}:{}}});else{const e={assembly:(new ne.default).toHexString(),assemblyName:c,fileId:u};p=w===Ne.GFF3&&v?new t.AddAssemblyAndFeaturesFromFileChange({typeName:"AddAssemblyAndFeaturesFromFileChange",...e}):new t.AddAssemblyFromFileChange({typeName:"AddAssemblyFromFileChange",...e})}r.done(i),await e.submit(p,{internetAccountId:g,updateJobsManager:!0}),x(!1),I(!1)}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},l.length>1?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogContentText,null,"Select account"),ae.default.createElement(m.Select,{value:F.internetAccountId,onChange:function(e){x(!1);const t=l.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);A(t)},disabled:C&&!d},r.map((e=>ae.default.createElement(m.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,ae.default.createElement(m.TextField,{margin:"dense",id:"name",label:"Assembly name",type:"TextField",fullWidth:!0,variant:"outlined",onChange:e=>{x(!1),u(e.target.value),function(e){const{assemblies:t}=o;t.find((t=>n.readConfObject(t,"displayName")===e))?(p(!1),f(`Assembly ${e} already exists.`)):(p(!0),f(""))}(e.target.value)},disabled:C&&!d}),ae.default.createElement(m.FormControl,{style:{marginTop:20}},ae.default.createElement(m.FormLabel,null,"Select GFF3, FASTA or EXTERNAL option"),ae.default.createElement(m.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:Ne.GFF3,name:"radio-buttons-group",onChange:function(e){S(e.target.value),E(e.target.value===Ne.GFF3),k(""),R(""),b(null)},value:w},ae.default.createElement(m.FormControlLabel,{value:Ne.GFF3,control:ae.default.createElement(m.Radio,null),label:"GFF3",disabled:C&&!d}),ae.default.createElement(m.FormControlLabel,{value:Ne.FASTA,control:ae.default.createElement(m.Radio,null),label:"FASTA",disabled:C&&!d}),ae.default.createElement(m.FormControlLabel,{value:Ne.EXTERNAL,control:ae.default.createElement(m.Radio,null),label:"External",disabled:C&&!d}))),w===Ne.EXTERNAL?ae.default.createElement(m.Box,{style:{marginTop:20}},ae.default.createElement(m.Typography,{variant:"caption"},"Enter FASTA and FASTA index(es) URL"),ae.default.createElement(m.TextField,{margin:"dense",helperText:"Can be bgz-compressed",id:"fasta",label:"FASTA",type:"TextField",fullWidth:!0,variant:"outlined",error:!P,onChange:e=>k(e.target.value),disabled:C&&!d,InputProps:{startAdornment:ae.default.createElement(ee.default,{position:"start"},ae.default.createElement(Q.default,null))}}),ae.default.createElement(m.TextField,{margin:"dense",id:"fasta-index",label:"FASTA Index",helperText:".fai or .gz.fai",type:"TextField",fullWidth:!0,variant:"outlined",error:!q,onChange:e=>R(e.target.value),disabled:C&&!d,InputProps:{startAdornment:ae.default.createElement(ee.default,{position:"start"},ae.default.createElement(Q.default,null))}}),ae.default.createElement(m.TextField,{margin:"dense",id:"fasta-gzi-index",label:"FASTA GZI Index",helperText:"Only for bgz-compressed FASTA, .gz.gzi",type:"TextField",fullWidth:!0,variant:"outlined",error:Boolean(M)&&!_,onChange:e=>T(e.target.value),disabled:C&&!d,InputProps:{startAdornment:ae.default.createElement(ee.default,{position:"start"},ae.default.createElement(Q.default,null))}})):ae.default.createElement(m.Box,{style:{marginTop:20}},ae.default.createElement("input",{type:"file",onChange:function(e){if(!e.target.files)return;const t=e.target.files.item(0);b(t),t?.name.toLowerCase().endsWith(".fasta")??t?.name.toLowerCase().endsWith(".fna")??t?.name.toLowerCase().endsWith(".fa")?S(Ne.FASTA):(t?.name.toLowerCase().endsWith(".gff3")??t?.name.toLowerCase().endsWith(".gff"))&&S(Ne.GFF3)},disabled:C&&!d}),ae.default.createElement(m.FormGroup,null,ae.default.createElement(m.FormControlLabel,{control:ae.default.createElement(m.Checkbox,{checked:w===Ne.GFF3&&v,onChange:()=>E(!v),disabled:w!==Ne.GFF3||C&&!d}),label:"Also load features from GFF3 file"})))),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!g||!((c&&h)??(c&&D&&N&&P&&q))||C,variant:"contained",type:"submit"},C?"Submitting...":"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:a},"Cancel"))),d?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},d)):null)}!function(e){e.GFF3="text/x-gff3",e.FASTA="text/x-fasta",e.EXTERNAL="text/x-external"}(Ne||(Ne={}));const Me=new Set(["i","me","my","myself","we","our","ours","ourselves","you","your","yours","yourself","yourselves","he","him","his","himself","she","her","hers","herself","it","its","itself","they","them","their","theirs","themselves","what","which","who","whom","this","that","these","those","am","is","are","was","were","be","been","being","have","has","had","having","do","does","did","doing","a","an","the","and","but","if","or","because","as","until","while","of","at","by","for","with","about","against","between","into","through","during","before","after","above","below","to","from","up","down","in","out","on","off","over","under","again","further","then","once","here","there","when","where","why","how","all","any","both","each","few","more","most","other","some","such","no","nor","not","only","own","same","so","than","too","very","s","t","can","will","just","don","should","now",..."1234567890"]);function Te(e,t){for(const[n,a]of t.entries())if(e.startsWith(a))return e.replace(a,n);return e}const Le="$PREFIXED_ID";function Ie(e,t,n){return t===Le?[Te(e.id,n)]:se.default.query(e,t)}function Pe(e){return e.toLowerCase().split(/[^\d:A-Za-z]+/).filter((e=>e&&!Me.has(e)))}function*qe(e){for(const t of e)yield*Pe(t)}function*_e(e){for(const t of e)if("string"==typeof t)yield t;else if("object"==typeof t){const e=se.default.query(t,"$..*");yield*_e(e)}}function*Ue(e,t,n){for(const a of t){const t=Ie(e,a,n);if(t.length>0)for(const e of qe(_e(t)))yield[a,e]}}async function Oe(e,t,n){const a=await this.db,o=t??a.transaction(["nodes"]);r.checkAbortSignal(n);const s=[...Pe(e)],l=[],i=new Map;l.push(...s.map((async(e,t)=>{r.checkAbortSignal(n);const a=o.objectStore("nodes").index("full-text-words");for await(const o of a.iterate(IDBKeyRange.bound(e,`${e}`,!1,!1))){r.checkAbortSignal(n);const e=o.value,a=i.get(e.id)??[e,new Set];a[1].add(t),i.set(e.id,a)}}))),await Promise.all(l),r.checkAbortSignal(n);const c=[];for(const[,[e,t]]of i)r.checkAbortSignal(n),c.push(...Be(this.textIndexFields,e,t,s,this.prefixes));return c.sort(((e,t)=>t.score-e.score)),c.slice(0,this.options.maxSearchResults??this.DEFAULT_MAX_SEARCH_RESULTS)}function Be(e,t,n,a,o){const r=[...n].sort().map((e=>a[e])),s=r.map((e=>{const t=e.replaceAll(/[$()*+./?[\\\]^{|}-]/g,"\\$&");return new RegExp(`\\b${t}`,"gi")}));let l=[],i=0;for(const[n,r]of e.entries()){const c=new Set,u=e.length-n-1,d=[..._e(Ie(t,r.jsonPath,o))];for(const e of d){let n=0;const o=[];for(const[t,r]of s.entries())for(const s of e.matchAll(r)){n+=1+1*u,c.add(t);const r=s.index,l=a[t];void 0!==r&&(n+=.01*l.length,n+=l.length/e.length*100*.05,o.push({wordIndex:t,position:r}))}n+=100*c.size,i<n&&(i=n),o.sort(((e,t)=>e.position-t.position)),o.length>0&&l.push({term:t,field:r,str:e,score:n,wordMatches:o})}}l=l.filter((e=>e.score===i));for(const e of l){const{wordMatches:t}=e;for(let n=0;n<t.length-1;n++){const a=t[n],o=t[n+1],s=o.wordIndex-a.wordIndex;if(1===s||-1===s){e.score+=1,1===s&&(e.score+=1);const t=Math.abs(o.position-(a.position+r[a.wordIndex].length))-1;e.score-=.05*t}}}return l}function je(e){return"string"==typeof e.id}function $e(e){return"string"==typeof e.sub&&"string"==typeof e.pred&&"string"==typeof e.obj}function Ge(e){return Boolean(e.meta?.deprecated)}async function We(e){return A.openDB(e,2,{upgrade(e,t,n,a,o){if(t<2&&(e.objectStoreNames.contains("meta")&&e.deleteObjectStore("meta"),e.objectStoreNames.contains("nodes")&&e.deleteObjectStore("nodes"),e.objectStoreNames.contains("edges")&&e.deleteObjectStore("edges")),e.objectStoreNames.contains("meta")||e.createObjectStore("meta"),!e.objectStoreNames.contains("nodes")){e.createObjectStore("nodes",{keyPath:"id"});const t=a.objectStore("nodes");t.createIndex("by-label","lbl"),t.createIndex("by-type","type"),t.createIndex("by-synonym",["meta","synonyms","val"]),t.createIndex("full-text-words","fullTextWords",{multiEntry:!0})}if(!e.objectStoreNames.contains("edges")){e.createObjectStore("edges",{autoIncrement:!0});const t=a.objectStore("edges");t.createIndex("by-subject","sub"),t.createIndex("by-object","obj"),t.createIndex("by-predicate","pred")}}})}function He(e){const t=new Set;for(const[,n]of e)t.add(n);return[...t]}async function ze(e){const t=Date.now(),n=JSON.parse(await x.openLocation(this.sourceLocation).readFile("utf8")),a=Date.now(),[o,...r]=n.graphs??[];if(o){if(r.length>0)throw new Error("multiple graphs not supported");try{const n=e.transaction(["meta","nodes","edges"],"readwrite");await n.objectStore("meta").clear(),await n.objectStore("nodes").clear(),await n.objectStore("edges").clear();const r=n.objectStore("nodes"),s=Ve.call(this).map((e=>e.jsonPath));for(const e of o.nodes??[])je(e)&&await r.add({...e,fullTextWords:He(Ue(e,s,this.prefixes))});const l=n.objectStore("edges");for(const e of o.edges??[])$e(e)&&await l.add(e);await n.done;const i=e.transaction("meta","readwrite");await i.objectStore("meta").add({ontologyRecord:{name:this.ontologyName,version:this.ontologyVersion,sourceLocation:this.sourceLocation},storeOptions:this.options,graphMeta:o.meta,timestamp:String(new Date),schemaVersion:2,timings:{overall:Date.now()-t,load:Date.now()-a}},"meta"),await i.done}catch(t){throw await e.transaction("meta","readwrite").objectStore("meta").clear(),t}}}function Ve(){return[{displayName:"ID",jsonPath:Le},...this.options.textIndexing?.indexFields??Ze]}async function Je(e){const[t]=await e.transaction("meta").objectStore("meta").getAll();return!!t&&le.default(this.options.prefixes,t.storeOptions?.prefixes)&&le.default(this.options.textIndexing,t.storeOptions?.textIndexing)}class Xe{ontologyName;ontologyVersion;sourceLocation;db;options;loadOboGraphJson=ze;getTermsByFulltext=Oe;openDatabase=We;isDatabaseCurrent=Je;get textIndexFields(){return Ve.call(this)}get prefixes(){return this.options.prefixes??new Map}DEFAULT_MAX_SEARCH_RESULTS=100;constructor(e,t,n,a){this.ontologyName=e,this.ontologyVersion=t,this.sourceLocation=n,this.db=this.prepareDatabase(),this.options=a??{}}validate(){const e=[],{sourceLocation:t,sourceType:n}=this;return n?"obo-graph-json"!==n&&e.push(new Error(`ontology source file ${JSON.stringify(t)} has type ${n}, which is not yet supported`)):e.push(new Error(`unable to determine format of ontology source file ${JSON.stringify(t)}, file name must end with ".json", ".obo", or ".owl"`)),e}get sourceType(){if(r.isUriLocation(this.sourceLocation)){if(this.sourceLocation.uri.endsWith(".json"))return"obo-graph-json"}else if("object"==typeof(e=this.sourceLocation)&&null!==e&&"localPath"in e&&this.sourceLocation.localPath.endsWith(".json"))return"obo-graph-json";var e}get dbName(){return`Apollo Ontology "${this.ontologyName}" "${this.ontologyVersion}"`}async prepareDatabase(){const e=this.validate();if(e.length>0)throw e;const t=await this.openDatabase(this.dbName);if(await this.isDatabaseCurrent(t))return t;const{sourceLocation:n,sourceType:a}=this;if("obo-graph-json"!==a)throw new Error(`ontology source file ${JSON.stringify(n)} has type ${a}, which is not yet supported`);return await this.loadOboGraphJson(t),t}async termCount(e){const t=await this.db;return(e??t.transaction("nodes")).objectStore("nodes").count()}async unique(e){const t=new Map,n=[];for(const a of e)t.has(a.id)||(t.set(a.id,!0),n.push(a));return n}async getTermsWithLabelOrSynonym(e,t,n){const a=t?.includeSubclasses??!0,o=await this.db,r=n??o.transaction(["nodes","edges"]),s=r.objectStore("nodes"),l=[...await s.index("by-label").getAll(e),...await s.index("by-synonym").getAll(e)];if(a){const e=await this.recurseEdges("by-object",l.map((e=>e.id)),(e=>"is_a"===e.pred),"sub",r);for(const t of e){const e=await s.get(t);e&&l.push(e)}}return l}async getPropertiesByLabel(e,t,n){const a=t?.includeSubProperties??!0,o=await this.db,r=n??o.transaction(["nodes","edges"]),s=(await this.getTermsWithLabelOrSynonym(e,{includeSubclasses:!1},r)).filter((e=>tt(e)));if(a){const e=await this.recurseEdges("by-object",s.map((e=>e.id)),(e=>"subPropertyOf"===e.pred),"sub",r),t=r.objectStore("nodes");for(const n of e){const e=await t.get(n);e&&tt(e)&&s.push(e)}}return s}async recurseEdges(e,t,n,a,o){const r=new Set;return await async function t(s){await Promise.all([...s].map((async s=>{const l=(await o.objectStore("edges").index(e).getAll(s)).filter((e=>n(e))).map((e=>e[a]));if(l.length>0){for(const e of l)r.add(e);await t(l)}})))}(t),r.values()}async*expandNodeSet(e,t="is_a",n,a){const o=await this.db,r=a??o.transaction(["edges"]),s=[...e],l=await this.recurseEdges("subclasses"===n?"by-object":"by-subject",s,(e=>e.pred===t),"subclasses"===n?"sub":"obj",r);for(const e of s)yield e;for(const e of l)yield e}expandSubclasses(e,t="is_a",n){return this.expandNodeSet(e,t,"subclasses",n)}expandSuperclasses(e,t="is_a",n){return this.expandNodeSet(e,t,"superclasses",n)}async getClassesThat(e,t,n){const a=await this.db,o=n??a.transaction(["nodes","edges"]),r=await this.getPropertiesByLabel(e,{includeSubProperties:!0},o),s=new Set(r.map((e=>e.id))),l=await async function(e){const t=[];for await(const n of e)t.push(n);return t}(this.expandSuperclasses(t.map((e=>e.id)),"is_a",o)),i=await this.recurseEdges("by-object",l,(e=>s.has(e.pred)),"sub",o),c=this.expandSubclasses(i,"is_a",o),u=[];for await(const e of c){const t=await o.objectStore("nodes").get(e);t&&et(t)&&!Ge(t)&&u.push(t)}return u}async getClassesWithoutPropertyLabeled(e,t,n){const a=await this.db,o=n??a.transaction(["nodes","edges"]),r=o.objectStore("nodes"),s=o.objectStore("edges"),l=(await this.getPropertiesByLabel(e,t,o)).map((e=>e.id)),i=await(async()=>{const e=new Set;for(const t of l)for await(const n of s.index("by-predicate").iterate(t))e.add(n.value.sub);const t=new Set;for await(const n of this.expandSubclasses(e,"is_a",o))t.add(n);return t})(),c=[];for await(const e of r){const t=e.value;et(t)&&!i.has(t.id)&&c.push(t.id)}const u=[];for await(const e of c){const t=await o.objectStore("nodes").get(e);t&&et(t)&&!Ge(t)&&u.push(t)}return u}async getAllClasses(e){const t=await this.db,n=e??t.transaction(["nodes"]);return(await n.objectStore("nodes").index("by-type").getAll("CLASS")).filter((e=>!Ge(e)))}async getAllTerms(e){const t=await this.db,n=e??t.transaction(["nodes"]);return(await n.objectStore("nodes").getAll()).filter((e=>!Ge(e)))}}const Ye=i.types.model("OntologyRecord",{name:i.types.string,version:"unversioned",source:i.types.union(E.LocalPathLocation,E.UriLocation,E.BlobLocation),options:i.types.frozen()}).volatile((e=>({dataStore:void 0}))).actions((e=>({ping(){},initDataStore(){e.dataStore=new Xe(e.name,e.version,i.getSnapshot(e.source),e.options)},afterCreate(){i.addDisposer(e,l.autorun((()=>{this.initDataStore()})))}}))),Ke=i.types.model("OntologyManager",{ontologies:i.types.array(Ye),prefixes:i.types.optional(i.types.map(i.types.string),{"GO:":"http://purl.obolibrary.org/obo/GO_","SO:":"http://purl.obolibrary.org/obo/SO_"})}).views((e=>({get featureTypeOntology(){return this.findOntology("Sequence Ontology")},findOntology:(t,n)=>e.ontologies.find((e=>e.name===t&&(void 0===n||e.version===n))),openOntology(e,t){return this.findOntology(e,t)?.dataStore},applyPrefixes:t=>Te(t,e.prefixes),expandPrefixes:t=>function(e,t){for(const[n,a]of t.entries())if(e.startsWith(n))return e.replace(n,a);return e}(t,e.prefixes)}))).actions((e=>({addOntology(t,n,a,o){const r=e.ontologies.push({name:t,version:n,source:a,options:{prefixes:new Map(e.prefixes.entries()),...o}});e.ontologies[r-1].ping()}}))),Ze=[{displayName:"Label",jsonPath:"$.lbl"},{displayName:"Synonym",jsonPath:"$.meta.synonyms[*].val"},{displayName:"Definition",jsonPath:"$.meta.definition.val"}],Qe=n.ConfigurationSchema("OntologyRecord",{name:{type:"string",description:'the full name of the ontology, e.g. "Gene Ontology"',defaultValue:"My Ontology"},version:{type:"string",description:"the ontology's version string",defaultValue:"unversioned"},source:{type:"fileLocation",description:"the download location for the ontology's source file",defaultValue:{locationType:"UriLocation",uri:"http://example.com/myontology.json"}},textIndexFields:{type:"frozen",description:"JSON paths for text fields that will be indexed for text searching",defaultValue:Ze}});function et(e){return"CLASS"===e.type}function tt(e){return"PROPERTY"===e.type}async function nt(e,t,n){if(!e)return;const a=await t.getTermsWithLabelOrSynonym(e.type,{includeSubclasses:!1}),o=a.filter(et);if(0===a.length)return;const r=await t.getClassesThat("part_of",o);return 0!==r.length?r:void 0}function at({fetchValidTerms:e,filterTerms:t,includeDeprecated:n,onChange:a,ontologyName:o,ontologyVersion:s,renderInput:l,session:i,style:c,value:u}){const[d,f]=y.useState(!1),[g,p]=y.useState(),[h,b]=y.useState(""),[w,S]=y.useState(),v=i.apolloDataStore.ontologyManager,E=v.findOntology(o,s)?.dataStore,C=E&&d&&!g,x=E&&!w,F=y.useCallback((e=>(n||!Ge(e))&&(!t||t(e))),[t,n]);y.useEffect((()=>{d||p(void 0)}),[d]),y.useEffect((()=>{const e=new AbortController,{signal:t}=e;return x&&(b(""),async function(e,t,n,a){if(!t)return;const o=(await e.getTermsWithLabelOrSynonym(t,{includeSubclasses:!1})).find(n??(()=>!0));if(!o)throw new Error(`not a valid ${e.ontologyName} term`);return o}(E,u,F).then((e=>{t.aborted||S(e)}),(e=>{t.aborted||r.isAbortException(e)||b(String(e))}))),()=>{e.abort()}}),[i,u,F,E,x]),y.useEffect((()=>{const t=new AbortController,{signal:n}=t;return C&&async function(e,t,n,a){let o;if(t){const n=await t(e,a);n&&(o=n)}return o||(o=await e.getAllTerms()),n?o.filter((e=>n(e))):o}(E,e,F,n).then((e=>{e&&!n.aborted&&p(e)}),(e=>{n.aborted||r.isAbortException(e)||i.notify(e.message,"error")})),()=>{t.abort()}}),[C,F,E,i,e]);const A={};return h&&(A.error=!0,A.helperText=h),ae.default.createElement(m.Autocomplete,{style:c,autoComplete:!0,filterSelectedOptions:!0,disableClearable:!0,selectOnFocus:!0,clearOnBlur:!0,handleHomeEndKeys:!0,freeSolo:!0,value:u,options:g??[],onOpen:()=>{f(!0)},onClose:()=>{f(!1)},loading:C,renderInput:l??(e=>ae.default.createElement(m.TextField,{...e,...A})),getOptionLabel:e=>"string"==typeof e?e:e.lbl??"",isOptionEqualToValue:(e,t)=>e.lbl===t.lbl,onChange:async(e,t)=>{t&&("string"==typeof t?(S(void 0),a(u,t)):t.lbl!==u&&(b(""),S(t),a(u,t.lbl)))}})}var ot;function rt({changeManager:e,handleClose:n,session:a,sourceAssemblyId:o,sourceFeature:r}){const{notify:s}=a,[l,i]=y.useState(String(r.end)),[c,u]=y.useState(String(r.start+1)),[d,f]=y.useState(""),[g,p]=y.useState(""),[h,b]=y.useState(),[w,S]=y.useState(!1),[v,E]=y.useState(""),[C,x]=y.useState(""),F=Number(l)<=Number(c);return ae.default.createElement(ke,{open:!0,title:"Add new child feature",handleClose:n,maxWidth:!1,"data-testid":"add-feature-dialog"},ae.default.createElement("form",{onSubmit:async function(a){if(a.preventDefault(),E(""),w&&""===g)return void E("The phase is REQUIRED for all CDS features.");const i=new t.AddFeatureChange({changedIds:[r._id],typeName:"AddFeatureChange",assembly:o,addedFeature:{_id:(new ne.default).toHexString(),gffId:"",refSeq:r.refSeq,start:Number(c)-1,end:Number(l),type:d,phase:h},parentFeatureId:r._id});await(e.submit?.(i)),s("Feature added successfully","success"),n(),a.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.TextField,{margin:"dense",id:"start",label:"Start",type:"number",fullWidth:!0,variant:"outlined",value:c,onChange:e=>u(e.target.value)}),ae.default.createElement(m.TextField,{margin:"dense",id:"end",label:"End",type:"number",fullWidth:!0,variant:"outlined",value:l,onChange:e=>i(e.target.value),error:F,helperText:F?'"End" must be greater than "Start"':null}),ae.default.createElement(at,{session:a,ontologyName:"Sequence Ontology",style:{width:170},value:d,filterTerms:et,fetchValidTerms:async function(e,t,n){const a=await nt(e,t);if(a)return a;x(`Type "${e?.type}" does not have any children in the ontology`)}.bind(null,r),renderInput:e=>ae.default.createElement(m.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0,error:Boolean(C),helperText:C}),onChange:(e,t)=>{var n;t&&(n=t,E(""),f(n),n.startsWith("CDS")?(S(!0),p("")):S(!1))}}),w?ae.default.createElement(m.FormControl,null,ae.default.createElement(m.InputLabel,null,"Phase"),ae.default.createElement(m.Select,{value:g,onChange:async function(e){switch(E(""),p(e.target.value),Number(e.target.value)){case 0:b(ot.zero);break;case 1:b(ot.one);break;case 2:b(ot.two);break;default:b(void 0)}}},ae.default.createElement(m.MenuItem,{value:0},"0"),ae.default.createElement(m.MenuItem,{value:1},"1"),ae.default.createElement(m.MenuItem,{value:2},"2"))):null),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit",disabled:F||!(c&&l&&d)},"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),v?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},v)):null)}function st(e,t){const n=(new ne.default).toHexString();t.push(n);const a={};if(e.children)for(const n of Object.values(e.children)){const e=st(n,t);a[e._id]=e}const o="string"==typeof e.refSeq?e.refSeq:e.refSeq.toHexString();return{...e,refSeq:o,children:e.children&&a,_id:n}}function lt({changeManager:e,handleClose:a,session:o,sourceAssemblyId:r,sourceFeature:s}){const{assemblyManager:l,notify:c}=o,u=l.assemblyList,[d,f]=y.useState(u.find((e=>e.name!==r))?.name),[g,p]=y.useState([]),[h,b]=y.useState(""),[w,S]=y.useState(s.start),[v,E]=y.useState("");function C(e,t){const n={};if(e.children)for(const a of Object.values(e.children)){const e=C(a,t);ne.default.isValid(e.gffId.toString())&&(e.gffId=e._id),e.refSeq=h,e.start=e.start+t,e.end=e.end+t,n[e._id]=e}const a="string"==typeof e.refSeq?e.refSeq:e.refSeq.toHexString(),o="string"==typeof e._id?e._id:e._id.toHexString();return{...e,refSeq:a,children:e.children&&n,_id:o}}return y.useEffect((()=>{b(""),async function(){if(!d)return void E("No assemblies to copy to");const e=await l.waitForAssembly(d);if(!e)return;const{refNameAliases:t}=e;if(!t)return;const n=[...Object.entries(t)].filter((([e,t])=>e!==t)).map((([e,t])=>({_id:e,name:t??""})));p(n),b(n[0]?._id||"")}().catch((e=>E(String(e))))}),[d,l]),ae.default.createElement(ke,{open:!0,title:"Copy features and annotations",handleClose:a,maxWidth:!1,"data-testid":"copy-feature"},ae.default.createElement("form",{onSubmit:async function(n){if(!d)return;n.preventDefault(),E("");const o=s.length,r=await l.waitForAssembly(d);if(!r)return void E(`Assembly not found: ${d}.`);const u=r?.getCanonicalRefName(h),f=r.regions?.find((e=>e.refName===u));if(!f)return void E(`RefSeq not found: ${h}.`);const m=w+o;if(m>f.end)return void E(`Feature would extend beyond the bounds of the selected reference sequence. (Feature would end at ${m}, but reference sequence ends at ${f.end})`);if(w<f.start)return void E(`Reference sequence starts at ${f.start}, feature cannot start before that.`);const g=[],p=st(i.getSnapshot(s),g),y={...p.attributes};"Parent"in y&&delete y.Parent,p.gffId&&ne.default.isValid(p.gffId.toString())&&(p.gffId=p._id),p.refSeq=h;const b=w-p.start;p.start=w,p.end=w+o;const S=C(p,b),v=new t.AddFeatureChange({changedIds:[p._id],typeName:"AddFeatureChange",assembly:d,addedFeature:{_id:p._id,refSeq:p.refSeq,start:p.start,end:p.end,type:p.type,children:S.children,attributes:y,discontinuousLocations:p.discontinuousLocations,strand:p.strand,score:p.score,phase:p.phase},copyFeature:!0,allIds:g});await(e.submit?.(v)),c("Feature copied successfully","success"),a(),n.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Target assembly"),ae.default.createElement(m.Select,{labelId:"label",value:d,onChange:async function(e){f(e.target.value)}},u.filter((e=>e.name!==r)).map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},n.readConfObject(e,"displayName"))))),ae.default.createElement(m.DialogContentText,null,"Target reference sequence"),ae.default.createElement(m.Select,{labelId:"label",value:h,onChange:async function(e){b(e.target.value)}},g.map((e=>ae.default.createElement(m.MenuItem,{key:e._id,value:e._id},e.name)))),ae.default.createElement(m.DialogContentText,null,"Start position in target reference sequence"),ae.default.createElement(m.TextField,{margin:"dense",type:"number",fullWidth:!0,variant:"outlined",value:w,onChange:e=>{S(Number(e.target.value))}})),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!d||!h||!w,variant:"contained",type:"submit"},"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:a},"Cancel"))),v?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},v)):null)}function it({changeManager:e,handleClose:n,session:a}){const{internetAccounts:o}=i.getRoot(a),[r,s]=y.useState(),[l,c]=y.useState(""),[u,d]=y.useState(!1),[f,g]=y.useState(!1),p=o.filter((e=>"ApolloInternetAccount"===e.type));if(0===p.length)throw new Error("No Apollo internet account found");const[h,b]=y.useState(p[0]),{collaborationServerDriver:w}=a.apolloDataStore,S=w.getAssemblies();return y.useEffect((()=>{S.length>0&&void 0===r&&s(S[0])}),[S,r]),ae.default.createElement(ke,{open:!0,title:"Delete Assembly",handleClose:n,maxWidth:!1,"data-testid":"delete-assembly"},ae.default.createElement("form",{onSubmit:async function(a){if(a.preventDefault(),g(!0),c(""),!r)return void c("Must select assembly!");const o=new t.DeleteAssemblyChange({typeName:"DeleteAssemblyChange",assembly:r.name});await(e.submit?.(o,{internetAccountId:h.internetAccountId})),n(),a.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},p.length>1?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogContentText,null,"Select account"),ae.default.createElement(m.Select,{value:h.internetAccountId,onChange:function(e){g(!1);const t=p.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);b(t)},disabled:f&&!l},o.map((e=>ae.default.createElement(m.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,ae.default.createElement(m.DialogContentText,null,"Select assembly"),ae.default.createElement(m.Select,{labelId:"label",value:r?.name??"",onChange:function(e){const t=S.find((t=>t.name===e.target.value));s(t)},disabled:0===S.length},S.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),ae.default.createElement(m.DialogContentText,null,ae.default.createElement("strong",{style:{color:"red"}},"NOTE: All assembly data will be deleted and this operation cannot be undone!")),ae.default.createElement(m.FormGroup,null,ae.default.createElement(m.FormControlLabel,{control:ae.default.createElement(m.Checkbox,{checked:u,onChange:()=>d(!u)}),label:"I understand that all assembly data will be deleted"}))),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!r||!u,variant:"contained",type:"submit"},"Delete"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),l?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},l)):null)}function ct({changeManager:e,handleClose:n,selectedFeature:a,session:o,setSelectedFeature:r,sourceAssemblyId:s,sourceFeature:l}){const{notify:c}=o,[u,d]=y.useState("");return ae.default.createElement(ke,{open:!0,title:"Delete feature",handleClose:n,maxWidth:!1,"data-testid":"delete-feature"},ae.default.createElement("form",{onSubmit:async function(o){o.preventDefault(),d(""),a?._id===l._id&&r();const u=new t.DeleteFeatureChange({changedIds:[l._id],typeName:"DeleteFeatureChange",assembly:s,deletedFeature:i.getSnapshot(l),parentFeatureId:l.parent?._id});await(e.submit?.(u)),c("Feature deleted successfully","success"),n(),o.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Are you sure you want to delete the selected feature?")),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit"},"Yes"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),u?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},u)):null)}function ut({handleClose:e,session:a}){const[o,r]=y.useState(),[s,l]=y.useState(""),{collaborationServerDriver:c,getInternetAccount:u,inMemoryFileDriver:d}=a.apolloDataStore,f=[...c.getAssemblies(),...d.getAssemblies()];return ae.default.createElement(ke,{open:!0,title:"Export GFF3",handleClose:e,maxWidth:!1,"data-testid":"download-gff3"},ae.default.createElement("form",{onSubmit:async function(r){if(r.preventDefault(),l(""),!o)return void l("Must select assembly to download");const{internetAccountConfigId:s}=n.getConf(o,["sequence","metadata"]);s?await async function(e){if(!o)return void l("Must select assembly to download");const t=u(o.configuration.name,e),n=new URL("export/getID",t.baseURL),a=new URLSearchParams({assembly:o.name});n.search=a.toString();const r=n.toString(),s=t.getFetcher({locationType:"UriLocation",uri:r}),i=await s(r,{method:"GET"});if(!i.ok){const e=await Ae(i,"Error when exporting ID");return void l(e)}const{exportID:c}=await i.json(),d=new URL("export",t.baseURL),f=new URLSearchParams({exportID:c});d.search=f.toString();const m=d.toString();window.open(m,"_blank")}(s):function(e){if(!o)return void l("Must select assembly to download");const{assemblies:a}=e.apolloDataStore,r=a.get(o.name),s=r?.refSeqs;if(!s)return void l(`No refSeqs found for assembly "${o.name}"`);const c=[{directive:"gff-version",value:"3"}],u=n.getConf(o,["sequence","adapter","features"]);for(const e of u){const{end:t,refName:n,start:a}=e;c.push({directive:"sequence-region",value:`${n} ${a+1} ${t}`})}for(const[,e]of s){const n=e?.features;if(n)for(const[,e]of n)c.push(t.makeGFF3Feature(i.getSnapshot(e)))}for(const e of u){const{refName:t,seq:n}=e;c.push({id:t,description:"",sequence:n})}const d=Z.default.formatSync(c),f=new Blob([d],{type:"text/plain;charset=utf-8"});D.saveAs(f,`${o.displayName??o.name}.gff3`)}(a),e()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Select assembly"),ae.default.createElement(m.Select,{labelId:"label",value:o?.name??"",onChange:function(e){const t=f.find((t=>t.name===e.target.value));r(t)},disabled:0===f.length},f.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),ae.default.createElement(m.DialogContentText,null,"Select assembly to export to GFF3")),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!o,variant:"contained",type:"submit"},"Download"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),s?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},s)):null)}function dt({changeManager:e,handleClose:a,session:o}){const{apolloDataStore:r}=o,[s,l]=y.useState(),[i,c]=y.useState(),[u,d]=y.useState(""),[f,g]=y.useState(!1),[p,h]=y.useState(),[b,w]=y.useState(!1),[S,v]=y.useState(!1),{collaborationServerDriver:E,getInternetAccount:C}=r,x=E.getAssemblies();return y.useEffect((()=>{i&&(async()=>{const{internetAccountConfigId:e}=n.getConf(i,["sequence","metadata"]),t=C(i.name,e);if(!t)throw new Error("No Apollo internet account found");const{baseURL:a}=t,o=new URL("/features/count",a),r=new URLSearchParams({assemblyId:i.name});o.search=r.toString();const s=t?.getFetcher({locationType:"UriLocation",uri:o.toString()});v(!0);const l=await s(o.toString(),{method:"GET"});if(!l.ok)throw new Error(await Ae(l));{const e=await l.json();h(e.count)}v(!1)})().catch((e=>{console.error(e),d(e.message??e)}))}),[C,o,i]),ae.default.createElement(ke,{open:!0,title:"Import Features from GFF3 file",handleClose:a,maxWidth:!1,"data-testid":"import-features-dialog"},S?ae.default.createElement(te.default,null):null,ae.default.createElement("form",{onSubmit:async function(r){r.preventDefault(),d(""),v(!0),g(!0);let l="";if(!s)return void d("must select a file");if(!i)return void d("Must select assembly to download");const{internetAccountConfigId:c}=n.getConf(i,["sequence","metadata"]),u=C(i.name,c),{baseURL:f}=u,m=new URL("/files",f).href,p=new FormData;p.append("file",s),p.append("fileName",s.name),p.append("type","text/x-gff3");const h=u?.getFetcher({locationType:"UriLocation",uri:m});a();const{jobsManager:y}=o,w=new AbortController,S={name:`Importing features for ${i.displayName}`,statusMessage:"Uploading file, this may take awhile",progressPct:0,cancelCallback:()=>{w.abort(),y.abortJob(S.name)}};if(y.runJob(S),h){const{signal:e}=w,t=await h(m,{method:"POST",body:p,signal:e});if(!t.ok){const e=await Ae(t,"Error when inserting new features (while uploading file)");return y.abortJob(S.name,e),void d(e)}l=(await t.json())._id}const E=new t.AddFeaturesFromFileChange({typeName:"AddFeaturesFromFileChange",assembly:i.name,fileId:l,deleteExistingFeatures:b});y.done(S),await e.submit(E,{updateJobsManager:!0})}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Select assembly"),ae.default.createElement(m.Select,{labelId:"label",value:i?.name??"",onChange:function(e){const t=x.find((t=>t.name===e.target.value));c(t),g(!1)},disabled:f&&!u},x.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name))))),ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.DialogContentText,null,"Upload GFF3 to load features"),ae.default.createElement("input",{type:"file",onChange:function(e){g(!1),e.target.files&&l(e.target.files[0])},disabled:f&&!u})),p&&p>0?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,null,"This assembly already has ",p," features, would you like to delete the existing features before importing new ones?"),ae.default.createElement(ce.default,{label:"Yes, delete existing features",disabled:f&&!u,control:ae.default.createElement(ie.default,{checked:b,onChange:function(e){w(e.target.checked)},inputProps:{"aria-label":"controlled"},color:"warning"})})):null,ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!(i&&s&&void 0!==p)||f,variant:"contained",type:"submit"},f?"Submitting...":"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:a},"Close"))),u?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},u)):null)}function ft({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),[a,o]=y.useState(),[r,s]=y.useState(""),[l,c]=y.useState(!1),u=n.filter((e=>"ApolloInternetAccount"===e.type));if(0===u.length)throw new Error("No Apollo internet account found");const[d,f]=y.useState(u[0]),[g,p]=y.useState([]),[h,b]=y.useState([]),{collaborationServerDriver:w}=t.apolloDataStore,S=w.getAssemblies();function v(e,t){const n=[...h],a=e.target.value;if(t)n.includes(a)||(n.push(a),b(n));else{const e=n.indexOf(a,0);e>-1&&n.splice(e,1),b(n)}}return y.useEffect((()=>{(async function(){const{baseURL:e,getFetcher:t}=d,n=new URL("/checks/types",e).href,a=t({locationType:"UriLocation",uri:n}),o=await a(n,{method:"GET"});if(!o.ok){const e=await Ae(o,"Error when retrieving checks from server");return void s(e)}const r=await o.json();p(r)})().catch((e=>s(String(e))))}),[d]),y.useEffect((()=>{S.length>0&&void 0===a&&o(S[0])}),[S,a]),y.useEffect((()=>{(async function(){if(!a)return;const{baseURL:e,getFetcher:t}=d,n=new URL(`/assemblies/${a.name}`,e).href,o=t({locationType:"UriLocation",uri:n}),r=await o(n,{method:"GET"});if(!r.ok){const e=await Ae(r,"Error when retrieving assembly from server");return void s(e)}const l=await r.json();b(l.checks)})().catch((e=>s(String(e))))}),[a,d]),ae.default.createElement(ke,{open:!0,title:"Manage Checks",handleClose:e,"data-testid":"manage-checks"},ae.default.createElement("form",{onSubmit:async function(n){if(n.preventDefault(),!a)return void s("Must select assembly!");const{notify:o}=t,{baseURL:r,getFetcher:l}=d,i=new URL("/assemblies/checks",r).href,c=l({locationType:"UriLocation",uri:i}),u=await c(i,{method:"POST",body:JSON.stringify({_id:a.name,checks:h,name:""}),headers:{"Content-Type":"application/json"}});if(u.ok)o("Assembly checks updated successfully","success"),e();else{const e=await Ae(u,"Error when updating assembly checks");s(e)}}},ae.default.createElement(m.DialogContent,null,u.length>1?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogContentText,null,"Select account"),ae.default.createElement(m.Select,{value:d.internetAccountId,onChange:function(e){c(!1);const t=u.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);f(t)},disabled:l&&!r},n.map((e=>ae.default.createElement(m.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,ae.default.createElement(m.DialogContentText,null,"Select assembly"),ae.default.createElement(m.Select,{style:{width:300},labelId:"label",value:a?.name??"",onChange:function(e){const t=S.find((t=>t.name===e.target.value));o(t)},disabled:0===S.length},S.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),ae.default.createElement("br",null),ae.default.createElement("br",null),ae.default.createElement(m.TableContainer,{component:m.Paper},ae.default.createElement(m.Table,null,ae.default.createElement(m.TableHead,null,ae.default.createElement(m.TableRow,null,ae.default.createElement(m.TableCell,null,"Check name"),ae.default.createElement(m.TableCell,null,"Use check"))),ae.default.createElement(m.TableBody,null,g.map((e=>ae.default.createElement(m.TableRow,{key:e._id},ae.default.createElement(m.TableCell,null,e.name),ae.default.createElement(m.TableCell,null,ae.default.createElement(m.Checkbox,{value:e._id,checked:h.includes(e._id),onChange:v}))))))))),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit"},"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:e},"Cancel"))),r?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},r)):null)}function mt({changeManager:e,handleClose:n,session:a}){const{internetAccounts:o}=i.getRoot(a),r=o.filter((e=>"ApolloInternetAccount"===e.type&&e.role?.includes("admin")));if(0===r.length)throw new Error("No Apollo internet account found");const[s,l]=y.useState(""),[c,u]=y.useState(r[0]),[d,f]=y.useState([]),g=y.useCallback((async()=>{const{baseURL:e}=c,t=new URL("/users",e).href,n=c?.getFetcher({locationType:"UriLocation",uri:t});if(n){const e=await n(t,{method:"GET"});if(!e.ok){const t=await Ae(e,"Error when getting user data from db");return void l(t)}const a=await e.json();f(a.map((e=>void 0===e.role?{...e,role:""}:e)))}}),[c]);function p(e){return e===c.getUserId()}y.useEffect((()=>{g().catch((e=>l(String(e))))}),[g]);const h=[{field:"username",headerName:"User",width:140},{field:"email",headerName:"Email",width:160},{field:"role",headerName:"Role",width:140,type:"singleSelect",valueOptions:["","readOnly","user","admin"],editable:!0},{field:"actions",type:"actions",getActions:n=>[ae.default.createElement(M.GridActionsCellItem,{key:`delete-${n.id}`,icon:ae.default.createElement(ue.default,null),onClick:async()=>{window.confirm("Delete this user?")&&await async function(n){const a=new t.DeleteUserChange({typeName:"DeleteUserChange",userId:n});await e.submit(a,{internetAccountId:c.internetAccountId}),f((e=>e.filter((e=>e._id!==n))))}(n.id)},disabled:p(n.id),label:"Delete"})]}];return ae.default.createElement(ke,{open:!0,fullScreen:!0,title:"Manage users",handleClose:n,"data-testid":"manage-users"},ae.default.createElement(m.DialogContent,null,r.length>1?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.DialogContentText,null,"Select account"),ae.default.createElement(m.Select,{value:c.internetAccountId,onChange:function(e){const t=r.find((t=>t.internetAccountId===e.target.value));if(!t)throw new Error(`Could not find internetAccount with ID "${e.target.value}"`);u(t)},disabled:!s},o.map((e=>ae.default.createElement(m.MenuItem,{key:e.id,value:e.internetAccountId},e.name))))):null,ae.default.createElement("div",{style:{height:"100%",width:"100%"}},ae.default.createElement(M.DataGrid,{pagination:!0,rows:d,columns:h,getRowId:e=>e._id,slots:{toolbar:M.GridToolbar},getRowHeight:()=>"auto",isCellEditable:e=>!p(e.id),processRowUpdate:async function(n){const a=new t.UserChange({typeName:"UserChange",role:n.role,userId:n._id});return await e.submit(a,{internetAccountId:c.internetAccountId}),n},onProcessRowUpdateError:e=>l(String(e))}))),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Close")),s?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},s)):null)}function gt({getTagProps:e,index:t,ontology:n,termId:a}){const o=i.getParent(n,2),[r,s]=oe.useState(""),[l,c]=oe.useState("");return oe.useEffect((()=>{const e=new AbortController,{signal:t}=e;return async function(){const e=o.expandPrefixes(a),r=await(n.dataStore?.db);if(!r||t.aborted)return;const l=await r.transaction("nodes").objectStore("nodes").get(e);l&&l.lbl&&!t.aborted&&s(l.lbl||"no label")}().catch((e=>{t.aborted||c(String(e))})),()=>{e.abort()}}),[a,n,o]),oe.createElement(m.Tooltip,{title:r},oe.createElement("div",null,oe.createElement(m.Chip,{label:l||o.applyPrefixes(a),color:l?"error":"default",size:"small",...e({index:t})})))}function pt({includeDeprecated:e,onChange:t,ontologyName:n,ontologyVersion:a,session:o,value:s}){const l=o.apolloDataStore.ontologyManager,i=l.findOntology(n,a),[c,u]=oe.useState(s.map((e=>({term:{id:e,type:"CLASS"}})))),[d,f]=oe.useState(""),[g,p]=oe.useState([]),[h,y]=oe.useState(!1),[b,w]=oe.useState(""),S=oe.useMemo((()=>T.debounce((async(t,n)=>{if(!i)return;const{dataStore:a}=i;if(!a)return;const{input:o,signal:s}=t;try{const t=await a.getTermsByFulltext(o,void 0,s),r=new Map,l=[];for(const n of t){if(!et(n.term)||!e&&Ge(n.term))continue;let t=r.get(n.term.id);t||(t={term:n.term,matches:[]},r.set(n.term.id,t),l.push(t)),t.matches.push(n)}n(l)}catch(e){r.isAbortException(e)||w(String(e))}}),400)),[e,i]);if(oe.useEffect((()=>{const e=new AbortController,{signal:t}=e;if(""!==d)return y(!0),S({input:d,signal:t},(e=>{let t=[];c.length>0&&(t=c),e&&(t=[...t,...e]),p(t),y(!1)})),()=>{e.abort()};p([])}),[S,i,e,d,c]),!i)return null;const v={};return b&&(v.error=!0,v.helperText=b),oe.createElement(m.Autocomplete,{getOptionLabel:e=>l.applyPrefixes(e.term.id),filterOptions:e=>e.filter((e=>et(e.term))),options:g,autoComplete:!0,includeInputInList:!0,filterSelectedOptions:!0,value:c,loading:h,isOptionEqualToValue:(e,t)=>l.applyPrefixes(e.term.id)===l.applyPrefixes(t.term.id),noOptionsText:d?"No matches":"Start typing to search",onChange:(e,n)=>{p(n?[...n,...g]:g),t(n.map((e=>l.applyPrefixes(e.term.id)))),u(n)},onInputChange:(e,t)=>{t&&y(!0),p([]),f(t)},multiple:!0,renderInput:e=>oe.createElement(m.TextField,{...e,...v,variant:"outlined",fullWidth:!0}),renderOption:(e,t)=>oe.createElement(yt,{...e,ontologyManager:l,option:t,inputValue:d}),renderTags:(e,t)=>e.map(((e,n)=>oe.createElement(gt,{termId:e.term.id,index:n,ontology:i,getTagProps:t,key:e.term.id})))})}function ht(e){const{search:t,str:n}=e,a=de.default(n,t,{insideWords:!0,findAllOccurrences:!0}),o=fe.default(n,a);return oe.createElement(oe.Fragment,null,o.map(((e,t)=>oe.createElement(m.Typography,{key:t,component:"span",sx:{fontWeight:e.highlight?"bold":"regular"},variant:"body2",color:"text.secondary"},e.text))))}function yt(e){const{inputValue:t,ontologyManager:n,option:a,...o}=e,r=(a.matches??[]).filter((e=>"$.lbl"!==e.field.jsonPath)).map((e=>oe.createElement(oe.Fragment,{key:`option-${e.term.id}-${e.str}`},oe.createElement(m.Typography,{component:"dt",variant:"body2",color:"text.secondary"},e.field.displayName),oe.createElement("dd",null,oe.createElement(ht,{str:e.str,search:t})))));return oe.createElement("li",{...o},oe.createElement(m.Grid,{container:!0},oe.createElement(m.Grid,{item:!0},oe.createElement(m.Typography,{component:"span"},n.applyPrefixes(a.term.id))," ",oe.createElement(ht,{str:a.term.lbl??"(no label)",search:t})," ",oe.createElement("dl",null,r))))}!function(e){e[e.zero=0]="zero",e[e.one=1]="one",e[e.two=2]="two"}(ot||(ot={}));const bt=new Map([["Gene Ontology",e=>ae.default.createElement(pt,{...e,ontologyName:"Gene Ontology"})],["Sequence Ontology",e=>ae.default.createElement(pt,{...e,ontologyName:"Sequence Ontology"})]]),wt=v.makeStyles()((e=>({attributeInput:{maxWidth:600},newAttributePaper:{padding:e.spacing(2)},attributeName:{background:e.palette.secondary.main,color:e.palette.secondary.contrastText,padding:e.spacing(1)}}))),St=["ID","Name","Alias","Target","Gap","Derives_from","Note","Dbxref","Ontology","Is_Circular"];function vt(e){const{onChange:t,value:n}=e;return ae.default.createElement(m.TextField,{type:"text",value:n,onChange:e=>{t(e.target.value.split(","))},variant:"outlined",fullWidth:!0,helperText:"Separate multiple values for the attribute with commas"})}function Et({changeManager:e,handleClose:n,session:a,sourceAssemblyId:o,sourceFeature:r}){const{notify:s}=a,{internetAccounts:l}=i.getRoot(a),c=y.useMemo((()=>l.find((e=>"ApolloInternetAccount"===e.type))),[l]),u=["admin","user"].includes((c?c.role:"admin")??""),[d,f]=y.useState(""),[g,p]=y.useState(Object.fromEntries([...r.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]})))),[h,b]=y.useState(!1),[w,S]=y.useState(""),{classes:v}=wt(),E=Object.values(g).some((e=>0===e.length||e.includes("")));return ae.default.createElement(ke,{open:!0,title:"Feature attributes",handleClose:n,maxWidth:!1,"data-testid":"modify-feature-attribute"},ae.default.createElement("form",{onSubmit:async function(a){a.preventDefault(),f("");const l={};if(g)for(const[e,t]of Object.entries(g))if(t&&"parent"!==e.toLowerCase())if([...bt.keys()].includes(e))l[e]=t;else switch(e){case"ID":l._id=t;break;case"Name":l.gff_name=t;break;case"Alias":l.gff_alias=t;break;case"Target":l.gff_target=t;break;case"Gap":l.gff_gap=t;break;case"Derives_from":l.gff_derives_from=t;break;case"Note":l.gff_note=t;break;case"Dbxref":l.gff_dbxref=t;break;case"Ontology_term":l.gff_ontology_term=t;break;case"Is_circular":l.gff_is_circular=t;break;default:l[e.toLowerCase()]=t}const i=new t.FeatureAttributeChange({changedIds:[r._id],typeName:"FeatureAttributeChange",assembly:o,featureId:r._id,attributes:l});await(e.submit?.(i)),s("Feature attributes modified successfully","success"),n(),a.preventDefault()}},ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.Grid,{container:!0,direction:"column",spacing:1},Object.entries(g).map((([e,t])=>{const n=bt.get(e)??vt;return ae.default.createElement(m.Grid,{container:!0,item:!0,spacing:3,alignItems:"center",key:e},ae.default.createElement(m.Grid,{item:!0,xs:"auto"},ae.default.createElement(m.Paper,{variant:"outlined",className:v.attributeName},ae.default.createElement(m.Typography,null,e))),ae.default.createElement(m.Grid,{item:!0,flexGrow:1},ae.default.createElement(n,{session:a,value:t,onChange:(o=e,e=>{p({...g,[o]:e})})})),ae.default.createElement(m.Grid,{item:!0,xs:1},ae.default.createElement(m.IconButton,{"aria-label":"delete",size:"medium",disabled:!u,onClick:()=>{!function(e){f("");const{[e]:t,...n}=g;p(n)}(e)}},ae.default.createElement(ue.default,{fontSize:"medium",key:e}))));var o})),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Button,{color:"primary",variant:"contained",disabled:h||!u,onClick:()=>{b(!0)}},"Add new")),h?ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Paper,{elevation:8,className:v.newAttributePaper},ae.default.createElement(m.Grid,{container:!0,direction:"column"},ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.FormControl,null,ae.default.createElement(m.FormLabel,{id:"attribute-radio-button-group"},"Select attribute type"),ae.default.createElement(m.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:"custom",name:"radio-buttons-group",onChange:function(e,t){"custom"===t?S(""):bt.has(t)?S(t):f("Unknown attribute type")}},ae.default.createElement(m.FormControlLabel,{value:"custom",control:ae.default.createElement(m.Radio,null),disableTypography:!0,label:ae.default.createElement(m.Grid,{container:!0,spacing:1,alignItems:"center"},ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Typography,null,"Custom")),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.TextField,{label:"Custom attribute key",variant:"outlined",value:bt.has(w)?"":w,disabled:bt.has(w),onChange:e=>{S(e.target.value)}})))}),[...bt.keys()].map((e=>ae.default.createElement(m.FormControlLabel,{key:e,value:e,control:ae.default.createElement(m.Radio,null),label:e})))))),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{key:"addButton",color:"primary",variant:"contained",style:{margin:2},onClick:function(){f(""),0!==w.trim().length?"Parent"!==w?w in g?f(`Attribute "${w}" already exists`):!/^[A-Z]/.test(w)||St.includes(w)||[...bt.keys()].includes(w)?(p({...g,[w]:[]}),b(!1),S("")):f(`Key cannot starts with uppercase letter unless key is one of these: ${St.join(", ")}`):f('"Parent" -key is handled internally and it cannot be modified manually'):f("Attribute key is mandatory")},disabled:!w},"Add"),ae.default.createElement(m.Button,{key:"cancelAddButton",variant:"outlined",type:"submit",onClick:()=>{b(!1),S(""),f("")}},"Cancel")))))):null),d?ae.default.createElement(m.DialogContentText,{color:"error"},d):null),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit",disabled:h||E||!u},"Submit changes"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",disabled:h,onClick:n},"Cancel"))))}function Ct({handleClose:e,session:t}){const{addApolloTrackConfig:n,apolloDataStore:a}=t,{addAssembly:o,addSessionAssembly:s,assemblyManager:l,notify:i}=t,[c,u]=y.useState(null),[f,g]=y.useState(""),[p,h]=y.useState(""),[b,w]=y.useState(!1),S=m.useTheme();return ae.default.createElement(ke,{open:!0,title:"Open local GFF3 file",handleClose:e,maxWidth:!1,"data-testid":"open-local-file"},ae.default.createElement("form",{onSubmit:async function(t){if(t.preventDefault(),h(""),w(!0),!c)throw new Error("No file selected");const u=await new Response(c).text(),m=`${f}-${c.name}-${d.nanoid(8)}`;try{await Ce(m,u,a)}catch(e){h(String(e)),w(!1)}const g={name:m,aliases:[f],displayName:f,sequence:{trackId:`sequenceConfigId-${f}`,type:"ReferenceSequenceTrack",adapter:{type:"ApolloSequenceAdapter",assemblyId:m},metadata:{apollo:!0,...r.isElectron?{file:c.path}:{}}}};await(s||o)(g);const p=await l.waitForAssembly(g.name);p?(n(p),i(`Loaded GFF3 ${c?.name}`,"success")):i(`Error loading GFF3 ${c?.name}`,"error"),e()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.FormControl,null,ae.default.createElement("div",{style:{flexDirection:"row"}},ae.default.createElement(m.Button,{variant:"contained",component:"label",style:{marginRight:S.spacing()}},"Choose File",ae.default.createElement("input",{type:"file",required:!0,hidden:!0,onChange:async function(e){const t=e.target.files?.item(0);if(t&&(h(""),u(t),!f)){const e=t.name,n=e.lastIndexOf(".");g(-1===n?e:e.slice(0,n))}}})),c?c.name:"No file chosen"),ae.default.createElement(m.FormHelperText,null,"Make sure your GFF3 has an embedded FASTA section")),ae.default.createElement(m.TextField,{required:!0,label:"Assembly name",value:f,onChange:function(e){g(e.target.value)}})),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{disabled:!1,variant:"contained",type:"submit"},b?"Submitting...":"Submit"),ae.default.createElement(m.Button,{disabled:b,variant:"outlined",type:"submit",onClick:e},"Cancel"))),p?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},p)):null)}const xt=v.makeStyles()((e=>({changeTextarea:{fontFamily:"monospace",width:600,resize:"none",border:`1px solid ${e.palette.divider}`,borderRadius:e.shape.borderRadius}})));function Ft({handleClose:t,session:n}){const{internetAccounts:a}=i.getRoot(n),o=a.find((e=>"ApolloInternetAccount"===e.type));if(!o)throw new Error("No Apollo internet account found");const{baseURL:r}=o,{classes:s}=xt(),[l,c]=y.useState(),[u,d]=y.useState([]),[f,g]=y.useState(""),[p,h]=y.useState([]),b=[{field:"sequence"},{field:"typeName",headerName:"Change type",width:200,type:"singleSelect",valueOptions:[...e.changeRegistry.changes.keys()]},{field:"changes",headerName:"Change JSON",width:600,renderCell:({value:e})=>ae.default.createElement("textarea",{className:s.changeTextarea,value:JSON.stringify(e),readOnly:!0}),valueFormatter:({value:e})=>JSON.stringify(e)},{field:"user",headerName:"User",width:140},{field:"createdAt",headerName:"Time",width:160,type:"dateTime",valueGetter:e=>e&&new Date(e)}];return y.useEffect((()=>{(async function(){const e=new URL("/assemblies",r).href,t=o?.getFetcher({locationType:"UriLocation",uri:e});if(t){const n=await t(e,{method:"GET"});if(!n.ok){const e=await Ae(n,"Error when retrieving assemblies from server");return void c(e)}const a=await n.json();d(a)}})().catch((e=>c(String(e))))}),[o,r]),y.useEffect((()=>{!f&&u.length>0&&g(u[0]._id)}),[f,u]),y.useEffect((()=>{(async function(){if(!f)return;const e=new URL("changes",r),t=new URLSearchParams({assembly:f});e.search=t.toString();const n=e.toString(),a=o?.getFetcher({locationType:"UriLocation",uri:n});if(a){const e=await a(n,{headers:new Headers({"Content-Type":"application/json"})});if(!e.ok){const t=await Ae(e,"Error when retrieving changes");return void c(t)}const t=await e.json();h(t)}})().catch((e=>c(String(e))))}),[f,o,r]),ae.default.createElement(ke,{open:!0,fullScreen:!0,title:"View change log",handleClose:t,"data-testid":"view-changelog"},ae.default.createElement(m.Select,{style:{width:200,marginLeft:40},value:f,onChange:async function(e){g(e.target.value)}},u.map((e=>ae.default.createElement(m.MenuItem,{key:e._id,value:e._id},e.name)))),ae.default.createElement(m.DialogContent,null,ae.default.createElement(M.DataGrid,{pagination:!0,rows:p,columns:b,getRowId:e=>e._id,slots:{toolbar:M.GridToolbar},initialState:{sorting:{sortModel:[{field:"sequence",sort:"desc"}]},columns:{columnVisibilityModel:{sequence:!1}}}})),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:t},"Close")),l?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},l)):null)}function At(e){const{color:t}=e;return ae.default.createElement(m.SvgIcon,{viewBox:"0 0 18 18",style:{fontSize:18,marginRight:4},...e},"disabled"===t?ae.default.createElement("path",{d:"M9.001,10.71 l0,-3.348 l8.424,0 c0.126,0.567,0.225,1.098,0.225,1.845 c0,5.139,-3.447,8.793,-8.64,8.793 c-4.968,0,-9,-4.032,-9,-9 c0,-4.968,4.032,-9,9,-9 c2.43,0,4.464,0.891,6.021,2.349 l-2.556,2.484 c-0.648,-0.612,-1.782,-1.332,-3.465,-1.332 c-2.979,0,-5.409,2.475,-5.409,5.508 c0,3.033,2.43,5.508,5.409,5.508 c3.447,0,4.716,-2.385,4.95,-3.798 l-4.959,0 l0,-0.009 z"}):ae.default.createElement(ae.default.Fragment,null,ae.default.createElement("path",{d:"M17.64,9.20454545 c0,-0.638,-0.057,-1.252,-0.164,-1.841 l-8.476,0 l0,3.481 l4.844,0 c-0.209,1.125,-0.843,2.079,-1.796,2.717 l0,2.258 l2.908,0 c1.702,-1.567,2.684,-3.874,2.684,-6.615 l0,0 z",fill:"#4285F4"}),ae.default.createElement("path",{d:"M9,18 c2.43,0,4.467,-0.806,5.956,-2.18 l-2.908,-2.259 c-0.806,0.54,-1.837,0.859,-3.048,0.859 c-2.344,0,-4.328,-1.583,-5.036,-3.71 l-3.007,0 l0,2.332 c1.481,2.941,4.525,4.958,8.043,4.958 l0,0 z",fill:"#34A853"}),ae.default.createElement("path",{d:"M3.96409091,10.71 c-0.18,-0.54,-0.282,-1.117,-0.282,-1.71 c0,-0.593,0.102,-1.17,0.282,-1.71 l0,-2.332 l-3.007,0 c-0.609,1.215,-0.957,2.59,-0.957,4.042 c0,1.452,0.348,2.827,0.957,4.042 l3.007,-2.332 l0,0 z",fill:"#FBBC05"}),ae.default.createElement("path",{d:"M9,3.57954545 c1.321,0,2.508,0.454,3.44,1.346 l2.582,-2.581 c-1.559,-1.453,-3.596,-2.345,-6.022,-2.345 c-3.518,0,-6.562,2.017,-8.043,4.959 l3.007,2.331 c0.708,-2.127,2.692,-3.71,5.036,-3.71 l0,0 z",fill:"#EA4335"})))}function Dt(e){const{color:t}=e;return ae.default.createElement(m.SvgIcon,{viewBox:"0 0 21 21",style:{fontSize:21},...e},ae.default.createElement("rect",{x:"1",y:"1",width:"9",height:"9",fill:"disabled"===t?"#7B7B7B":"#F25022"}),ae.default.createElement("rect",{x:"1",y:"11",width:"9",height:"9",fill:"disabled"===t?"#7B7B7B":"#00A4EF"}),ae.default.createElement("rect",{x:"11",y:"1",width:"9",height:"9",fill:"disabled"===t?"#939393":"#7FBA00"}),ae.default.createElement("rect",{x:"11",y:"11",width:"9",height:"9",fill:"disabled"===t?"#B9B9B9":"#FFB900"}))}const kt=v.makeStyles()((e=>({loginButton:{marginBottom:e.spacing(1),width:"220px",height:"40px",fontSize:"16px",textTransform:"none",justifyContent:"left",padding:"3px 12px"}})));function Nt(e){const{classes:t}=kt(),{disabled:n}=e;return ae.default.createElement(m.Button,{className:t.loginButton,variant:"outlined",startIcon:ae.default.createElement(At,{color:n?"disabled":void 0}),...e},"Sign in with Google")}function Rt(e){const{classes:t}=kt(),{disabled:n}=e;return ae.default.createElement(m.Button,{className:t.loginButton,variant:"outlined",startIcon:ae.default.createElement(Dt,{color:n?"disabled":void 0}),...e},"Sign in with Microsoft")}function Mt(e){const{classes:t}=kt();return ae.default.createElement(m.Button,{className:t.loginButton,variant:"outlined",startIcon:ae.default.createElement(me.default,{fontSize:"small"}),...e},"Continue as Guest")}const Tt=v.makeStyles()((e=>({divider:{marginTop:e.spacing(4),marginBottom:e.spacing(5)}}))),Lt=({baseURL:e,handleClose:t,name:n})=>{const{classes:a}=Tt(),[o,s]=y.useState(""),[l,i]=y.useState([]);function c(e){t("google"===e?"google":"microsoft"===e?"microsoft":"guest")}y.useEffect((()=>{const t=new AbortController,{signal:n}=t;return async function(){const t=new URL("/auth/types",e).href,a=await fetch(t,{method:"GET",signal:n});if(!a.ok){const e=await Ae(a,"Error when retrieving auth types from server");return void s(e)}const o=await a.json();i(o)}().catch((e=>r.isAbortException(e)?"":s(String(e)))),()=>{t.abort()}}),[e]);const u=l.includes("google"),d=l.includes("microsoft"),f=l.includes("guest");return ae.default.createElement(ke,{open:!0,title:`Log in to ${n}`,handleClose:t,maxWidth:!1,"data-testid":"login-apollo"},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column",paddingTop:8}},u?ae.default.createElement(Nt,{disabled:!u,onClick:()=>c("google")}):null,d?ae.default.createElement(Rt,{disabled:!d,onClick:()=>c("microsoft")}):null,f?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Divider,{className:a.divider}),ae.default.createElement(Mt,{onClick:()=>c("guest")})):null),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:()=>{t()}},"Cancel")),o?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},o)):null)},It="undefined"==typeof sessionStorage,Pt=o=>a.InternetAccount.named("ApolloInternetAccount").props({type:i.types.literal("ApolloInternetAccount"),configuration:n.ConfigurationReference(o)}).views((e=>({get baseURL(){return n.getConf(e,"baseURL")},getUserId(){const n=e.retrieveToken();if(n)return t.getDecodedToken(n).id}}))).volatile((()=>({role:void 0}))).actions((e=>{let n=!1;return{setRole(){const a=e.retrieveToken();if(!a)return void(e.role=void 0);const o=t.getDecodedToken(a),{role:r}=o;if(!r&&!n){const{session:t}=i.getRoot(e);t.notify("You have registered as a user but have not been given access. Ask your administrator to enable access for your account.","warning"),n=!0}e.role!==r&&(e.role=r)}}})).actions((e=>{let t;return{addMessageChannel(e,n){t=t=>{this.finishOAuthWindow(t,e,n)},window.addEventListener("message",t)},deleteMessageChannel(){window.removeEventListener("message",t)},async finishOAuthWindow(t,n,a){if(t.data.name!==`JBrowseAuthWindow-${e.internetAccountId}`)return this.deleteMessageChannel();const o=t.data.redirectUri.replace("#","?"),r=new URL(o),s=new URLSearchParams(r.search).get("access_token");return this.deleteMessageChannel(),s?(e.storeToken(s),e.setRole(),n(s)):a(new Error("Error with token endpoint"))},async openAuthWindow(t,n,a){const o=r.isElectron?"http://localhost/auth":window.location.origin+window.location.pathname,s=new URL("auth/login",e.baseURL),l=new URLSearchParams({type:t,redirect_uri:o});s.search=l.toString();const i=`JBrowseAuthWindow-${e.internetAccountId}`;if(r.isElectron){const{ipcRenderer:t}=window.require("electron"),r=await t.invoke("openAuthWindow",{internetAccountId:e.internetAccountId,data:{redirect_uri:o},url:s.toString()}),l=new MessageEvent("message",{data:{name:i,redirectUri:r}});this.finishOAuthWindow(l,n,a)}else this.addMessageChannel(n,a),window.open(s,i,"width=500,height=600")}}})).actions((e=>({async getTokenFromUser(t,n){const{baseURL:a}=e,o=await new Promise(((t,n)=>{const{session:a}=i.getRoot(e),{baseURL:o,name:r}=e;a.queueDialog((e=>[Lt,{name:r,handleClose:a=>{a?a instanceof Error?n(a):t(a):n(new Error("user cancelled entry")),e()},baseURL:o}]))}));if("guest"!==o)return void e.openAuthWindow(o,t,n);const r=new URL("auth/login",a),s=new URLSearchParams({type:o});r.search=s.toString();const l=r.toString(),c=await fetch(l);if(!c.ok){const e=await Ae(c,"Error when logging in");return n(new Error(e))}const{token:u}=await c.json();t(u)}}))).volatile((()=>({lastChangeSequenceNumber:void 0}))).actions((e=>({setLastChangeSequenceNumber(t){e.lastChangeSequenceNumber=t}}))).actions((t=>({updateLastChangeSequenceNumber:i.flow((function*(){const{baseURL:e}=t,n=new URL("changes",e),a=new URLSearchParams({limit:"1"});n.search=a.toString();const o=n.toString(),r=t.getFetcher({locationType:"UriLocation",uri:o}),s=yield r(o,{method:"GET"});if(!s.ok){const e=yield Ae(s,"Error when fetching server LastChangeSequence");throw new Error(e)}const l=yield s.json();t.setLastChangeSequenceNumber(l.length>0?l[0].sequence:0)})),getMissingChanges:i.flow((function*(){const{session:n}=i.getRoot(t),{changeManager:a}=n.apolloDataStore;if(!t.lastChangeSequenceNumber)throw new Error("No LastChangeSequence stored in session. Please, refresh you browser to get last updates from server");const{baseURL:o,lastChangeSequenceNumber:r}=t,s=new URL("changes",o),l=new URLSearchParams({since:String(r),sort:"1"});s.search=l.toString();const c=s.toString(),u=t.getFetcher({locationType:"UriLocation",uri:c}),d=yield u(c,{method:"GET"});if(!d.ok)return void console.error(`Error when fetching the last updates to recover socket connection — ${d.status}`);const f=yield d.json();for(const t of f){const n=e.Change.fromJSON(t);a?.submit(n,{submitToBackend:!1})}}))}))).volatile((e=>({socket:c.io(e.baseURL)}))).actions((n=>({addSocketListeners(){const{session:a}=i.getRoot(n),{notify:o}=a,r=n.retrieveToken();if(!r)throw new Error("No Token found");const{socket:s}=n,{addCheckResult:l,changeManager:c,deleteCheckResult:u}=a.apolloDataStore;s.on("connect",(async()=>{await n.getMissingChanges()})),s.on("connect_error",(()=>{o("Could not connect to the Apollo server.","error")})),s.on("COMMON",(t=>{if("checkResult"in t)return void(t.deleted?u(t.checkResult._id.toString()):l(t.checkResult));if(sessionStorage.setItem("LastChangeSequence",String(t.changeSequence)),t.userSessionId===r)return;const n=e.Change.fromJSON(t.changeInfo);c?.submit(n,{submitToBackend:!1})})),s.on("USER_LOCATION",(e=>{const{channel:n,locations:o,userName:s,userSessionId:l}=e,i=t.getDecodedToken(r),c=t.makeUserSessionId(i);"USER_LOCATION"===n&&l!==c&&a.addOrUpdateCollaborator({name:s,id:l,locations:o})})),s.on("REQUEST_INFORMATION",(e=>{const{channel:t,reqType:n,userSessionId:o}=e;"REQUEST_INFORMATION"===t&&o!==r&&"CURRENT_LOCATION"===n&&a.broadcastLocations()}))}}))).actions((e=>({postUserLocation:(t=>{let n;return t=>{clearTimeout(n),n=setTimeout((()=>async function(t){const{baseURL:n}=e,a=new URL("users/userLocation",n).href,o=new URLSearchParams(JSON.stringify(t)),r=e.getFetcher({locationType:"UriLocation",uri:a});try{if(!(await r(a,{method:"POST",body:o})).ok)throw new Error("ignore")}catch{console.error("Broadcasting user location failed")}}(t)),300)}})()}))).actions((e=>({initialize:i.flow((function*(t){if("admin"===t){const t=i.getRoot(e);r.isAbstractMenuManager(t)&&function(e){e.appendToMenu("Apollo",{label:"Add Assembly",onClick:e=>{e.queueDialog((t=>[Re,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Delete Assembly",onClick:e=>{e.queueDialog((t=>[it,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Import Features",onClick:e=>{e.queueDialog((t=>[dt,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Manage Users",onClick:e=>{e.queueDialog((t=>[mt,{session:e,handleClose:()=>{t()},changeManager:e.apolloDataStore.changeManager}]))}}),e.appendToMenu("Apollo",{label:"Undo",onClick:e=>{const{apolloDataStore:t}=e,{notify:n}=e;t.changeManager.recentChanges.length>0?t.changeManager.revertLastChange():n("No changes to undo","info")}})}(t)}yield e.updateLastChangeSequenceNumber(),e.addSocketListeners();const{baseURL:n}=e,a=new URL("/users/locations",n).href,o=e.getFetcher({locationType:"UriLocation",uri:a});yield o(a,{method:"GET"}),window.addEventListener("beforeunload",(()=>{e.postUserLocation([])})),document.addEventListener("visibilitychange",(()=>{if("hidden"===document.visibilityState&&e.postUserLocation([]),"visible"===document.visibilityState){const{session:t}=i.getRoot(e);t.broadcastLocations()}}))}))}))).actions((e=>({afterAttach(){e.setRole(),l.autorun((async t=>{It||e.role&&(await e.initialize(e.role),t.dispose())}),{name:"ApolloInternetAccount"})}})));function qt(e){return"object"==typeof e&&null!==e&&"apollo"in e&&!0===e.apollo}const _t="undefined"==typeof sessionStorage;class Ut extends _.BaseSequenceAdapter{regions;async getRefNames(e){return(await this.getRegions(e)).map((e=>e.refName))}async getRegions(e){if(this.regions)return this.regions;const t=n.readConfObject(this.config,"assemblyId");if(!_t){const e=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!e)throw new Error("No Apollo data store found");const n=e.getBackendDriver(t),a=await n.getRegions(t);return this.regions=a,a}const a=await new Promise(((n,a)=>{const o=setTimeout((()=>{a("timeout")}),2e4),r=d.nanoid(),s=e=>{const{data:t}=e;qt(t)&&t.messageId===r&&(clearTimeout(o),removeEventListener("message",s),n(t.regions))};addEventListener("message",s,e),globalThis.rpcServer.emit("apollo",{apollo:!0,method:"getRegions",assembly:t,messageId:r})}));return this.regions=a,a}getFeatures(e,t){const{end:a,refName:o,start:r}=e,s=n.readConfObject(this.config,"assemblyId"),l={...e,assemblyName:s};return U.ObservableCreate((async e=>{if(!_t){const t=this.pluginManager?.rootModel?.session?.apolloDataStore;if(!t)return void e.error("No Apollo data store found");const n=t.getBackendDriver(s),{seq:i}=await n.getSequence(l);return e.next(new pe.default({id:`${o} ${r}-${a}`,data:{refName:o,start:r,end:a,seq:i}})),void e.complete()}const n=await new Promise(((e,n)=>{const a=setTimeout((()=>{n("timeout")}),2e4),o=d.nanoid(),r=t=>{const{data:n}=t;qt(n)&&n.messageId===o&&(clearTimeout(a),removeEventListener("message",r),e(n.sequence))};addEventListener("message",r,t),globalThis.rpcServer.emit("apollo",{apollo:!0,method:"getSequence",region:l,messageId:o})}));e.next(new pe.default({id:`${o} ${r}-${a}`,data:{refName:o,start:r,end:a,seq:n}})),e.complete()}))}freeResources(){}}var Ot=n.ConfigurationSchema("ApolloSequenceAdapter",{assemblyId:{type:"string",defaultValue:""}},{explicitlyTyped:!0});function Bt(e,t,n,a,o,r){const s=a/o;e.fillStyle="black",e.fillRect(t,n,s,r),s>2&&(e.clearRect(t+1,n+1,s-2,r-2),e.fillStyle="rgba(255,255,255,0.75)",e.fillRect(t+1,n+1,s-2,r-2))}var jt=S.observer((function(e){const[a,o]=y.useState(),[s,c]=y.useState(),u=y.useRef(null),d=y.useRef(null),f=y.useRef(null),[g,p]=y.useState(!1),[h,b]=y.useState(!0),[w,S]=y.useState(),[v,E]=y.useState(!1),[C,x]=y.useState([]),{bpPerPx:F,displayModel:A,regions:D}=e,{session:k}=A,{collaborators:N}=k;y.useEffect((()=>l.autorun((()=>x(l.toJS(N))))),[]);const[R]=D,M=(R.end-R.start)/F,{apolloFeatureUnderMouse:T,apolloRowHeight:L,apolloRowUnderMouse:I,changeManager:P,codonLayout:q,featureLayout:_,features:U,featuresHeight:O,getAssemblyId:B,selectedFeature:j,setApolloFeatureUnderMouse:$,setApolloRowUnderMouse:G,setSelectedFeature:W,showIntronLines:H,showStartCodons:z,showStopCodons:V}=A,J=[...U.values()].map((e=>[...e.values()].map((e=>i.getSnapshot(e))))),X=y.useMemo((()=>{const{internetAccounts:e}=i.getRoot(k),{assemblyName:t}=R,{assemblyManager:a}=r.getSession(A),o=a.get(t);if(!o)throw new Error(`No assembly found with name ${t}`);const{internetAccountConfigId:s}=n.getConf(o,["sequence","metadata"]),l=e.find((e=>n.getConf(e,"internetAccountId")===s));if(!l)throw new Error(`No InternetAccount found with config id ${s}`);return l}),[A,R,k]),{role:Y}=X;return y.useEffect((()=>{Y?.includes("admin")&&p(!0),(Y?.includes("admin")??Y?.includes("user"))&&b(!1)}),[Y]),y.useEffect((()=>{const e=u.current;if(!e)return;const t=e.getContext("2d");if(!t)return;const n={};t.clearRect(0,0,M,O);for(const[e,a]of _)for(const[o,r]of a){const a=R.reversed?R.end-r.end:r.start-R.start-1,s=r.end-R.start-1,l=a/F,i=s/F;Bt(t,l,e*L,s-a,F,L);const c=e*L+L/2;n[o]||(n[o]=[]),n[o].some((e=>e[0]===l&&e[1]===c))||n[o].push([l,c]),n[o].some((e=>e[0]===i&&e[1]===c))||n[o].push([i,c])}if(H){let e=-Math.floor(Object.keys(n).length/2);for(const a in n){t.strokeStyle=`hsl(${e*(180*(3-Math.sqrt(5)))+60},100%,50%)`;const o=n[a].sort(((e,t)=>e[0]-t[0]));let[r]=o;for(const[n,a]of o.entries())if(0!==n){if(n%2==0){const n=[(a[0]-r[0])/2+r[0],Math.max(1,Math.min(r[1],a[1])-L/2+2*e)];t.beginPath(),t.moveTo(r[0],r[1]+2*e),t.lineTo(...n),t.stroke(),t.moveTo(...n),t.lineTo(a[0],a[1]+2*e),t.stroke()}r=a}e+=1}}}),[H,R,F,R.start,R.end,R.reversed,M,_,O,U,L,J]),y.useEffect((()=>{const e=f.current;if(!e)return;const t=e.getContext("2d");if(t){t.clearRect(0,0,M,O);for(const[e,{starts:n,stops:a}]of q){const o=F;for(const a of n){const n=a/o;R.start/o<=n&&n<=R.end/o&&(t.fillStyle="rgba(255,0,255,1)",z?t.fillRect(Math.round(n-.5-R.start/o),e*L,1,L):t.clearRect(Math.round(n-.5-R.start/o),e*L,1,L))}for(const n of a){const a=n/o;R.start/o<=a&&a<=R.end/o&&(t.fillStyle="black",V?t.fillRect(Math.round(a-.5-R.start/o),e*L,1,L):t.clearRect(Math.round(a-.5-R.start/o),e*L,1,L))}}}}),[z,V,q,M,O,F,L,R,R.start,R.end]),y.useEffect((()=>{const e=d.current;if(!e)return;const t=e.getContext("2d");if(t){t.clearRect(0,0,M,O);for(const e of C){const{locations:n}=e;if(0===n.length)return;for(const a of n){const{end:n,start:o}=a,r=(R.reversed?R.end-o:o-R.start)/F,s=(n-o)/F;t.fillStyle="rgba(0,255,0,.2)",t.fillRect(r,1,s,100),t.fillStyle="black",t.fillText(e.name,r+1,11,s-2)}}}}),[T,I,F,O,M,R,R.start,R.end,R.reversed,w,L,C]),ae.default.createElement("div",{style:{position:"relative",width:M,height:O}},ae.default.createElement(m.Menu,{open:Boolean(s),anchorReference:"anchorPosition",anchorPosition:a?{left:a[0],top:a[1]}:void 0,"data-testid":"base_linear_display_context_menu",onClose:()=>{c(void 0)}},ae.default.createElement(m.MenuItem,{disabled:h,key:1,value:1,onClick:()=>{if(!s)return;const e=B(R.assemblyName);k.queueDialog((t=>[rt,{session:k,handleClose:()=>{t(),c(void 0)},changeManager:P,sourceFeature:s,sourceAssemblyId:e,internetAccount:X}]))}},"Add child feature"),ae.default.createElement(m.MenuItem,{disabled:h,key:2,value:2,onClick:()=>{if(!s)return;const e=B(R.assemblyName);k.queueDialog((t=>[lt,{session:k,handleClose:()=>{t(),c(void 0)},changeManager:P,sourceFeature:s,sourceAssemblyId:e}]))}},"Copy features and annotations"),ae.default.createElement(m.MenuItem,{disabled:!g,key:3,value:3,onClick:()=>{if(!s)return;const e=B(R.assemblyName);k.queueDialog((t=>[ct,{session:k,handleClose:()=>{t(),c(void 0)},changeManager:P,sourceFeature:s,sourceAssemblyId:e,selectedFeature:j,setSelectedFeature:W}]))}},"Delete feature")),ae.default.createElement("canvas",{ref:u,width:M,height:O,style:{position:"absolute",left:0,top:0}}),ae.default.createElement("canvas",{ref:d,width:M,height:O,onMouseLeave:function(){$(),G()},onMouseUp:async function(){if(v){if(w){const e=B(R.assemblyName),{bp:n,edge:a,feature:o}=w;let r;if("end"===a){const a=o._id,s=o.end,l=Math.round(n);r=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[a],featureId:a,oldEnd:s,newEnd:l,assembly:e})}else{const a=o._id,s=o.start,l=Math.round(n);r=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[a],featureId:a,oldStart:s,newStart:l,assembly:e})}await(P?.submit(r))}}else T&&W(T);S(void 0),E(!1)},onContextMenu:function(e){e.preventDefault(),c(T),o([e.pageX,e.pageY])},style:{position:"absolute",left:0,top:0}}),ae.default.createElement("canvas",{ref:f,width:M,height:6*L,style:{position:"absolute",left:0,top:0}}))})),$t=n.ConfigurationSchema("ApolloSixFrameRenderer",{},{explicitlyTyped:!0});class Gt extends a.RendererType{async renderInClient(e,t){return this.render(t)}async freeResourcesInClient(e,t){return 0}}class Wt extends _.BaseAdapter{get baseURL(){return n.readConfObject(this.config,"baseURL").uri}get trackId(){return n.readConfObject(this.config,"trackId")}get assemblyNames(){return n.readConfObject(this.config,"assemblyNames")}mapBaseResult(e,t){return e.map((e=>new he.default({label:t,trackId:this.trackId,locString:`${e.refSeq?.name}:${e.start+1}..${e.end}`})))}async searchIndex(e){const t=[];for(const n of this.assemblyNames){const a=this.pluginManager?.rootModel?.session,o=a?.apolloDataStore.getBackendDriver(n),r=await o.searchFeatures(e.queryString,[n]);t.push(...r)}return this.mapBaseResult(t,e.queryString)}freeResources(){}}var Ht,zt=n.ConfigurationSchema("ApolloTextSearchAdapter",{assemblyNames:{type:"stringArray",defaultValue:[],description:"List of assemblies covered by text search adapter"},trackId:{type:"string",defaultValue:""},baseURL:{type:"fileLocation",defaultValue:{uri:"",locationType:"UriLocation"}}},{explicitlyTyped:!0,explicitIdentifier:"textSearchAdapterId"});function Vt({changeManager:e,handleClose:n,region:a,session:o}){const{notify:r}=o,[s,l]=y.useState(String(a.end)),[i,c]=y.useState(String(a.start+1)),[u,d]=y.useState(""),[f,g]=y.useState(""),[p,h]=y.useState(),[b,w]=y.useState(),[S,v]=y.useState(!1),[E,C]=y.useState(""),x=Number(s)<=Number(i);return ae.default.createElement(ke,{open:!0,title:"Add new feature",handleClose:n,maxWidth:!1,"data-testid":"add-feature-dialog"},ae.default.createElement("form",{onSubmit:async function(l){if(l.preventDefault(),C(""),S&&""===f)return void C("The phase is REQUIRED for all CDS features.");let c;for(const[,e]of o.apolloDataStore.assemblies??new Map)if(e._id===a.assemblyName)for(const[,t]of e.refSeqs??new Map)t.name===a.refName&&(c=t._id);if(!c)return void C("Invalid refseq id");const d=(new ne.default).toHexString(),m=new t.AddFeatureChange({changedIds:[d],typeName:"AddFeatureChange",assembly:a.assemblyName,addedFeature:{_id:d,gffId:"",refSeq:c,start:Number(i)-1,end:Number(s),type:u,phase:b,strand:p}});await(e.submit?.(m)),r("Feature added successfully","success"),n(),l.preventDefault()}},ae.default.createElement(m.DialogContent,{style:{display:"flex",flexDirection:"column"}},ae.default.createElement(m.TextField,{margin:"dense",id:"start",label:"Start",type:"number",fullWidth:!0,variant:"outlined",value:Number(i),onChange:e=>c(e.target.value)}),ae.default.createElement(m.TextField,{margin:"dense",id:"end",label:"End",type:"number",fullWidth:!0,variant:"outlined",value:s,onChange:e=>l(e.target.value),error:x,helperText:x?'"End" must be greater than "Start"':null}),ae.default.createElement(at,{session:o,ontologyName:"Sequence Ontology",style:{width:170},value:u,filterTerms:et,renderInput:e=>ae.default.createElement(m.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0}),onChange:(e,t)=>{var n;t&&(n=t,C(""),d(n),n.startsWith("CDS")?(v(!0),g("")):v(!1))}}),ae.default.createElement(m.FormControl,null,ae.default.createElement(m.InputLabel,{id:"demo-simple-select-label"},"Strand"),ae.default.createElement(m.Select,{labelId:"demo-simple-select-label",id:"demo-simple-select",label:"Strand",value:p?.toString(),onChange:function(e){switch(C(""),Number(e.target.value)){case 1:h(1);break;case-1:h(-1);break;default:h(void 0)}}},ae.default.createElement(m.MenuItem,{value:void 0}),ae.default.createElement(m.MenuItem,{value:1},"+"),ae.default.createElement(m.MenuItem,{value:-1},"-"))),S?ae.default.createElement(m.FormControl,null,ae.default.createElement(m.InputLabel,null,"Phase"),ae.default.createElement(m.Select,{value:f,onChange:async function(e){switch(C(""),g(e.target.value),Number(e.target.value)){case 0:w(Ht.zero);break;case 1:w(Ht.one);break;case 2:w(Ht.two);break;default:w(void 0)}}},ae.default.createElement(m.MenuItem,{value:0},"0"),ae.default.createElement(m.MenuItem,{value:1},"1"),ae.default.createElement(m.MenuItem,{value:2},"2"))):null),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"contained",type:"submit",disabled:x||!(i&&s&&u)},"Submit"),ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:n},"Cancel"))),E?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},E)):null)}function Jt({handleClose:e,session:t}){const{internetAccounts:n}=i.getRoot(t),{collaborationServerDriver:a}=t.apolloDataStore,o=n.find((e=>"ApolloInternetAccount"===e.type));if(!o)throw new Error("No Apollo internet account found");const{baseURL:r}=o,[s,l]=y.useState(),[c,u]=y.useState(),[d,f]=y.useState([]),g=a.getAssemblies();return y.useEffect((()=>{!c&&g.length>0&&u(g[0])}),[g,c]),y.useEffect((()=>{(async function(){const e=c?.name;if(!e)return;const t=new URL("checks",r),n=new URLSearchParams({assembly:e});t.search=n.toString();const a=t.toString(),s=o?.getFetcher({locationType:"UriLocation",uri:a});if(s){const e=await s(a,{headers:new Headers({"Content-Type":"application/json"})});if(!e.ok){const t=await Ae(e,"Error when retrieving checks");return void l(t)}const t=await e.json();f(t)}})().catch((e=>l(String(e))))}),[c,o,r]),ae.default.createElement(ke,{open:!0,fullScreen:!0,title:"View check results",handleClose:e,"data-testid":"view-check-results"},ae.default.createElement(m.Select,{style:{width:200,marginLeft:40},value:c?.name??"",onChange:function(e){const t=g.find((t=>t.name===e.target.value));u(t)},disabled:0===g.length},g.map((e=>ae.default.createElement(m.MenuItem,{key:e.name,value:e.name},e.displayName??e.name)))),ae.default.createElement(m.DialogContent,null,ae.default.createElement(M.DataGrid,{pagination:!0,rows:d,columns:[{field:"_id",headerName:"id",width:50},{field:"name",headerName:"Check name",width:200},{field:"refSeq",headerName:"Reference sequence ID",width:200},{field:"ids",headerName:"Feature IDs",width:200},{field:"message",headerName:"Message",flex:1}],getRowId:e=>e._id,slots:{toolbar:M.GridToolbar},initialState:{sorting:{sortModel:[{field:"name",sort:"asc"}]},columns:{columnVisibilityModel:{name:!0}}}})),ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{variant:"outlined",type:"submit",onClick:e},"Close")),s?ae.default.createElement(m.DialogContent,null,ae.default.createElement(m.DialogContentText,{color:"error"},s)):null)}!function(e){e[e.zero=0]="zero",e[e.one=1]="one",e[e.two=2]="two"}(Ht||(Ht={}));const Xt=n.ConfigurationSchema("ApolloPlugin",{ontologies:i.types.array(Qe)});function Yt(e){if("LinearPileupDisplay"!==e.name)return e;const{stateModel:n}=e,a=n.views((e=>({getFirstRegion:()=>r.getContainingView(e).dynamicBlocks.contentBlocks[0],getAssembly(){const t=e.getFirstRegion(),n=r.getSession(e),{assemblyManager:a}=n,{assemblyName:o}=t,s=a.get(o);if(!s)throw new Error(`Could not find assembly named ${o}`);return s},getRefSeqId(t){const n=e.getFirstRegion(),{refName:a}=n,{refNameAliases:o}=t;if(!o)throw new Error(`Could not find aliases for ${t.name}`);const r=[...Object.entries(o)].filter((([e,t])=>e!==t)).map((([e,t])=>({_id:e,name:t??""}))),s=r.find((e=>e.name===a))?._id;if(!s)throw new Error(`Could not find refSeqId named ${a}`);return s},createFeature(){const t=e.contextMenuFeature,n=e.getAssembly(),a=e.getRefSeqId(n),o=(t.get("CIGAR").toUpperCase().match(/\d+\D/g)??[]).map((e=>[(e.match(/\D/)??[])[0],Number.parseInt(e,10)]));let r=0;const s=t.get("start");let l;const i=[];for(const[e,t]of o)"M"===e||"="===e?void 0===l&&(l=r+s):"N"===e&&void 0!==l&&(i.push({start:l,end:r+l}),l=void 0),"I"!==e&&(r+=t);void 0!==l&&i.push({start:l,end:r+s});const c={_id:ne.default().toHexString(),gffId:"",refSeq:a,start:t.get("start"),end:t.get("end"),type:"mRNA",strand:t.get("strand")};if(0===i.length)return c;c.children={};const[u]=i,d={_id:ne.default().toHexString(),gffId:"",refSeq:a,start:u.start,end:u.end,type:"CDS",strand:t.get("strand"),phase:0};if(c.children[d._id]=d,1===i.length){const e={_id:ne.default().toHexString(),gffId:"",refSeq:a,start:u.start,end:u.end,type:"exon",strand:t.get("strand")};return c.children[e._id]=e,c}const f=[];let m=0;for(const e of i){d.start=Math.min(d.start,e.start),d.end=Math.max(d.end,e.end);const{end:n,start:o}=e;f?.push({start:o,end:n,phase:m}),m=(m+(n-o)%3)%3;const r={_id:ne.default().toHexString(),gffId:"",refSeq:a,start:o,end:n,type:"exon",strand:t.get("strand")};c.children[r._id]=r}return d.discontinuousLocations=f,c},async onPileupFeatureContext(){const n=e.createFeature(),a=e.getAssembly(),o=new t.AddFeatureChange({changedIds:[n._id],typeName:"AddFeatureChange",assembly:a.name,addedFeature:n}),s=r.getSession(e);await(s.apolloDataStore.changeManager.submit?.(o)),s.notify("Annotation added successfully","success")}}))).views((e=>{const t=e.contextMenuItems;return{contextMenuItems:()=>e.contextMenuFeature?[...t(),{label:"Create Apollo annotation",icon:K.default,onClick:e.onPileupFeatureContext}]:t()}}));return e.stateModel=a,e}const Kt=S.observer((function({onChangeCommitted:e,value:t,...n}){const[a,o]=y.useState(String(t)),[r,s]=y.useState(!1),[l,i]=y.useState(null);return y.useEffect((()=>{o(String(t))}),[t]),y.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]),ae.default.createElement(m.TextField,{...n,type:"text",onChange:function(e){o(e.target.value)},value:a,onKeyDown:e=>{"Enter"===e.key?l?.blur():"Escape"===e.key&&(o(String(t)),s(!0))},onBlur:()=>{a!==String(t)&&e(a)},inputRef:e=>i(e)})})),Zt=new Map([["Gene Ontology",e=>ae.default.createElement(pt,{...e,ontologyName:"Gene Ontology"})],["Sequence Ontology",e=>ae.default.createElement(pt,{...e,ontologyName:"Sequence Ontology"})]]),Qt=["ID","Name","Alias","Target","Gap","Derives_from","Note","Dbxref","Ontology","Is_Circular"],en=v.makeStyles()((e=>({newAttributePaper:{padding:e.spacing(2)},attributeName:{background:e.palette.secondary.main,color:e.palette.secondary.contrastText,padding:e.spacing(1)}})));function tn(e){const{onChange:t,value:n}=e;return ae.default.createElement(Kt,{value:n,onChangeCommitted:e=>{t(e.split(","))},variant:"outlined",fullWidth:!0,helperText:"Separate multiple values for the attribute with commas"})}const nn=S.observer((function({assembly:e,editable:n,feature:a,session:o}){const[r,s]=y.useState(""),[l,c]=y.useState(!1),{classes:u}=en(),[d,f]=y.useState(""),g=Object.fromEntries([...a.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]}))),{notify:p}=o,{changeManager:h}=o.apolloDataStore;async function b(n,o){s("");const r={};if(g){const e=Object.entries({...g,[n]:o});for(const[t,n]of e)if(n&&"parent"!==t.toLowerCase())if([...Zt.keys()].includes(t))r[t]=n;else switch(t){case"ID":r._id=n;break;case"Name":r.gff_name=n;break;case"Alias":r.gff_alias=n;break;case"Target":r.gff_target=n;break;case"Gap":r.gff_gap=n;break;case"Derives_from":r.gff_derives_from=n;break;case"Note":r.gff_note=n;break;case"Dbxref":r.gff_dbxref=n;break;case"Ontology_term":r.gff_ontology_term=n;break;case"Is_circular":r.gff_is_circular=n;break;default:r[t.toLowerCase()]=n}}const l=new t.FeatureAttributeChange({changedIds:[a._id],typeName:"FeatureAttributeChange",assembly:e,featureId:a._id,attributes:r});await(h.submit?.(l)),p("Feature attributes modified successfully","success")}return ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h4"},"Attributes"),ae.default.createElement(m.Grid,{container:!0,direction:"column",spacing:1},Object.entries(g).map((([e,t])=>{const a=Zt.get(e)??tn;return ae.default.createElement(m.Grid,{container:!0,item:!0,spacing:3,alignItems:"center",key:e},ae.default.createElement(m.Grid,{item:!0,xs:"auto"},ae.default.createElement(m.Paper,{variant:"outlined",className:u.attributeName},ae.default.createElement(m.Typography,null,e))),ae.default.createElement(m.Grid,{item:!0,flexGrow:1},ae.default.createElement(a,{session:o,value:t,onChange:t=>b(e,t)})),ae.default.createElement(m.Grid,{item:!0,xs:1},ae.default.createElement(m.IconButton,{"aria-label":"delete",size:"medium",disabled:!n,onClick:()=>b(e)},ae.default.createElement(ue.default,{fontSize:"medium",key:e}))))})),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Button,{color:"primary",variant:"contained",disabled:l||!n,onClick:()=>{c(!0)}},"Add new")),l?ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Paper,{elevation:8,className:u.newAttributePaper},ae.default.createElement(m.Grid,{container:!0,direction:"column"},ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.FormControl,null,ae.default.createElement(m.FormLabel,{id:"attribute-radio-button-group"},"Select attribute type"),ae.default.createElement(m.RadioGroup,{"aria-labelledby":"demo-radio-buttons-group-label",defaultValue:"custom",name:"radio-buttons-group",onChange:function(e,t){"custom"===t?f(""):Zt.has(t)?f(t):s("Unknown attribute type")}},ae.default.createElement(m.FormControlLabel,{value:"custom",control:ae.default.createElement(m.Radio,null),disableTypography:!0,label:ae.default.createElement(m.Grid,{container:!0,spacing:1,alignItems:"center"},ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.Typography,null,"Custom")),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.TextField,{label:"Custom attribute key",variant:"outlined",value:Zt.has(d)?"":d,disabled:Zt.has(d),onChange:e=>{f(e.target.value)}})))}),[...Zt.keys()].map((e=>ae.default.createElement(m.FormControlLabel,{key:e,value:e,control:ae.default.createElement(m.Radio,null),label:e})))))),ae.default.createElement(m.Grid,{item:!0},ae.default.createElement(m.DialogActions,null,ae.default.createElement(m.Button,{key:"addButton",color:"primary",variant:"contained",onClick:function(){s(""),0!==d.trim().length?"Parent"!==d?d in g?s(`Attribute "${d}" already exists`):!/^[A-Z]/.test(d)||Qt.includes(d)||[...Zt.keys()].includes(d)?b(d,[]):s(`Key cannot starts with uppercase letter unless key is one of these: ${Qt.join(", ")}`):s('"Parent" -key is handled internally and it cannot be modified manually'):s("Attribute key is mandatory")},disabled:!d},"Add"),ae.default.createElement(m.Button,{key:"cancelAddButton",variant:"outlined",type:"submit",onClick:()=>{c(!1),f(""),s("")}},"Cancel")))))):null),r?ae.default.createElement(m.Typography,{color:"error"},r):null)})),an=S.observer((function({onChangeCommitted:e,value:t,...n}){const[a,o]=y.useState(String(t)),[r,s]=y.useState(!1),[l,i]=y.useState(null);y.useEffect((()=>{o(String(t))}),[t]),y.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]);const c=Number.isNaN(Number(a));return ae.default.createElement(m.TextField,{...n,type:"text",onChange:function(e){o(e.target.value)},value:a,onKeyDown:e=>{"Enter"===e.key?l?.blur():"Escape"===e.key&&(o(String(t)),s(!0))},onBlur:()=>{const n=Number(a);a!==String(t)&&(Number.isNaN(n)?o(String(t)):e(n))},inputRef:e=>i(e),error:c,helperText:c?"Not a valid number":void 0})})),on=S.observer((function({assembly:e,feature:n,session:a}){const[o,r]=y.useState(""),[s,l]=y.useState(""),{_id:i,assemblyId:c,end:u,start:d,strand:f,type:g}=n,p=e=>a.notify(e.message,"error"),{changeManager:h}=a.apolloDataStore;return ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h4"},"Basic information"),ae.default.createElement(an,{margin:"dense",id:"start",label:"Start",fullWidth:!0,variant:"outlined",value:d+1,onChangeCommitted:function(n){n--;const a=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[i],featureId:i,oldStart:d,newStart:n,assembly:e});return h.submit(a)}}),ae.default.createElement(an,{margin:"dense",id:"end",label:"End",fullWidth:!0,variant:"outlined",value:u,onChangeCommitted:function(n){const a=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[i],featureId:i,oldEnd:u,newEnd:n,assembly:e});return h.submit(a)}}),ae.default.createElement(at,{session:a,ontologyName:"Sequence Ontology",value:g,filterTerms:et,fetchValidTerms:async function(e,t,n){const a=await nt(e,t);if(a)return a;l(`Type "${e?.type}" does not have any children in the ontology`)}.bind(null,n),renderInput:e=>ae.default.createElement(m.TextField,{...e,label:"Type",variant:"outlined",fullWidth:!0,error:Boolean(s),helperText:s}),onChange:(e,n)=>{n&&function(e){r("");const n=new t.TypeChange({typeName:"TypeChange",changedIds:[i],featureId:i,oldType:g,newType:e,assembly:c});return h.submit(n)}(n).catch(p)}}),ae.default.createElement(m.FormControl,null,ae.default.createElement(m.FormLabel,null,"Strand"),ae.default.createElement(m.RadioGroup,{row:!0,value:f??"",onChange:function(n){const{value:a}=n.target,o=a?Number(a):void 0,r=new t.StrandChange({typeName:"StrandChange",changedIds:[i],featureId:i,oldStrand:f,newStrand:o,assembly:e});return h.submit(r)}},ae.default.createElement(m.FormControlLabel,{value:"1",control:ae.default.createElement(m.Radio,null),label:"Forward (+)"}),ae.default.createElement(m.FormControlLabel,{value:"-1",control:ae.default.createElement(m.Radio,null),label:"Reverse (-)"}),ae.default.createElement(m.FormControlLabel,{value:"",control:ae.default.createElement(m.Radio,null),label:"None"}))),o?ae.default.createElement(m.Typography,{color:"error"},o):null)})),rn=v.makeStyles()((e=>({paper:{margin:e.spacing(2),padding:e.spacing(2),display:"flex",flexDirection:"column"}}))),sn=S.observer((function({assembly:e,feature:t,refName:n,session:a}){const{classes:o}=rn(),{parent:r}=t,{children:s}=t,l=t=>{if(r){const o=a.addWidget("ApolloFeatureDetailsWidget","apolloFeatureDetailsWidget",{feature:t,assembly:e,refName:n});a.showWidget?.(o)}};return r||s&&s.size>0?ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h4"},"Related features"),r&&ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h5"},"Parent"),ae.default.createElement(m.Paper,{elevation:6,className:o.paper},`Start: ${r.start}, End: ${r.end}, Type: ${r.type}`,ae.default.createElement(m.Button,{variant:"contained",onClick:()=>l(r)},"Go to parent"))),s&&s.size>0&&ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h5"},"Children"),[...s.values()].map((e=>ae.default.createElement(m.Paper,{elevation:6,className:o.paper,key:e._id},`Start: ${e.start}, End: ${e.end}, Type: ${e.type}`,ae.default.createElement(m.Button,{variant:"contained",onClick:()=>l(e)},"Go to child")))))):null})),ln=v.makeStyles()({sequence:{width:"100%",resize:"vertical"}}),cn=S.observer((function({assembly:e,feature:t,refName:n,session:a}){const o=a.apolloDataStore.assemblies.get(e),[r,s]=y.useState(!1),{classes:l}=ln();if(!t||!o)return null;const i=o.getByRefName(n);if(!i)return null;const{end:c,start:u}=t;let d="";return r&&(d=i.getSequence(u,c),d?d=function(e,t,n,a,o){return`>${t}:${n+1}–${a}\n${e}`}(d,n,u,c):a.apolloDataStore.loadRefSeq([{assemblyName:e,refName:n,start:u,end:c}])),ae.default.createElement(ae.default.Fragment,null,ae.default.createElement(m.Typography,{variant:"h4"},"Sequence"),ae.default.createElement(m.Button,{variant:"contained",onClick:()=>{s(!r)}},r?"Hide sequence":"Show sequence"),ae.default.createElement("div",null,r&&ae.default.createElement("textarea",{readOnly:!0,rows:20,className:l.sequence,value:d})))})),un=v.makeStyles()((e=>({root:{padding:e.spacing(2)}}))),dn=S.observer((function(e){const{model:t}=e,{assembly:n,feature:a,refName:o}=t,s=r.getSession(t),l=s.apolloDataStore.assemblies.get(n),{classes:c}=un(),{internetAccounts:u}=i.getRoot(s),d=y.useMemo((()=>u.find((e=>"ApolloInternetAccount"===e.type))),[u]),f=["admin","user"].includes((d?d.role:"admin")??"");if(!a||!l)return null;const m=l.getByRefName(o);if(!m)return null;const{end:g,start:p}=a;return m.getSequence(p,g)||s.apolloDataStore.loadRefSeq([{assemblyName:n,refName:o,start:p,end:g}]),ae.default.createElement("div",{className:c.root},ae.default.createElement(on,{feature:a,session:s,assembly:l._id}),ae.default.createElement("hr",null),ae.default.createElement(nn,{feature:a,session:s,assembly:l._id,editable:f}),ae.default.createElement("hr",null),ae.default.createElement(cn,{feature:a,session:s,assembly:l._id,refName:o}),ae.default.createElement("hr",null),ae.default.createElement(sn,{feature:a,refName:o,session:s,assembly:l._id}))})),fn=i.types.model("ApolloFeatureDetailsWidget",{id:E.ElementId,type:i.types.literal("ApolloFeatureDetailsWidget"),feature:i.types.maybe(i.types.reference(j.AnnotationFeature,{onInvalidated(e){e.parent.setTryReload(e.invalidId),e.removeRef()}})),assembly:i.types.string,refName:i.types.string}).volatile((()=>({tryReload:void 0}))).actions((e=>({setFeature(t){e.feature=t},setTryReload(t){e.tryReload=t}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((t=>{if(!e.tryReload)return;const n=r.getSession(e),{apolloDataStore:a}=n;if(!a)return;const o=a.getFeature(e.tryReload);o&&(e.setFeature(o),e.setTryReload(),t.dispose())})))}})));function mn(e,n,a,o,r){const s=n._id,l=void 0===r?new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[s],featureId:s,oldStart:a,newStart:o,assembly:n.assemblyId}):new t.DiscontinuousLocationStartChange({typeName:"DiscontinuousLocationStartChange",changedIds:[s],featureId:s,oldStart:a,newStart:o,assembly:n.assemblyId,index:r});return e.submit(l)}function gn(e,n,a,o,r){const s=n._id,l=void 0===r?new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[s],featureId:s,oldEnd:a,newEnd:o,assembly:n.assemblyId}):new t.DiscontinuousLocationEndChange({typeName:"DiscontinuousLocationEndChange",changedIds:[s],featureId:s,oldEnd:a,newEnd:o,assembly:n.assemblyId,index:r});return e.submit(l)}const pn=v.makeStyles()({highlighted:{background:"orange"}}),hn=({highlight:e,text:t})=>{const{classes:n}=pn();if(!e)return ae.default.createElement(ae.default.Fragment,null,t);const a=t.split(e);if(1===a.length)return ae.default.createElement(ae.default.Fragment,null,t);const o=[];for(let t=0;t<a.length-1;t++)o.push(a[t],ae.default.createElement("span",{className:n.highlighted},e));return ae.default.createElement(ae.default.Fragment,null,o,a.at(-1))},yn=S.observer((function({feature:e,filterText:t}){const n=[...e.attributes.entries()].map((([e,t])=>{if(e.startsWith("gff_")){const n=e.slice(4);return[n.charAt(0).toUpperCase()+n.slice(1),i.getSnapshot(t)]}return"_id"===e?["ID",i.getSnapshot(t)]:[e,i.getSnapshot(t)]})).map((([e,t])=>`${e}=${Array.isArray(t)?t.join(", "):t}`)).join(", ");return ae.default.createElement(hn,{text:n,highlight:t})})),bn=v.makeStyles()((e=>({inputWrapper:{position:"relative"},hiddenWidthSpan:{padding:e.spacing(.5),color:"transparent"},numberTextInput:{border:"none",background:"inherit",font:"inherit",position:"absolute",width:"100%",left:0}}))),wn=S.observer((function({initialValue:e,notifyError:t,onChangeCommitted:n}){const[a,o]=y.useState(e),[r,s]=y.useState(!1),[l,i]=y.useState(null),{classes:c}=bn();return y.useEffect((()=>{r&&(l?.blur(),s(!1))}),[r,l]),ae.default.createElement("span",{className:c.inputWrapper},ae.default.createElement("span",{className:c.hiddenWidthSpan,"aria-hidden":!0},a),ae.default.createElement("input",{type:"text",value:a,className:c.numberTextInput,onChange:function(e){const t=Number(e.target.value);Number.isNaN(t)||o(t)},onKeyDown:t=>{"Enter"===t.key?l?.blur():"Escape"===t.key&&(o(e),s(!0))},onBlur:()=>{a!==e&&n(a).catch(t)},ref:e=>i(e)}))})),Sn=v.makeStyles()((e=>({typeContent:{display:"inline-block",width:"174px",height:"100%",cursor:"text"},feature:{td:{position:"relative",verticalAlign:"top",paddingLeft:"0.5em"}},arrow:{display:"inline-block",width:"1.6em",textAlign:"center",cursor:"pointer"},arrowExpanded:{transform:"rotate(90deg)"},hoveredFeature:{backgroundColor:e.palette.action.hover},typeInputElement:{border:"none",background:"none"},typeErrorMessage:{color:"red"}})));function vn(e,t){const{changeManager:n,getAssemblyId:a,regions:o,selectedFeature:r,session:s,setSelectedFeature:l}=e;return function(e,t,n,a,o,r,s){const l=function(e){const{internetAccounts:t}=i.getParent(e);return t.find((e=>"ApolloInternetAccount"===e.type))}(r),c=l?l.role:"admin",u="admin"===c,d=!(c&&["admin","user"].includes(c)),f=[];if(e){const i=n(t.assemblyName),c=n(t.assemblyName);f.push({label:"Add child feature",disabled:d,onClick:()=>{r.queueDialog((t=>[rt,{session:r,handleClose:()=>{t()},changeManager:s,sourceFeature:e,sourceAssemblyId:i,internetAccount:l}]))}},{label:"Copy features and annotations",disabled:d,onClick:()=>{r.queueDialog((t=>[lt,{session:r,handleClose:()=>{t()},changeManager:s,sourceFeature:e,sourceAssemblyId:c}]))}},{label:"Delete feature",disabled:!u,onClick:()=>{r.queueDialog((t=>[ct,{session:r,handleClose:()=>{t()},changeManager:s,sourceFeature:e,sourceAssemblyId:c,selectedFeature:a,setSelectedFeature:o}]))}},{label:"Edit attributes",disabled:d,onClick:()=>{r.queueDialog((t=>[Et,{session:r,handleClose:()=>{t()},changeManager:s,sourceFeature:e,sourceAssemblyId:c}]))}})}return f}(t,o[0],a,r,l,s,n)}function En(e){let t=e;for(;t.parent;)t=t.parent;return t}const Cn=S.observer((function e({depth:n,feature:a,isHovered:o,isSelected:r,model:s,selectedFeatureClass:l,setContextMenu:i}){const{classes:c}=Sn(),{apolloHover:u,changeManager:d,selectedFeature:f,session:m,tabularEditor:g}=s,{featureCollapsed:p,filterText:h}=g,{_id:y,children:b,discontinuousLocations:w,end:S,phase:v,start:E,strand:C,type:x}=a,F=!p.get(y),A=e=>m.notify(e.message,"error");return ae.default.createElement(ae.default.Fragment,null,ae.default.createElement("tr",{onMouseEnter:e=>{s.setApolloHover({feature:a,topLevelFeature:En(a)})},className:c.feature+(r?` ${l}`:o?` ${c.hoveredFeature}`:""),onClick:e=>{e.stopPropagation(),s.setSelectedFeature(a)},onContextMenu:e=>(e.preventDefault(),i({position:{left:e.clientX+2,top:e.clientY-6},items:vn(s,a)}),!1)},ae.default.createElement("td",{style:{whiteSpace:"nowrap",borderLeft:2*n+"em solid transparent"}},b?.size?ae.default.createElement("div",{onClick:e=>{e.stopPropagation(),g.setFeatureCollapsed(y,F)},className:c.arrow+(F?` ${c.arrowExpanded}`:"")},"❯"):null,ae.default.createElement("div",{className:c.typeContent},ae.default.createElement(at,{session:m,ontologyName:"Sequence Ontology",style:{width:170},value:x,filterTerms:et,fetchValidTerms:xn.bind(null,a),renderInput:e=>ae.default.createElement("div",{ref:e.InputProps.ref},ae.default.createElement("input",{type:"text",...e.inputProps,className:c.typeInputElement,style:{width:170}}),e.error?ae.default.createElement("div",{className:c.typeErrorMessage},e.errorMessage??"unknown error"):null),onChange:(e,n)=>{n&&function(e,n,a,o){const r=n._id,s=new t.TypeChange({typeName:"TypeChange",changedIds:[r],featureId:r,oldType:String(a),newType:String(o),assembly:n.assemblyId});return e.submit(s)}(d,a,e,n).catch(A)}}))),ae.default.createElement("td",null,w&&w.length>0?ae.default.createElement("div",{style:{display:"flex",flexDirection:"column"}},w.map(((e,t)=>ae.default.createElement(wn,{key:`${y}:${e.start},${e.phase}`,initialValue:e.start+1,notifyError:A,onChangeCommitted:e=>mn(d,a,w[t].start,e-1,t)})))):ae.default.createElement(wn,{initialValue:E+1,notifyError:A,onChangeCommitted:e=>mn(d,a,E,e-1)})),ae.default.createElement("td",null,w&&w.length>0?ae.default.createElement("div",{style:{display:"flex",flexDirection:"column"}},w.map(((e,t)=>ae.default.createElement(wn,{key:`${y}:${e.end},${e.phase}`,initialValue:e.end,notifyError:A,onChangeCommitted:e=>gn(d,a,w[t].end,e,t)})))):ae.default.createElement(wn,{initialValue:S,notifyError:A,onChangeCommitted:e=>gn(d,a,S,e)})),ae.default.createElement("td",null,1===C?"+":-1===C?"-":void 0),ae.default.createElement("td",null,v),ae.default.createElement("td",null,ae.default.createElement(yn,{filterText:h,feature:a}))),F&&b?[...b.entries()].filter((e=>{if(!h)return!0;const[,t]=e;return JSON.stringify(t).includes(h)})).map((([t,a])=>ae.default.createElement(e,{isHovered:u?.feature?._id===a._id,isSelected:f?._id===a._id,selectedFeatureClass:l,key:t,depth:(n||0)+1,feature:a,model:s,setContextMenu:i}))):null)}));async function xn(e,t,n){const{parent:a}=e;if(a){const e=(await t.getTermsWithLabelOrSynonym(a.type,{includeSubclasses:!1})).filter(et);if(e.length>0)return await t.getClassesThat("part_of",e)}}const Fn=v.makeStyles()((e=>({scrollableTable:{width:"100%",height:"100%",th:{position:"sticky",top:0,zIndex:2,textAlign:"left",background:e.palette.background.paper,paddingTop:"3.2em"},td:{whiteSpace:"normal"}},selectedFeature:{backgroundColor:e.palette.action.selected}}))),An=S.observer((function({model:e}){const{apolloHover:t,seenFeatures:n,selectedFeature:a,tabularEditor:o}=e,r=m.useTheme(),{classes:s}=Fn(),l=y.useRef(null),[i,c]=y.useState(null),{filterText:u}=o;return y.useEffect((()=>{const e=l.current;if(e&&a){const t=e.querySelector(`.${s.selectedFeature}`);if(t){const n=e.scrollTop,a=t.offsetTop-25;a>n&&a<n+e.offsetHeight||e.scroll({top:a-40,behavior:"smooth"})}}}),[a,n,s.selectedFeature]),ae.default.createElement("div",{ref:l,style:{width:"100%",overflowY:"auto",height:"100%"}},ae.default.createElement("table",{className:s.scrollableTable},ae.default.createElement("thead",null,ae.default.createElement("tr",null,ae.default.createElement("th",null,"Type"),ae.default.createElement("th",null,"Start"),ae.default.createElement("th",null,"End"),ae.default.createElement("th",null,"Strand"),ae.default.createElement("th",null,"Phase"),ae.default.createElement("th",null,"Attributes"))),ae.default.createElement("tbody",null,[...n.entries()].filter((e=>{if(!u)return!0;const[,t]=e;return JSON.stringify(t).includes(u)})).sort(((e,t)=>e[1].start-t[1].start)).map((([n,o])=>ae.default.createElement(Cn,{key:n,isSelected:a?._id===n,isHovered:t?.feature?._id===n,selectedFeatureClass:s.selectedFeature,feature:o,model:e,depth:0,setContextMenu:c}))))),ae.default.createElement(b.Menu,{open:Boolean(i),onMenuItemClick:(e,t)=>{t(),c(null)},onClose:()=>{c(null)},TransitionProps:{onExit:()=>{c(null)}},style:{zIndex:r.zIndex.tooltip},menuItems:i?.items??[],anchorReference:"anchorPosition",anchorPosition:i?.position}))})),Dn=v.makeStyles()({toolbar:{width:"100%",display:"flex",paddingRight:"2em",flexDirection:"row",justifyContent:"space-between",position:"absolute",zIndex:4},filterText:{}}),kn=S.observer((function({model:e}){const t=e.tabularEditor,{classes:n}=Dn();return ae.default.createElement("div",{className:n.toolbar},ae.default.createElement(m.Tooltip,{title:"Collapse all"},ae.default.createElement(m.IconButton,{"aria-label":"collapse",sx:{marginTop:0},onClick:t.collapseAllFeatures},ae.default.createElement(be.default,null))),ae.default.createElement(m.TextField,{className:n.filterText,label:"Filter features",value:t.filterText,sx:{marginTop:0},variant:"outlined",onChange:e=>t.setFilterText(e.target.value),InputProps:{endAdornment:ae.default.createElement(m.InputAdornment,{position:"end"},ae.default.createElement(m.IconButton,{onClick:()=>t.clearFilterText()},ae.default.createElement(ye.default,null)))}}))}));function Nn(e){e.stopPropagation()}const Rn=S.observer((function({model:e}){return e.tabularEditor.isShown?ae.default.createElement("div",{onMouseDown:Nn,onClick:Nn,style:{width:"100%",height:"100%",position:"relative"}},ae.default.createElement(kn,{model:e}),ae.default.createElement(An,{model:e})):null})),Mn=i.types.model("TabularEditor",{isShown:!0,featureCollapsed:i.types.map(i.types.boolean),filterText:""}).actions((e=>({setFeatureCollapsed(t,n){e.featureCollapsed.set(t,n)},setFilterText(t){e.filterText=t},clearFilterText(){e.filterText=""},collapseAllFeatures(){const t=i.getParent(e);for(const[n]of t.seenFeatures.entries())e.featureCollapsed.set(n,!0)},togglePane(){e.isShown=!e.isShown},hidePane(){e.isShown=!1},showPane(){e.isShown=!0}})));class Tn{drawHover(e,t,n,a,o){}drawDragPreview(e,t){}startDrag(e,t){return!1}executeDrag(e,t){}onMouseDown(e,t){}onMouseMove(e,t){}onMouseLeave(e,t){}onMouseUp(e,t){}onContextMenu(e,t){}drawTooltip(e,t){const{apolloHover:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e;if(!n)return;const{feature:l,mousePosition:i}=n;if(!l||!i)return;const{regionNumber:c,y:u}=i,d=o[c],{refName:f,reversed:g}=d,{bpPerPx:p,bpToPx:h,offsetPx:y}=r,{discontinuousLocations:b}=l;let w,S,v,E="Loc: ";if(b&&b.length>0){const e=b.at(-1);if(!e)return;if(({start:w}=e),({end:S}=e),v=e.end-e.start,b.length<=2)for(const[e,t]of b.entries())E+=`${t.start+1}–${t.end}`,e!==b.length-1&&(E+=",");else{const[t]=b;E+=`${t.start+1}–${t.end},…,${e.start+1}–${e.end}`}}else({end:S,length:v,start:w}=l),E+=`${w+1}–${S}`;let C=(h({refName:f,coord:g?S:w,regionNumber:c})?.offsetPx??0)-y;const x=Math.floor(u/a)*a,F=v/p,A=`Type: ${l.type}`,{attributes:D}=l,k=D.get("gff_name")?.find((e=>""!==e)),N=[t.measureText(A).width,t.measureText(E).width];k&&N.push(t.measureText(`Name: ${k}`).width);const R=Math.max(...N);C=C+F+5,t.fillStyle=m.alpha(s?.palette.text.primary??"rgb(1, 1, 1)",.7),t.fillRect(C,x,R+4,3===N.length?45:35),t.beginPath(),t.moveTo(C,x),t.lineTo(C-5,x+5),t.lineTo(C,x+10),t.fill(),t.fillStyle=s?.palette.background.default??"rgba(255, 255, 255)";let M=x+12;t.fillText(A,C+2,M),k&&(M+=12,t.fillText(`Name: ${k}`,C+2,M)),M+=12,t.fillText(E,C+2,M)}getAdjacentFeatures(e,t){let n,a,o=0;if(!e||!t||!t.children)return{prevFeature:n,nextFeature:a};for(const[,n]of t.children){if(n._id===e._id)break;o++}const r=[...t.children.keys()];return o>0&&(n=t.children.get(r[o-1])),o<r.length-1&&(a=t.children.get(r[o+1])),{prevFeature:n,nextFeature:a}}getParentFeature(e,t){let n;if(!e||!t||!t.children)return n;for(const[,a]of t.children){if(a._id===e._id){n=t;break}if(a?.children){for(const[,t]of a.children)if(t._id===e._id){n=a;break}if(n)break}}return n}getContextMenuItems(e){const{apolloHover:t,apolloInternetAccount:n,changeManager:a,getAssemblyId:o,regions:r,selectedFeature:s,session:l,setSelectedFeature:i}=e,{feature:c}=t??{},u=n?n.role:"admin",d="admin"===u,f=!(u&&["admin","user"].includes(u)),m=[];if(c){const[e]=r,t=o(e.assemblyName),u=o(e.assemblyName);m.push({label:"Add child feature",disabled:f,onClick:()=>{l.queueDialog((e=>[rt,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:t,internetAccount:n}]))}},{label:"Copy features and annotations",disabled:f,onClick:()=>{l.queueDialog((e=>[lt,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:u}]))}},{label:"Delete feature",disabled:!d,onClick:()=>{l.queueDialog((e=>[ct,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:u,selectedFeature:s,setSelectedFeature:i}]))}},{label:"Modify feature attribute",disabled:f,onClick:()=>{l.queueDialog((e=>[Et,{session:l,handleClose:()=>{e()},changeManager:a,sourceFeature:c,sourceAssemblyId:u}]))}},{label:"Edit feature details",onClick:()=>{const t=l.addWidget("ApolloFeatureDetailsWidget","apolloFeatureDetailsWidget",{feature:c,assembly:u,refName:e.refName});l.showWidget?.(t)}})}return m}}class Ln extends Tn{getRowCount(e){return 1}getIsSelectedFeature(e,t){return Boolean(t&&e._id===t._id)}getBackgroundColor(e,t){return t?e?.palette.text.primary??"black":e?.palette.background.default??"white"}getTextColor(e,t){return t?e?.palette.getContrastText(this.getBackgroundColor(e,t))??"white":e?.palette.text.primary??"black"}drawBox(e,t,n,a,o,r){e.fillStyle=r,e.fillRect(t,n,a,o)}drawBoxOutline(e,t,n,a,o,r){this.drawBox(e,t,n,a,o,r),e.clearRect(t+1,n+1,a-2,o-2)}drawBoxFill(e,t,n,a,o,r){this.drawBox(e,t+1,n+1,a-2,o-2,r)}drawBoxText(e,t,n,a,o,r){e.fillStyle=o;const s=Math.max(t+1,0);e.fillText(r,s,n+11,t-1+a-s)}draw(e,t,n,a,o,r){const{apolloRowHeight:s,lgv:l,session:i,theme:c}=e,{bpPerPx:u}=l,{apolloSelectedFeature:d}=i,f=(n.start-n.min)/u,m=n.length/u,g=r?a-f-m:a+f,p=o*s,h=this.getIsSelectedFeature(n,d),y=this.getBackgroundColor(c,h),b=this.getTextColor(c,h),w=h?"rgba(130,0,0,0.45)":"rgba(255,0,0,0.25)",S=[g,p,m,s];if(this.drawBoxOutline(t,...S,b),m<=2)return;let v=[n];if(n.discontinuousLocations&&n.discontinuousLocations.length>0&&(v=n.discontinuousLocations.map((e=>({start:e.start,end:e.end,type:n.type})))),v.length>1){this.drawBoxFill(t,...S,w);for(const e of v){const o=(e.start-n.min)/u,l=(e.end-e.start)/u;this.drawBoxOutline(t,r?a-o-l:a+o,p,l,s,b)}}for(const e of v){const o=(e.start-n.min)/u,l=(e.end-e.start)/u,i=r?a-o-l:a+o;this.drawBoxFill(t,i,p,l,s,y),this.drawBoxText(t,i,p,l,b,e.type)}}getFeatureFromLayout(e,t,n){return e}getRowForFeature(e,t){return 0}isMouseOnFeatureEdge(e,t,n){if(!e)return;const{refName:a,regionNumber:o,x:r}=e,{lgv:s}=n,{bpToPx:l,offsetPx:i}=s,c=l({refName:a,coord:t.start,regionNumber:o}),u=l({refName:a,coord:t.end,regionNumber:o});if(void 0!==c&&void 0!==u){const e=c.offsetPx-i,t=u.offsetPx-i;if(Math.abs(t-e)<8)return;if(Math.abs(e-r)<4)return"start";if(Math.abs(t-r)<4)return"end"}}drawHover(e,t){const{apolloHover:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e;if(!n)return;const{feature:l,mousePosition:i}=n;if(!l||!i)return;const{bpPerPx:c,bpToPx:u,offsetPx:d}=r,f=o[i.regionNumber],{refName:m,reversed:g}=f,{end:p,length:h,start:y}=l,{regionNumber:b,y:w}=i,S=(u({refName:m,coord:g?p:y,regionNumber:b})?.offsetPx??0)-d,v=Math.floor(w/a)*a,E=h/c;t.fillStyle=s?.palette.action.focus??"rgba(0,0,0,0.04)",t.fillRect(S,v,E,a)}drawDragPreview(e,t){const{apolloDragging:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e,{bpPerPx:l,offsetPx:i}=r;if(!n)return;const{feature:c,glyph:u,mousePosition:d}=n.start;if(!c)throw new Error("no feature for drag preview??");if(u!==this)throw new Error("drawDragPreview() called on wrong glyph?");const{mousePosition:f}=n.current,g=this.isMouseOnFeatureEdge(d,c,e);if(!g)return;const p=Math.floor(d.y/a),h=o[d.regionNumber],y=this.getRowCount(c),b=(h.reversed?h.end-c[g]:c[g]-h.start)/l-i,w=Math.min(f.x,b),S=p*a,v=Math.abs(f.x-b),E=a*y;t.strokeStyle=s?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(w,S,v,E),t.fillStyle=m.alpha(s?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(w,S,v,E)}onMouseMove(e,t){const{feature:n,mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);e.apolloDragging?e.setCursor("col-resize"):n&&a&&(this.isMouseOnFeatureEdge(a,n,e)?e.setCursor("col-resize"):e.setCursor())}onMouseDown(e,t){const{feature:n,mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);n&&a&&this.isMouseOnFeatureEdge(a,n,e)&&t.stopPropagation()}onMouseUp(e,t){if(e.apolloDragging??0!==t.button)return;const{feature:n}=e.getFeatureAndGlyphUnderMouse(t);n&&e.setSelectedFeature(n)}startDrag(e){const{feature:t,mousePosition:n}=e.apolloDragging?.start??{};return!!(t&&n&&this.isMouseOnFeatureEdge(n,t,e))}continueDrag(e,t){const{feature:n,glyph:a,mousePosition:o,topLevelFeature:r}=e.apolloDragging?.start??{};t&&o&&e.setDragging({start:{feature:n,topLevelFeature:r,glyph:a,mousePosition:o},current:{feature:n,topLevelFeature:r,glyph:a,mousePosition:t}})}executeDrag(e){const{apolloDragging:n,changeManager:a,displayedRegions:o,getAssemblyId:r,setCursor:s}=e;if(!n)return;const{feature:l,glyph:i,mousePosition:c}=n.start;if(!l)throw new Error("no feature for drag preview??");if(i!==this)throw new Error("drawDragPreview() called on wrong glyph?");const u=this.isMouseOnFeatureEdge(c,l,e);if(!u)return;const{mousePosition:d}=n.current,f=d.bp,m=r(o[c.regionNumber].assemblyName);let g;if("end"===u){const e=l._id;g=new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[e],featureId:e,oldEnd:l.end,newEnd:f,assembly:m})}else{const e=l._id;g=new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[e],featureId:e,oldStart:l.start,newStart:f,assembly:m})}if(!a)throw new Error("no change manager");a.submit(g),s()}}const In=i.types.model({heightPreConfig:i.types.maybe(i.types.refinement("displayHeight",i.types.number,(e=>e>=20)))}).volatile((()=>({scrollTop:0}))).views((e=>({get height(){return e.heightPreConfig??n.getConf(e,"height")}}))).actions((e=>({setScrollTop(t){e.scrollTop=t},setHeight:t=>(e.heightPreConfig=Math.max(t,20),e.height),resizeHeight(t){const n=e.height;return this.setHeight(e.height+t)-n}})));function Pn(e,t,n,a){return 1===n?(e+a)%3+1:(t-a)%3*-1-1}const qn=[null,"#FF8080","#80FF80","#8080FF","#8080FF","#80FF80","#FF8080"];function _n(e,t){return t?.palette.bases[e.toUpperCase()].main.toString()??"lightgray"}function Un(e,t,n,a,o){const r=Math.min(n,10);e.fillStyle="#000",e.font=`${r}px`;const s=e.measureText(a).width;e.fillText(a,t+(n-s)/2,o+10)}function On(e,t,n,a,o,s,l,i,c,u){let d=l.slice(i,i+3).toUpperCase();c&&(d=function(e){return[...e].map((e=>r.revcom(e))).reverse().join("")}(d));const f=r.defaultCodonTable[d];f&&(e.beginPath(),e.fillStyle=function(e,t,n){const a={M:"#33ee33","*":"#f44336"};return void 0!==a[e?.toUpperCase()]?a[e?.toUpperCase()]:n<=.1?t:"lightgray"}(f,u,t),e.rect(n,a,o,s),e.fill(),t<=.1&&(e.stroke(),Un(e,n,o,f,a)))}let Bn=null,jn=null;if("document"in window)for(const e of["forward","backward"]){const t=document.createElement("canvas"),n=10;t.width=t.height=n;const a=t.getContext("2d");if(a){const o="rgba(0,0,0,0)",r="rgba(255,255,255,0.25)",s="forward"===e?a.createLinearGradient(0,n,n,0):a.createLinearGradient(0,0,n,n);s.addColorStop(0,o),s.addColorStop(.25,o),s.addColorStop(.25,r),s.addColorStop(.5,r),s.addColorStop(.5,o),s.addColorStop(.75,o),s.addColorStop(.75,r),s.addColorStop(1,r),a.fillStyle=s,a.fillRect(0,0,10,10),"forward"===e?Bn=a.createPattern(t,"repeat"):jn=a.createPattern(t,"repeat")}}let $n=null,Gn=null;if("document"in window)for(const e of["forward","backward"]){const t=document.createElement("canvas"),n=10;t.width=t.height=n;const a=t.getContext("2d");if(a){const o="rgba(0,0,0,0)",r="rgba(255,255,255,0.25)",s="forward"===e?a.createLinearGradient(0,n,n,0):a.createLinearGradient(0,0,n,n);s.addColorStop(0,o),s.addColorStop(.25,o),s.addColorStop(.25,r),s.addColorStop(.5,r),s.addColorStop(.5,o),s.addColorStop(.75,o),s.addColorStop(.75,r),s.addColorStop(1,r),a.fillStyle=s,a.fillRect(0,0,10,10),"forward"===e?$n=a.createPattern(t,"repeat"):Gn=a.createPattern(t,"repeat")}}const Wn=new Ln,Hn=new class extends Tn{featuresForRow(e){const t=[];for(const[,n]of e.children??new Map)for(const[,e]of n.children??new Map)"CDS"===e.type&&t.push({parent:n,cds:e});const n=[];for(const e of t){const t=[];for(const[,n]of e.parent.children??new Map)if("CDS"!==n.type||n._id===e.cds._id)if(n.discontinuousLocations&&n.discontinuousLocations.length>0)for(const a of n.discontinuousLocations)t.push({annotationFeature:n,parent:e.parent,start:a.start,end:a.end,phase:a.phase});else t.push({annotationFeature:n,parent:e.parent});t.push({annotationFeature:e.parent}),n.push(t)}return n}getRowCount(e,t){let n=0;for(const[,t]of e.children??new Map)for(const[,e]of t.children??new Map)"CDS"===e.type&&(n+=1);return n}draw(e,t,n,a,o,r){const{apolloRowHeight:s,lgv:l,session:i,theme:c}=e,{bpPerPx:u}=l,d=s,f=Math.round(.6*d),m=Math.round(.9*d),{_id:g,children:p,min:h,strand:y}=n,{apolloSelectedFeature:b}=i;let w=0;for(const[,e]of p??new Map)if("mRNA"===e.type)for(const[,n]of e.children??new Map){if("CDS"!==n.type)continue;const s=(e.start-h)/u,l=e.length/u,i=r?a-s-l:a+s,f=Math.round((w+.5)*d)+o*d;t.strokeStyle=c?.palette.text.primary??"black",t.beginPath(),t.moveTo(i,f),t.lineTo(i+l,f),t.stroke(),w+=1}w=0;for(const[,e]of p??new Map){if("mRNA"!==e.type)continue;const n=[...e.children??[]].filter((([,e])=>"CDS"===e.type)).length;for(let s=0;s<n;s++){for(const[,n]of e.children??new Map){if("exon"!==n.type)continue;const e=(n.start-h)/u,s=n.length/u,l=r?a-e-s:a+e,i=(o+w)*d+(d-f)/2;if(t.fillStyle=c?.palette.text.primary??"black",t.fillRect(l,i,s,f),s>2&&(t.clearRect(l+1,i+1,s-2,f-2),t.fillStyle=b&&n._id===b._id?"rgb(0,0,0)":"rgb(211,211,211)",t.fillRect(l+1,i+1,s-2,f-2),Bn&&jn&&y)){const e=r?-1:1,[n,a]=y*e==1?[Bn,jn]:[jn,Bn];t.fillStyle=n,t.fillRect(l+1,i+1,s-2,(f-2)/2),t.fillStyle=a,t.fillRect(l+1,i+1+(f-2)/2,s-2,(f-2)/2)}}w+=1}}w=0;for(const[,e]of p??new Map)if("mRNA"===e.type)for(const[,n]of e.children??new Map)if("CDS"===n.type){if(n.discontinuousLocations)for(const e of n.discontinuousLocations){const s=(e.start-h)/u,l=(e.end-e.start)/u,i=r?a-s-l:a+s;t.fillStyle=c?.palette.text.primary??"black";const f=(o+w)*d+(d-m)/2;if(t.fillRect(i,f,l,m),l>2){t.clearRect(i+1,f+1,l-2,m-2);const a=Pn(e.start,e.end,e.strand,e.phase),o=qn.at(a)??"rgb(171,71,188)";if(t.fillStyle=b&&n._id===b._id?"rgb(0,0,0)":o,t.fillRect(i+1,f+1,l-2,m-2),Bn&&jn&&y){const e=r?-1:1,[n,a]=y*e==1?[Bn,jn]:[jn,Bn];t.fillStyle=n,t.fillRect(i+1,f+1,l-2,(m-2)/2),t.fillStyle=a,t.fillRect(i+1,f+(m-2)/2,l-2,(m-2)/2)}}}w+=1}if(b)if(g===b._id){const e=n.length/u,s=r?a-e:a,l=o*d,i=this.getRowCount(n)*d;t.fillStyle=c?.palette.action.selected??"rgba(0,0,0,0.08)",t.fillRect(s,l,e,i)}else{let e,n,s=0;for(const[,t]of p??new Map)t._id===b?._id&&(e=t,n=s),s++;if(void 0===e||void 0===n)return;const l=this.cdsCount(e);let i=d;l>1&&(i*=l);const f=e.length/u,m=r?a-f:a+(e.start-h)/u,g=(o+n)*d;t.fillStyle=c?.palette.action.selected??"rgba(0,0,0,08)",t.fillRect(m,g,f,i)}}cdsCount(e){let t=0;for(const[,n]of e?.children??new Map)"CDS"===n.type&&n.discontinuousLocations&&n.discontinuousLocations.length>0&&t++;return t}drawHover(e,t,n,a,o){const{apolloHover:r}=e;if(!r)return;const{feature:s}=r;if(s)if(s.discontinuousLocations&&s.discontinuousLocations.length>0)for(const n of s.discontinuousLocations)this.drawShadeForFeature(e,t,n.start,n.end,n.end-n.start);else this.drawShadeForFeature(e,t,s.start,s.end,s.length,n,a,o)}drawShadeForFeature(e,t,n,a,o,r,s,l){const{apolloHover:i,apolloRowHeight:c,displayedRegions:u,lgv:d,theme:f}=e,{bpPerPx:m,bpToPx:g,offsetPx:p}=d;if(!i)return;const{feature:h,topLevelFeature:y}=i;if(!h||!y)return;let b,w,S,v=0;for(const[,e]of y.children??new Map){e._id===h?._id&&(b=e,S=v);for(const[,t]of e.children??new Map)t._id===h._id&&(w=t,b=e,S=v);v++}const E=this.cdsCount(b);if(E>1&&r&&s){if(void 0===b||void 0===S)return;const e=w?w.length/m:b.length/m,n=l?s-e:s+(w?(w.start-h.min)/m:(b.start-h.min)/m),a=(r+S)*c;t.fillStyle=f?.palette.action.selected??"rgba(0,0,0,04)",t.fillRect(n,a,e,c*E)}else{const{mousePosition:e}=i;if(!e)return;const r=c,{regionNumber:s,y:l}=e,d=Math.floor(l/r),h=u[s],{refName:y,reversed:b}=h,w=(g({refName:y,coord:b?a:n,regionNumber:s})?.offsetPx??0)-p,S=d*r,v=o/m;t.fillStyle=f?.palette.action.focus??"rgba(0,0,0,0.04)",t.fillRect(w,S,v,r)}}drawDragPreview(e,t){const{apolloDragging:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e,{bpPerPx:l,offsetPx:i}=r;if(!n)return;const{discontinuousLocation:c,feature:u,glyph:d,mousePosition:f}=n.start;if(!u)throw new Error("no feature for drag preview??");if(d!==this)throw new Error("drawDragPreview() called on wrong glyph?");const{mousePosition:g}=n.current,p=this.isMouseOnFeatureEdge(f,u,e);if(!p)return;const h=Math.floor(f.y/a),y=o[f.regionNumber];let b;b=c?y.reversed?y.end-c[p]:c[p]-y.start:y.reversed?y.end-u[p]:u[p]-y.start;const w=b/l-i,S=Math.min(g.x,w),v=h*a,E=Math.abs(g.x-w),C=1*a;t.strokeStyle=s?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(S,v,E,C),t.fillStyle=m.alpha(s?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(S,v,E,C)}isMouseOnFeatureEdge(e,t,n,a){if(!e)return;const{bp:o,refName:r,regionNumber:s,x:l}=e,{lgv:i}=n,{bpToPx:c,offsetPx:u}=i;let d,f;if(t.discontinuousLocations&&t.discontinuousLocations.length>0){let e;for(const n of t.discontinuousLocations)if(o>=n.start&&o<=n.end){e=n;break}if(!e)return;d=c({refName:r,coord:e.start,regionNumber:s}),f=c({refName:r,coord:e.end,regionNumber:s})}else d=c({refName:r,coord:t.start,regionNumber:s}),f=c({refName:r,coord:t.end,regionNumber:s});if(void 0!==d&&void 0!==f){const e=d.offsetPx-u,n=f.offsetPx-u;if(Math.abs(n-e)<8)return;const o=this.getParentFeature(t,a);if(o){if("gene"===o.type)return;if(t.start<=o.start&&Math.abs(e-l)<4)return;if(t.end>=o.end&&Math.abs(n-l)<4)return}if(Math.abs(e-l)<4)return"start";if(Math.abs(n-l)<4)return"end"}}onMouseMove(e,t){const{feature:n,mousePosition:a,topLevelFeature:o}=e.getFeatureAndGlyphUnderMouse(t);e.apolloDragging?e.setCursor("col-resize"):n&&a&&(this.isMouseOnFeatureEdge(a,n,e,o)?e.setCursor("col-resize"):e.setCursor())}onMouseDown(e,t){const{feature:n,mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);n&&a&&this.isMouseOnFeatureEdge(a,n,e)&&t.stopPropagation()}onMouseUp(e,t){if(e.apolloDragging??0!==t.button)return;const{feature:n}=e.getFeatureAndGlyphUnderMouse(t);n&&e.setSelectedFeature(n)}startDrag(e){const{feature:t,mousePosition:n,topLevelFeature:a}=e.apolloDragging?.start??{},{mousePosition:o}=e.apolloDragging?.current??{};return!!(t&&n&&o&&this.isMouseOnFeatureEdge(n,t,e,a))}adjacentExonsOfCdsDL(e,t){let n,a,o,r;if(t){for(const[n,a]of t.entries()){const t=a.cdsDL;if(e.start===t?.start&&e.end===t.end&&e.phase===t.phase){r=n;break}}if(void 0!==r){const{exon:e}=t[r];o=e}void 0!==r&&r>0&&(n=t[r-1].exon),void 0!==r&&r<t.length-1&&(a=t[r+1].exon)}return{prevExon:n,matchingExon:o,nextExon:a}}exonCDSRelation(e,t){const n=[];if(!e)return n;const a=this.getParentFeature(e,t);if(!a?.children)return n;for(const[,t]of a.children)if("exon"===t.type){const a=this.cdsDLForExon(t,e);n.push({exon:t,cdsDL:a?{start:a.start,end:a.end,phase:a.phase}:void 0})}return n}cdsDLForExon(e,t){let n;if(t.discontinuousLocations&&t.discontinuousLocations.length>0)for(const a of t.discontinuousLocations)if(a.start>=e.start&&a.end<=e.end){n=a;break}return n}cdsDlsForExon(e,t){const n=[],a=this.getParentFeature(e,t);if(!a?.children||!t)return n;const o=[];for(const[,e]of a.children)"CDS"===e.type&&o.push(e);for(const t of o)for(const[,o]of a.children)if("exon"===o.type&&o._id===e._id){const e=this.cdsDLForExon(o,t);e&&n.push(e)}return n}adjacentExonsOfExon(e,t){const n=this.getParentFeature(e,t);if(!n||!n.children)return;let a,o,r=0;for(const[,t]of n.children){if(t._id===e._id)break;r++}const s=[...n.children.keys()];if(r>0){const e=n.children.get(s[r-1]);e&&"exon"===e.type&&(a=e)}if(r<s.length-1){const e=n.children.get(s[r+1]);e&&"exon"===e.type&&(o=e)}return{prevExon:a,nextExon:o}}continueDrag(e,t){const{discontinuousLocation:n,feature:a,glyph:o,mousePosition:r,topLevelFeature:s}=e.apolloDragging?.start??{};if(!t||!r)return;const{bp:l}=t;if(!a||!t)return;const i=this.isMouseOnFeatureEdge(r,a,e,s);if("CDS"===a.type&&a.discontinuousLocations&&a.discontinuousLocations.length>0&&n){const e=this.exonCDSRelation(a,s),{matchingExon:t,nextExon:o,prevExon:r}=this.adjacentExonsOfCdsDL(n,e);if(o&&l>=o.start-1)return;if(r&&l<=r.end+1)return;if(!r&&o&&t&&l<t.start)return;if(r&&!o&&t&&l>t.end)return;if(i&&("start"===i&&l>=n.end-1||"end"===i&&l<=n.start+1))return}if("CDS"!==a.type){const e=this.adjacentExonsOfExon(a,s);if(e?.nextExon&&l>=e?.nextExon.start-1)return;if(e?.prevExon&&l<=e?.prevExon.end+1)return;const t=this.cdsDlsForExon(a,s);if(t&&t.length>0){let e;for(const n of t)if(i&&("start"===i&&l>=n.start-1||"end"===i&&l<=n.end+1)){e=!0;break}if(e)return}else if(i&&("start"===i&&l>=a.end-1||"end"===i&&l<=a.start+1))return}e.setDragging({start:{feature:a,topLevelFeature:s,glyph:o,discontinuousLocation:n,mousePosition:r},current:{feature:a,topLevelFeature:s,glyph:o,mousePosition:t}})}getFeatureFromLayout(e,t,n){const a=this.featuresForRow(e)[n];let o;for(const e of a)void 0!==e.start&&void 0!==e.end&&void 0!==e.phase?t>=e.start&&t<=e.end&&e.parent&&(o=e.annotationFeature):t>=e.annotationFeature.start&&t<=e.annotationFeature.end&&e.parent&&(o=e.annotationFeature);return o||(o=a.at(-1)?.annotationFeature),o}getRowForFeature(e,t){const n=this.featuresForRow(e);for(const[e,a]of n.entries())if(a.some((e=>e.annotationFeature._id===t._id)))return e}async executeDrag(e){const{apolloDragging:t,changeManager:n,displayedRegions:a,getAssemblyId:o,setCursor:r}=e;if(!t)return;const{discontinuousLocation:s,feature:l,glyph:i,mousePosition:c,topLevelFeature:u}=t.start;if(!l)throw new Error("no feature for drag preview??");if(i!==this)throw new Error("drawDragPreview() called on wrong glyph?");const d=this.isMouseOnFeatureEdge(c,l,e);if(!d)return;const{mousePosition:f}=t.current,m=f.bp,g=o(a[c.regionNumber].assemblyName),p=[];if("start"===d)if(void 0!==s?.idx&&l.discontinuousLocations&&l.discontinuousLocations.length>0){this.addDiscontinuousLocStartChange(p,l,m,l.discontinuousLocations[s.idx].start,g,s.idx);const e=this.exonCDSRelation(l,u),t=this.adjacentExonsOfCdsDL(s,e);t&&t.matchingExon&&m<t.matchingExon.start&&this.addStartLocationChange(p,t.matchingExon,m,g)}else this.addStartLocationChange(p,l,m,g);else if(void 0!==s?.idx&&l.discontinuousLocations&&l.discontinuousLocations.length>0){this.addDiscontinuousLocEndChange(p,l,m,l.discontinuousLocations[s.idx].end,g,s.idx);const e=this.exonCDSRelation(l,u),t=this.adjacentExonsOfCdsDL(s,e);t&&t.matchingExon&&m>t.matchingExon.end&&this.addEndLocationChange(p,t.matchingExon,m,g)}else this.addEndLocationChange(p,l,m,g);if(!n)throw new Error("no change manager");for(const e of p)await n.submit(e);r()}addDiscontinuousLocStartChange(e,n,a,o,r,s){e.push(new t.DiscontinuousLocationStartChange({typeName:"DiscontinuousLocationStartChange",changedIds:[n._id],featureId:n._id,newStart:a,oldStart:o,index:s,assembly:r}))}addDiscontinuousLocEndChange(e,n,a,o,r,s){e.push(new t.DiscontinuousLocationEndChange({typeName:"DiscontinuousLocationEndChange",changedIds:[n._id],featureId:n._id,newEnd:a,oldEnd:o,index:s,assembly:r}))}addEndLocationChange(e,n,a,o){const r=n._id;e.push(new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[r],featureId:r,oldEnd:n.end,newEnd:a,assembly:o}))}addStartLocationChange(e,n,a,o){const r=n._id;e.push(new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[r],featureId:r,oldStart:n.start,newStart:a,assembly:o}))}},zn=new class extends Ln{featuresForRow(e){const t=[[e]];if(e.children)for(const[,n]of e.children??new Map)t.push(...this.featuresForRow(n));return t}getRowCount(e){return this.featuresForRow(e).length}draw(e,t,n,a,o,r){for(let s=0;s<this.getRowCount(n);s++)this.drawRow(e,t,n,a,o+s,o,r)}drawRow(e,t,n,a,o,r,s){const l=this.featuresForRow(n)[o-r];for(const r of l)this.drawFeature(e,t,n,r,a,o,s)}drawFeature(e,t,n,a,o,r,s){const{apolloRowHeight:l,lgv:i,session:c}=e,{bpPerPx:u}=i,{apolloSelectedFeature:d}=c,f=(a.start-n.min)/u,m=a.length/u,g=s?o-f-m:o+f,p=r*l,h=this.getRowCount(a),y=this.getIsSelectedFeature(a,d);h>1&&this.drawBox(t,g,p,m,h*l,y?"rgba(130,0,0,0.45)":"rgba(255,0,0,0.25)"),super.draw(e,t,a,g,r,s)}drawHover(e,t){const{apolloHover:n,apolloRowHeight:a,displayedRegions:o,lgv:r}=e;if(!n)return;const{feature:s,mousePosition:l}=n;if(!s||!l)return;const{regionNumber:i,y:c}=l,u=o[i],{refName:d,reversed:f}=u,{bpPerPx:m,bpToPx:g,offsetPx:p}=r,{end:h,length:y,start:b}=s,w=(g({refName:d,coord:f?h:b,regionNumber:i})?.offsetPx??0)-p,S=Math.floor(c/a)*a,v=y/m;t.fillStyle="rgba(0,0,0,0.2)",t.fillRect(w,S,v,a*this.getRowCount(s))}onMouseUp(e,t){if(e.apolloDragging??0!==t.button)return;const{feature:n}=e.getFeatureAndGlyphUnderMouse(t);n&&e.setSelectedFeature(n)}continueDrag(e,t){}getFeatureFromLayout(e,t,n){const a=this.featuresForRow(e)[n];return a?.find((e=>t>=e.start&&t<=e.end))}getRowForFeature(e,t){const n=this.featuresForRow(e);for(const[e,a]of n.entries())if(a.some((e=>e._id===t._id)))return e}},Vn=new class extends Tn{featuresForRow(e){const t=[];for(const[,n]of e.children??new Map){const e=[];for(const[,t]of n.children??new Map)e.push(t);e.push(n),t.push(e)}return t}getRowCount(e){let t=0;for(const[,n]of e.children??new Map)"mRNA"===n.type&&(t+=1);return t}draw(e,t,n,a,o,r){const{apolloRowHeight:s,lgv:l,session:i,theme:c}=e,{bpPerPx:u}=l,d=s,f=Math.round(.6*d),m=Math.round(.9*d),{_id:g,children:p,min:h,strand:y}=n,{apolloSelectedFeature:b}=i;let w=0;for(const[,e]of p??new Map){if("mRNA"!==e.type)continue;const n=(e.start-h)/u,s=e.length/u,l=r?a-n-s:a+n,i=Math.round((w+.5)*d)+o*d;t.strokeStyle=c?.palette.text.primary??"black",t.beginPath(),t.moveTo(l,i),t.lineTo(l+s,i),t.stroke(),w+=1}w=0;for(const[,e]of p??new Map){if("mRNA"!==e.type)continue;const n=[...e.children??[]].filter((([,e])=>"CDS"===e.type)).length;for(let s=0;s<n;s++)for(const[,n]of e.children??new Map){const e="CDS"===n.type,s=n.type.endsWith("UTR");if(!e&&!s)continue;const l=(n.start-h)/u,i=n.length/u,g=r?a-l-i:a+l;t.fillStyle=c?.palette.text.primary??"black";const p=e?m:f,S=(o+w)*d+(d-p)/2;if(t.fillRect(g,S,i,p),i>2){t.clearRect(g+1,S+1,i-2,p-2);let a="rgb(211,211,211)";if(e){const e=Pn(n.start,n.end,n.strand,n.phase);a=qn.at(e)??"rgb(171,71,188)"}if(t.fillStyle=b&&n._id===b._id?"rgb(0,0,0)":a,t.fillRect(g+1,S+1,i-2,p-2),$n&&Gn&&y){const e=r?-1:1,[n,a]=y*e==1?[$n,Gn]:[Gn,$n];t.fillStyle=n,t.fillRect(g+1,S+1,i-2,(p-2)/2),t.fillStyle=a,t.fillRect(g+1,S+1+(p-2)/2,i-2,(p-2)/2)}}}w+=1}if(b)if(g===b._id){const e=n.length/u,s=r?a-e:a,l=o*d,i=this.getRowCount(n)*d;t.fillStyle=c?.palette.action.selected??"rgba(0,0,0,0.08)",t.fillRect(s,l,e,i)}else{let e,n,s=0;for(const[,t]of p??new Map)t._id===b?._id&&(e=t,n=s),s++;if(void 0===e||void 0===n)return;const l=e.length/u,i=r?a-l:a+(e.start-h)/u,f=(o+n)*d;t.fillStyle=c?.palette.action.selected??"rgba(0,0,0,08)",t.fillRect(i,f,l,d)}}drawHover(e,t){const{apolloHover:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e;if(!n)return;const{feature:l,mousePosition:i}=n;if(!l||!i)return;const{regionNumber:c,y:u}=i,{bpPerPx:d,bpToPx:f,offsetPx:m}=r,g=a,p=Math.floor(u/g),h=o[c],{refName:y,reversed:b}=h,w=(f({refName:y,coord:b?l.end:l.start,regionNumber:c})?.offsetPx??0)-m,S=p*g,v=l.length/d;t.fillStyle=s?.palette.action.focus??"rgba(0,0,0,0.04)",t.fillRect(w,S,v,g)}drawDragPreview(e,t){const{apolloDragging:n,apolloRowHeight:a,displayedRegions:o,lgv:r,theme:s}=e,{bpPerPx:l,offsetPx:i}=r;if(!n)return;const{feature:c,glyph:u,mousePosition:d}=n.start;if(!c)throw new Error("no feature for drag preview??");if(u!==this)throw new Error("drawDragPreview() called on wrong glyph?");const{mousePosition:f}=n.current,g=this.isMouseOnFeatureEdge(d,c,e);if(!g)return;const p=Math.floor(d.y/a),h=o[d.regionNumber],y=(h.reversed?h.end-c[g]:c[g]-h.start)/l-i,b=Math.min(f.x,y),w=p*a,S=Math.abs(f.x-y),v=1*a;t.strokeStyle=s?.palette.info.main??"rgb(255,0,0)",t.setLineDash([6]),t.strokeRect(b,w,S,v),t.fillStyle=m.alpha(s?.palette.info.main??"rgb(255,0,0)",.2),t.fillRect(b,w,S,v)}isMouseOnFeatureEdge(e,t,n,a){if(!e)return;const{refName:o,regionNumber:r,x:s}=e,{lgv:l}=n,{bpToPx:i,offsetPx:c}=l,u=i({refName:o,coord:t.start,regionNumber:r}),d=i({refName:o,coord:t.end,regionNumber:r});if(void 0!==u&&void 0!==d){const e=u.offsetPx-c,n=d.offsetPx-c;if(Math.abs(n-e)<8)return;const o=this.getParentFeature(t,a);if(o&&t.start<=o.start&&Math.abs(e-s)<4)return;if(o&&t.end>=o.end&&Math.abs(n-s)<4)return;if(Math.abs(e-s)<4)return"start";if(Math.abs(n-s)<4)return"end"}}onMouseMove(e,t){const{feature:n,mousePosition:a,topLevelFeature:o}=e.getFeatureAndGlyphUnderMouse(t);e.apolloDragging?e.setCursor("col-resize"):n&&a&&(this.isMouseOnFeatureEdge(a,n,e,o)?e.setCursor("col-resize"):e.setCursor())}onMouseDown(e,t){const{feature:n,mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);n&&a&&this.isMouseOnFeatureEdge(a,n,e)&&t.stopPropagation()}onMouseUp(e,t){if(e.apolloDragging??0!==t.button)return;const{feature:n}=e.getFeatureAndGlyphUnderMouse(t);n&&e.setSelectedFeature(n)}startDrag(e){const{feature:t,mousePosition:n,topLevelFeature:a}=e.apolloDragging?.start??{},{mousePosition:o}=e.apolloDragging?.current??{};return!!(t&&n&&o&&this.isMouseOnFeatureEdge(n,t,e,a))}continueDrag(e,t){const{feature:n,glyph:a,mousePosition:o,topLevelFeature:r}=e.apolloDragging?.start??{};if(!t||!o)return;const s=this.getParentFeature(n,r),l=this.getAdjacentFeatures(n,s);if(!n||!t)return;const{bp:i}=t,c=this.isMouseOnFeatureEdge(o,n,e,r);if(!c||!("start"===c&&i>=n.end-1||"end"===c&&i<=n.start+1)){if("CDS"!==n.type){if(l.prevFeature&&!l.nextFeature){if("CDS"===l.prevFeature.type&&i<=l.prevFeature.start+1)return;if("CDS"!==l.prevFeature.type&&i<=l.prevFeature.end+1)return}if(!l.prevFeature&&l.nextFeature){if("CDS"===l.nextFeature.type&&i>=l.nextFeature.end-1)return;if("CDS"!==l.nextFeature.type&&i>=l.nextFeature.start-1)return}}if(l.prevFeature&&l.nextFeature)if("CDS"===n.type){if("CDS"!==l.nextFeature.type&&i>=l.nextFeature.end-1)return;if("CDS"===l.nextFeature.type&&i>=l.nextFeature.start-1)return;if("CDS"!==l.prevFeature.type&&i<=l.prevFeature.start+1)return;if("CDS"===l.prevFeature.type&&i<=l.prevFeature.end+1)return}else{if("CDS"===l.prevFeature.type&&i<=l.prevFeature.start+1)return;if("CDS"!==l.prevFeature.type&&i<=l.prevFeature.end+1)return;if("CDS"!==l.nextFeature.type&&i>=l.nextFeature.start-1)return;if("CDS"===l.nextFeature.type&&i>=l.nextFeature.end-1)return}e.setDragging({start:{feature:n,topLevelFeature:r,glyph:a,mousePosition:o},current:{feature:n,topLevelFeature:r,glyph:a,mousePosition:t}})}}getFeatureFromLayout(e,t,n){const a=this.featuresForRow(e)[n];return a?.find((e=>t>=e.start&&t<=e.end))}getRowForFeature(e,t){const n=this.featuresForRow(e);for(const[e,a]of n.entries())if(a.some((e=>e._id===t._id)))return e}async executeDrag(e){const{apolloDragging:t,changeManager:n,displayedRegions:a,getAssemblyId:o,setCursor:r}=e;if(!t)return;const{feature:s,glyph:l,mousePosition:i,topLevelFeature:c}=t.start;if(!s)throw new Error("no feature for drag preview??");if(l!==this)throw new Error("drawDragPreview() called on wrong glyph?");const u=this.isMouseOnFeatureEdge(i,s,e);if(!u)return;const{mousePosition:d}=t.current,f=d.bp,m=o(a[i.regionNumber].assemblyName),g=this.getParentFeature(s,c),p=this.getAdjacentFeatures(s,g),h=[];if("end"===u){this.addEndLocation(h,s,f,m);const{nextFeature:e}=p;if(!e)return;("CDS"!==s.type&&"CDS"===e.type||"CDS"===s.type&&"CDS"!==e.type)&&this.addStartLocation(h,e,f+1,m)}else{this.addStartLocation(h,s,f,m);const{prevFeature:e}=p;if(!e)return;("CDS"!==s.type&&"CDS"===e.type||"CDS"===s.type&&"CDS"!==e.type)&&this.addEndLocation(h,e,f-1,m)}if(!n)throw new Error("no change manager");for(const e of h)await n.submit(e);r()}getAdjacentFeatures(e,t){let n,a,o=0;if(!e||!t||!t.children)return{prevFeature:n,nextFeature:a};for(const[,n]of t.children){if(n._id===e._id)break;o++}const r=[...t.children.keys()];return o>0&&(n=t.children.get(r[o-1])),o<r.length-1&&(a=t.children.get(r[o+1])),{prevFeature:n,nextFeature:a}}addEndLocation(e=[],n,a,o){const r=n._id;e.push(new t.LocationEndChange({typeName:"LocationEndChange",changedIds:[r],featureId:r,oldEnd:n.end,newEnd:a,assembly:o}))}addStartLocation(e=[],n,a,o){const r=n._id;e.push(new t.LocationStartChange({typeName:"LocationStartChange",changedIds:[r],featureId:r,oldStart:n.start,newStart:a,assembly:o}))}};function Jn(e,t){if("gene"===e.type){let t=!1;for(const[,n]of e.children??new Map)if("mRNA"===n.type)for(const[,e]of n.children??new Map)"exon"===e.type&&(t=!0);return t?Hn:Vn}return e.children?.size?zn:Wn}function Xn(e,t){return"CDS"===e.type&&void 0!==e.phase?-1===e.strand?(e.end-e.phase)%3+(t<=1?5:3):Math.abs((e.start+e.phase)%3-2):t<=1?-1===e.strand?4:3:void 0}function Yn(e,t,n,a,o,r){void 0!==o&&(e.fillStyle=t?.palette.action.focus??"rgba(0,0,0,0.04)",e.fillRect(n,a*o,r,a))}function Kn(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return function(e,t){const o=function(e,t){return i.types.compose(a.BaseDisplay,In).named("BaseLinearApolloDisplay").props({type:i.types.literal("LinearApolloDisplay"),configuration:n.ConfigurationReference(t)}).volatile((e=>({lgv:r.getContainingView(e)}))).views((e=>{const{configuration:t,renderProps:n}=e;return{renderProps:()=>({...n(),...W.getParentRenderProps(e),config:t.renderer})}})).views((e=>({get rendererTypeName(){return e.configuration.renderer.type},get session(){return r.getSession(e)},get regions(){return e.lgv.dynamicBlocks.contentBlocks.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:Math.round(a),end:Math.round(t)})))},get displayedRegions(){return e.lgv.displayedRegions},regionCannotBeRendered(){if(e.lgv&&e.lgv.bpPerPx>=200)return"Zoom in to see annotations"}}))).views((e=>({get apolloInternetAccount(){const[t]=e.regions,{internetAccounts:a}=i.getRoot(e),{assemblyName:o}=t,{assemblyManager:r}=e.session,s=r.get(o);if(!s)throw new Error(`No assembly found with name ${o}`);const{internetAccountConfigId:l}=n.getConf(s,["sequence","metadata"]);return a.find((e=>n.getConf(e,"internetAccountId")===l))},get changeManager(){return e.session.apolloDataStore?.changeManager},getAssemblyId(t){const{assemblyManager:n}=e.session,a=n.get(t);if(!a)throw new Error(`Could not find assembly named ${t}`);return a.name},get selectedFeature(){return e.session.apolloSelectedFeature}}))).actions((e=>({setSelectedFeature:t=>e.session.apolloSetSelectedFeature(t),afterAttach(){i.addDisposer(e,l.autorun((()=>{e.lgv.initialized&&!e.regionCannotBeRendered()&&(e.session.apolloDataStore.loadFeatures(e.regions),e.session.apolloDataStore.loadRefSeq(e.regions))}),{name:"LinearApolloDisplayLoadFeatures",delay:1e3}))}})))}(0,t);return o.named("LinearApolloDisplayLayouts").props({featuresMinMaxLimit:5e5}).volatile((()=>({seenFeatures:l.observable.map()}))).views((e=>({get featuresMinMax(){const{assemblyManager:t}=e.session;return e.displayedRegions.map((n=>{const a=t.get(n.assemblyName);let o,s;const{end:l,refName:i,start:c}=n;for(const[,t]of e.seenFeatures)i!==a?.getCanonicalRefName(t.refSeq)||!r.doesIntersect2(c,l,t.min,t.max)||t.length>e.featuresMinMaxLimit||(void 0===o&&({min:o}=t),void 0===s&&({max:s}=t),t.min<o&&({min:o}=t),t.end>s&&({max:s}=t));if(void 0!==o&&void 0!==s)return[o,s]}))}}))).actions((e=>({addSeenFeature(t){e.seenFeatures.set(t._id,t)},deleteSeenFeature(t){e.seenFeatures.delete(t)}}))).views((e=>({get featureLayouts(){const{assemblyManager:t}=e.session;return e.displayedRegions.map(((n,a)=>{const o=t.get(n.assemblyName),s=new Map,l=e.featuresMinMax[a];if(!l)return s;const[c,u]=l,d=[],{end:f,refName:m,start:g}=n;for(const[t,n]of e.seenFeatures.entries()){if(!i.isAlive(n)){e.deleteSeenFeature(t);continue}if(m!==o?.getCanonicalRefName(n.refSeq)||!r.doesIntersect2(g,f,n.min,n.max))continue;const a=Jn(n).getRowCount(n,e.lgv.bpPerPx);let l=0,p=!1;for(;!p;){let e=d.slice(l,l+a);if(e.length<a){for(let t=0;t<a-e.length;t++){const e=d.length;d[e]=Array.from({length:u-c}),s.set(e,[])}e=d.slice(l,l+a)}if(e.map((e=>{const t=n.max-n.min==0?n.min+1:n.max;let a=n.min-c,o=t-c;return n.min-c<0&&(a=0,o=t-n.min),e.slice(a,o).some(Boolean)})).some(Boolean))l+=1;else{for(let e=l;e<l+a;e++){let t=n.min-c,a=n.max-c;n.min-c<0&&(t=0,a=n.max-n.min),d[e].fill(!0,t,a);const o=s.get(e);o?.push([e-l,n])}p=!0}}}return s}))},getFeatureLayoutPosition(e){const{featureLayouts:t}=this;for(const n of t)for(const[t,a]of n)for(const[n,o]of a)if(0===n){if(e._id===o._id)return{layoutRow:t,featureRow:n};if(o.hasDescendant(e._id)){const n=Jn(o).getRowForFeature(o,e);if(void 0!==n)return{layoutRow:t,featureRow:n}}}}}))).views((e=>({get highestRow(){return Math.max(0,...e.featureLayouts.map((e=>Math.max(...e.keys()))))}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(e.lgv.initialized&&!e.regionCannotBeRendered())for(const t of e.regions){const n=e.session.apolloDataStore.assemblies.get(t.assemblyName),a=n?.getByRefName(t.refName);for(const[,n]of a?.features??new Map)r.doesIntersect2(t.start,t.end,n.start,n.end)&&!e.seenFeatures.has(n._id)&&e.addSeenFeature(n)}}),{name:"LinearApolloDisplaySetSeenFeatures",delay:1e3}))}})))}(0,t).named("LinearApolloDisplayRendering").props({sequenceRowHeight:15,apolloRowHeight:20,detailsMinHeight:200,detailsHeight:200,lastRowTooltipBufferHeight:40,isShown:!0}).volatile((()=>({canvas:null,overlayCanvas:null,collaboratorCanvas:null,seqTrackCanvas:null,seqTrackOverlayCanvas:null,theme:void 0}))).views((e=>({get featuresHeight(){return(e.highestRow+1)*e.apolloRowHeight+e.lastRowTooltipBufferHeight}}))).actions((e=>({toggleShown(){e.isShown=!e.isShown},setDetailsHeight(t){e.detailsHeight=e.isShown?Math.max(Math.min(t,e.height-100),Math.min(e.height,e.detailsMinHeight)):t},setCanvas(t){e.canvas=t},setOverlayCanvas(t){e.overlayCanvas=t},setCollaboratorCanvas(t){e.collaboratorCanvas=t},setSeqTrackCanvas(t){e.seqTrackCanvas=t},setSeqTrackOverlayCanvas(t){e.seqTrackOverlayCanvas=t},setTheme(t){e.theme=t},afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.collaboratorCanvas?.getContext("2d");if(t){t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);for(const n of e.session.collaborators){const{locations:a}=n;if(0===a.length)continue;let o=0;for(const r of e.lgv.displayedRegions){for(const s of a){if(s.refSeq!==r.refName)continue;const{end:a,refSeq:l,start:i}=s,c=e.lgv.bpToPx({refName:l,coord:i,regionNumber:o});if(!c)continue;const u=c.offsetPx-e.lgv.offsetPx,d=(a-i)/e.lgv.bpPerPx;t.fillStyle="rgba(0,255,0,.2)",t.fillRect(u,1,d,100),t.fillStyle="black",t.fillText(n.name,u+1,11,d-2)}o++}}}}),{name:"LinearApolloDisplayRenderCollaborators"}))}})))}(0,t);return o.actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((async()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;if(e.lgv.bpPerPx>3)return;const t=e.seqTrackCanvas?.getContext("2d");if(t){t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.lgv.bpPerPx<=1?125:95);for(const[n,a]of e.regions.entries()){const o=e.session.apolloDataStore.getBackendDriver(a.assemblyName);if(!o)throw new Error("Failed to get the backend driver");const{seq:s}=await o.getSequence(a);if(!s)return;for(const[o,l]of[...s].entries()){const i=(e.lgv.bpToPx({refName:a.refName,coord:a.start+o,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx,c=3/e.lgv.bpPerPx,u=e.displayedRegions[n].reversed?i-c:i;for(let n=2;n>=0;n--){const r=qn.at(n+1)??"#ffffff";(a.start+o)%3===n&&On(t,e.lgv.bpPerPx,u,e.sequenceRowHeight*(2-n),c,e.sequenceRowHeight,s,o,!1,r)}if(e.lgv.bpPerPx<=1){const s=(e.lgv.bpToPx({refName:a.refName,coord:a.start+o,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx,i=1/e.lgv.bpPerPx,c=e.displayedRegions[n].reversed?s-i:s;t.beginPath(),t.fillStyle=_n(l,e.theme),t.rect(c,3*e.sequenceRowHeight,i,e.sequenceRowHeight),t.fill(),e.lgv.bpPerPx<=.1&&(t.stroke(),Un(t,c,i,l,3*e.sequenceRowHeight));const u=r.revcom(l);t.beginPath(),t.fillStyle=_n(u,e.theme),t.rect(c,4*e.sequenceRowHeight,i,e.sequenceRowHeight),t.fill(),e.lgv.bpPerPx<=.1&&(t.stroke(),Un(t,c,i,u,4*e.sequenceRowHeight))}for(let n=0;n<=2;n++){const r=qn.at(-(n+1))??"#ffffff";(a.start+o)%3===n&&On(t,e.lgv.bpPerPx,u,e.sequenceRowHeight*((e.lgv.bpPerPx<=1?5:3)+n),c,e.sequenceRowHeight,s,o,!0,r)}}}}}),{name:"LinearApolloDisplayRenderSequence"}))}})))}(0,t).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.canvas?.getContext("2d");if(t){t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);for(const[n,a]of e.featureLayouts.entries()){const o=e.displayedRegions[n];for(const[s,l]of a.entries())for(const[a,i]of l){if(a>0)continue;if(!r.doesIntersect2(o.start,o.end,i.min,i.max))continue;const l=(e.lgv.bpToPx({refName:o.refName,coord:i.min,regionNumber:n})?.offsetPx??0)-e.lgv.offsetPx;Jn(i).draw(e,t,i,l,s,o.reversed)}}}}),{name:"LinearApolloDisplayRenderFeatures"}))}})))}(0,t);return o.named("LinearApolloDisplayMouseEvents").volatile((()=>({apolloDragging:null,cursor:void 0,apolloHover:null}))).views((e=>({getFeatureAndGlyphUnderMouse(t){const n=function(e,t){const n=e.currentTarget,{clientX:a,clientY:o}=e,{left:r,top:s}=n.getBoundingClientRect()||{left:0,top:0},l=a-r,i=o-s,{coord:c,index:u,refName:d}=t.pxToBp(l);return{x:l,y:i,refName:d,bp:c,regionNumber:u}}(t,e.lgv),{bp:a,regionNumber:o,y:r}=n,s=Math.floor(r/e.apolloRowHeight),l=e.featureLayouts[o].get(s);if(!l)return{mousePosition:n};const i=l.find((e=>a>=e[1].min&&a<=e[1].max));if(!i)return{mousePosition:n};const[c,u]=i,d=Jn(u);return{feature:d.getFeatureFromLayout(u,a,c),topLevelFeature:u,glyph:d,mousePosition:n}}}))).actions((e=>({continueDrag(t){if(!e.apolloDragging)throw new Error("continueDrag() called with no current drag in progress");t.stopPropagation();const{glyph:n}=e.apolloDragging.start,{mousePosition:a}=e.getFeatureAndGlyphUnderMouse(t);a&&n&&n.continueDrag(e,a)},setDragging(t){e.apolloDragging=t??null}}))).actions((e=>({setApolloHover(t){e.apolloHover=t},setCursor(t){e.cursor!==t&&(e.cursor=t)}}))).actions((()=>({onClick(){}})))}(0,t).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((async()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.seqTrackOverlayCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.lgv.bpPerPx<=1?125:95);const{apolloHover:n,displayedRegions:a,lgv:o,regions:r,sequenceRowHeight:s,theme:l}=e;if(!n)return;const{feature:i,mousePosition:c}=n;if(i&&c)for(const[e,n]of r.entries()){const r=Xn(i,o.bpPerPx);if(i.discontinuousLocations&&i.discontinuousLocations.length>0)for(const c of i.discontinuousLocations){const i=(o.bpToPx({refName:n.refName,coord:c.start,regionNumber:e})?.offsetPx??0)-o.offsetPx,u=(c.end-c.start)/o.bpPerPx;Yn(t,l,a[e].reversed?i-u:i,s,r,u)}else{const c=(o.bpToPx({refName:n.refName,coord:i.start,regionNumber:e})?.offsetPx??0)-o.offsetPx,u=i.length/o.bpPerPx;Yn(t,l,a[e].reversed?c-u:c,s,r,u)}}}),{name:"LinearApolloDisplayRenderSeqHighlight"}))}})))}(0,t);return o.views((e=>({contextMenuItems(t){const{apolloHover:n}=e,{topLevelFeature:a}=n??{};return a&&t?Jn(a).getContextMenuItems(e):[]}}))).actions((e=>({startDrag(t){const{feature:n,glyph:a,mousePosition:o,topLevelFeature:r}=e.getFeatureAndGlyphUnderMouse(t);if(n&&r&&a&&o){let s,l;if(n.discontinuousLocations&&n.discontinuousLocations.length>0)for(let e=0;e<n.discontinuousLocations.length;e++)if(o.bp>=n.discontinuousLocations[e].start&&o.bp<=n.discontinuousLocations[e].end){l=e,s=n.discontinuousLocations[l];break}e.apolloDragging={start:{glyph:a,feature:n,topLevelFeature:r,discontinuousLocation:s?{start:s.start,end:s.end,phase:s.phase,idx:l}:void 0,mousePosition:o},current:{glyph:a,feature:n,topLevelFeature:r,mousePosition:o}},a.startDrag(e,t)||(e.apolloDragging=null)}},endDrag(t){e.continueDrag(t),e.apolloDragging?.start.glyph?.executeDrag(e,t),e.setDragging()}}))).actions((e=>({onMouseDown(t){const{feature:n,glyph:a,topLevelFeature:o}=e.getFeatureAndGlyphUnderMouse(t);a&&n&&o&&a.onMouseDown(e,t)},onMouseMove(t){const{buttons:n}=t,a=e.getFeatureAndGlyphUnderMouse(t),{glyph:o}=a;if(o&&o.onMouseMove(e,t),n)1===n&&(e.apolloDragging?e.continueDrag(t):e.startDrag(t));else{const{feature:t,topLevelFeature:n}=a;t&&o&&n?e.setApolloHover(a):(e.setApolloHover(null),e.setCursor())}},onMouseLeave(t){e.setDragging();const{glyph:n}=e.getFeatureAndGlyphUnderMouse(t);n&&n.onMouseLeave(e,t)},onMouseUp(t){const{glyph:n}=e.getFeatureAndGlyphUnderMouse(t);n&&n.onMouseUp(e,t),e.apolloDragging&&e.endDrag(t)}}))).actions((e=>({afterAttach(){i.addDisposer(e,l.autorun((()=>{if(!e.lgv.initialized||e.regionCannotBeRendered())return;const t=e.overlayCanvas?.getContext("2d");if(!t)return;t.clearRect(0,0,e.lgv.dynamicBlocks.totalWidthPx,e.featuresHeight);const{apolloDragging:n,apolloHover:a,displayedRegions:o,featureLayouts:r,lgv:s}=e;if(!a)return;const{feature:l,glyph:i}=a;if(!l)return;let c=0,u=0,d=!1;for(const[e,t]of r.entries()){const n=o[e];for(const[a,o]of t.entries())if(0===c)for(const[,t]of o)for(const[,o]of t.children??new Map)if(0===c)if(u=(s.bpToPx({refName:n.refName,coord:l.min,regionNumber:e})?.offsetPx??0)-s.offsetPx,({reversed:d}=n),o._id!==l._id)for(const[,e]of o.children??new Map)0===c&&(e._id!==l._id||(c=a));else c=a}i?.drawHover(e,t,c,u,d),i?.drawTooltip(e,t),n&&n.start.glyph?.drawDragPreview(e,t)}),{name:"LinearApolloDisplayRenderMouseoverAndDrag"}))}})))}(0,t).props({tabularEditor:i.types.optional(Mn,{})}).named("LinearApolloDisplay")}const Zn=v.makeStyles()((e=>({canvasContainer:{position:"relative",left:0},canvas:{position:"absolute",left:0},ellipses:{textOverflow:"ellipsis",overflow:"hidden"},avatar:{position:"absolute",color:e.palette.warning.light,backgroundColor:e.palette.warning.contrastText}}))),Qn=S.observer((function(e){const t=m.useTheme(),{model:n}=e,{apolloRowHeight:a,contextMenuItems:o,cursor:s,featuresHeight:l,isShown:i,onMouseDown:c,onMouseLeave:u,onMouseMove:d,onMouseUp:f,regionCannotBeRendered:g,session:p,setCanvas:h,setCollaboratorCanvas:w,setOverlayCanvas:S,setSeqTrackCanvas:v,setSeqTrackOverlayCanvas:E,setTheme:C,tabularEditor:x}=n,{classes:F}=Zn(),A=r.getContainingView(n);y.useEffect((()=>C(t)),[t,C]);const[D,k]=y.useState(),[N,R]=y.useState([]),M=g();if(!i)return null;const{assemblyManager:T}=p;return ae.default.createElement(ae.default.Fragment,null,A.bpPerPx<=3?ae.default.createElement("div",{className:F.canvasContainer,style:{width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95}},ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),v(e)},width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95,className:F.canvas,"data-testid":"seqTrackCanvas"}),ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),E(e)},width:A.dynamicBlocks.totalWidthPx,height:A.bpPerPx<=1?125:95,className:F.canvas,"data-testid":"seqTrackOverlayCanvas"})):null,ae.default.createElement("div",{className:F.canvasContainer,style:{width:A.dynamicBlocks.totalWidthPx,height:l},onContextMenu:e=>{if(e.preventDefault(),N.length>0)R([]);else{const t=[e.clientX,e.clientY];k(t),R(o(t))}}},M?ae.default.createElement(m.Alert,{severity:"warning",classes:{message:F.ellipses}},ae.default.createElement(m.Tooltip,{title:M},ae.default.createElement("div",null,M))):ae.default.createElement(ae.default.Fragment,null,ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),w(e)},width:A.dynamicBlocks.totalWidthPx,height:l,className:F.canvas,"data-testid":"collaboratorCanvas"}),ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),h(e)},width:A.dynamicBlocks.totalWidthPx,height:l,className:F.canvas,"data-testid":"canvas"}),ae.default.createElement("canvas",{ref:async e=>{await Promise.resolve(),S(e)},width:A.dynamicBlocks.totalWidthPx,height:l,onMouseMove:d,onMouseLeave:u,onMouseDown:c,onMouseUp:f,onClick:()=>{x.showPane()},className:F.canvas,style:{cursor:s??"default"},"data-testid":"overlayCanvas"}),A.displayedRegions.flatMap(((e,t)=>{const o=T.get(e.assemblyName);return[...p.apolloDataStore.checkResults.values()].filter((t=>o?.isValidRefName(t.refSeq)&&o?.getCanonicalRefName(t.refSeq)===e.refName&&r.doesIntersect2(e.start,e.end,t.start,t.end))).map((o=>{const r=(A.bpToPx({refName:e.refName,coord:o.start,regionNumber:t})?.offsetPx??0)-A.offsetPx,[s]=o.ids;if(!s)return null;const{topLevelFeature:l}=s,i=parent?n.getFeatureLayoutPosition(l)?.layoutRow??0:0;return ae.default.createElement(m.Tooltip,{key:o._id,title:o.message},ae.default.createElement(m.Avatar,{className:F.avatar,style:{top:i*a,left:r,height:a,width:a}},ae.default.createElement(ve.default,null)))}))})),ae.default.createElement(b.Menu,{open:N.length>0,onMenuItemClick:(e,t)=>{t(),R([])},onClose:()=>{R([])},TransitionProps:{onExit:()=>{R([])}},anchorReference:"anchorPosition",anchorPosition:D?{top:D[1],left:D[0]}:void 0,style:{zIndex:t.zIndex.tooltip},menuItems:N}))))})),ea=S.observer((function({model:e}){const{height:t}=e;return ae.default.createElement("div",{style:{position:"absolute",left:0,top:t/2,width:"100%"}},ae.default.createElement("hr",{style:{margin:0,top:0,color:"black"}}))})),ta=v.makeStyles()((e=>({shading:{background:m.alpha(e.palette.primary.main,.2),overflowY:"scroll",overflowX:"hidden"},details:{background:e.palette.background.paper},accordionControl:{height:12,width:"100%","&:hover":{background:e.palette.action.hover},display:"flex",alignItems:"center",justifyContent:"center"},accordionRoot:{background:e.palette.divider},resizeHandle:{width:"100%",height:4,position:"absolute",cursor:"row-resize",zIndex:100},expandIcon:{},title:{userSelect:"none"}}))),na=({onResize:e})=>{const{classes:t}=ta(),n=y.useCallback((t=>{t.stopPropagation(),t.preventDefault(),e(t.movementY)}),[e]),a=y.useCallback((e=>{e.stopPropagation(),e.preventDefault(),window.removeEventListener("mousemove",n),window.removeEventListener("mouseup",a),window.removeEventListener("mouseleave",a)}),[n]);return ae.default.createElement("div",{onMouseDown:e=>{e.stopPropagation(),window.addEventListener("mousemove",n),window.addEventListener("mouseup",a),window.addEventListener("mouseleave",a)},onClick:e=>{e.stopPropagation(),e.preventDefault()},className:t.resizeHandle})},aa=S.observer((function({onClick:e,onResize:t,open:n,title:a}){const{classes:o}=ta();return ae.default.createElement("div",{className:o.accordionRoot},n&&t?ae.default.createElement(na,{onResize:t}):null,ae.default.createElement("div",{className:o.accordionControl,onClick:e},ae.default.createElement(n?we.default:Se.default,{className:o.expandIcon}),a?ae.default.createElement(m.Typography,{className:o.title,variant:"caption",component:"span"},a):null))})),oa=S.observer((function({model:e,...t}){const{classes:n}=ta(),{height:a,isShown:o,selectedFeature:r,tabularEditor:s,toggleShown:l}=e,i=s.isShown?e.detailsHeight:0,c=o?a-i-24:0,u=y.useRef(null);return y.useEffect((()=>function(e,t){const{apolloRowHeight:n,selectedFeature:a}=e;if(t.current&&a){const o=e.getFeatureLayoutPosition(a);o&&t.current.scroll({top:(o.layoutRow+o.featureRow)*n,behavior:"smooth"})}}(e,u)),[e,r]),ae.default.createElement("div",{className:n.details,style:{height:a}},ae.default.createElement(aa,{open:o,title:"Graphical",onClick:l}),ae.default.createElement("div",{className:n.shading,ref:u,style:{height:c}},ae.default.createElement(Qn,{model:e,...t})),ae.default.createElement(aa,{title:"Table",open:s.isShown,onClick:s.togglePane,onResize:t=>{e.setDetailsHeight(e.detailsHeight-t)}}),ae.default.createElement("div",{style:{height:i}},ae.default.createElement(Rn,{model:e})))})),ra=i.types.model("JobsManager",{}).views((e=>({get jobStatusWidget(){const{widgets:t}=r.getSession(e);let n=t.get("JobsList");return n||(n=r.getSession(e).addWidget("JobsListWidget","JobsList")),n}}))).actions((e=>({update(t,n,a){e.jobStatusWidget.updateJobStatusMessage(t,n),a&&e.jobStatusWidget.updateJobProgressPct(t,a)},abortJob(t,n){const a=r.getSession(e);if(r.isSessionModelWithWidgets(a)){a.showWidget(e.jobStatusWidget),e.jobStatusWidget.updateJobStatusMessage(t,n??"Aborted unexpectedly");const o=e.jobStatusWidget.jobs.findIndex((e=>e.name===t));e.jobStatusWidget.addAbortedJob({...e.jobStatusWidget.jobs[o]}),e.jobStatusWidget.removeJob(t),a.notify("Job aborted","info")}},runJob(t){const n=r.getSession(e);r.isSessionModelWithWidgets(n)&&(n.showWidget(e.jobStatusWidget),e.jobStatusWidget.addJob(t))},done(t){const n=r.getSession(e);r.isSessionModelWithWidgets(n)&&(n.showWidget(e.jobStatusWidget),e.jobStatusWidget.removeJob(t.name),e.jobStatusWidget.addFinishedJob({name:t.name,statusMessage:"All operations successful",progressPct:100,cancelCallback:t.cancelCallback}))}})));class sa{clientStore;constructor(e){this.clientStore=e}}class la{dataStore;constructor(e){this.dataStore=e}recentChanges=[];async submit(n,a={}){const{addToRecents:o=!0,submitToBackend:s=!0,updateJobsManager:l=!1}=a,i=r.getSession(this.dataStore),c=new AbortController,{jobsManager:u}=r.getSession(this.dataStore),d={name:`${n.typeName}`,statusMessage:"Pre-validating",progressPct:0,cancelCallback:()=>{c.abort()}};l&&u.runJob(d);const f=await t.validationRegistry.frontendPreValidate(n);if(!f.ok){const e=`Pre-validation failed: "${f.resultsMessages}"`;return l&&u.abortJob(d.name,e),void i.notify(e,"error")}try{await n.execute(this.dataStore)}catch(e){return l&&u.abortJob(d.name,String(e)),console.error(e),void i.notify(String(e),"error")}if((await t.validationRegistry.frontendPostValidate(n,this.dataStore)).ok||await this.revert(n),s){l&&u.update(d.name,"Submitting to driver");const{collaborationServerDriver:t,getBackendDriver:o}=this.dataStore,r=e.isAssemblySpecificChange(n)?o(n.assembly):t;let s;try{s=await r.submitChange(n,a)}catch(e){return l&&u.abortJob(d.name,String(e)),console.error(e),i.notify(String(e),"error"),void await this.revert(n,!1)}if(!s.ok){const e=`Post-validation failed: "${f.resultsMessages}"`;return l&&u.abortJob(d.name,e),i.notify(e,"error"),void await this.revert(n,!1)}n.notification&&i.notify(n.notification,"success")}o&&this.recentChanges.push(n),l&&u.done(d)}async revert(e,t=!0){const n=e.getInverse();return this.submit(n,{submitToBackend:t,addToRecents:!1})}async revertLastChange(){const e=this.recentChanges.pop();if(e)return this.revert(e);r.getSession(this.dataStore).notify("No changes to undo!","warning")}}class ia extends sa{inFlight=new Map;async fetch(e,t,n){return e.getFetcher({locationType:"UriLocation",uri:t.toString()})(t,n)}async searchFeatures(e,t){const n=this.clientStore.getInternetAccount(t[0]),{baseURL:a}=n,o=new URL("features/searchFeatures",a),r=new URLSearchParams({assemblies:t.join(","),term:e});o.search=r.toString();const s=o.toString(),l=await this.fetch(n,s);if(!l.ok){const e=await Ae(l,"searchFeatures failed");throw new Error(e)}return l.json()}async getFeatures(e){const{assemblyName:t,end:a,refName:o,start:s}=e,{assemblyManager:l}=r.getSession(this.clientStore),i=l.get(t);if(!i)throw new Error(`Could not find assembly with name "${t}"`);const{ids:c}=n.getConf(i,["sequence","metadata"]),u=c[o];if(!u)throw new Error(`Could not find refSeq "${o}"`);const d=this.clientStore.getInternetAccount(t),{baseURL:f}=d,m=new URL("features/getFeatures",f),g=new URLSearchParams({refSeq:u,start:String(s),end:String(a)});m.search=g.toString();const p=m.toString(),h=await this.fetch(d,p);if(!h.ok){const e=await Ae(h,"getFeatures failed");throw new Error(e)}return await this.checkSocket(t,o,d),h.json()}async checkSocket(t,n,a){const{socket:o}=a,r=a.retrieveToken(),s=`${t}-${n}`,l=new la(this.clientStore);o.hasListeners(s)||o.on(s,(async t=>{if(a.setLastChangeSequenceNumber(Number(t.changeSequence)),t.userSessionId!==r&&t.channel===s){const n=e.Change.fromJSON(t.changeInfo);await l.submit(n,{submitToBackend:!1})}}))}async getSequence(e){const t=`${e.refName}:${e.start}-${e.end}`,a=this.inFlight.get(t),{assemblyName:o,end:s,refName:l,start:i}=e,{assemblyManager:c}=r.getSession(this.clientStore),u=c.get(o);if(!u)throw new Error(`Could not find assembly with name "${o}"`);const{ids:d}=n.getConf(u,["sequence","metadata"]),f=d[l];if(!f)throw new Error(`Could not find refSeq "${l}"`);if(a)return{seq:await a,refSeq:f};let m=this.clientStore.assemblies.get(o);m||(m=this.clientStore.addAssembly(o));let g=m?.refSeqs.get(f);g||(g=m.addRefSeq(f,l));const p=g.getSequence(i,s);if(p.length===s-i)return{seq:p,refSeq:f};const h=this.clientStore.getInternetAccount(o),{baseURL:y}=h,b=new URL("sequence",y),w=new URLSearchParams({refSeq:f,start:String(i),end:String(s)});b.search=w.toString();const S=b.toString(),v=this.getSeqFromServer(h,S,g,i,s);this.inFlight.set(t,v);const E=await v;return await this.checkSocket(o,l,h),this.inFlight.delete(t),{seq:E,refSeq:f}}async getSeqFromServer(e,t,n,a,o){const r=await this.fetch(e,t);if(!r.ok){let e;try{e=await r.text()}catch{e=""}throw new Error(`getSequence failed: ${r.status} (${r.statusText})${e?` (${e})`:""}`)}const s=await r.text();return n.addSequence({sequence:s,start:a,stop:o}),s}async getRegions(e){const{assemblyManager:t}=r.getSession(this.clientStore);if(!t.get(e))throw new Error(`Could not find assembly with name "${e}"`);const n=this.clientStore.getInternetAccount(e),{baseURL:a}=n,o=new URL("refSeqs",a),s=new URLSearchParams({assembly:e});o.search=s.toString();const l=o.toString(),i=await this.fetch(n,l);if(!i.ok){let e;try{e=await i.text()}catch{e=""}throw new Error(`getRegions failed: ${i.status} (${i.statusText})${e?` (${e})`:""}`)}return(await i.json()).map((e=>({refName:e.name,start:0,end:e.length})))}getAssemblies(e){const{assemblyManager:t}=r.getSession(this.clientStore);return t.assemblies.filter((t=>{const a=n.getConf(t,["sequence","metadata"]);return!(!(a&&a.apollo&&a.internetAccountConfigId)||e&&a.internetAccountConfigId!==e)}))}async submitChange(e,n={}){const{internetAccountId:a}=n,o=this.clientStore.getInternetAccount("assembly"in e?e.assembly:void 0,a),{baseURL:r}=o,s=new URL("changes",r).href,l=await this.fetch(o,s,{method:"POST",body:JSON.stringify(e.toJSON()),headers:{"Content-Type":"application/json"}});if(!l.ok){const e=await Ae(l,"submitChange failed");throw new Error(e)}const i=new t.ValidationResultSet;return l.ok||(i.ok=!1),i}}class ca extends sa{async getFeatures(){return[[],[]]}async getSequence(e){const{assemblyName:t,end:n,refName:a,start:o}=e,r=this.clientStore.assemblies.get(t);if(!r)return{seq:"",refSeq:a};const s=r.refSeqs.get(a);return s?{seq:s.getSequence(o,n),refSeq:a}:{seq:"",refSeq:a}}async getRegions(e){const t=this.clientStore.assemblies.get(e);if(!t)return[];const n=[];for(const[,a]of t.refSeqs)n.push({assemblyName:e,refName:a.name,start:a.sequence[0].start,end:a.sequence[0].stop});return n}getAssemblies(){const{assemblyManager:e}=r.getSession(this.clientStore);return e.assemblies.filter((e=>{const t=n.getConf(e,["sequence","metadata"]);return Boolean(t&&t.apollo&&!t.file&&!t.internetAccountConfigId)}))}async submitChange(e,n={}){return new t.ValidationResultSet}async searchFeatures(e,t){return[]}}class ua extends sa{async loadAssembly(e){const{assemblyManager:t}=r.getSession(this.clientStore),a=t.get(e);if(!a)throw new Error(`Assembly ${e} not found`);const{file:o}=n.getConf(a,["sequence","metadata"]),s=require("node:fs");return Ce(e,await s.promises.readFile(o,"utf8"),this.clientStore)}async getAssembly(e){let t=this.clientStore.assemblies.get(e);return t||(t=await this.loadAssembly(e)),t}async getFeatures(e){return await this.getAssembly(e.assemblyName),[[],[]]}async getSequence(e){const{assemblyName:t,end:n,refName:a,start:o}=e,r=(await this.getAssembly(t)).refSeqs.get(a);if(!r)throw new Error(`refSeq ${a} not found in client data store`);return{seq:r.getSequence(o,n),refSeq:a}}async getRegions(e){const t=await this.getAssembly(e),n=[];for(const[,a]of t.refSeqs)n.push({assemblyName:e,refName:a.name,start:a.sequence[0].start,end:a.sequence[0].stop});return n}getAssemblies(){const{assemblyManager:e}=r.getSession(this.clientStore);return e.assemblies.filter((e=>{const t=n.getConf(e,["sequence","metadata"]);return Boolean(t&&t.apollo&&!t.internetAccountConfigId&&t.file)}))}async submitChange(a){if(!e.isAssemblySpecificChange(a))throw new Error(`Cannot use this type of change with local file: "${a.typeName}"`);const{assemblyManager:o}=r.getSession(this.clientStore),s=o.get(a.assembly);if(!s)throw new Error(`Could not find assembly with name "${a.assembly}"`);const{file:l}=n.getConf(s,["sequence","metadata"]),c=this.clientStore.assemblies.get(a.assembly);if(!c)throw new Error(`Could not find assembly in client with name "${a.assembly}"`);const u=new Set(...c.refSeqs.keys()),{checkResults:d}=this.clientStore;for(const e of d.values())u.has(e.refSeq)&&d.delete(e._id);const f=await xe(c);this.clientStore.addCheckResults(f);const m=[{directive:"gff-version",value:"3"}];for(const[,e]of c.refSeqs)m.push({directive:"sequence-region",value:`${e.name} 1 ${e.sequence[0].stop}`});for(const e of c.comments)m.push({comment:e});for(const[,e]of c.refSeqs){const{features:n}=e;for(const[,e]of n)m.push(t.makeGFF3Feature(i.getSnapshot(e)))}for(const[,e]of c.refSeqs){const[n]=e.sequence,a=t.splitStringIntoChunks(n.sequence,80).join("\n");m.push({id:e.name,description:e.description,sequence:a})}const g=Z.default.formatSync(m),p=require("node:fs");return await p.promises.writeFile(l,g,"utf8"),new t.ValidationResultSet}async searchFeatures(e,t){return[]}}function da(e,t){const a=new AbortController,{signal:o}=a,s=e.evaluateExtensionPoint("Apollo-extendAnnotationFeature",j.AnnotationFeature),c=function(e){const t=i.types.model("ClientDataStore",{typeName:i.types.optional(i.types.literal("Client"),"Client"),assemblies:i.types.map(j.ApolloAssembly),checkResults:i.types.map(j.CheckResult)}).views((t=>({get internetAccounts(){return i.getRoot(t).internetAccounts},get pluginConfiguration(){return i.getRoot(t).jbrowse.configuration.ApolloPlugin},getFeature:n=>i.resolveIdentifier(e,t.assemblies,n)}))).actions((e=>({addAssembly:t=>e.assemblies.put({_id:t,refSeqs:{}}),addFeature(t,n){const a=e.assemblies.get(t);if(!a)throw new Error(`Could not find assembly "${t}" to add feature "${n._id}"`);const o=a.refSeqs.get(n.refSeq);if(!o)throw new Error(`Could not find refSeq "${n.refSeq}" to add feature "${n._id}"`);o.features.put(n)},deleteFeature(t){const n=e.getFeature(t);if(!n)throw new Error(`Could not find feature "${t}" to delete`);const{_id:a,parent:o}=n;o?o.deleteChild(t):i.getParentOfType(n,j.ApolloRefSeq).deleteFeature(a)},deleteAssembly(t){e.assemblies.delete(t)},addCheckResult(t){e.checkResults.put(t)},addCheckResults(t){for(const n of t)e.checkResults.has(n._id)||e.checkResults.put(n)},deleteCheckResult(t){e.checkResults.delete(t)}}))).volatile((e=>({changeManager:new la(e),collaborationServerDriver:new ia(e),inMemoryFileDriver:new ca(e),desktopFileDriver:r.isElectron?new ua(e):void 0,ontologyManager:Ke.create()}))).actions((e=>({afterCreate(){const{ontologyManager:t,pluginConfiguration:a}=e,o=a.ontologies;for(const e of o||[]){const[a,o,r,s]=[n.readConfObject(e,"name"),n.readConfObject(e,"version"),n.readConfObject(e,"source"),n.readConfObject(e,"textIndexFields")];t.findOntology(a)||t.addOntology(a,o,r,{textIndexing:{indexFields:s}})}}}))).views((e=>({getBackendDriver(t){if(!t)return e.collaborationServerDriver;const a=r.getSession(e),{assemblyManager:o}=a,s=o.get(t);if(!s)return e.collaborationServerDriver;const{file:l,internetAccountConfigId:i}=n.getConf(s,["sequence","metadata"]);return r.isElectron&&l?e.desktopFileDriver:i?e.collaborationServerDriver:e.inMemoryFileDriver},getInternetAccount(t,a){if(!(t??a))throw new Error("Must provide either assemblyName or internetAccountId");let o=a;if(t&&!o){const{assemblyManager:a}=r.getSession(e),s=a.get(t);if(!s)throw new Error(`No assembly found with name ${t}`);({internetAccountConfigId:o}=n.getConf(s,["sequence","metadata"]))}const{internetAccounts:s}=e,l=s.find((e=>e.internetAccountId===o));if(!l)throw new Error(`No InternetAccount found with config id ${a}`);return l}}))).actions((e=>({loadFeatures:i.flow((function*(t){for(const n of t){const t=e.getBackendDriver(n.assemblyName);if(!t)return;const[a,o]=yield t.getFeatures(n);if(0===a.length)continue;const{assemblyName:r,refName:s}=n;let l=e.assemblies.get(r);l||(l=e.assemblies.put({_id:r,refSeqs:{}}));const[i]=a;let c=l.refSeqs.get(i.refSeq);c||(c=l.refSeqs.put({_id:i.refSeq,name:s,features:{}}));for(const e of a)c.features.has(e._id)||c.features.put(e);e.addCheckResults(o)}})),loadRefSeq:i.flow((function*(t){for(const n of t){const t=e.getBackendDriver(n.assemblyName);if(!t)return;const{refSeq:a,seq:o}=yield t.getSequence(n),{assemblyName:r,end:s,refName:l,start:i}=n;let c=e.assemblies.get(r);c||(c=e.assemblies.put({_id:r,refSeqs:{}}));let u=c.refSeqs.get(a);u||(u=c.refSeqs.put({_id:a,name:l,sequence:[]})),u.addSequence({start:i,stop:s,sequence:o})}}))})));return i.types.snapshotProcessor(t,{postProcessor:e=>(e.assemblies={},e.checkResults={},e)})}(s);return t.props({apolloDataStore:i.types.optional(c,{typeName:"Client"}),apolloSelectedFeature:i.types.safeReference(s),jobsManager:i.types.optional(ra,{})}).extend((()=>{const e=l.observable.array([]);return{views:{get collaborators(){return e}},actions:{addOrUpdateCollaborator(t){const n=e.find((e=>e.id===t.id));n?n.locations=t.locations:e.push(t)}}}})).actions((e=>({apolloSetSelectedFeature(t){e.apolloSelectedFeature=t},addApolloTrackConfig(t,a){const o=`apollo_track_${t.name}`;e.tracks.some((e=>e.trackId===o))||e.addTrackConf({type:"ApolloTrack",trackId:o,name:`Annotations (${n.getConf(t,"displayName")||t.name})`,assemblyNames:[t.name],textSearching:{textSearchAdapter:{type:"ApolloTextSearchAdapter",trackId:o,assemblyNames:[t.name],textSearchAdapterId:`apollo_search_${t.name}`,...a?{baseURL:{uri:a,locationType:"UriLocation"}}:{}}},displays:[{type:"LinearApolloDisplay",displayId:`${o}-LinearApolloDisplay`},{type:"SixFrameFeatureDisplay",displayId:`${o}-SixFrameFeatureDisplay`}]})},broadcastLocations(){const{internetAccounts:t}=i.getRoot(e),n=[];for(const t of e.views){if("LinearGenomeView"!==t.type)return;const e=t;if(e.initialized){const{dynamicBlocks:t}=e;t.forEach((e=>{if(void 0!==e.regionNumber){const{assemblyName:t,end:a,refName:o,start:r}=e;n.push({assemblyName:t,refName:o,start:r,end:a})}}))}}if(0===n.length){for(const e of t)"baseURL"in e&&e.postUserLocation([]);return}const a=[];for(const e of t)if("baseURL"in e){for(const e of n)a.push({assemblyId:e.assemblyName,refSeq:e.refName,start:e.start,end:e.end});e.postUserLocation(a)}}}))).actions((e=>({afterCreate:i.flow((function*(){const{internetAccounts:t}=i.getRoot(e);l.autorun((()=>{const n=[];for(const t of e.views){if("LinearGenomeView"!==t.type)return;const e=t;if(e.initialized){const{dynamicBlocks:t}=e;t.forEach((e=>{if(void 0!==e.regionNumber){const{assemblyName:t,end:a,refName:o,start:r}=e;n.push({assemblyName:t,refName:o,start:r,end:a})}}))}}if(0===n.length){for(const e of t)"baseURL"in e&&e.postUserLocation([]);return}const a=[];for(const e of t)if("baseURL"in e){for(const e of n)a.push({assemblyId:e.assemblyName,refSeq:e.refName,start:e.start,end:e.end});e.postUserLocation(a)}}),{name:"ApolloSession"});for(const n of t){if("ApolloInternetAccount"!==n.type)continue;const{baseURL:t,configuration:a}=n,r=new URL("assemblies",t).href,s=n.getFetcher({locationType:"UriLocation",uri:r});let l,i;try{l=yield s(r,{signal:o})}catch(e){console.error(e);continue}if(l.ok){try{i=yield l.json()}catch(e){console.error(e);continue}for(const r of i){const{addAssembly:s,addSessionAssembly:l,assemblyManager:i}=e,c=i.get(r.name);if(c){e.addApolloTrackConfig(c,t);continue}const u=new URL("refSeqs",t),d=new URLSearchParams({assembly:r._id});u.search=d.toString();const f=u.toString(),m=n.getFetcher({locationType:"UriLocation",uri:f}),g=yield m(f,{signal:o});if(!g.ok){let e;try{e=yield g.text()}catch{e=""}throw new Error(`Failed to fetch fasta info — ${g.status} (${g.statusText})${e?` (${e})`:""}`)}const p=yield g.json(),h={},y=p.map((e=>(h[e.name]=e._id,{refName:e.name,aliases:[e._id],uniqueId:`alias-${e._id}`}))),b={name:r._id,aliases:[r.name,...r.aliases??[]],displayName:r.displayName??r.name,sequence:{trackId:`sequenceConfigId-${r.name}`,type:"ReferenceSequenceTrack",adapter:{type:"ApolloSequenceAdapter",assemblyId:r._id,baseURL:{uri:t,locationType:"UriLocation"}},metadata:{apollo:!0,internetAccountConfigId:a.internetAccountId,ids:h}},refNameAliases:{adapter:{type:"FromConfigAdapter",features:y}}};(l||s)(b);const w=yield i.waitForAssembly(b.name);e.addApolloTrackConfig(w,t)}}else{const e=yield Ae(l,"Failed to fetch assemblies");console.error(e)}}})),beforeDestroy(){a.abort()}})))}const fa={0:2,1:1,2:0},ma={3:0,4:1,5:2};function ga(e,t){const a=e.getPlugin("LinearGenomeViewPlugin"),{BaseLinearDisplay:o}=a.exports;return o.named("SixFrameFeatureDisplay").props({type:i.types.literal("SixFrameFeatureDisplay"),configuration:n.ConfigurationReference(t),apolloRowHeight:20,detailsMinHeight:200,showStartCodons:!1,showStopCodons:!0,showIntronLines:!0}).volatile((()=>({apolloFeatureUnderMouse:void 0,apolloRowUnderMouse:void 0}))).views((e=>{const{configuration:t,renderProps:n}=e;return{renderProps:()=>({...n(),...W.getParentRenderProps(e),config:t.renderer})}})).views((e=>({get regions(){let t;try{({blockDefinitions:t}=e)}catch{return[]}return t.contentBlocks.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))},regionCannotBeRendered(){const t=r.getContainingView(e);if(t&&t.bpPerPx>=200)return"Zoom in to see annotations"},get session(){return r.getSession(e)}}))).actions((e=>{let t=[];return{afterAttach(){i.addDisposer(e,l.autorun((()=>{const n=r.getSession(e);if(r.getContainingView(e).initialized){if(e.regionCannotBeRendered())return;const a=[],o=[];for(const n of e.blockDefinitions.contentBlocks)a.push(n.key),t.includes(n.key)||o.push(n);n.apolloDataStore.loadFeatures(o.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))),n.apolloDataStore.loadRefSeq(o.map((({assemblyName:e,end:t,refName:n,start:a})=>({assemblyName:e,refName:n,start:a,end:t})))),t=a}}),{name:"SixFrameFeatureDisplay"}))}}})).views((e=>({get rendererTypeName(){return e.configuration.renderer.type},get changeManager(){const t=r.getSession(e);return t.apolloDataStore?.changeManager},get sequence(){const{regions:t}=e,n=r.getSession(e),a=new Map;for(const e of t){const t=n.apolloDataStore.assemblies.get(e.assemblyName),o=t?.getByRefName(e.refName),r=o?.getSequence(e.start,e.end);a.set(e.start,r??"")}return a},get features(){const{regions:t}=e,n=r.getSession(e),a=new Map;for(const e of t){const t=n.apolloDataStore.assemblies.get(e.assemblyName),o=t?.getByRefName(e.refName);let r=a.get(e.refName);r||(r=new Map,a.set(e.refName,r));for(const[t,n]of o?.features.entries()??new Map)e.start<n.end&&e.end>n.start&&r.set(t,n)}return a},get featuresMinMax(){const e={};for(const[t,n]of this.features||[]){let a,o;for(const[,e]of n)void 0===a&&({min:a}=e),void 0===o&&({max:o}=e),e.min<a&&({min:a}=e),e.end>o&&({max:o}=e);void 0!==a&&void 0!==o&&(e[t]=[a,o])}return e},get codonLayout(){const e=new Map;let t="",n=0;for(const[e,a]of this.sequence||[])a&&(t||(n=e),t+=a);for(let a=0;a<6;a++){const o=[],s=[],l=a in ma;let i,c,u;l?(i=(t.length+n)%3,c=(ma[a]+i+3)%3,u=r.reverse(t).slice(c)):(i=3-n%3,c=(fa[a]+i+3)%3,u=t.slice(c));for(let e=0;e<u.length;e+=3){const t=u.slice(e,e+3),a=l?r.reverse(r.revcom(t)):t,i=l?n+u.length-(3+e):n+e+c;r.defaultStarts.includes(a.toUpperCase())?o.push(i):r.defaultStops.includes(a.toUpperCase())&&s.push(i)}e.set(a,{starts:o,stops:s})}return e},get featureLayout(){const e=new Map;for(const[t,n]of this.features||[]){if(!n)continue;const a=this.featuresMinMax[t];if(!a)continue;const[o,r]=a,s=[],l=6;for(let t=0;t<l;t++){const t=s.length;s[t]=Array.from({length:r-o}),e.set(t,[])}for(const t of[...n.values()].sort(((e,t)=>{const{max:n,min:a}=e,{max:o,min:r}=t;return a-r||n-o})))for(const[,n]of t.children??new Map)if("mRNA"===n.type)for(const[,a]of n.children||new Map){let o;if("CDS"===a.type){let r;a.discontinuousLocations.length>0?({discontinuousLocations:r}=a):r=[a];for(const a of r){const r=a.start+3,s=a.end-3;for(const[l,{stops:i}]of this.codonLayout)if((l<3&&1===t.strand||l>=3&&-1===t.strand)&&0===i.filter((e=>e>=r&&e<=s)).length){o=l;const t=e.get(o);t?.push([n.featureId,a]);break}}}}}return e},getAssemblyId(t){const{assemblyManager:n}=r.getSession(e),a=n.get(t);if(!a)throw new Error(`Could not find assembly named ${t}`);return a.name},get selectedFeature(){return r.getSession(e).apolloSelectedFeature},get setSelectedFeature(){return r.getSession(e).apolloSetSelectedFeature}}))).actions((e=>({setSelectedFeature:t=>r.getSession(e).apolloSetSelectedFeature(t),setApolloFeatureUnderMouse(t){e.apolloFeatureUnderMouse=t},setApolloRowUnderMouse(t){e.apolloRowUnderMouse=t},toggleShowStartCodons(){e.showStartCodons=!e.showStartCodons},toggleShowStopCodons(){e.showStopCodons=!e.showStopCodons},toggleShowIntronLines(){e.showIntronLines=!e.showIntronLines}}))).views((e=>({get highestRow(){return 0===e.featureLayout.size?0:Math.max(...e.featureLayout.keys())},get featuresHeight(){return(this.highestRow+1)*e.apolloRowHeight},get detailsHeight(){return Math.max(e.detailsMinHeight,e.height-this.featuresHeight)},trackMenuItems:()=>[{label:"Show start codons",type:"checkbox",checked:e.showStartCodons,onClick:()=>e.toggleShowStartCodons()},{label:"Show stop codons",type:"checkbox",checked:e.showStopCodons,onClick:()=>e.toggleShowStopCodons()},{label:"Show intron lines",type:"checkbox",checked:e.showIntronLines,onClick:()=>e.toggleShowIntronLines()}]})))}const pa="WorkerGlobalScope"in globalThis;for(const[n,a]of Object.entries(t.changes))e.changeRegistry.registerChange(n,a);const ha=new t.CDSCheck;e.checkRegistry.registerCheck(ha.name,ha),t.validationRegistry.registerValidation(new t.CoreValidation),t.validationRegistry.registerValidation(new t.ParentChildValidation),exports.default=class extends Y.default{name="ApolloPlugin";version="1.2.3";configurationSchema=Xt;install(e){!function(e){e.addAdapterType((()=>new ge.default({name:"ApolloSequenceAdapter",configSchema:Ot,adapterMetadata:{category:void 0,hiddenFromGUI:!0,description:void 0},AdapterClass:Ut})))}(e),function(e){e.addTextSearchAdapterType((()=>new a.TextSearchAdapterType({name:"ApolloTextSearchAdapter",displayName:"Apollo text search adapter",configSchema:zt,AdapterClass:Wt,description:"Apollo Text Search adapter"})))}(e),e.addWidgetType((()=>{const e=n.ConfigurationSchema("ApolloFeatureDetailsWidget",{});return new a.WidgetType({name:"ApolloFeatureDetailsWidget",heading:"Apollo feature details",configSchema:e,stateModel:fn,ReactComponent:dn})})),e.addTrackType((()=>{const t=n.ConfigurationSchema("ApolloTrack",{adapter:""},{baseConfiguration:a.createBaseTrackConfig(e),explicitIdentifier:"trackId"});return new a.TrackType({name:"ApolloTrack",configSchema:t,stateModel:a.createBaseTrackModel(e,"ApolloTrack",t)})})),e.addInternetAccountType((()=>new a.InternetAccountType({name:"ApolloInternetAccount",configSchema:Ee,stateModel:Pt(Ee)}))),e.addDisplayType((()=>{const t=function(e){const t=e.getPlugin("LinearGenomeViewPlugin"),{baseLinearDisplayConfigSchema:a}=t.exports;return n.ConfigurationSchema("LinearApolloDisplay",{height:{type:"number",defaultValue:500}},{baseConfiguration:a,explicitlyTyped:!0})}(e);return new a.DisplayType({name:"LinearApolloDisplay",configSchema:t,stateModel:Kn(0,t),trackType:"ApolloTrack",viewType:"LinearGenomeView",ReactComponent:oa})})),e.addDisplayType((()=>{const t=function(e){const t=e.getPlugin("LinearGenomeViewPlugin"),{baseLinearDisplayConfigSchema:a}=t.exports;return n.ConfigurationSchema("SixFrameFeatureDisplay",{renderer:$t,height:{type:"number",defaultValue:120}},{baseConfiguration:a,explicitlyTyped:!0})}(e),o=function(e){const t=e.getPlugin("LinearGenomeViewPlugin");if(!t)throw new Error("LinearGenomeView plugin not found");const{BaseLinearDisplayComponent:n}=t.exports;return S.observer((function({model:e,...t}){const{classes:a}=ta(),{height:o,selectedFeature:r}=e;let{detailsHeight:s}=e;return r||(s=0),ae.default.createElement("div",{style:{height:e.height}},ae.default.createElement("div",{className:a.shading,style:{height:o-s}},ae.default.createElement(n,{model:e,...t})),ae.default.createElement("div",{className:"testTrackLines"},ae.default.createElement(ea,{model:e})))}))}(e);return new a.DisplayType({name:"SixFrameFeatureDisplay",configSchema:t,stateModel:ga(e,t),trackType:"ApolloTrack",viewType:"LinearGenomeView",ReactComponent:o})})),e.addRendererType((()=>new Gt({name:"ApolloSixFrameRenderer",ReactComponent:jt,configSchema:$t,pluginManager:e}))),e.addToExtensionPoint("Core-extendSession",da.bind(this,e)),e.addToExtensionPoint("Core-extendPluggableElement",(e=>{if("LinearGenomeView"===e.name){const{stateModel:t}=e,n=t.views((e=>{const t=e.rubberBandMenuItems;return{rubberBandMenuItems:()=>[...t(),{label:"Add new feature",icon:K.default,onClick:()=>{const t=r.getSession(e),{leftOffset:n,rightOffset:a}=e,o=e.getSelectedRegions(n,a);t.queueDialog((e=>[Vt,{session:t,handleClose:()=>{e()},region:o[0],changeManager:t.apolloDataStore.changeManager}]))}}]}}));e.stateModel=n}return e})),e.addToExtensionPoint("Core-extendPluggableElement",Yt),pa||e.addToExtensionPoint("Core-extendWorker",(t=>"on"in t&&t.on?(t.on("apollo",(async n=>{if("object"!=typeof(a=n)||null===a||!("apollo"in a)||!0!==a.apollo)return;var a;const{apollo:o,messageId:r,method:s}=n;switch(s){case"getSequence":{const{region:a}=n,{assemblyName:s}=a,l=e.rootModel?.session?.apolloDataStore;if(!l)break;const i=l.getBackendDriver(s),{seq:c}=await i.getSequence(a);t.workers[0].postMessage({apollo:o,messageId:r,sequence:c});break}case"getRegions":{const{assembly:a}=n,s=e.rootModel?.session?.apolloDataStore;if(!s)break;const l=s.getBackendDriver(a),i=await l.getRegions(a);t.workers[0].postMessage({apollo:o,messageId:r,regions:i});break}}})),t):t))}configure(e){r.isAbstractMenuManager(e.rootModel)&&(e.rootModel.appendToMenu("Apollo",{label:"Download GFF3",onClick:e=>{e.queueDialog((t=>[ut,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Manage Checks",onClick:e=>{e.queueDialog((t=>[ft,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"View Change Log",onClick:e=>{e.queueDialog((t=>[Ft,{session:e,handleClose:()=>{t()}}]))}}),e.rootModel.appendToMenu("Apollo",{label:"Open local GFF3 file",onClick:e=>{e.queueDialog((t=>[Ct,{session:e,handleClose:()=>{t()},inMemoryFileDriver:e.apolloDataStore.inMemoryFileDriver}]))}}),e.rootModel.appendToMenu("Apollo",{label:"View check results",onClick:e=>{e.queueDialog((t=>[Jt,{session:e,handleClose:()=>{t()}}]))}}))}};
|
|
2
2
|
//# sourceMappingURL=jbrowse-plugin-apollo.cjs.production.min.js.map
|