jbrowse-plugin-msaview 5.2.0 → 5.3.0
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/MsaViewPanel/model.d.ts +25 -29
- package/dist/chunks/AboutDialog-447TIFAW.js +2 -0
- package/dist/chunks/{AboutDialog-IRBPUPJK.js.map → AboutDialog-447TIFAW.js.map} +4 -4
- package/dist/chunks/AnnotationFileDialog-S3N5EHHE.js +2 -0
- package/dist/chunks/AnnotationFileDialog-S3N5EHHE.js.map +7 -0
- package/dist/chunks/ExportSVGDialog-7ZHKKQ7W.js +2 -0
- package/dist/chunks/ExportSVGDialog-7ZHKKQ7W.js.map +7 -0
- package/dist/chunks/{FeatureDialog-ZBX3XQZ5.js → FeatureDialog-EEOGSLOG.js} +1 -1
- package/dist/chunks/{FeatureDialog-ZBX3XQZ5.js.map → FeatureDialog-EEOGSLOG.js.map} +1 -1
- package/dist/chunks/HelpDialog-TCWNBZOV.js +2 -0
- package/dist/chunks/HelpDialog-TCWNBZOV.js.map +7 -0
- package/dist/chunks/{LaunchMsaViewDialog-GJAUPGFC.js → LaunchMsaViewDialog-R6CNRASN.js} +2 -2
- package/dist/chunks/{LaunchMsaViewDialog-GJAUPGFC.js.map → LaunchMsaViewDialog-R6CNRASN.js.map} +1 -1
- package/dist/chunks/MetadataDialog-MNSI6NEW.js +2 -0
- package/dist/chunks/{MetadataDialog-KZWQFRF7.js.map → MetadataDialog-MNSI6NEW.js.map} +2 -2
- package/dist/chunks/MsaViewPanel-R2WAER5O.js +2 -0
- package/dist/chunks/{MsaViewPanel-RUZAKFCB.js.map → MsaViewPanel-R2WAER5O.js.map} +1 -1
- package/dist/chunks/{TrackInfoDialog-IFIG77WO.js → TrackInfoDialog-W2F77IPG.js} +2 -2
- package/dist/chunks/{TrackInfoDialog-IFIG77WO.js.map → TrackInfoDialog-W2F77IPG.js.map} +1 -1
- package/dist/chunks/TreeNodeInfoDialog-T5XMPG3R.js +2 -0
- package/dist/chunks/{TreeNodeInfoDialog-VRCVIF26.js.map → TreeNodeInfoDialog-T5XMPG3R.js.map} +2 -2
- package/dist/chunks/chunk-6EOYBBT4.js +2 -0
- package/dist/chunks/chunk-6EOYBBT4.js.map +7 -0
- package/dist/chunks/chunk-A63PUWQZ.js +6 -0
- package/dist/chunks/chunk-A63PUWQZ.js.map +7 -0
- package/dist/chunks/{chunk-NI3VGKQP.js → chunk-BAM67QHH.js} +2 -2
- package/dist/chunks/chunk-CSCUNTGJ.js +18 -0
- package/dist/chunks/chunk-CSCUNTGJ.js.map +7 -0
- package/dist/chunks/chunk-DEFUNIWW.js +8 -0
- package/dist/chunks/chunk-DEFUNIWW.js.map +7 -0
- package/dist/chunks/{chunk-YOTSFJMU.js → chunk-ERCMNTEQ.js} +1 -1
- package/dist/chunks/{chunk-YOTSFJMU.js.map → chunk-ERCMNTEQ.js.map} +1 -1
- package/dist/chunks/{chunk-GDFVLZYX.js → chunk-FEUZKN5V.js} +2 -2
- package/dist/chunks/{chunk-GDFVLZYX.js.map → chunk-FEUZKN5V.js.map} +1 -1
- package/dist/chunks/{chunk-GIHMPOCO.js → chunk-JF6CW6MO.js} +1 -1
- package/dist/chunks/{chunk-GIHMPOCO.js.map → chunk-JF6CW6MO.js.map} +1 -1
- package/dist/chunks/chunk-K55ZVN73.js +5 -0
- package/dist/chunks/chunk-K55ZVN73.js.map +7 -0
- package/dist/chunks/chunk-L6CBIH6H.js +2 -0
- package/dist/chunks/chunk-L6CBIH6H.js.map +7 -0
- package/dist/chunks/{chunk-F3EC6OCO.js → chunk-NWHZOZMG.js} +1 -1
- package/dist/chunks/{chunk-F3EC6OCO.js.map → chunk-NWHZOZMG.js.map} +1 -1
- package/dist/chunks/chunk-OVAXNTPN.js +2 -0
- package/dist/chunks/chunk-OVAXNTPN.js.map +7 -0
- package/dist/chunks/chunk-TSHN6J7U.js +2 -0
- package/dist/chunks/chunk-TSHN6J7U.js.map +7 -0
- package/dist/chunks/{chunk-H6IQBAW7.js → chunk-WAPIOD25.js} +5 -5
- package/dist/chunks/{chunk-H6IQBAW7.js.map → chunk-WAPIOD25.js.map} +1 -1
- package/dist/chunks/chunk-XVNCZQMR.js +2 -0
- package/dist/chunks/{chunk-ZCT7RD24.js.map → chunk-XVNCZQMR.js.map} +1 -1
- package/dist/chunks/{dist-CMWKVHC7.js → dist-GXYZN4ZR.js} +2 -2
- package/dist/chunks/{dist-CMWKVHC7.js.map → dist-GXYZN4ZR.js.map} +3 -3
- package/dist/chunks/dist-N4ZJK63Q.js +2 -0
- package/dist/chunks/{model-VE7IYWNU.js → model-TCPB6WNJ.js} +2 -2
- package/dist/chunks/{model-VE7IYWNU.js.map → model-TCPB6WNJ.js.map} +1 -1
- package/dist/chunks/renderToSvg-53FEV6IJ.js +2 -0
- package/dist/jbrowse-plugin-msaview.esm.js +2 -2
- package/dist/jbrowse-plugin-msaview.esm.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/src/version.ts +1 -1
- package/dist/chunks/AboutDialog-IRBPUPJK.js +0 -2
- package/dist/chunks/AnnotationFileDialog-FCYYZ4JN.js +0 -2
- package/dist/chunks/AnnotationFileDialog-FCYYZ4JN.js.map +0 -7
- package/dist/chunks/ExportSVGDialog-TYYPI6VB.js +0 -2
- package/dist/chunks/ExportSVGDialog-TYYPI6VB.js.map +0 -7
- package/dist/chunks/MetadataDialog-KZWQFRF7.js +0 -2
- package/dist/chunks/MsaViewPanel-RUZAKFCB.js +0 -2
- package/dist/chunks/TreeNodeInfoDialog-VRCVIF26.js +0 -2
- package/dist/chunks/chunk-F726IWCW.js +0 -2
- package/dist/chunks/chunk-F726IWCW.js.map +0 -7
- package/dist/chunks/chunk-NMYD2GWF.js +0 -18
- package/dist/chunks/chunk-NMYD2GWF.js.map +0 -7
- package/dist/chunks/chunk-QQ5LZUIO.js +0 -11
- package/dist/chunks/chunk-QQ5LZUIO.js.map +0 -7
- package/dist/chunks/chunk-QUWPHTZQ.js +0 -2
- package/dist/chunks/chunk-QUWPHTZQ.js.map +0 -7
- package/dist/chunks/chunk-ZCT7RD24.js +0 -2
- package/dist/chunks/dist-R73J3CC3.js +0 -2
- package/dist/chunks/renderToSvg-VDXAB7TT.js +0 -2
- /package/dist/chunks/{chunk-NI3VGKQP.js.map → chunk-BAM67QHH.js.map} +0 -0
- /package/dist/chunks/{dist-R73J3CC3.js.map → dist-N4ZJK63Q.js.map} +0 -0
- /package/dist/chunks/{renderToSvg-VDXAB7TT.js.map → renderToSvg-53FEV6IJ.js.map} +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{g as p,i as ye}from"./chunks/chunk-JFL3LJPO.js";import{a as Me}from"./chunks/chunk-FCWXYIFC.js";import{d as h}from"./chunks/chunk-DECSTFAT.js";import{a as we}from"./chunks/chunk-NSASZ5FM.js";import{a as u,c as f,d as B}from"./chunks/chunk-IBBQUV2I.js";import{a as q}from"./chunks/chunk-2IWD4OO4.js";import{a as P}from"./chunks/chunk-CVLB4VFP.js";import{a as c}from"./chunks/chunk-J6KYLXRD.js";import{a as z,b as i}from"./chunks/chunk-FY3BTKY4.js";var R=z((Ge,D)=>{D.exports=JBrowseExports["@jbrowse/core/Plugin"]});var le=z((pt,me)=>{me.exports=JBrowseExports["@jbrowse/core/pluggableElementTypes/ViewType"]});var de=i(R()),j=i(q()),ge=i(u()),G=i(Me());var $=i(B(),1),O=(0,f.createSvgIcon)((0,$.jsx)("path",{d:"M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M8 20H4v-4h4zm0-6H4v-4h4zm0-6H4V4h4zm6 12h-4v-4h4zm0-6h-4v-4h4zm0-6h-4V4h4zm6 12h-4v-4h4zm0-6h-4v-4h4zm0-6h-4V4h4z"}),"GridOn");var Z=i(c()),ee=i(u());function M(e){return e.type==="MsaView"}var g=i(c()),X=i(P());var V=i(c()),J=i(u()),v=i(P());var _=i(we()),w=(0,_.makeStyles)()({highlight:{height:"100%",background:"rgba(255,255,0,0.2)",border:"1px solid rgba(50,50,0,0.2)",position:"absolute",zIndex:99,textAlign:"center",pointerEvents:"none",overflow:"hidden"}});var be=(0,v.observer)(function({model:e}){let{hovered:t,views:r}=(0,J.getSession)(e);return r.some(o=>M(o)&&o.connectedViewId===e.id)&&p(t)?V.default.createElement(xe,{model:e,hovered:t}):null}),xe=(0,v.observer)(function({model:e,hovered:t}){let{classes:r}=w(),{offsetPx:n}=e,{coord:o,refName:s}=t.hoverPosition,a=e.bpToPx({refName:s,coord:o-1}),m=e.bpToPx({refName:s,coord:o});if(a&&m){let l=Math.max(Math.abs(m.offsetPx-a.offsetPx),4),b=Math.min(a.offsetPx,m.offsetPx)-n;return V.default.createElement("div",{className:r.highlight,style:{left:b,width:l}})}return null}),W=be;var d=i(c()),K=i(u()),T=i(P());function U(e,t,r){let n=e.filter(Pe).filter(o=>o.connectedViewId===t).flatMap(o=>[...o.connectedClickHighlights,...r?[]:o.connectedHoverHighlights]);return[...new Map(n.map(o=>[`${o.refName}:${o.start}-${o.end}`,o])).values()]}function Pe(e){return e.type==="MsaView"}var Ve=(0,T.observer)(function({model:t}){let{views:r,hovered:n}=(0,K.getSession)(t),o=U(r,t.id,p(n));return o.length?d.default.createElement(ve,{model:t,highlights:o}):null}),ve=(0,T.observer)(function({model:e,highlights:t}){let{classes:r}=w(),{offsetPx:n}=e;return d.default.createElement(d.default.Fragment,null,t.map(o=>{let s=e.bpToPx({refName:o.refName,coord:o.start}),a=e.bpToPx({refName:o.refName,coord:o.end});if(s&&a){let m=Math.max(Math.abs(a.offsetPx-s.offsetPx),4),l=Math.min(s.offsetPx,a.offsetPx)-n;return d.default.createElement("div",{key:`${o.refName}-${o.start}-${o.end}`,className:r.highlight,style:{left:l,width:m}})}return null}))}),Q=Ve;var Te=(0,X.observer)(function({model:t}){return g.default.createElement(g.default.Fragment,null,g.default.createElement(Q,{model:t}),g.default.createElement(W,{model:t}))}),Y=Te;function S(e){e.contributeToExtensionPoint("LinearGenomeView-TracksContainerComponent",({model:t})=>{let{views:r}=(0,ee.getSession)(t);return r.some(n=>M(n)&&n.connectedViewId===t.id)?Z.default.createElement(Y,{key:"highlight_protein_viewer_msaview",model:t}):void 0})}var oe=i(ye());var te=i(q());function F(e){let t=e.getAdapterType("BgzipFastaAdapter");return(0,te.ConfigurationSchema)("BgzipFastaMsaAdapter",{msaRegex:{type:"string",defaultValue:"_"}},{baseConfiguration:t.configSchema})}function L(e){return e.addAdapterType(()=>new oe.AdapterType({name:"BgzipFastaMsaAdapter",configSchema:F(e),adapterMetadata:{hiddenFromGUI:!0},getAdapterClass:()=>import("./chunks/BgzipFastaMsaAdapter-WWIGI57O.js").then(t=>t.default)}))}var se=i(c()),y=i(u());var re=i(B(),1),ne=(0,f.createSvgIcon)((0,re.jsx)("path",{d:"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z"}),"Add");function Se(e){return e.get("type")?.toLowerCase()==="cds"}function I(e){return Se(e)||!!e.get("subfeatures")?.some(I)}var ie=i(u());function ae(e){let t=e.contextMenuInfo;return t&&(0,ie.isGeneLikeType)(t.item.type)?{fetchFeature:()=>e.fetchFullFeature(t.item.featureId,t.displayedRegionIndex),preferredTranscriptId:t.subfeature?.featureId}:void 0}var Fe=(0,se.lazy)(()=>import("./chunks/LaunchMsaViewDialog-
|
|
2
|
-
`)?e:void 0,o=t?.trimStart().startsWith("(")?t:void 0,s=n||o?{...r.data,...n?{msa:n}:{},...o?{tree:o}:{}}:r.data;return{...r,data:s,...e&&!n?{msaFileLocation:{uri:e}}:{},...t&&!o?{treeFileLocation:{uri:t}}:{},querySeqName:r.querySeqName??r.query}}function C(e){e.addToExtensionPoint("LaunchView-MsaView",async t=>{let{session:r,query:n,data:o,msaFileLocation:s,msaIndexedLocation:a,msaName:m,treeFileLocation:l,querySeqName:b,searchParams:x,...N}=He(t);if(!o&&!s&&!a&&!N.orthologParams&&!x)throw new Error("No MSA data, file location, orthologParams or searchParams provided when launching MSA view");let E={msaUrl:s?.uri,msaIndexedLocation:a,msaName:m,querySeqName:b},{expandSpec:fe}=await import("./chunks/dist-
|
|
1
|
+
import{g as p,i as ye}from"./chunks/chunk-JFL3LJPO.js";import{a as Me}from"./chunks/chunk-FCWXYIFC.js";import{d as h}from"./chunks/chunk-DECSTFAT.js";import{a as we}from"./chunks/chunk-NSASZ5FM.js";import{a as u,c as f,d as B}from"./chunks/chunk-IBBQUV2I.js";import{a as q}from"./chunks/chunk-2IWD4OO4.js";import{a as P}from"./chunks/chunk-CVLB4VFP.js";import{a as c}from"./chunks/chunk-J6KYLXRD.js";import{a as z,b as i}from"./chunks/chunk-FY3BTKY4.js";var R=z((Ge,D)=>{D.exports=JBrowseExports["@jbrowse/core/Plugin"]});var le=z((pt,me)=>{me.exports=JBrowseExports["@jbrowse/core/pluggableElementTypes/ViewType"]});var de=i(R()),j=i(q()),ge=i(u()),G=i(Me());var $=i(B(),1),O=(0,f.createSvgIcon)((0,$.jsx)("path",{d:"M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M8 20H4v-4h4zm0-6H4v-4h4zm0-6H4V4h4zm6 12h-4v-4h4zm0-6h-4v-4h4zm0-6h-4V4h4zm6 12h-4v-4h4zm0-6h-4v-4h4zm0-6h-4V4h4z"}),"GridOn");var Z=i(c()),ee=i(u());function M(e){return e.type==="MsaView"}var g=i(c()),X=i(P());var V=i(c()),J=i(u()),v=i(P());var _=i(we()),w=(0,_.makeStyles)()({highlight:{height:"100%",background:"rgba(255,255,0,0.2)",border:"1px solid rgba(50,50,0,0.2)",position:"absolute",zIndex:99,textAlign:"center",pointerEvents:"none",overflow:"hidden"}});var be=(0,v.observer)(function({model:e}){let{hovered:t,views:r}=(0,J.getSession)(e);return r.some(o=>M(o)&&o.connectedViewId===e.id)&&p(t)?V.default.createElement(xe,{model:e,hovered:t}):null}),xe=(0,v.observer)(function({model:e,hovered:t}){let{classes:r}=w(),{offsetPx:n}=e,{coord:o,refName:s}=t.hoverPosition,a=e.bpToPx({refName:s,coord:o-1}),m=e.bpToPx({refName:s,coord:o});if(a&&m){let l=Math.max(Math.abs(m.offsetPx-a.offsetPx),4),b=Math.min(a.offsetPx,m.offsetPx)-n;return V.default.createElement("div",{className:r.highlight,style:{left:b,width:l}})}return null}),W=be;var d=i(c()),K=i(u()),T=i(P());function U(e,t,r){let n=e.filter(Pe).filter(o=>o.connectedViewId===t).flatMap(o=>[...o.connectedClickHighlights,...r?[]:o.connectedHoverHighlights]);return[...new Map(n.map(o=>[`${o.refName}:${o.start}-${o.end}`,o])).values()]}function Pe(e){return e.type==="MsaView"}var Ve=(0,T.observer)(function({model:t}){let{views:r,hovered:n}=(0,K.getSession)(t),o=U(r,t.id,p(n));return o.length?d.default.createElement(ve,{model:t,highlights:o}):null}),ve=(0,T.observer)(function({model:e,highlights:t}){let{classes:r}=w(),{offsetPx:n}=e;return d.default.createElement(d.default.Fragment,null,t.map(o=>{let s=e.bpToPx({refName:o.refName,coord:o.start}),a=e.bpToPx({refName:o.refName,coord:o.end});if(s&&a){let m=Math.max(Math.abs(a.offsetPx-s.offsetPx),4),l=Math.min(s.offsetPx,a.offsetPx)-n;return d.default.createElement("div",{key:`${o.refName}-${o.start}-${o.end}`,className:r.highlight,style:{left:l,width:m}})}return null}))}),Q=Ve;var Te=(0,X.observer)(function({model:t}){return g.default.createElement(g.default.Fragment,null,g.default.createElement(Q,{model:t}),g.default.createElement(W,{model:t}))}),Y=Te;function S(e){e.contributeToExtensionPoint("LinearGenomeView-TracksContainerComponent",({model:t})=>{let{views:r}=(0,ee.getSession)(t);return r.some(n=>M(n)&&n.connectedViewId===t.id)?Z.default.createElement(Y,{key:"highlight_protein_viewer_msaview",model:t}):void 0})}var oe=i(ye());var te=i(q());function F(e){let t=e.getAdapterType("BgzipFastaAdapter");return(0,te.ConfigurationSchema)("BgzipFastaMsaAdapter",{msaRegex:{type:"string",defaultValue:"_"}},{baseConfiguration:t.configSchema})}function L(e){return e.addAdapterType(()=>new oe.AdapterType({name:"BgzipFastaMsaAdapter",configSchema:F(e),adapterMetadata:{hiddenFromGUI:!0},getAdapterClass:()=>import("./chunks/BgzipFastaMsaAdapter-WWIGI57O.js").then(t=>t.default)}))}var se=i(c()),y=i(u());var re=i(B(),1),ne=(0,f.createSvgIcon)((0,re.jsx)("path",{d:"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z"}),"Add");function Se(e){return e.get("type")?.toLowerCase()==="cds"}function I(e){return Se(e)||!!e.get("subfeatures")?.some(I)}var ie=i(u());function ae(e){let t=e.contextMenuInfo;return t&&(0,ie.isGeneLikeType)(t.item.type)?{fetchFeature:()=>e.fetchFullFeature(t.item.featureId,t.displayedRegionIndex),preferredTranscriptId:t.subfeature?.featureId}:void 0}var Fe=(0,se.lazy)(()=>import("./chunks/LaunchMsaViewDialog-R6CNRASN.js"));function Le(e){return e.name==="LinearBasicDisplay"}function Ie(e){return e.get("name")??e.get("id")??"This feature"}function Ae(e,t){let r=(0,y.getContainingTrack)(e),n=(0,y.getSession)(r),{preferredTranscriptId:o}=t,s=a=>{n.queueDialog(m=>[Fe,{model:r,handleClose:m,feature:a,preferredTranscriptId:o}])};t.fetchFeature().then(a=>{a?I(a)?s(a):n.notify(`${Ie(a)} has no coding sequence, so there is no protein to align`,"info"):n.notify("Could not load feature for MSA view","warning")}).catch(a=>{n.notifyError(`${a}`,a)})}function Ce(e){return e.views(t=>{let r=t.contextMenuItems;return{contextMenuItems(){let n=ae(t);return[...r.call(t),...n?[{label:"Launch MSA view",icon:ne,onClick:()=>{Ae(t,n)}}]:[]]}}})}function A(e){e.addToExtensionPoint("Core-extendPluggableElement",t=>(Le(t)&&(t.stateModel=Ce(t.stateModel)),t))}function He({msa:e,tree:t,...r}){let n=e?.includes(`
|
|
2
|
+
`)?e:void 0,o=t?.trimStart().startsWith("(")?t:void 0,s=n||o?{...r.data,...n?{msa:n}:{},...o?{tree:o}:{}}:r.data;return{...r,data:s,...e&&!n?{msaFileLocation:{uri:e}}:{},...t&&!o?{treeFileLocation:{uri:t}}:{},querySeqName:r.querySeqName??r.query}}function C(e){e.addToExtensionPoint("LaunchView-MsaView",async t=>{let{session:r,query:n,data:o,msaFileLocation:s,msaIndexedLocation:a,msaName:m,treeFileLocation:l,querySeqName:b,searchParams:x,...N}=He(t);if(!o&&!s&&!a&&!N.orthologParams&&!x)throw new Error("No MSA data, file location, orthologParams or searchParams provided when launching MSA view");let E={msaUrl:s?.uri,msaIndexedLocation:a,msaName:m,querySeqName:b},{expandSpec:fe}=await import("./chunks/dist-N4ZJK63Q.js");return await h(r,{...fe({...N,query:n}),...x?{blastParams:x}:{},data:o,...l?{treeFilehandle:{...l,locationType:"UriLocation"}}:{},...Object.values(E).some(he=>he!==void 0)?{init:E}:{}}),t})}var ue=i(c()),ce=i(le()),je=(0,ue.lazy)(()=>import("./chunks/MsaViewPanel-R2WAER5O.js"));function H(e){e.addViewType(()=>new ce.default({name:"MsaView",stateModel:()=>import("./chunks/model-TCPB6WNJ.js").then(t=>t.default()),ReactComponent:je}))}var pe="5.3.0";var k=class extends de.default{constructor(){super(...arguments);this.name="MsaViewPlugin";this.version=pe;this.rootConfigurationSchema=r=>({msa:(0,j.ConfigurationSchema)("MSA",{datasets:G.types.maybe(G.types.array((0,j.ConfigurationSchema)("MSAEntry",{datasetId:{type:"string",defaultValue:""},description:{type:"string",defaultValue:""},name:{type:"string",defaultValue:""},adapter:r.pluggableConfigSchemaType("adapter")})))})})}install(r){H(r),A(r),C(r),S(r),L(r)}configure(r){try{(0,ge.isAbstractMenuManager)(r.rootModel)&&r.rootModel.appendToSubMenu(["Add"],{label:"Multiple sequence alignment view",icon:O,onClick:n=>{h(n,{}).catch(o=>{console.error(o),n.notifyError(`${o}`,o)})}})}catch(n){console.error("jbrowse-plugin-msaview: could not add the Add menu item",n)}}};export{k as default};
|
|
3
3
|
//# sourceMappingURL=jbrowse-plugin-msaview.esm.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["global-externals:@jbrowse/core/Plugin", "global-externals:@jbrowse/core/pluggableElementTypes/ViewType", "../src/index.ts", "../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/GridOn.mjs", "../src/AddHighlightModel/index.tsx", "../src/MsaViewPanel/isMsaView.ts", "../src/AddHighlightModel/HighlightComponents.tsx", "../src/AddHighlightModel/GenomeMouseoverHighlight.tsx", "../src/AddHighlightModel/util.ts", "../src/AddHighlightModel/MsaToGenomeHighlight.tsx", "../src/AddHighlightModel/connectedHighlights.ts", "../src/BgzipFastaMsaAdapter/index.ts", "../src/BgzipFastaMsaAdapter/configSchema.ts", "../src/LaunchMsaView/index.ts", "../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Add.mjs", "../src/LaunchMsaView/codingFeature.ts", "../src/LaunchMsaView/launchTarget.ts", "../src/LaunchMsaViewExtensionPoint/index.ts", "../src/MsaViewPanel/index.ts", "../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["module.exports = JBrowseExports[\"@jbrowse/core/Plugin\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/ViewType\"];", "import Plugin from '@jbrowse/core/Plugin'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { isAbstractMenuManager } from '@jbrowse/core/util'\nimport { types } from '@jbrowse/mobx-state-tree'\nimport GridOn from '@mui/icons-material/GridOn'\n\nimport AddHighlightModelF from './AddHighlightModel'\nimport BgzipFastaMsaAdapterF from './BgzipFastaMsaAdapter'\nimport LaunchMsaViewF from './LaunchMsaView'\nimport LaunchMsaViewExtensionPointF from './LaunchMsaViewExtensionPoint'\nimport MsaViewF from './MsaViewPanel'\nimport { launchMsaView } from './utils/launchMsaView'\nimport { version } from './version'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\n\nexport default class MsaViewPlugin extends Plugin {\n name = 'MsaViewPlugin'\n version = version\n\n install(pluginManager: PluginManager) {\n MsaViewF(pluginManager)\n LaunchMsaViewF(pluginManager)\n LaunchMsaViewExtensionPointF(pluginManager)\n AddHighlightModelF(pluginManager)\n BgzipFastaMsaAdapterF(pluginManager)\n }\n\n configure(pluginManager: PluginManager) {\n // a throw here error-pages the whole app, and a menu entry is not worth a\n // session\n try {\n if (isAbstractMenuManager(pluginManager.rootModel)) {\n pluginManager.rootModel.appendToSubMenu(['Add'], {\n label: 'Multiple sequence alignment view',\n icon: GridOn,\n onClick: (session: AbstractSessionModel) => {\n // stacked, by default: nothing was launched from, so there is no\n // connected view for it to sit beside\n launchMsaView(session, {}).catch((e: unknown) => {\n console.error(e)\n session.notifyError(`${e}`, e)\n })\n },\n })\n }\n } catch (e) {\n console.error(\n 'jbrowse-plugin-msaview: could not add the Add menu item',\n e,\n )\n }\n }\n\n rootConfigurationSchema = (pluginManager: PluginManager) => {\n return {\n msa: ConfigurationSchema('MSA', {\n datasets: types.maybe(\n types.array(\n ConfigurationSchema('MSAEntry', {\n datasetId: {\n type: 'string',\n defaultValue: '',\n },\n description: {\n type: 'string',\n defaultValue: '',\n },\n name: {\n type: 'string',\n defaultValue: '',\n },\n adapter: pluginManager.pluggableConfigSchemaType('adapter'),\n }),\n ),\n ),\n }),\n }\n }\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M8 20H4v-4h4zm0-6H4v-4h4zm0-6H4V4h4zm6 12h-4v-4h4zm0-6h-4v-4h4zm0-6h-4V4h4zm6 12h-4v-4h4zm0-6h-4v-4h4zm0-6h-4V4h4z\"\n}), 'GridOn');", "import React from 'react'\n\nimport { getSession } from '@jbrowse/core/util'\n\nimport { isMsaView } from '../MsaViewPanel/isMsaView'\nimport HighlightComponents from './HighlightComponents'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function AddHighlightComponentsModelF(\n pluginManager: PluginManager,\n) {\n pluginManager.contributeToExtensionPoint(\n 'LinearGenomeView-TracksContainerComponent',\n ({ model }) => {\n const { views } = getSession(model)\n return views.some(v => isMsaView(v) && v.connectedViewId === model.id) ? (\n <HighlightComponents\n key=\"highlight_protein_viewer_msaview\"\n model={model}\n />\n ) : undefined\n },\n )\n}\n", "import type { JBrowsePluginMsaViewModel } from './model'\n\nexport function isMsaView(view: {\n type: string\n}): view is JBrowsePluginMsaViewModel {\n return view.type === 'MsaView'\n}\n", "import React from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport GenomeMouseoverHighlight from './GenomeMouseoverHighlight'\nimport MsaToGenomeHighlight from './MsaToGenomeHighlight'\n\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\ntype LGV = LinearGenomeViewModel\n\nconst HighlightComponents = observer(function HighlightComponents2({\n model,\n}: {\n model: LGV\n}) {\n return (\n <>\n <MsaToGenomeHighlight model={model} />\n <GenomeMouseoverHighlight model={model} />\n </>\n )\n})\n\nexport default HighlightComponents\n", "import React from 'react'\n\nimport { getSession } from '@jbrowse/core/util'\nimport { observer } from 'mobx-react'\n\nimport { isMsaView } from '../MsaViewPanel/isMsaView'\nimport { hasHoverPosition, useStyles } from './util'\n\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\nconst GenomeMouseoverHighlight = observer(function ({\n model,\n}: {\n model: LinearGenomeViewModel\n}) {\n const { hovered, views } = getSession(model)\n const hasMsaView = views.some(\n s => isMsaView(s) && s.connectedViewId === model.id,\n )\n return hasMsaView && hasHoverPosition(hovered) ? (\n <GenomeMouseoverHighlightRenderer model={model} hovered={hovered} />\n ) : null\n})\n\nconst GenomeMouseoverHighlightRenderer = observer(function ({\n model,\n hovered,\n}: {\n model: LinearGenomeViewModel\n hovered: { hoverPosition: { coord: number; refName: string } }\n}) {\n const { classes } = useStyles()\n const { offsetPx } = model\n const { coord, refName } = hovered.hoverPosition\n\n const s = model.bpToPx({ refName, coord: coord - 1 })\n const e = model.bpToPx({ refName, coord })\n\n if (s && e) {\n const width = Math.max(Math.abs(e.offsetPx - s.offsetPx), 4)\n const left = Math.min(s.offsetPx, e.offsetPx) - offsetPx\n return <div className={classes.highlight} style={{ left, width }} />\n }\n\n return null\n})\n\nexport default GenomeMouseoverHighlight\n", "import { makeStyles } from 'tss-react/mui'\n\nexport { hasHoverPosition } from '../MsaViewPanel/util'\n\nexport const useStyles = makeStyles()({\n highlight: {\n height: '100%',\n background: 'rgba(255,255,0,0.2)',\n border: '1px solid rgba(50,50,0,0.2)',\n position: 'absolute',\n zIndex: 99,\n textAlign: 'center',\n pointerEvents: 'none',\n overflow: 'hidden',\n },\n})\n", "import React from 'react'\n\nimport { getSession } from '@jbrowse/core/util'\nimport { observer } from 'mobx-react'\n\nimport { connectedHighlights } from './connectedHighlights'\nimport { hasHoverPosition, useStyles } from './util'\n\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\ntype LGV = LinearGenomeViewModel\n\nconst MsaToGenomeHighlight = observer(function MsaToGenomeHighlight2({\n model,\n}: {\n model: LGV\n}) {\n const { views, hovered } = getSession(model)\n const highlights = connectedHighlights(\n views,\n model.id,\n hasHoverPosition(hovered),\n )\n\n return highlights.length ? (\n <MsaToGenomeHighlightRenderer model={model} highlights={highlights} />\n ) : null\n})\n\nconst MsaToGenomeHighlightRenderer = observer(function ({\n model,\n highlights,\n}: {\n model: LGV\n highlights: { refName: string; start: number; end: number }[]\n}) {\n const { classes } = useStyles()\n const { offsetPx } = model\n\n return (\n <>\n {highlights.map(r => {\n // bpToPx matches refNames exactly, so canonicalizing \"chr17\" to \"17\"\n // would miss a view whose regions say \"chr17\"\n const s = model.bpToPx({ refName: r.refName, coord: r.start })\n const e = model.bpToPx({ refName: r.refName, coord: r.end })\n if (s && e) {\n const width = Math.max(Math.abs(e.offsetPx - s.offsetPx), 4)\n const left = Math.min(s.offsetPx, e.offsetPx) - offsetPx\n return (\n <div\n key={`${r.refName}-${r.start}-${r.end}`}\n className={classes.highlight}\n style={{ left, width }}\n />\n )\n }\n return null\n })}\n </>\n )\n})\n\nexport default MsaToGenomeHighlight\n", "interface Region {\n refName: string\n start: number\n end: number\n}\n\ninterface LinkedView {\n type: string\n connectedViewId?: string\n connectedClickHighlights: Region[]\n connectedHoverHighlights: Region[]\n}\n\nexport function connectedHighlights(\n views: readonly { type: string }[],\n genomeViewId: string,\n genomeHovered: boolean,\n) {\n const regions = views\n .filter(isLinkedMsaView)\n .filter(v => v.connectedViewId === genomeViewId)\n .flatMap(v => [\n ...v.connectedClickHighlights,\n ...(genomeHovered ? [] : v.connectedHoverHighlights),\n ])\n return [\n ...new Map(\n regions.map(r => [`${r.refName}:${r.start}-${r.end}`, r]),\n ).values(),\n ]\n}\n\nfunction isLinkedMsaView(view: { type: string }): view is LinkedView {\n return view.type === 'MsaView'\n}\n", "import { AdapterType } from '@jbrowse/core/pluggableElementTypes'\n\nimport configSchemaF from './configSchema'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function BgzipFastaMsaAdapterF(pluginManager: PluginManager) {\n return pluginManager.addAdapterType(() => {\n return new AdapterType({\n name: 'BgzipFastaMsaAdapter',\n configSchema: configSchemaF(pluginManager),\n adapterMetadata: {\n hiddenFromGUI: true,\n },\n getAdapterClass: () =>\n import('./BgzipFastaMsaAdapter').then(t => t.default),\n })\n })\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function configSchemaF(pluginManager: PluginManager) {\n const base = pluginManager.getAdapterType('BgzipFastaAdapter')\n return ConfigurationSchema(\n 'BgzipFastaMsaAdapter',\n {\n msaRegex: {\n type: 'string',\n defaultValue: '_',\n },\n },\n {\n baseConfiguration: base.configSchema,\n },\n )\n}\n", "import { lazy } from 'react'\n\nimport { getContainingTrack, getSession } from '@jbrowse/core/util'\nimport AddIcon from '@mui/icons-material/Add'\n\nimport { isCodingFeature } from './codingFeature'\nimport { launchTarget } from './launchTarget'\n\nimport type { DisplayModel, MenuTarget } from './launchTarget'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { PluggableElementType } from '@jbrowse/core/pluggableElementTypes'\nimport type DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\nimport type { Feature } from '@jbrowse/core/util'\nimport type { IAnyModelType } from '@jbrowse/mobx-state-tree'\n\nconst LaunchMsaViewDialog = lazy(\n () => import('./components/LaunchMsaViewDialog'),\n)\n\nfunction isDisplay(elt: { name: string }): elt is DisplayType {\n return elt.name === 'LinearBasicDisplay'\n}\n\n// Walking to the track and the session at click time, not while the menu is\n// built: contextMenuItems runs on every right-click and, on a host whose base\n// method reads `this`, is the one place a plugin can take the whole menu down.\n// Keeping it to a pure read of the display is also what lets a test call it.\nfunction featureName(feature: Feature) {\n return feature.get('name') ?? feature.get('id') ?? 'This feature'\n}\n\nfunction openDialog(self: DisplayModel, target: MenuTarget) {\n const track = getContainingTrack(self)\n const session = getSession(track)\n const { preferredTranscriptId } = target\n const open = (feature: Feature) => {\n session.queueDialog(handleClose => [\n LaunchMsaViewDialog,\n { model: track, handleClose, feature, preferredTranscriptId },\n ])\n }\n target\n .fetchFeature()\n .then(feature => {\n if (!feature) {\n session.notify('Could not load feature for MSA view', 'warning')\n } else if (!isCodingFeature(feature)) {\n // the canvas hit test carries a type and nothing else, so this is the\n // first point at which the CDS can be looked for. Saying so beats\n // opening a dialog whose Submit never leaves grey.\n session.notify(\n `${featureName(feature)} has no coding sequence, so there is no protein to align`,\n 'info',\n )\n } else {\n open(feature)\n }\n })\n .catch((e: unknown) => {\n session.notifyError(`${e}`, e)\n })\n}\n\nexport function extendStateModel(stateModel: IAnyModelType) {\n return stateModel.views((self: DisplayModel) => {\n const superContextMenuItems = self.contextMenuItems\n return {\n contextMenuItems() {\n const target = launchTarget(self)\n return [\n // a detached call leaves `this` undefined for a host method that\n // reads it, and the throw takes the host's own rows with it\n ...superContextMenuItems.call(self),\n ...(target\n ? [\n {\n label: 'Launch MSA view',\n icon: AddIcon,\n onClick: () => {\n openDialog(self, target)\n },\n },\n ]\n : []),\n ]\n },\n }\n })\n}\n\nexport default function LaunchMsaViewF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint(\n 'Core-extendPluggableElement',\n (elt: PluggableElementType) => {\n if (isDisplay(elt)) {\n elt.stateModel = extendStateModel(elt.stateModel)\n }\n return elt\n },\n )\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z\"\n}), 'Add');", "import type { Feature } from '@jbrowse/core/util'\n\nfunction isCDS(feature: Feature) {\n return feature.get('type')?.toLowerCase() === 'cds'\n}\n\n// The feature itself counts: a viral polyprotein hangs its cleavage products\n// off its CDS rather than off further CDSs.\nexport function isCodingFeature(feature: Feature): boolean {\n return isCDS(feature) || !!feature.get('subfeatures')?.some(isCodingFeature)\n}\n", "import { isGeneLikeType } from '@jbrowse/core/util'\n\nimport type { MenuItem } from '@jbrowse/core/ui'\nimport type { Feature } from '@jbrowse/core/util'\n\nexport interface ContextMenuInfo {\n item: { featureId: string; type?: string }\n // the isoform under the pointer when the click landed on a gene's child\n subfeature?: { featureId: string }\n displayedRegionIndex: number\n}\n\nexport interface DisplayModel {\n contextMenuItems: () => MenuItem[]\n contextMenuInfo?: ContextMenuInfo\n fetchFullFeature: (\n featureId: string,\n displayedRegionIndex: number,\n ) => Promise<Feature | undefined>\n}\n\n/**\n * What the menu item launches on. The hit test carries a type and an id, so\n * whether the feature codes for anything can only be answered after the fetch,\n * and the caller answers it there.\n */\nexport interface MenuTarget {\n fetchFeature: () => Promise<Feature | undefined>\n /**\n * The isoform the click actually landed on, when the dialog opens on its\n * gene. Climbing to the gene is what puts every isoform in the picker, and it\n * threw away which one the user pointed at: the picker then opened on the\n * longest transcript.\n */\n preferredTranscriptId?: string\n}\n\n// Read off the clicked item rather than off the display: LinearBasicDisplay's\n// `isGeneLike` getter was inlined into its own `contextMenuItems`\n// (jbrowse-components 684142b3), and gating on it silently took the item off\n// every gene track.\nexport function launchTarget(self: DisplayModel): MenuTarget | undefined {\n const info = self.contextMenuInfo\n return info && isGeneLikeType(info.item.type)\n ? {\n fetchFeature: () =>\n self.fetchFullFeature(info.item.featureId, info.displayedRegionIndex),\n preferredTranscriptId: info.subfeature?.featureId,\n }\n : undefined\n}\n", "import { launchMsaView } from '../utils/launchMsaView'\n\nimport type { BlastParams, OrthologParams } from '../MsaViewPanel/model'\nimport type { MsaViewPlacement } from '../utils/workspaces'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\nimport type {\n Clade,\n ColumnTrackShorthand,\n Encoding,\n HighlightShorthand,\n RegionShorthand,\n ResidueMapping,\n RowPanelSpec,\n} from 'react-msaview'\n\ninterface LaunchMsaViewArgs {\n session: AbstractSessionModel\n /**\n * Shorthand, see react-msaview's docs/layers.md: `msa` and `tree` take a\n * url or the text itself, and `query` names the row the spec is about, the\n * `querySeqName` and the `row` of every highlight, region and column track\n * that names none\n */\n msa?: string\n tree?: string\n query?: string\n data?: { msa: string; tree?: string }\n msaFileLocation?: { uri: string }\n msaIndexedLocation?: { uri: string }\n msaName?: string\n treeFileLocation?: { uri: string }\n connectedViewId?: string\n connectedFeature?: Record<string, unknown>\n /**\n * The short form of `connectedFeature`: a transcript id looked up in the\n * connected genome view's open tracks at launch, and translated to become\n * the query row of a `searchParams` or `orthologParams` launch that names\n * no `proteinSequence` of its own.\n */\n connectedTranscript?: string\n displayName?: string\n colorSchemeName?: string\n colWidth?: number\n rowHeight?: number\n treeAreaWidth?: number\n treeWidth?: number\n drawNodeBubbles?: boolean\n labelsAlignRight?: boolean\n showBranchLen?: boolean\n querySeqName?: string\n /**\n * Transcript residues before the query row's first residue, for a row that\n * carries only part of the protein -- what BLAST reports when it trims the\n * query to the aligned region. Genome navigation is off by this much without\n * it.\n */\n querySeqOffset?: number\n highlightColumns?: number[]\n /**\n * Labeled highlights in 1-based inclusive coordinates: `{row, start, end}`\n * for residues of that row, `{start, end}` for alignment columns, `{rows}`\n * for whole rows. Prefer this over `highlightColumns`: a residue range stays\n * put when `allowedGappyness` changes the visible columns.\n */\n highlights?: HighlightShorthand[]\n /** per-column tracks supplied as data, see react-msaview's docs/layers.md */\n columnTracks?: ColumnTrackShorthand[]\n /**\n * Where the view opens, in `highlights` coordinates: `{row, start, end}`\n * zooms onto residues of that row, `{start, end}` onto alignment columns.\n * Applied once the alignment has loaded, then dropped from the session.\n */\n region?: RegionShorthand\n /**\n * Passed through untouched as react-msaview snapshot properties; see its\n * docs/layers.md. A bare `{ uri }` is enough for the two filehandles.\n */\n clades?: Clade[]\n encodings?: Encoding[]\n rowPanels?: RowPanelSpec[]\n relativeTo?: string\n residueMappings?: ResidueMapping[]\n trackHeights?: Record<string, number>\n turnedOffFeatures?: Record<string, boolean>\n gffFilehandle?: { uri: string }\n treeMetadataFilehandle?: { uri: string }\n /**\n * Build the alignment from NCBI orthologs at launch time instead of naming a\n * file: `{ taxId, geneCandidates }` is enough, and `taxa` and\n * `proteinSequence` both default (see OrthologParams). This is the launch\n * dialog's Orthologs tab, reachable from a session spec \u2014 so a link can say\n * \"NLRP1 across species\" and the view builds it.\n */\n orthologParams?: OrthologParams\n /**\n * Search for the alignment at launch: the dialog's BLAST tab reached\n * declaratively. `{ searchProgram: 'phmmer', blastDatabase: 'rp15',\n * accession: 'P04637' }` is a whole request. The query comes from\n * `proteinSequence`, else fetched for `accession`, else translated from the\n * view's `connectedTranscript`. Stored on the model as `blastParams`, the\n * name the dialog has always used.\n */\n searchParams?: BlastParams\n /**\n * Hide any column gappier than this percentage, 100 being \"hide nothing\".\n * A native react-msaview property, named here because it is the one setting\n * that decides WHICH columns a freshly launched view opens on: proteins that\n * differ in length put one row's private N-terminal extension at column 0,\n * and everything else is gap there. Anything else react-msaview takes as a\n * snapshot property passes through the same way.\n */\n allowedGappyness?: number\n /**\n * Where the view lands: `stack` (default), `splitRight` or `newTab`. The\n * declarative half of the launch \u2014 a link states the arrangement it wants\n * instead of the reader dragging the view into place.\n *\n * The default is `stack` and has to stay `stack`: it is what every link\n * written before this key existed already does, and the only thing an\n * embedded session can do. The launch DIALOG defaults to `splitRight`\n * instead (see `DEFAULT_LAUNCH_PLACEMENT`), because a launch from a gene\n * feature is a connected pair and reads as a split.\n *\n * A spec that arranges more than these two views should use the host's own\n * `layout` key instead, which states the whole tree and is applied after\n * every view in the spec has launched. Both may be given; `layout` wins,\n * being the later and more specific statement.\n */\n placement?: MsaViewPlacement\n}\n\n/**\n * `msa` and `tree` onto the plugin's own sources, so a url still goes through\n * `init.msaUrl` and its format sniffing, and `query` onto `querySeqName`\n */\nfunction withLongSources({ msa, tree, ...args }: LaunchMsaViewArgs) {\n const inlineMsa = msa?.includes('\\n') ? msa : undefined\n const inlineTree = tree?.trimStart().startsWith('(') ? tree : undefined\n const data =\n inlineMsa || inlineTree\n ? {\n ...args.data,\n ...(inlineMsa ? { msa: inlineMsa } : {}),\n ...(inlineTree ? { tree: inlineTree } : {}),\n }\n : args.data\n return {\n ...args,\n data: data as LaunchMsaViewArgs['data'],\n ...(msa && !inlineMsa ? { msaFileLocation: { uri: msa } } : {}),\n ...(tree && !inlineTree ? { treeFileLocation: { uri: tree } } : {}),\n querySeqName: args.querySeqName ?? args.query,\n }\n}\n\nexport default function LaunchMsaViewExtensionPointF(\n pluginManager: PluginManager,\n) {\n pluginManager.addToExtensionPoint(\n 'LaunchView-MsaView',\n async (args: LaunchMsaViewArgs) => {\n const {\n session,\n query,\n data,\n msaFileLocation,\n msaIndexedLocation,\n msaName,\n treeFileLocation,\n querySeqName,\n searchParams,\n ...rest\n } = withLongSources(args)\n\n // `orthologParams` and `searchParams` name no alignment at all \u2014 the\n // view builds one at launch, which is the dialog's Orthologs and BLAST\n // tabs reached declaratively.\n if (\n !data &&\n !msaFileLocation &&\n !msaIndexedLocation &&\n !rest.orthologParams &&\n !searchParams\n ) {\n throw new Error(\n 'No MSA data, file location, orthologParams or searchParams provided when launching MSA view',\n )\n }\n\n // inline data and the tree URL are native react-msaview snapshot props, set\n // directly, and so is orthologParams (the model's own autorun picks it up).\n // Only sources needing launch-time resolution go through `init`: msaUrl\n // (AlphaFold sniff) and the name-indexed bgzip block (no native loader).\n //\n // An init whose every field is undefined is still a truthy object, and\n // MsaViewPanel reads any init as a launch in flight, so an inline-data\n // launch flashed \"Loading alignment\" until processInit cleared it.\n const init = {\n msaUrl: msaFileLocation?.uri,\n msaIndexedLocation,\n msaName,\n querySeqName,\n }\n const { expandSpec } = await import('react-msaview')\n await launchMsaView(session, {\n ...expandSpec({ ...rest, query }),\n ...(searchParams ? { blastParams: searchParams } : {}),\n data,\n ...(treeFileLocation\n ? {\n treeFilehandle: {\n ...treeFileLocation,\n locationType: 'UriLocation',\n },\n }\n : {}),\n ...(Object.values(init).some(v => v !== undefined) ? { init } : {}),\n })\n\n return args\n },\n )\n}\n", "import { lazy } from 'react'\n\nimport ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nconst MsaViewPanel = lazy(() => import('./components/MsaViewPanel'))\n\nexport default function MsaViewF(pluginManager: PluginManager) {\n pluginManager.addViewType(() => {\n return new ViewType({\n name: 'MsaView',\n // a thunk, so react-msaview loads with the first view rather than with\n // the plugin; addView refuses the type until then, hence launchView\n stateModel: () => import('./model').then(m => m.default()),\n ReactComponent: MsaViewPanel,\n })\n })\n}\n", "export const version = '5.2.0'\n"],
|
|
4
|
+
"sourcesContent": ["module.exports = JBrowseExports[\"@jbrowse/core/Plugin\"];", "module.exports = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/ViewType\"];", "import Plugin from '@jbrowse/core/Plugin'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { isAbstractMenuManager } from '@jbrowse/core/util'\nimport { types } from '@jbrowse/mobx-state-tree'\nimport GridOn from '@mui/icons-material/GridOn'\n\nimport AddHighlightModelF from './AddHighlightModel'\nimport BgzipFastaMsaAdapterF from './BgzipFastaMsaAdapter'\nimport LaunchMsaViewF from './LaunchMsaView'\nimport LaunchMsaViewExtensionPointF from './LaunchMsaViewExtensionPoint'\nimport MsaViewF from './MsaViewPanel'\nimport { launchMsaView } from './utils/launchMsaView'\nimport { version } from './version'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\n\nexport default class MsaViewPlugin extends Plugin {\n name = 'MsaViewPlugin'\n version = version\n\n install(pluginManager: PluginManager) {\n MsaViewF(pluginManager)\n LaunchMsaViewF(pluginManager)\n LaunchMsaViewExtensionPointF(pluginManager)\n AddHighlightModelF(pluginManager)\n BgzipFastaMsaAdapterF(pluginManager)\n }\n\n configure(pluginManager: PluginManager) {\n // a throw here error-pages the whole app, and a menu entry is not worth a\n // session\n try {\n if (isAbstractMenuManager(pluginManager.rootModel)) {\n pluginManager.rootModel.appendToSubMenu(['Add'], {\n label: 'Multiple sequence alignment view',\n icon: GridOn,\n onClick: (session: AbstractSessionModel) => {\n // stacked, by default: nothing was launched from, so there is no\n // connected view for it to sit beside\n launchMsaView(session, {}).catch((e: unknown) => {\n console.error(e)\n session.notifyError(`${e}`, e)\n })\n },\n })\n }\n } catch (e) {\n console.error(\n 'jbrowse-plugin-msaview: could not add the Add menu item',\n e,\n )\n }\n }\n\n rootConfigurationSchema = (pluginManager: PluginManager) => {\n return {\n msa: ConfigurationSchema('MSA', {\n datasets: types.maybe(\n types.array(\n ConfigurationSchema('MSAEntry', {\n datasetId: {\n type: 'string',\n defaultValue: '',\n },\n description: {\n type: 'string',\n defaultValue: '',\n },\n name: {\n type: 'string',\n defaultValue: '',\n },\n adapter: pluginManager.pluggableConfigSchemaType('adapter'),\n }),\n ),\n ),\n }),\n }\n }\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M8 20H4v-4h4zm0-6H4v-4h4zm0-6H4V4h4zm6 12h-4v-4h4zm0-6h-4v-4h4zm0-6h-4V4h4zm6 12h-4v-4h4zm0-6h-4v-4h4zm0-6h-4V4h4z\"\n}), 'GridOn');", "import React from 'react'\n\nimport { getSession } from '@jbrowse/core/util'\n\nimport { isMsaView } from '../MsaViewPanel/isMsaView'\nimport HighlightComponents from './HighlightComponents'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function AddHighlightComponentsModelF(\n pluginManager: PluginManager,\n) {\n pluginManager.contributeToExtensionPoint(\n 'LinearGenomeView-TracksContainerComponent',\n ({ model }) => {\n const { views } = getSession(model)\n return views.some(v => isMsaView(v) && v.connectedViewId === model.id) ? (\n <HighlightComponents\n key=\"highlight_protein_viewer_msaview\"\n model={model}\n />\n ) : undefined\n },\n )\n}\n", "import type { JBrowsePluginMsaViewModel } from './model'\n\nexport function isMsaView(view: {\n type: string\n}): view is JBrowsePluginMsaViewModel {\n return view.type === 'MsaView'\n}\n", "import React from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport GenomeMouseoverHighlight from './GenomeMouseoverHighlight'\nimport MsaToGenomeHighlight from './MsaToGenomeHighlight'\n\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\ntype LGV = LinearGenomeViewModel\n\nconst HighlightComponents = observer(function HighlightComponents2({\n model,\n}: {\n model: LGV\n}) {\n return (\n <>\n <MsaToGenomeHighlight model={model} />\n <GenomeMouseoverHighlight model={model} />\n </>\n )\n})\n\nexport default HighlightComponents\n", "import React from 'react'\n\nimport { getSession } from '@jbrowse/core/util'\nimport { observer } from 'mobx-react'\n\nimport { isMsaView } from '../MsaViewPanel/isMsaView'\nimport { hasHoverPosition, useStyles } from './util'\n\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\nconst GenomeMouseoverHighlight = observer(function ({\n model,\n}: {\n model: LinearGenomeViewModel\n}) {\n const { hovered, views } = getSession(model)\n const hasMsaView = views.some(\n s => isMsaView(s) && s.connectedViewId === model.id,\n )\n return hasMsaView && hasHoverPosition(hovered) ? (\n <GenomeMouseoverHighlightRenderer model={model} hovered={hovered} />\n ) : null\n})\n\nconst GenomeMouseoverHighlightRenderer = observer(function ({\n model,\n hovered,\n}: {\n model: LinearGenomeViewModel\n hovered: { hoverPosition: { coord: number; refName: string } }\n}) {\n const { classes } = useStyles()\n const { offsetPx } = model\n const { coord, refName } = hovered.hoverPosition\n\n const s = model.bpToPx({ refName, coord: coord - 1 })\n const e = model.bpToPx({ refName, coord })\n\n if (s && e) {\n const width = Math.max(Math.abs(e.offsetPx - s.offsetPx), 4)\n const left = Math.min(s.offsetPx, e.offsetPx) - offsetPx\n return <div className={classes.highlight} style={{ left, width }} />\n }\n\n return null\n})\n\nexport default GenomeMouseoverHighlight\n", "import { makeStyles } from 'tss-react/mui'\n\nexport { hasHoverPosition } from '../MsaViewPanel/util'\n\nexport const useStyles = makeStyles()({\n highlight: {\n height: '100%',\n background: 'rgba(255,255,0,0.2)',\n border: '1px solid rgba(50,50,0,0.2)',\n position: 'absolute',\n zIndex: 99,\n textAlign: 'center',\n pointerEvents: 'none',\n overflow: 'hidden',\n },\n})\n", "import React from 'react'\n\nimport { getSession } from '@jbrowse/core/util'\nimport { observer } from 'mobx-react'\n\nimport { connectedHighlights } from './connectedHighlights'\nimport { hasHoverPosition, useStyles } from './util'\n\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\ntype LGV = LinearGenomeViewModel\n\nconst MsaToGenomeHighlight = observer(function MsaToGenomeHighlight2({\n model,\n}: {\n model: LGV\n}) {\n const { views, hovered } = getSession(model)\n const highlights = connectedHighlights(\n views,\n model.id,\n hasHoverPosition(hovered),\n )\n\n return highlights.length ? (\n <MsaToGenomeHighlightRenderer model={model} highlights={highlights} />\n ) : null\n})\n\nconst MsaToGenomeHighlightRenderer = observer(function ({\n model,\n highlights,\n}: {\n model: LGV\n highlights: { refName: string; start: number; end: number }[]\n}) {\n const { classes } = useStyles()\n const { offsetPx } = model\n\n return (\n <>\n {highlights.map(r => {\n // bpToPx matches refNames exactly, so canonicalizing \"chr17\" to \"17\"\n // would miss a view whose regions say \"chr17\"\n const s = model.bpToPx({ refName: r.refName, coord: r.start })\n const e = model.bpToPx({ refName: r.refName, coord: r.end })\n if (s && e) {\n const width = Math.max(Math.abs(e.offsetPx - s.offsetPx), 4)\n const left = Math.min(s.offsetPx, e.offsetPx) - offsetPx\n return (\n <div\n key={`${r.refName}-${r.start}-${r.end}`}\n className={classes.highlight}\n style={{ left, width }}\n />\n )\n }\n return null\n })}\n </>\n )\n})\n\nexport default MsaToGenomeHighlight\n", "interface Region {\n refName: string\n start: number\n end: number\n}\n\ninterface LinkedView {\n type: string\n connectedViewId?: string\n connectedClickHighlights: Region[]\n connectedHoverHighlights: Region[]\n}\n\nexport function connectedHighlights(\n views: readonly { type: string }[],\n genomeViewId: string,\n genomeHovered: boolean,\n) {\n const regions = views\n .filter(isLinkedMsaView)\n .filter(v => v.connectedViewId === genomeViewId)\n .flatMap(v => [\n ...v.connectedClickHighlights,\n ...(genomeHovered ? [] : v.connectedHoverHighlights),\n ])\n return [\n ...new Map(\n regions.map(r => [`${r.refName}:${r.start}-${r.end}`, r]),\n ).values(),\n ]\n}\n\nfunction isLinkedMsaView(view: { type: string }): view is LinkedView {\n return view.type === 'MsaView'\n}\n", "import { AdapterType } from '@jbrowse/core/pluggableElementTypes'\n\nimport configSchemaF from './configSchema'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function BgzipFastaMsaAdapterF(pluginManager: PluginManager) {\n return pluginManager.addAdapterType(() => {\n return new AdapterType({\n name: 'BgzipFastaMsaAdapter',\n configSchema: configSchemaF(pluginManager),\n adapterMetadata: {\n hiddenFromGUI: true,\n },\n getAdapterClass: () =>\n import('./BgzipFastaMsaAdapter').then(t => t.default),\n })\n })\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function configSchemaF(pluginManager: PluginManager) {\n const base = pluginManager.getAdapterType('BgzipFastaAdapter')\n return ConfigurationSchema(\n 'BgzipFastaMsaAdapter',\n {\n msaRegex: {\n type: 'string',\n defaultValue: '_',\n },\n },\n {\n baseConfiguration: base.configSchema,\n },\n )\n}\n", "import { lazy } from 'react'\n\nimport { getContainingTrack, getSession } from '@jbrowse/core/util'\nimport AddIcon from '@mui/icons-material/Add'\n\nimport { isCodingFeature } from './codingFeature'\nimport { launchTarget } from './launchTarget'\n\nimport type { DisplayModel, MenuTarget } from './launchTarget'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { PluggableElementType } from '@jbrowse/core/pluggableElementTypes'\nimport type DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\nimport type { Feature } from '@jbrowse/core/util'\nimport type { IAnyModelType } from '@jbrowse/mobx-state-tree'\n\nconst LaunchMsaViewDialog = lazy(\n () => import('./components/LaunchMsaViewDialog'),\n)\n\nfunction isDisplay(elt: { name: string }): elt is DisplayType {\n return elt.name === 'LinearBasicDisplay'\n}\n\n// Walking to the track and the session at click time, not while the menu is\n// built: contextMenuItems runs on every right-click and, on a host whose base\n// method reads `this`, is the one place a plugin can take the whole menu down.\n// Keeping it to a pure read of the display is also what lets a test call it.\nfunction featureName(feature: Feature) {\n return feature.get('name') ?? feature.get('id') ?? 'This feature'\n}\n\nfunction openDialog(self: DisplayModel, target: MenuTarget) {\n const track = getContainingTrack(self)\n const session = getSession(track)\n const { preferredTranscriptId } = target\n const open = (feature: Feature) => {\n session.queueDialog(handleClose => [\n LaunchMsaViewDialog,\n { model: track, handleClose, feature, preferredTranscriptId },\n ])\n }\n target\n .fetchFeature()\n .then(feature => {\n if (!feature) {\n session.notify('Could not load feature for MSA view', 'warning')\n } else if (!isCodingFeature(feature)) {\n // the canvas hit test carries a type and nothing else, so this is the\n // first point at which the CDS can be looked for. Saying so beats\n // opening a dialog whose Submit never leaves grey.\n session.notify(\n `${featureName(feature)} has no coding sequence, so there is no protein to align`,\n 'info',\n )\n } else {\n open(feature)\n }\n })\n .catch((e: unknown) => {\n session.notifyError(`${e}`, e)\n })\n}\n\nexport function extendStateModel(stateModel: IAnyModelType) {\n return stateModel.views((self: DisplayModel) => {\n const superContextMenuItems = self.contextMenuItems\n return {\n contextMenuItems() {\n const target = launchTarget(self)\n return [\n // a detached call leaves `this` undefined for a host method that\n // reads it, and the throw takes the host's own rows with it\n ...superContextMenuItems.call(self),\n ...(target\n ? [\n {\n label: 'Launch MSA view',\n icon: AddIcon,\n onClick: () => {\n openDialog(self, target)\n },\n },\n ]\n : []),\n ]\n },\n }\n })\n}\n\nexport default function LaunchMsaViewF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint(\n 'Core-extendPluggableElement',\n (elt: PluggableElementType) => {\n if (isDisplay(elt)) {\n elt.stateModel = extendStateModel(elt.stateModel)\n }\n return elt\n },\n )\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z\"\n}), 'Add');", "import type { Feature } from '@jbrowse/core/util'\n\nfunction isCDS(feature: Feature) {\n return feature.get('type')?.toLowerCase() === 'cds'\n}\n\n// The feature itself counts: a viral polyprotein hangs its cleavage products\n// off its CDS rather than off further CDSs.\nexport function isCodingFeature(feature: Feature): boolean {\n return isCDS(feature) || !!feature.get('subfeatures')?.some(isCodingFeature)\n}\n", "import { isGeneLikeType } from '@jbrowse/core/util'\n\nimport type { MenuItem } from '@jbrowse/core/ui'\nimport type { Feature } from '@jbrowse/core/util'\n\nexport interface ContextMenuInfo {\n item: { featureId: string; type?: string }\n // the isoform under the pointer when the click landed on a gene's child\n subfeature?: { featureId: string }\n displayedRegionIndex: number\n}\n\nexport interface DisplayModel {\n contextMenuItems: () => MenuItem[]\n contextMenuInfo?: ContextMenuInfo\n fetchFullFeature: (\n featureId: string,\n displayedRegionIndex: number,\n ) => Promise<Feature | undefined>\n}\n\n/**\n * What the menu item launches on. The hit test carries a type and an id, so\n * whether the feature codes for anything can only be answered after the fetch,\n * and the caller answers it there.\n */\nexport interface MenuTarget {\n fetchFeature: () => Promise<Feature | undefined>\n /**\n * The isoform the click actually landed on, when the dialog opens on its\n * gene. Climbing to the gene is what puts every isoform in the picker, and it\n * threw away which one the user pointed at: the picker then opened on the\n * longest transcript.\n */\n preferredTranscriptId?: string\n}\n\n// Read off the clicked item rather than off the display: LinearBasicDisplay's\n// `isGeneLike` getter was inlined into its own `contextMenuItems`\n// (jbrowse-components 684142b3), and gating on it silently took the item off\n// every gene track.\nexport function launchTarget(self: DisplayModel): MenuTarget | undefined {\n const info = self.contextMenuInfo\n return info && isGeneLikeType(info.item.type)\n ? {\n fetchFeature: () =>\n self.fetchFullFeature(info.item.featureId, info.displayedRegionIndex),\n preferredTranscriptId: info.subfeature?.featureId,\n }\n : undefined\n}\n", "import { launchMsaView } from '../utils/launchMsaView'\n\nimport type { BlastParams, OrthologParams } from '../MsaViewPanel/model'\nimport type { MsaViewPlacement } from '../utils/workspaces'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\nimport type {\n Clade,\n ColumnTrackShorthand,\n Encoding,\n HighlightShorthand,\n RegionShorthand,\n ResidueMapping,\n RowPanelSpec,\n} from 'react-msaview'\n\ninterface LaunchMsaViewArgs {\n session: AbstractSessionModel\n /**\n * Shorthand, see react-msaview's docs/layers.md: `msa` and `tree` take a\n * url or the text itself, and `query` names the row the spec is about, the\n * `querySeqName` and the `row` of every highlight, region and column track\n * that names none\n */\n msa?: string\n tree?: string\n query?: string\n data?: { msa: string; tree?: string }\n msaFileLocation?: { uri: string }\n msaIndexedLocation?: { uri: string }\n msaName?: string\n treeFileLocation?: { uri: string }\n connectedViewId?: string\n connectedFeature?: Record<string, unknown>\n /**\n * The short form of `connectedFeature`: a transcript id looked up in the\n * connected genome view's open tracks at launch, and translated to become\n * the query row of a `searchParams` or `orthologParams` launch that names\n * no `proteinSequence` of its own.\n */\n connectedTranscript?: string\n displayName?: string\n colorSchemeName?: string\n colWidth?: number\n rowHeight?: number\n treeAreaWidth?: number\n treeWidth?: number\n drawNodeBubbles?: boolean\n labelsAlignRight?: boolean\n showBranchLen?: boolean\n querySeqName?: string\n /**\n * Transcript residues before the query row's first residue, for a row that\n * carries only part of the protein -- what BLAST reports when it trims the\n * query to the aligned region. Genome navigation is off by this much without\n * it.\n */\n querySeqOffset?: number\n highlightColumns?: number[]\n /**\n * Labeled highlights in 1-based inclusive coordinates: `{row, start, end}`\n * for residues of that row, `{start, end}` for alignment columns, `{rows}`\n * for whole rows. Prefer this over `highlightColumns`: a residue range stays\n * put when `allowedGappyness` changes the visible columns.\n */\n highlights?: HighlightShorthand[]\n /** per-column tracks supplied as data, see react-msaview's docs/layers.md */\n columnTracks?: ColumnTrackShorthand[]\n /**\n * Where the view opens, in `highlights` coordinates: `{row, start, end}`\n * zooms onto residues of that row, `{start, end}` onto alignment columns.\n * Applied once the alignment has loaded, then dropped from the session.\n */\n region?: RegionShorthand\n /**\n * Passed through untouched as react-msaview snapshot properties; see its\n * docs/layers.md. A bare `{ uri }` is enough for the two filehandles.\n */\n clades?: Clade[]\n encodings?: Encoding[]\n rowPanels?: RowPanelSpec[]\n relativeTo?: string\n residueMappings?: ResidueMapping[]\n trackHeights?: Record<string, number>\n turnedOffFeatures?: Record<string, boolean>\n gffFilehandle?: { uri: string }\n treeMetadataFilehandle?: { uri: string }\n /**\n * Build the alignment from NCBI orthologs at launch time instead of naming a\n * file: `{ taxId, geneCandidates }` is enough, and `taxa` and\n * `proteinSequence` both default (see OrthologParams). This is the launch\n * dialog's Orthologs tab, reachable from a session spec \u2014 so a link can say\n * \"NLRP1 across species\" and the view builds it.\n */\n orthologParams?: OrthologParams\n /**\n * Search for the alignment at launch: the dialog's BLAST tab reached\n * declaratively. `{ searchProgram: 'phmmer', blastDatabase: 'rp15',\n * accession: 'P04637' }` is a whole request. The query comes from\n * `proteinSequence`, else fetched for `accession`, else translated from the\n * view's `connectedTranscript`. Stored on the model as `blastParams`, the\n * name the dialog has always used.\n */\n searchParams?: BlastParams\n /**\n * Hide any column gappier than this percentage, 100 being \"hide nothing\".\n * A native react-msaview property, named here because it is the one setting\n * that decides WHICH columns a freshly launched view opens on: proteins that\n * differ in length put one row's private N-terminal extension at column 0,\n * and everything else is gap there. Anything else react-msaview takes as a\n * snapshot property passes through the same way.\n */\n allowedGappyness?: number\n /**\n * Where the view lands: `stack` (default), `splitRight` or `newTab`. The\n * declarative half of the launch \u2014 a link states the arrangement it wants\n * instead of the reader dragging the view into place.\n *\n * The default is `stack` and has to stay `stack`: it is what every link\n * written before this key existed already does, and the only thing an\n * embedded session can do. The launch DIALOG defaults to `splitRight`\n * instead (see `DEFAULT_LAUNCH_PLACEMENT`), because a launch from a gene\n * feature is a connected pair and reads as a split.\n *\n * A spec that arranges more than these two views should use the host's own\n * `layout` key instead, which states the whole tree and is applied after\n * every view in the spec has launched. Both may be given; `layout` wins,\n * being the later and more specific statement.\n */\n placement?: MsaViewPlacement\n}\n\n/**\n * `msa` and `tree` onto the plugin's own sources, so a url still goes through\n * `init.msaUrl` and its format sniffing, and `query` onto `querySeqName`\n */\nfunction withLongSources({ msa, tree, ...args }: LaunchMsaViewArgs) {\n const inlineMsa = msa?.includes('\\n') ? msa : undefined\n const inlineTree = tree?.trimStart().startsWith('(') ? tree : undefined\n const data =\n inlineMsa || inlineTree\n ? {\n ...args.data,\n ...(inlineMsa ? { msa: inlineMsa } : {}),\n ...(inlineTree ? { tree: inlineTree } : {}),\n }\n : args.data\n return {\n ...args,\n data: data as LaunchMsaViewArgs['data'],\n ...(msa && !inlineMsa ? { msaFileLocation: { uri: msa } } : {}),\n ...(tree && !inlineTree ? { treeFileLocation: { uri: tree } } : {}),\n querySeqName: args.querySeqName ?? args.query,\n }\n}\n\nexport default function LaunchMsaViewExtensionPointF(\n pluginManager: PluginManager,\n) {\n pluginManager.addToExtensionPoint(\n 'LaunchView-MsaView',\n async (args: LaunchMsaViewArgs) => {\n const {\n session,\n query,\n data,\n msaFileLocation,\n msaIndexedLocation,\n msaName,\n treeFileLocation,\n querySeqName,\n searchParams,\n ...rest\n } = withLongSources(args)\n\n // `orthologParams` and `searchParams` name no alignment at all \u2014 the\n // view builds one at launch, which is the dialog's Orthologs and BLAST\n // tabs reached declaratively.\n if (\n !data &&\n !msaFileLocation &&\n !msaIndexedLocation &&\n !rest.orthologParams &&\n !searchParams\n ) {\n throw new Error(\n 'No MSA data, file location, orthologParams or searchParams provided when launching MSA view',\n )\n }\n\n // inline data and the tree URL are native react-msaview snapshot props, set\n // directly, and so is orthologParams (the model's own autorun picks it up).\n // Only sources needing launch-time resolution go through `init`: msaUrl\n // (AlphaFold sniff) and the name-indexed bgzip block (no native loader).\n //\n // An init whose every field is undefined is still a truthy object, and\n // MsaViewPanel reads any init as a launch in flight, so an inline-data\n // launch flashed \"Loading alignment\" until processInit cleared it.\n const init = {\n msaUrl: msaFileLocation?.uri,\n msaIndexedLocation,\n msaName,\n querySeqName,\n }\n const { expandSpec } = await import('react-msaview')\n await launchMsaView(session, {\n ...expandSpec({ ...rest, query }),\n ...(searchParams ? { blastParams: searchParams } : {}),\n data,\n ...(treeFileLocation\n ? {\n treeFilehandle: {\n ...treeFileLocation,\n locationType: 'UriLocation',\n },\n }\n : {}),\n ...(Object.values(init).some(v => v !== undefined) ? { init } : {}),\n })\n\n return args\n },\n )\n}\n", "import { lazy } from 'react'\n\nimport ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nconst MsaViewPanel = lazy(() => import('./components/MsaViewPanel'))\n\nexport default function MsaViewF(pluginManager: PluginManager) {\n pluginManager.addViewType(() => {\n return new ViewType({\n name: 'MsaView',\n // a thunk, so react-msaview loads with the first view rather than with\n // the plugin; addView refuses the type until then, hence launchView\n stateModel: () => import('./model').then(m => m.default()),\n ReactComponent: MsaViewPanel,\n })\n })\n}\n", "export const version = '5.3.0'\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["require_Plugin", "__commonJSMin", "exports", "module", "require_ViewType", "__commonJSMin", "exports", "module", "import_Plugin", "import_configuration", "import_util", "import_mobx_state_tree", "import_jsx_runtime", "GridOn_default", "_jsx", "import_react", "import_util", "isMsaView", "view", "import_react", "import_mobx_react", "import_react", "import_util", "import_mobx_react", "import_mui", "useStyles", "GenomeMouseoverHighlight", "model", "hovered", "views", "s", "isMsaView", "hasHoverPosition", "React", "GenomeMouseoverHighlightRenderer", "classes", "useStyles", "offsetPx", "coord", "refName", "e", "width", "left", "GenomeMouseoverHighlight_default", "import_react", "import_util", "import_mobx_react", "connectedHighlights", "views", "genomeViewId", "genomeHovered", "regions", "isLinkedMsaView", "v", "r", "view", "MsaToGenomeHighlight", "model", "views", "hovered", "highlights", "connectedHighlights", "hasHoverPosition", "React", "MsaToGenomeHighlightRenderer", "classes", "useStyles", "offsetPx", "r", "e", "width", "left", "MsaToGenomeHighlight_default", "HighlightComponents", "model", "React", "MsaToGenomeHighlight_default", "GenomeMouseoverHighlight_default", "HighlightComponents_default", "AddHighlightComponentsModelF", "pluginManager", "model", "views", "v", "isMsaView", "React", "HighlightComponents_default", "import_pluggableElementTypes", "import_configuration", "configSchemaF", "pluginManager", "base", "BgzipFastaMsaAdapterF", "pluginManager", "configSchemaF", "import_react", "import_util", "import_jsx_runtime", "Add_default", "_jsx", "isCDS", "feature", "isCodingFeature", "import_util", "launchTarget", "self", "info", "LaunchMsaViewDialog", "isDisplay", "elt", "featureName", "feature", "openDialog", "self", "target", "track", "session", "preferredTranscriptId", "open", "handleClose", "isCodingFeature", "e", "extendStateModel", "stateModel", "superContextMenuItems", "launchTarget", "Add_default", "LaunchMsaViewF", "pluginManager", "withLongSources", "msa", "tree", "args", "inlineMsa", "inlineTree", "data", "LaunchMsaViewExtensionPointF", "pluginManager", "session", "query", "msaFileLocation", "msaIndexedLocation", "msaName", "treeFileLocation", "querySeqName", "searchParams", "rest", "init", "expandSpec", "launchMsaView", "v", "import_react", "import_ViewType", "MsaViewPanel", "MsaViewF", "pluginManager", "ViewType", "m", "version", "MsaViewPlugin", "Plugin", "version", "pluginManager", "MsaViewF", "LaunchMsaViewF", "LaunchMsaViewExtensionPointF", "AddHighlightComponentsModelF", "BgzipFastaMsaAdapterF", "GridOn_default", "session", "launchMsaView", "e"]
|
|
7
7
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "5.
|
|
1
|
+
export declare const version = "5.3.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.
|
|
1
|
+
export const version = '5.3.0';
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "5.
|
|
2
|
+
"version": "5.3.0",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "jbrowse-plugin-msaview",
|
|
5
5
|
"repository": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"puppeteer": "^25.12.0",
|
|
56
56
|
"react": "^19.3.0",
|
|
57
57
|
"react-dom": "^19.3.0",
|
|
58
|
-
"react-msaview": "^9.
|
|
58
|
+
"react-msaview": "^9.1.0",
|
|
59
59
|
"rimraf": "^6.1.3",
|
|
60
60
|
"rxjs": "^7.8.2",
|
|
61
61
|
"serve": "^14.2.6",
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.
|
|
1
|
+
export const version = '5.3.0'
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as i}from"./chunk-DNFD5II2.js";import{a as m}from"./chunk-BX4Z274Q.js";import{a}from"./chunk-J6KYLXRD.js";import{b as r}from"./chunk-FY3BTKY4.js";var e=r(a(),1),o=r(i(),1),t=r(m(),1);var l="9.0.0";function c({onClose:n}){return e.default.createElement(o.Dialog,{open:!0,title:"About",onClose:()=>{n()}},e.default.createElement(t.DialogContent,null,e.default.createElement(t.Typography,null,"MSAView ",l," (",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://github.com/gmod/react-msaview"},"Github"),")"),e.default.createElement("ul",null,e.default.createElement("li",null,e.default.createElement(t.Typography,null,"We use some color schemes from the"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://github.com/biotite-dev/biotite"},"biotite")," ","project, and their license is reproduced"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://github.com/biotite-dev/biotite/blob/master/LICENSE.rst"},"here"))),e.default.createElement("li",null,e.default.createElement(t.Typography,null,"See this page for some information on jalview colorings"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://www.jalview.org/help/html/colourSchemes/"},"here"))),e.default.createElement("li",null,e.default.createElement(t.Typography,null,"See this page for some info on the clustal, cinema, maeditor, and lesk color schemes"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"http://www.bioinformatics.nl/~berndb/aacolour.html"},"here"))),e.default.createElement("li",null,e.default.createElement(t.Typography,null,"See this paper about the flower color scheme"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7245768/"},"here"))))))}export{c as default};
|
|
2
|
-
//# sourceMappingURL=AboutDialog-IRBPUPJK.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{h as E,k as d}from"./chunk-QQ5LZUIO.js";import"./chunk-73KAPCJ2.js";import{a as x}from"./chunk-CVLB4VFP.js";import{a as w}from"./chunk-DNFD5II2.js";import{a as T}from"./chunk-BX4Z274Q.js";import{a as C}from"./chunk-J6KYLXRD.js";import{b as i}from"./chunk-FY3BTKY4.js";var e=i(C(),1),c=i(w(),1),t=i(T(),1),h=i(x(),1);function b(r){let n=r.trimStart();if(!n.startsWith("{"))return r;let a=JSON.parse(n);return d(E(a))}async function O(r){let n=await fetch(r);if(!n.ok)throw new Error(`HTTP ${n.status} fetching ${r} ${await n.text()}`);return n.text()}var R=(0,h.observer)(function({handleClose:r,model:n}){let[a,g]=(0,e.useState)(),[l,v]=(0,e.useState)("file"),[s,F]=(0,e.useState)(""),[m,u]=(0,e.useState)(),[y,f]=(0,e.useState)(!1);return e.default.createElement(c.Dialog,{maxWidth:"xl",title:"Open annotation file",onClose:()=>{r()},open:!0},e.default.createElement(t.DialogContent,null,m?e.default.createElement(c.ErrorMessage,{error:m}):null,e.default.createElement(t.Typography,null,"Open a GFF3 file of annotations, such as the one `react-msaview-cli interpro` writes, or the JSON an InterProScan run returns."),e.default.createElement("div",{style:{display:"flex",margin:30}},e.default.createElement(t.FormControl,{component:"fieldset"},e.default.createElement(t.RadioGroup,{value:l,onChange:o=>{v(o.target.value)}},e.default.createElement(t.FormControlLabel,{value:"url",control:e.default.createElement(t.Radio,null),label:"URL"}),e.default.createElement(t.FormControlLabel,{value:"file",control:e.default.createElement(t.Radio,null),label:"File"}))),l==="url"?e.default.createElement("div",null,e.default.createElement(t.Typography,null,"Open an annotation file from a URL"),e.default.createElement(t.TextField,{label:"URL",value:s,onChange:o=>{F(o.target.value)}})):e.default.createElement("div",{style:{paddingTop:20}},e.default.createElement(t.Typography,null,"Open an annotation file from your local drive"),e.default.createElement(t.Button,{variant:"outlined",component:"label"},"Choose File",e.default.createElement("input",{type:"file",hidden:!0,onChange:({target:o})=>{let p=o.files?.[0];p&&g(p)}})),a?e.default.createElement(t.Typography,null,a.name):null))),e.default.createElement(t.DialogActions,null,e.default.createElement(t.Button,{variant:"contained",color:"primary",disabled:y||(l==="file"?!a:!s.trim()),onClick:()=>{(async()=>{f(!0),u(void 0);try{let o=await(l==="file"&&a?a.text():O(s));n.setGFF(b(o)),n.setShowDomains(!0),r()}catch(o){console.error(o),u(o)}finally{f(!1)}})()}},"Open annotations"),e.default.createElement(t.Button,{variant:"contained",color:"secondary",onClick:()=>{r()}},"Cancel")))}),D=R;export{D as default};
|
|
2
|
-
//# sourceMappingURL=AnnotationFileDialog-FCYYZ4JN.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../node_modules/.pnpm/react-msaview@9.0.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/dialogs/AnnotationFileDialog.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useState } from 'react'\n\nimport { Dialog, ErrorMessage } from '@jbrowse/core/ui'\nimport {\n Button,\n DialogActions,\n DialogContent,\n FormControl,\n FormControlLabel,\n Radio,\n RadioGroup,\n TextField,\n Typography,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\nimport {\n annotationsToGFF,\n interProScanResponseToAnnotations,\n} from 'msa-parsers'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { InterProScanResponse } from 'msa-parsers'\n\n// GFF3 as the CLI writes it, or the JSON an InterProScan run returns. Both\n// arrive as text and the model keeps GFF, so the JSON is converted on the way\n// in rather than given a second path through the model\nfunction toGFF(text: string) {\n const trimmed = text.trimStart()\n if (!trimmed.startsWith('{')) {\n return text\n }\n const response: InterProScanResponse = JSON.parse(trimmed)\n return annotationsToGFF(interProScanResponseToAnnotations(response))\n}\n\nasync function fetchText(url: string) {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(\n `HTTP ${response.status} fetching ${url} ${await response.text()}`,\n )\n }\n return response.text()\n}\n\nconst AnnotationFileDialog = observer(function ({\n handleClose,\n model,\n}: {\n handleClose: () => void\n model: MsaViewModel\n}) {\n const [file, setFile] = useState<File>()\n const [choice, setChoice] = useState('file')\n const [url, setUrl] = useState('')\n const [error, setError] = useState<unknown>()\n const [loading, setLoading] = useState(false)\n\n // the error is shown here rather than notified: the standalone app and the\n // MSAViewer component have no jbrowse session to notify, and asking one for\n // its notify() threw out of the success path into the catch, which threw\n // again on the same missing session\n return (\n <Dialog\n maxWidth=\"xl\"\n title=\"Open annotation file\"\n onClose={() => {\n handleClose()\n }}\n open\n >\n <DialogContent>\n {error ? <ErrorMessage error={error} /> : null}\n <Typography>\n Open a GFF3 file of annotations, such as the one `react-msaview-cli\n interpro` writes, or the JSON an InterProScan run returns.\n </Typography>\n\n <div style={{ display: 'flex', margin: 30 }}>\n <FormControl component=\"fieldset\">\n <RadioGroup\n value={choice}\n onChange={event => {\n setChoice(event.target.value)\n }}\n >\n <FormControlLabel value=\"url\" control={<Radio />} label=\"URL\" />\n <FormControlLabel value=\"file\" control={<Radio />} label=\"File\" />\n </RadioGroup>\n </FormControl>\n {choice === 'url' ? (\n <div>\n <Typography>Open an annotation file from a URL</Typography>\n <TextField\n label=\"URL\"\n value={url}\n onChange={event => {\n setUrl(event.target.value)\n }}\n />\n </div>\n ) : (\n <div style={{ paddingTop: 20 }}>\n <Typography>\n Open an annotation file from your local drive\n </Typography>\n <Button variant=\"outlined\" component=\"label\">\n Choose File\n <input\n type=\"file\"\n hidden\n onChange={({ target }) => {\n const chosen = target.files?.[0]\n if (chosen) {\n setFile(chosen)\n }\n }}\n />\n </Button>\n {file ? <Typography>{file.name}</Typography> : null}\n </div>\n )}\n </div>\n </DialogContent>\n <DialogActions>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={loading || (choice === 'file' ? !file : !url.trim())}\n onClick={() => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n ;(async () => {\n setLoading(true)\n setError(undefined)\n try {\n const text = await (choice === 'file' && file\n ? file.text()\n : fetchText(url))\n // through the model's own GFF text, so the annotations travel\n // in the snapshot and the shared URL like every other layer.\n // Setting them straight onto the volatile left a view whose\n // link opened without them\n model.setGFF(toGFF(text))\n model.setShowDomains(true)\n handleClose()\n } catch (e) {\n console.error(e)\n setError(e)\n } finally {\n setLoading(false)\n }\n })()\n }}\n >\n Open annotations\n </Button>\n <Button\n variant=\"contained\"\n color=\"secondary\"\n onClick={() => {\n handleClose()\n }}\n >\n Cancel\n </Button>\n </DialogActions>\n </Dialog>\n )\n})\n\nexport default AnnotationFileDialog\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_react", "import_ui", "import_material", "import_mobx_react", "toGFF", "text", "trimmed", "response", "annotationsToGFF", "interProScanResponseToAnnotations", "fetchText", "url", "AnnotationFileDialog", "handleClose", "model", "file", "setFile", "choice", "setChoice", "setUrl", "error", "setError", "loading", "setLoading", "React", "event", "target", "chosen", "e", "AnnotationFileDialog_default"]
|
|
7
|
-
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as p}from"./chunk-YOTSFJMU.js";import{a as P}from"./chunk-CVLB4VFP.js";import{a as R}from"./chunk-DNFD5II2.js";import{a as q}from"./chunk-BX4Z274Q.js";import{a as W}from"./chunk-J6KYLXRD.js";import{b as a}from"./chunk-FY3BTKY4.js";var t=a(W(),1),i=a(R(),1),e=a(q(),1),v=a(P(),1);function z(r){requestAnimationFrame(()=>{requestAnimationFrame(r)})}var O=(0,v.observer)(function({model:r,onClose:c}){let[s,f]=(0,t.useState)(!0),[n,x]=(0,t.useState)(!0),[o,k]=(0,t.useState)("viewport"),[h,y]=(0,t.useState)(),[m,d]=(0,t.useState)(!1),T=(0,e.useTheme)(),{totalWidth:C,totalHeight:b,effectiveTreeAreaWidth:w,rowPanelsWidth:M,turnedOnTracks:A,totalTrackAreaHeight:S,numColumns:F,leaves:G,showMsaLetters:I,treeOverviewHeight:D}=r,E=A.length>0,H=C+w+M,L=b+(n?S:0)+D,g=I&&o==="entire"?F*G.length:0,V=g>1e5;return t.default.createElement(i.Dialog,{onClose:()=>{c()},open:!0,title:"Export SVG"},t.default.createElement(e.DialogContent,null,h?t.default.createElement(i.ErrorMessage,{error:h}):null,t.default.createElement(e.Typography,null,"Settings:"),t.default.createElement(p,{label:"Include minimap?",disabled:o==="entire",checked:s,onChange:()=>{f(!s)}}),E?t.default.createElement(p,{label:"Include tracks?",checked:n,onChange:()=>{x(!n)}}):null,t.default.createElement("div",null,t.default.createElement(e.FormControl,null,t.default.createElement(e.FormLabel,null,"Export type"),t.default.createElement(e.RadioGroup,{value:o,onChange:l=>{let{value:u}=l.target;(u==="entire"||u==="viewport")&&k(u)}},t.default.createElement(e.FormControlLabel,{value:"entire",control:t.default.createElement(e.Radio,null),label:"Entire MSA"}),t.default.createElement(e.FormControlLabel,{value:"viewport",control:t.default.createElement(e.Radio,null),label:"Current viewport only"})))),V?t.default.createElement(e.Alert,{severity:"warning",style:{marginTop:8}},"The entire MSA is ",Math.round(H),"x",Math.round(L)," pixels and draws"," ",Math.round(g/1e3),"k residue letters, each its own SVG element. Export may be slow or fail \u2014 zooming out far enough to hide the letters exports the same alignment as an image instead."):null),t.default.createElement(e.DialogActions,null,t.default.createElement(e.Button,{variant:"contained",color:"primary",disabled:m,startIcon:m?t.default.createElement(e.CircularProgress,{size:16,color:"inherit"}):null,onClick:()=>{d(!0),z(()=>{r.exportSVG({theme:T,includeMinimap:s,includeTracks:E&&n,exportType:o}).then(()=>{c()}).catch(l=>{console.error(l),y(l)}).finally(()=>{d(!1)})})}},m?"Exporting\u2026":"Export"),t.default.createElement(e.Button,{variant:"contained",color:"secondary",onClick:()=>{c()}},"Cancel")))}),_=O;export{_ as default};
|
|
2
|
-
//# sourceMappingURL=ExportSVGDialog-TYYPI6VB.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../node_modules/.pnpm/react-msaview@9.0.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/dialogs/ExportSVGDialog.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useState } from 'react'\n\nimport { Dialog, ErrorMessage } from '@jbrowse/core/ui'\nimport {\n Alert,\n Button,\n CircularProgress,\n DialogActions,\n DialogContent,\n FormControl,\n FormControlLabel,\n FormLabel,\n Radio,\n RadioGroup,\n Typography,\n useTheme,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport Checkbox2 from '../Checkbox2.tsx'\n\nimport type { MsaViewModel } from '../../model.ts'\n\n// Run after the browser has painted. A requestAnimationFrame callback still\n// runs *before* the frame it was queued for, so one alone hands the main thread\n// to the render with the spinner not yet on screen; the second fires once that\n// frame is out.\nfunction afterPaint(fn: () => void) {\n requestAnimationFrame(() => {\n requestAnimationFrame(fn)\n })\n}\n\nconst ExportSVGDialog = observer(function ({\n model,\n onClose,\n}: {\n model: MsaViewModel\n onClose: () => void\n}) {\n const [includeMinimap, setIncludeMinimap] = useState(true)\n const [includeTracks, setIncludeTracks] = useState(true)\n const [exportType, setExportType] = useState<'entire' | 'viewport'>(\n 'viewport',\n )\n const [error, setError] = useState<unknown>()\n const [exporting, setExporting] = useState(false)\n const theme = useTheme()\n const {\n totalWidth,\n totalHeight,\n effectiveTreeAreaWidth,\n rowPanelsWidth,\n turnedOnTracks,\n totalTrackAreaHeight,\n numColumns,\n leaves,\n showMsaLetters,\n treeOverviewHeight,\n } = model\n const hasTracks = turnedOnTracks.length > 0\n const entireWidth = totalWidth + effectiveTreeAreaWidth + rowPanelsWidth\n const entireHeight =\n totalHeight +\n (includeTracks ? totalTrackAreaHeight : 0) +\n treeOverviewHeight\n // the background is one raster image whatever its size, so what the figure\n // actually costs is its residue letters: each is an svg element of its own.\n // Past roughly this many the export runs to tens of seconds and can exhaust\n // the tab's memory outright\n const glyphs =\n showMsaLetters && exportType === 'entire' ? numColumns * leaves.length : 0\n const isLargeExport = glyphs > 100_000\n return (\n <Dialog\n onClose={() => {\n onClose()\n }}\n open\n title=\"Export SVG\"\n >\n <DialogContent>\n {error ? <ErrorMessage error={error} /> : null}\n <Typography>Settings:</Typography>\n <Checkbox2\n label=\"Include minimap?\"\n disabled={exportType === 'entire'}\n checked={includeMinimap}\n onChange={() => {\n setIncludeMinimap(!includeMinimap)\n }}\n />\n {hasTracks ? (\n <Checkbox2\n label=\"Include tracks?\"\n checked={includeTracks}\n onChange={() => {\n setIncludeTracks(!includeTracks)\n }}\n />\n ) : null}\n <div>\n <FormControl>\n <FormLabel>Export type</FormLabel>\n <RadioGroup\n value={exportType}\n onChange={event => {\n const { value } = event.target\n if (value === 'entire' || value === 'viewport') {\n setExportType(value)\n }\n }}\n >\n <FormControlLabel\n value=\"entire\"\n control={<Radio />}\n label=\"Entire MSA\"\n />\n <FormControlLabel\n value=\"viewport\"\n control={<Radio />}\n label=\"Current viewport only\"\n />\n </RadioGroup>\n </FormControl>\n </div>\n {isLargeExport ? (\n <Alert severity=\"warning\" style={{ marginTop: 8 }}>\n The entire MSA is {Math.round(entireWidth)}x\n {Math.round(entireHeight)} pixels and draws{' '}\n {Math.round(glyphs / 1000)}k residue letters, each its own SVG\n element. Export may be slow or fail \u2014 zooming out far enough to hide\n the letters exports the same alignment as an image instead.\n </Alert>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button\n variant=\"contained\"\n color=\"primary\"\n // rendering runs on the main thread and a large figure holds it for\n // seconds; without this the button stays live through the freeze and\n // a second click starts a second export\n disabled={exporting}\n startIcon={\n exporting ? <CircularProgress size={16} color=\"inherit\" /> : null\n }\n onClick={() => {\n setExporting(true)\n afterPaint(() => {\n void model\n .exportSVG({\n theme,\n includeMinimap,\n includeTracks: hasTracks && includeTracks,\n exportType,\n })\n .then(() => {\n onClose()\n })\n .catch((e: unknown) => {\n console.error(e)\n setError(e)\n })\n .finally(() => {\n setExporting(false)\n })\n })\n }}\n >\n {exporting ? 'Exporting\u2026' : 'Export'}\n </Button>\n <Button\n variant=\"contained\"\n color=\"secondary\"\n onClick={() => {\n onClose()\n }}\n >\n Cancel\n </Button>\n </DialogActions>\n </Dialog>\n )\n})\n\nexport default ExportSVGDialog\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_react", "import_ui", "import_material", "import_mobx_react", "afterPaint", "fn", "ExportSVGDialog", "model", "onClose", "includeMinimap", "setIncludeMinimap", "includeTracks", "setIncludeTracks", "exportType", "setExportType", "error", "setError", "exporting", "setExporting", "theme", "totalWidth", "totalHeight", "effectiveTreeAreaWidth", "rowPanelsWidth", "turnedOnTracks", "totalTrackAreaHeight", "numColumns", "leaves", "showMsaLetters", "treeOverviewHeight", "hasTracks", "entireWidth", "entireHeight", "glyphs", "isLargeExport", "React", "Checkbox2", "event", "value", "e", "ExportSVGDialog_default"]
|
|
7
|
-
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as n,b as m,c as l}from"./chunk-H6IQBAW7.js";import"./chunk-YOTSFJMU.js";import"./chunk-F3EC6OCO.js";import"./chunk-QQ5LZUIO.js";import"./chunk-73KAPCJ2.js";import"./chunk-GDFVLZYX.js";import"./chunk-GIHMPOCO.js";import{a as u}from"./chunk-CVLB4VFP.js";import{a as f}from"./chunk-DNFD5II2.js";import{a as d}from"./chunk-BX4Z274Q.js";import{a as s}from"./chunk-J6KYLXRD.js";import{b as a}from"./chunk-FY3BTKY4.js";var e=a(s(),1),i=a(f(),1),t=a(d(),1),c=a(u(),1);var E=(0,c.observer)(function({model:r,onClose:p}){let{header:o}=r;return e.default.createElement(i.Dialog,{onClose:()=>{p()},open:!0,title:"Metadata",maxWidth:"xl"},e.default.createElement(t.DialogContent,null,Object.values(o).every(n)?e.default.createElement(t.Typography,null,"This alignment has no metadata."):e.default.createElement(m,{record:o}),e.default.createElement(t.Typography,{variant:"h6"},"Sequences"),e.default.createElement(l,{str:r.rows})))}),v=E;export{v as default};
|
|
2
|
-
//# sourceMappingURL=MetadataDialog-KZWQFRF7.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as b,c as k,d as C}from"./chunk-ZCT7RD24.js";import{e as M}from"./chunk-NMYD2GWF.js";import"./chunk-F3EC6OCO.js";import"./chunk-FCWXYIFC.js";import{a as B}from"./chunk-6YFCSBEE.js";import"./chunk-F726IWCW.js";import"./chunk-YUKJI2AH.js";import"./chunk-QQ5LZUIO.js";import{a as L}from"./chunk-NSASZ5FM.js";import"./chunk-IBBQUV2I.js";import"./chunk-QUWPHTZQ.js";import"./chunk-73KAPCJ2.js";import"./chunk-GIHMPOCO.js";import{a as y}from"./chunk-CVLB4VFP.js";import{a as P}from"./chunk-DNFD5II2.js";import{a as w}from"./chunk-BX4Z274Q.js";import{a as h}from"./chunk-J6KYLXRD.js";import{b as i}from"./chunk-FY3BTKY4.js";var e=i(h()),z=i(P()),E=i(y());var I=i(L());var o=i(h()),d=i(P()),n=i(w()),S=i(y()),x=i(L());var c=i(h()),J=i(w());function N({jobId:s}){let r=C(s)?k(s):b(s);return c.default.createElement(J.Typography,null,"Job ",s," (",c.default.createElement(B,{href:r},"see status"),")")}var v=N;var U=(0,x.makeStyles)()({margin:{padding:20},progressRow:{display:"flex",alignItems:"center",gap:12}}),D=(0,S.observer)(function({model:r}){let{progress:u,rid:a,error:m}=r,{classes:t}=U(),f=!r.launchCompleted,{blastParams:l,orthologParams:g}=r,p=l?`Running EBI ${l.searchProgram==="phmmer"?"phmmer":"BLAST"}`:g?g.source==="uniref"?"Building UniRef homolog alignment":"Building ortholog alignment":"Loading alignment";return o.default.createElement("div",{className:t.margin},m?o.default.createElement(o.default.Fragment,null,o.default.createElement(n.Typography,{variant:"h5"},f?`${p} failed`:"Alignment no longer available"),a?o.default.createElement(v,{jobId:a}):null,o.default.createElement(d.ErrorMessage,{error:m}),o.default.createElement("div",{className:t.progressRow},o.default.createElement(n.Button,{variant:"outlined",size:"small",onClick:()=>{r.retryLaunch()}},"Retry"),o.default.createElement(n.Button,{variant:"outlined",size:"small",onClick:()=>{r.cancelLaunch()}},"Dismiss"))):o.default.createElement(o.default.Fragment,null,o.default.createElement(d.LoadingEllipses,{message:p,variant:"h5"}),a?o.default.createElement(v,{jobId:a}):null,o.default.createElement("div",{className:t.progressRow},o.default.createElement(n.Typography,null,u||"Initializing"),o.default.createElement(n.Button,{variant:"outlined",size:"small",onClick:()=>{r.cancelLaunch()}},"Cancel"))))}),V=D;var $=(0,I.makeStyles)()({loadingContainer:{padding:20}}),q=(0,E.observer)(function({model:r}){let{classes:u}=$(),{blastParams:a,orthologParams:m,init:t,loadingStoredData:f}=r,l=a??m,g=!!l&&!r.launchCompleted,p=!!(r.data.msa||r.data.tree),T=!!l&&!!r.error&&!p,A=g||T||!!t&&!r.dataInitialized;return e.default.createElement("div",null,A?e.default.createElement(V,{model:r}):f&&!r.dataInitialized?e.default.createElement("div",{className:u.loadingContainer},e.default.createElement(z.LoadingEllipses,{message:"Loading MSA data",variant:"h6"})):e.default.createElement(M,{model:r}))}),X=q;export{X as default};
|
|
2
|
-
//# sourceMappingURL=MsaViewPanel-RUZAKFCB.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{b as n,c}from"./chunk-H6IQBAW7.js";import"./chunk-YOTSFJMU.js";import"./chunk-F3EC6OCO.js";import"./chunk-QQ5LZUIO.js";import"./chunk-73KAPCJ2.js";import"./chunk-GDFVLZYX.js";import"./chunk-GIHMPOCO.js";import{a as g}from"./chunk-CVLB4VFP.js";import{a as h}from"./chunk-DNFD5II2.js";import{a as x}from"./chunk-BX4Z274Q.js";import{a as d}from"./chunk-J6KYLXRD.js";import{b as r}from"./chunk-FY3BTKY4.js";var e=r(d(),1),i=r(h(),1),t=r(x(),1),f=r(g(),1);var T=(0,f.observer)(function({info:u,model:o,nodeName:a,onClose:E}){let{rows:p}=o,l=o.rowDataOf(a),m=p.find(s=>s[0]===a);return e.default.createElement(i.Dialog,{onClose:()=>{E()},open:!0,title:"Tree node info",maxWidth:"xl"},e.default.createElement(t.DialogContent,null,e.default.createElement(t.Typography,{variant:"h6"},"Attributes"),e.default.createElement(n,{record:{nodeName:a,...u}}),e.default.createElement(t.Typography,{variant:"h6"},"Sequence"),m?e.default.createElement(c,{str:[m]}):e.default.createElement(t.Typography,null,"Sequence not found"),l?e.default.createElement(e.default.Fragment,null,e.default.createElement(t.Typography,{variant:"h6"},"Extra metadata"),e.default.createElement(n,{record:l})):null))}),b=T;export{b as default};
|
|
2
|
-
//# sourceMappingURL=TreeNodeInfoDialog-VRCVIF26.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as S}from"./chunk-J6KYLXRD.js";import{b as x}from"./chunk-FY3BTKY4.js";function A(t){try{return new URL(t).host}catch{return t}}var p=class extends Error{constructor(r,o){super(r);this.status=o}};async function b(t,e){let r;try{r=await fetch(t,e)}catch(o){throw o instanceof TypeError?new Error(`Could not reach ${A(t)} \u2014 the request failed at the network level. This is usually a CORS restriction (the server refused to let this site read the response), an offline connection, or a blocked request.`,{cause:o}):o}if(!r.ok)throw new p(`HTTP ${r.status} fetching ${t} ${(await r.text()).slice(0,500)}`,r.status);return r}async function c(t,e){return(await b(t,e)).text()}async function v(t,e){return(await b(t,e)).json()}function l(t,e){return new Promise((r,o)=>{if(e?.aborted){o(new DOMException("Aborted","AbortError"));return}let s=()=>{clearTimeout(n),o(new DOMException("Aborted","AbortError"))},n=setTimeout(()=>{e?.removeEventListener("abort",s),r()},t);e?.addEventListener("abort",s,{once:!0})})}function h(t){return t instanceof Error&&t.name==="AbortError"}var f=x(S());function u(t,e){try{let r=globalThis.localStorage.getItem(t);return r===null?e:JSON.parse(r)}catch(r){return console.error(r),e}}function O(t,e){let[r,o]=(0,f.useState)(()=>u(t,e));return[r,n=>{o(n);try{globalThis.localStorage.setItem(t,JSON.stringify(n))}catch(a){console.error(a)}}]}async function d({check:t,intervalSeconds:e,onCountdown:r,signal:o}){for(;;){if(o?.throwIfAborted(),await t())return;for(let s=e;s>0;s--)r(s),await l(1e3,o)}}var m="https://www.ebi.ac.uk/Tools/services/rest",y="msa-ebiContactEmail",g="jbrowse2@berkeley.edu";function T(){return u(y,g).trim()||g}var B=new Set(["ERROR","FAILURE","NOT_FOUND"]);async function I({tool:t,params:e,signal:r}){return(await c(`${m}/${t}/run`,{method:"POST",body:new URLSearchParams({email:T(),...e}),signal:r})).trim()}var w=900*1e3;async function P({tool:t,jobId:e,intervalSeconds:r=10,onCountdown:o,signal:s}){let n;await d({intervalSeconds:r,onCountdown:o,signal:s,check:async()=>{let a;try{a=(await c(`${m}/${t}/status/${e}`,{signal:s})).trim()}catch(i){if(h(i))throw i;if(n??=Date.now(),Date.now()-n>=w)throw new Error(`Could not reach EBI to check ${t} job ${e} for ${Math.round(w/6e4)} minutes`,{cause:i});return console.warn("[msaview] EBI status check failed, retrying:",i),!1}if(n=void 0,a==="FINISHED")return!0;if(B.has(a))throw new Error(`EBI ${t} job ${e} returned status ${a}`);return!1}})}async function H({tool:t,label:e,params:r,onProgress:o,onRid:s,signal:n}){o(`Submitting ${e} to EBI...`);let a=await I({tool:t,params:r,signal:n});return s?.(a),await P({tool:t,jobId:a,signal:n,onCountdown:i=>{o(`Re-checking ${e} status in... ${i}`)}}),{jobId:a,result:i=>c(`${m}/${t}/result/${a}/${i}`,{signal:n})}}var N="https://blast.ncbi.nlm.nih.gov/Blast.cgi",R=["clustalo","muscle","kalign","mafft"],V=[...R,"browser"],G={clustalo:"Clustal Omega (EBI)",muscle:"MUSCLE (EBI)",kalign:"Kalign (EBI)",mafft:"MAFFT (EBI)",browser:"in browser, query-anchored"},D=["uniprotkb_swissprot","uniprotkb","pan_proteomes","uniprotkb_trembl"],L="uniprotkb_swissprot",Y=["blastp","phmmer"],z={blastp:"blastp (sequence search)",phmmer:"phmmer (profile HMM search)"},$=["swissprot","uniprotkb","uniprotrefprot","rp75","rp55","rp35","rp15"],_="swissprot",E=[5,10,20,50,100,150,200,250,500,750,1e3],Q=100;function W(t){return E.find(e=>e>=t)??E.at(-1)}function X(t){return t==="phmmer"?{program:t,database:_}:{program:t,database:L}}function Z(t){return t==="phmmer"?$:D}var k={uniprotkb_swissprot:"UniProtKB/Swiss-Prot (curated)",swissprot:"UniProtKB/Swiss-Prot (curated)",uniprotkb:"UniProtKB (all entries)",uniprotkb_trembl:"UniProtKB/TrEMBL (unreviewed)",pan_proteomes:"Pan-proteomes",uniprotrefprot:"UniProt reference proteomes",rp75:"Representative proteomes, 75%",rp55:"Representative proteomes, 55%",rp35:"Representative proteomes, 35%",rp15:"Representative proteomes, 15% (widest spread)"};function tt(t){return k[t]}export{p as a,b,c,v as d,l as e,h as f,O as g,y as h,g as i,H as j,N as k,V as l,G as m,Y as n,z as o,Q as p,W as q,X as r,Z as s,tt as t};
|
|
2
|
-
//# sourceMappingURL=chunk-F726IWCW.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/utils/fetch.ts", "../../src/utils/useLocalStorage.ts", "../../src/utils/poll.ts", "../../src/utils/ebiJobDispatcher.ts", "../../src/LaunchMsaView/components/BlastQuery/consts.ts"],
|
|
4
|
-
"sourcesContent": ["function hostOf(url: string) {\n try {\n return new URL(url).host\n } catch {\n // a relative url, e.g. a same-origin proxy path\n return url\n }\n}\n\nexport class HttpError extends Error {\n constructor(\n message: string,\n readonly status: number,\n ) {\n super(message)\n }\n}\n\nexport async function handleFetch(url: string, args?: RequestInit) {\n let response: Response\n try {\n response = await fetch(url, args)\n } catch (e) {\n // fetch rejects with a bare \"TypeError: Failed to fetch\" for every network\n // level failure, including a cross-origin response the browser refused to\n // hand over. That is not a hypothetical: NCBI's Blast.cgi stopped sending\n // Access-Control-Allow-Origin to third-party origins, and the raw TypeError\n // told users nothing at all about why. See docs/blast.md.\n if (e instanceof TypeError) {\n throw new Error(\n `Could not reach ${hostOf(url)} \u2014 the request failed at the network level. This is usually a CORS restriction (the server refused to let this site read the response), an offline connection, or a blocked request.`,\n { cause: e },\n )\n }\n throw e\n }\n\n if (!response.ok) {\n throw new HttpError(\n `HTTP ${response.status} fetching ${url} ${(await response.text()).slice(0, 500)}`,\n response.status,\n )\n }\n\n return response\n}\n\nexport async function textfetch(url: string, args?: RequestInit) {\n const response = await handleFetch(url, args)\n return response.text()\n}\n\nexport async function jsonfetch<T>(url: string, args?: RequestInit) {\n const response = await handleFetch(url, args)\n return response.json() as Promise<T>\n}\n\nexport function timeout(time: number, signal?: AbortSignal) {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException('Aborted', 'AbortError'))\n return\n }\n // the listener is removed on the natural path too: one signal serves every\n // tick of a poll, and a 10-minute job is ~600 sleeps -- leaving each\n // listener behind accumulates them all on that one signal\n const onAbort = () => {\n clearTimeout(id)\n reject(new DOMException('Aborted', 'AbortError'))\n }\n const id = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, time)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\n/**\n * A cancelled launch has to be told apart from a failed one: it must not render\n * the \"failed\" panel, and it must not touch a model that may already be gone.\n * `fetch` and the sleep above both reject with a DOMException named AbortError,\n * which subclasses Error.\n */\nexport function isAbortError(e: unknown) {\n return e instanceof Error && e.name === 'AbortError'\n}\n", "import { useState } from 'react'\n\n// Vendored rather than imported from `@jbrowse/core/util`: that barrel is\n// host-provided, and a barrel split dropped this export, making the BLAST panel\n// throw \"(0, PR.useLocalStorage) is not a function\" on hosts built during that\n// window. Same failure mode as `defaultCodonTable`; keeping our own copy takes\n// this plugin out of the whack-a-mole.\nexport function readLocalStorage<T>(key: string, initialValue: T): T {\n try {\n const item = globalThis.localStorage.getItem(key)\n return item === null ? initialValue : (JSON.parse(item) as T)\n } catch (error) {\n console.error(error)\n return initialValue\n }\n}\n\nexport function useLocalStorage<T>(key: string, initialValue: T) {\n const [storedValue, setStoredValue] = useState<T>(() =>\n readLocalStorage(key, initialValue),\n )\n const setValue = (value: T) => {\n setStoredValue(value)\n try {\n globalThis.localStorage.setItem(key, JSON.stringify(value))\n } catch (error) {\n console.error(error)\n }\n }\n return [storedValue, setValue] as const\n}\n", "import { timeout } from './fetch'\n\n/**\n * Poll a remote job until it reports done. `check` returns true when finished,\n * false when still pending, and throws on failure. Between checks it counts down\n * `intervalSeconds`, calling `onCountdown` each second so the UI can show\n * progress.\n *\n * `signal` ends the loop with an AbortError: the countdown rejects on the tick\n * it is aborted rather than at the end of the interval, so a cancelled launch\n * stops within a second instead of running for the job's lifetime.\n */\nexport async function pollLoop({\n check,\n intervalSeconds,\n onCountdown,\n signal,\n}: {\n check: () => Promise<boolean>\n intervalSeconds: number\n onCountdown: (secondsRemaining: number) => void\n signal?: AbortSignal\n}) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while (true) {\n signal?.throwIfAborted()\n if (await check()) {\n return\n }\n for (let i = intervalSeconds; i > 0; i--) {\n onCountdown(i)\n await timeout(1000, signal)\n }\n }\n}\n", "import { isAbortError, textfetch } from './fetch'\nimport { pollLoop } from './poll'\nimport { readLocalStorage } from './useLocalStorage'\n\n/**\n * EBI's Job Dispatcher REST services (clustalo, muscle, ncbiblast, ...) all\n * speak the same run/status/result protocol, so the transport lives here and\n * each tool only supplies its own parameters and result types.\n *\n * Unlike NCBI's Blast.cgi these endpoints send `Access-Control-Allow-Origin: *`,\n * which is why the BLAST backend moved here \u2014 see docs/blast.md.\n */\nexport const EBI_BASE = 'https://www.ebi.ac.uk/Tools/services/rest'\n\n/**\n * EBI asks for a contact address on every submission so they can reach whoever\n * is generating the load. The default is the project's mailbox; a deployment\n * that sends real volume should name its own maintainer in the BLAST settings\n * dialog.\n */\nexport const EBI_EMAIL_STORAGE_KEY = 'msa-ebiContactEmail'\nexport const DEFAULT_EBI_EMAIL = 'jbrowse2@berkeley.edu'\n\nexport function getEbiEmail() {\n const configured = readLocalStorage(\n EBI_EMAIL_STORAGE_KEY,\n DEFAULT_EBI_EMAIL,\n ).trim()\n return configured || DEFAULT_EBI_EMAIL\n}\n\n/** Statuses that mean the job is over and produced no result. */\nconst FAILED_STATUSES = new Set(['ERROR', 'FAILURE', 'NOT_FOUND'])\n\nasync function submitEbiJob({\n tool,\n params,\n signal,\n}: {\n tool: string\n params: Record<string, string>\n signal?: AbortSignal\n}) {\n const jobId = await textfetch(`${EBI_BASE}/${tool}/run`, {\n method: 'POST',\n body: new URLSearchParams({ email: getEbiEmail(), ...params }),\n signal,\n })\n return jobId.trim()\n}\n\n/**\n * A status check that could not reach EBI at all says nothing about the job, so\n * it is not a reason to abandon one. A job the server has accepted keeps running\n * whatever happens to the poller's connection, and EBI's cluster has answered\n * status checks with a 502 for ten minutes on jobs that then finished (see\n * docs/blast.md).\n *\n * So the poll gives up only once checks have failed without a break for this\n * long: an endpoint that has genuinely gone away must not be polled forever.\n */\nexport const STATUS_FAILURE_BUDGET_MS = 15 * 60 * 1000\n\nexport async function waitForEbiJob({\n tool,\n jobId,\n intervalSeconds = 10,\n onCountdown,\n signal,\n}: {\n tool: string\n jobId: string\n intervalSeconds?: number\n onCountdown: (secondsRemaining: number) => void\n signal?: AbortSignal\n}) {\n let failingSince: number | undefined\n await pollLoop({\n intervalSeconds,\n onCountdown,\n signal,\n check: async () => {\n let status: string\n try {\n status = (\n await textfetch(`${EBI_BASE}/${tool}/status/${jobId}`, { signal })\n ).trim()\n } catch (e) {\n // a cancelled request is the caller giving up, not EBI being\n // unreachable, so it must end the poll rather than be retried\n if (isAbortError(e)) {\n throw e\n }\n failingSince ??= Date.now()\n if (Date.now() - failingSince >= STATUS_FAILURE_BUDGET_MS) {\n throw new Error(\n `Could not reach EBI to check ${tool} job ${jobId} for ${Math.round(STATUS_FAILURE_BUDGET_MS / 60_000)} minutes`,\n { cause: e },\n )\n }\n console.warn('[msaview] EBI status check failed, retrying:', e)\n return false\n }\n failingSince = undefined\n // exact match, not includes(): a job whose status is ERROR must not be\n // able to poll forever waiting for a FINISHED that will never arrive\n if (status === 'FINISHED') {\n return true\n }\n if (FAILED_STATUSES.has(status)) {\n throw new Error(`EBI ${tool} job ${jobId} returned status ${status}`)\n }\n // RUNNING, QUEUED, PENDING and anything else EBI adds later\n return false\n },\n })\n}\n\nexport async function runEbiJob({\n tool,\n label,\n params,\n onProgress,\n onRid,\n signal,\n}: {\n tool: string\n label: string\n params: Record<string, string>\n onProgress: (arg: string) => void\n onRid?: (jobId: string) => void\n signal?: AbortSignal\n}) {\n onProgress(`Submitting ${label} to EBI...`)\n const jobId = await submitEbiJob({ tool, params, signal })\n onRid?.(jobId)\n await waitForEbiJob({\n tool,\n jobId,\n signal,\n onCountdown: s => {\n onProgress(`Re-checking ${label} status in... ${s}`)\n },\n })\n return {\n jobId,\n result: (type: string) =>\n textfetch(`${EBI_BASE}/${tool}/result/${jobId}/${type}`, { signal }),\n }\n}\n", "/**\n * Only used to build the link-out on the manual panel, which sends the user to\n * NCBI's own site to run BLAST there. Nothing fetches this url: NCBI stopped\n * sending Access-Control-Allow-Origin to third-party origins, so a browser\n * cannot read a response from it at all. See docs/blast.md.\n */\nexport const BASE_BLAST_URL = 'https://blast.ncbi.nlm.nih.gov/Blast.cgi'\n\n/** The aligners EBI's Job Dispatcher runs, each a tool name at their REST api. */\nexport const ebiMsaAlgorithms = [\n 'clustalo',\n 'muscle',\n 'kalign',\n 'mafft',\n] as const\nexport type EbiMsaAlgorithm = (typeof ebiMsaAlgorithms)[number]\n\n/**\n * `browser` is no job at all: each sequence is aligned to the query in the\n * page and the rows merged on the query (utils/browserAlign.ts), with the tree\n * built by react-msaview's neighbour joining. It is the aligner for a launch\n * that must not depend on EBI, and for one that wants to be quick -- a\n * hundred 400-residue rows take under a second, and a hundred 1400-residue\n * rows eight, against a Job Dispatcher queue that has been measured at\n * anything from ten seconds to fifteen minutes. Past the per-sequence limit in\n * browserAlign.ts it refuses and names an EBI aligner instead.\n */\nexport const msaAlgorithms = [...ebiMsaAlgorithms, 'browser'] as const\nexport type MsaAlgorithm = (typeof msaAlgorithms)[number]\n\nexport const msaAlgorithmLabels: Record<MsaAlgorithm, string> = {\n clustalo: 'Clustal Omega (EBI)',\n muscle: 'MUSCLE (EBI)',\n kalign: 'Kalign (EBI)',\n mafft: 'MAFFT (EBI)',\n browser: 'in browser, query-anchored',\n}\n\n/**\n * EBI rejects a submission naming a database outside its own list with a 400,\n * so every value here has to appear in\n * https://www.ebi.ac.uk/Tools/services/rest/ncbiblast/parameterdetails/database\n * -- `uniprotkb_reference_proteomes` did not, and 3.0.0 shipped it as a dead\n * menu entry.\n */\nexport const blastDatabaseOptions = [\n 'uniprotkb_swissprot',\n 'uniprotkb',\n 'pan_proteomes',\n 'uniprotkb_trembl',\n] as const\nexport type BlastDatabase = (typeof blastDatabaseOptions)[number]\n\n// curated, so it returns roughly one good sequence per species rather than the\n// many near-identical TrEMBL entries an alignment reads poorly\nconst defaultBlastDatabase: BlastDatabase = 'uniprotkb_swissprot'\n\nexport const searchPrograms = ['blastp', 'phmmer'] as const\nexport type SearchProgram = (typeof searchPrograms)[number]\n\nexport const searchProgramLabels: Record<SearchProgram, string> = {\n blastp: 'blastp (sequence search)',\n phmmer: 'phmmer (profile HMM search)',\n}\n\n/**\n * phmmer offers PDB, AlphaFold, Ensembl Genomes, MEROPS and ChEMBL too, but\n * targets outside UniProt carry no species in their description, so those rows\n * would lose their species and common name. Only the databases that label their\n * hits are offered.\n *\n * rp15..rp75 are the Representative Proteomes: UniProt's reference proteomes\n * thinned so that no two are more than 15% (35%, 55%, 75%) similar, which is\n * the widest taxonomic spread per hit that any of these databases gives. rp15\n * is the one to reach for when the question is \"what is this like across all\n * of life\"; swissprot when it is \"what is this like in the curated set\".\n */\nexport const phmmerDatabaseOptions = [\n 'swissprot',\n 'uniprotkb',\n 'uniprotrefprot',\n 'rp75',\n 'rp55',\n 'rp35',\n 'rp15',\n] as const\nexport type PhmmerDatabase = (typeof phmmerDatabaseOptions)[number]\n\nconst defaultPhmmerDatabase: PhmmerDatabase = 'swissprot'\n\n/**\n * The hit counts EBI's ncbiblast accepts for `alignments` and `scores`. A value\n * off this list is a 400 at submit time, so a request is rounded up to the next\n * one on it.\n */\nconst blastHitCounts = [5, 10, 20, 50, 100, 150, 200, 250, 500, 750, 1000]\n\nexport const defaultMaxHits = 100\n\nexport function snapBlastHitCount(maxHits: number) {\n return blastHitCounts.find(n => n >= maxHits) ?? blastHitCounts.at(-1)!\n}\n\n/**\n * A program together with a database that program actually has.\n *\n * The pair travels as one value because neither service knows the other's\n * database names \u2014 `swissprot` is a phmmer database and `uniprotkb_swissprot` a\n * blastp one \u2014 so a program held apart from its database can drift into a\n * combination EBI answers with a 400, minutes after the user pressed Submit.\n */\nexport type SearchChoice =\n | { program: 'blastp'; database: BlastDatabase }\n | { program: 'phmmer'; database: PhmmerDatabase }\n\nexport function defaultSearchFor(program: SearchProgram): SearchChoice {\n return program === 'phmmer'\n ? { program, database: defaultPhmmerDatabase }\n : { program, database: defaultBlastDatabase }\n}\n\nexport function databaseOptionsFor(program: SearchProgram) {\n return program === 'phmmer' ? phmmerDatabaseOptions : blastDatabaseOptions\n}\n\n/**\n * What each database is called in the menu. The keys are what EBI is sent and\n * are not negotiable; `uniprotkb_swissprot` and `swissprot` are the same\n * collection under each service's own name, so they read the same here.\n */\nconst databaseLabels: Record<BlastDatabase | PhmmerDatabase, string> = {\n uniprotkb_swissprot: 'UniProtKB/Swiss-Prot (curated)',\n swissprot: 'UniProtKB/Swiss-Prot (curated)',\n uniprotkb: 'UniProtKB (all entries)',\n uniprotkb_trembl: 'UniProtKB/TrEMBL (unreviewed)',\n pan_proteomes: 'Pan-proteomes',\n uniprotrefprot: 'UniProt reference proteomes',\n rp75: 'Representative proteomes, 75%',\n rp55: 'Representative proteomes, 55%',\n rp35: 'Representative proteomes, 35%',\n rp15: 'Representative proteomes, 15% (widest spread)',\n}\n\nexport function databaseLabel(database: BlastDatabase | PhmmerDatabase) {\n return databaseLabels[database]\n}\n"],
|
|
5
|
-
"mappings": "gFAAA,SAASA,EAAOC,EAAa,CAC3B,GAAI,CACF,OAAO,IAAI,IAAIA,CAAG,EAAE,IACtB,MAAQ,CAEN,OAAOA,CACT,CACF,CAEO,IAAMC,EAAN,cAAwB,KAAM,CACnC,YACEC,EACSC,EACT,CACA,MAAMD,CAAO,EAFJ,YAAAC,CAGX,CACF,EAEA,eAAsBC,EAAYJ,EAAaK,EAAoB,CACjE,IAAIC,EACJ,GAAI,CACFA,EAAW,MAAM,MAAMN,EAAKK,CAAI,CAClC,OAASE,EAAG,CAMV,MAAIA,aAAa,UACT,IAAI,MACR,mBAAmBR,EAAOC,CAAG,CAAC,4LAC9B,CAAE,MAAOO,CAAE,CACb,EAEIA,CACR,CAEA,GAAI,CAACD,EAAS,GACZ,MAAM,IAAIL,EACR,QAAQK,EAAS,MAAM,aAAaN,CAAG,KAAK,MAAMM,EAAS,KAAK,GAAG,MAAM,EAAG,GAAG,CAAC,GAChFA,EAAS,MACX,EAGF,OAAOA,CACT,CAEA,eAAsBE,EAAUR,EAAaK,EAAoB,CAE/D,OADiB,MAAMD,EAAYJ,EAAKK,CAAI,GAC5B,KAAK,CACvB,CAEA,eAAsBI,EAAaT,EAAaK,EAAoB,CAElE,OADiB,MAAMD,EAAYJ,EAAKK,CAAI,GAC5B,KAAK,CACvB,CAEO,SAASK,EAAQC,EAAcC,EAAsB,CAC1D,OAAO,IAAI,QAAc,CAACC,EAASC,IAAW,CAC5C,GAAIF,GAAQ,QAAS,CACnBE,EAAO,IAAI,aAAa,UAAW,YAAY,CAAC,EAChD,MACF,CAIA,IAAMC,EAAU,IAAM,CACpB,aAAaC,CAAE,EACfF,EAAO,IAAI,aAAa,UAAW,YAAY,CAAC,CAClD,EACME,EAAK,WAAW,IAAM,CAC1BJ,GAAQ,oBAAoB,QAASG,CAAO,EAC5CF,EAAQ,CACV,EAAGF,CAAI,EACPC,GAAQ,iBAAiB,QAASG,EAAS,CAAE,KAAM,EAAK,CAAC,CAC3D,CAAC,CACH,CAQO,SAASE,EAAaV,EAAY,CACvC,OAAOA,aAAa,OAASA,EAAE,OAAS,YAC1C,CCtFA,IAAAW,EAAyB,OAOlB,SAASC,EAAoBC,EAAaC,EAAoB,CACnE,GAAI,CACF,IAAMC,EAAO,WAAW,aAAa,QAAQF,CAAG,EAChD,OAAOE,IAAS,KAAOD,EAAgB,KAAK,MAAMC,CAAI,CACxD,OAASC,EAAO,CACd,eAAQ,MAAMA,CAAK,EACZF,CACT,CACF,CAEO,SAASG,EAAmBJ,EAAaC,EAAiB,CAC/D,GAAM,CAACI,EAAaC,CAAc,KAAI,YAAY,IAChDP,EAAiBC,EAAKC,CAAY,CACpC,EASA,MAAO,CAACI,EARUE,GAAa,CAC7BD,EAAeC,CAAK,EACpB,GAAI,CACF,WAAW,aAAa,QAAQP,EAAK,KAAK,UAAUO,CAAK,CAAC,CAC5D,OAASJ,EAAO,CACd,QAAQ,MAAMA,CAAK,CACrB,CACF,CAC6B,CAC/B,CClBA,eAAsBK,EAAS,CAC7B,MAAAC,EACA,gBAAAC,EACA,YAAAC,EACA,OAAAC,CACF,EAKG,CAED,OAAa,CAEX,GADAA,GAAQ,eAAe,EACnB,MAAMH,EAAM,EACd,OAEF,QAASI,EAAIH,EAAiBG,EAAI,EAAGA,IACnCF,EAAYE,CAAC,EACb,MAAMC,EAAQ,IAAMF,CAAM,CAE9B,CACF,CCtBO,IAAMG,EAAW,4CAQXC,EAAwB,sBACxBC,EAAoB,wBAE1B,SAASC,GAAc,CAK5B,OAJmBC,EACjBH,EACAC,CACF,EAAE,KAAK,GACcA,CACvB,CAGA,IAAMG,EAAkB,IAAI,IAAI,CAAC,QAAS,UAAW,WAAW,CAAC,EAEjE,eAAeC,EAAa,CAC1B,KAAAC,EACA,OAAAC,EACA,OAAAC,CACF,EAIG,CAMD,OALc,MAAMC,EAAU,GAAGV,CAAQ,IAAIO,CAAI,OAAQ,CACvD,OAAQ,OACR,KAAM,IAAI,gBAAgB,CAAE,MAAOJ,EAAY,EAAG,GAAGK,CAAO,CAAC,EAC7D,OAAAC,CACF,CAAC,GACY,KAAK,CACpB,CAYO,IAAME,EAA2B,IAAU,IAElD,eAAsBC,EAAc,CAClC,KAAAL,EACA,MAAAM,EACA,gBAAAC,EAAkB,GAClB,YAAAC,EACA,OAAAN,CACF,EAMG,CACD,IAAIO,EACJ,MAAMC,EAAS,CACb,gBAAAH,EACA,YAAAC,EACA,OAAAN,EACA,MAAO,SAAY,CACjB,IAAIS,EACJ,GAAI,CACFA,GACE,MAAMR,EAAU,GAAGV,CAAQ,IAAIO,CAAI,WAAWM,CAAK,GAAI,CAAE,OAAAJ,CAAO,CAAC,GACjE,KAAK,CACT,OAASU,EAAG,CAGV,GAAIC,EAAaD,CAAC,EAChB,MAAMA,EAGR,GADAH,IAAiB,KAAK,IAAI,EACtB,KAAK,IAAI,EAAIA,GAAgBL,EAC/B,MAAM,IAAI,MACR,gCAAgCJ,CAAI,QAAQM,CAAK,QAAQ,KAAK,MAAMF,EAA2B,GAAM,CAAC,WACtG,CAAE,MAAOQ,CAAE,CACb,EAEF,eAAQ,KAAK,+CAAgDA,CAAC,EACvD,EACT,CAIA,GAHAH,EAAe,OAGXE,IAAW,WACb,MAAO,GAET,GAAIb,EAAgB,IAAIa,CAAM,EAC5B,MAAM,IAAI,MAAM,OAAOX,CAAI,QAAQM,CAAK,oBAAoBK,CAAM,EAAE,EAGtE,MAAO,EACT,CACF,CAAC,CACH,CAEA,eAAsBG,EAAU,CAC9B,KAAAd,EACA,MAAAe,EACA,OAAAd,EACA,WAAAe,EACA,MAAAC,EACA,OAAAf,CACF,EAOG,CACDc,EAAW,cAAcD,CAAK,YAAY,EAC1C,IAAMT,EAAQ,MAAMP,EAAa,CAAE,KAAAC,EAAM,OAAAC,EAAQ,OAAAC,CAAO,CAAC,EACzD,OAAAe,IAAQX,CAAK,EACb,MAAMD,EAAc,CAClB,KAAAL,EACA,MAAAM,EACA,OAAAJ,EACA,YAAagB,GAAK,CAChBF,EAAW,eAAeD,CAAK,iBAAiBG,CAAC,EAAE,CACrD,CACF,CAAC,EACM,CACL,MAAAZ,EACA,OAASa,GACPhB,EAAU,GAAGV,CAAQ,IAAIO,CAAI,WAAWM,CAAK,IAAIa,CAAI,GAAI,CAAE,OAAAjB,CAAO,CAAC,CACvE,CACF,CC/IO,IAAMkB,EAAiB,2CAGjBC,EAAmB,CAC9B,WACA,SACA,SACA,OACF,EAaaC,EAAgB,CAAC,GAAGD,EAAkB,SAAS,EAG/CE,EAAmD,CAC9D,SAAU,sBACV,OAAQ,eACR,OAAQ,eACR,MAAO,cACP,QAAS,4BACX,EASaC,EAAuB,CAClC,sBACA,YACA,gBACA,kBACF,EAKMC,EAAsC,sBAE/BC,EAAiB,CAAC,SAAU,QAAQ,EAGpCC,EAAqD,CAChE,OAAQ,2BACR,OAAQ,6BACV,EAcaC,EAAwB,CACnC,YACA,YACA,iBACA,OACA,OACA,OACA,MACF,EAGMC,EAAwC,YAOxCC,EAAiB,CAAC,EAAG,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,EAE5DC,EAAiB,IAEvB,SAASC,EAAkBC,EAAiB,CACjD,OAAOH,EAAe,KAAKI,GAAKA,GAAKD,CAAO,GAAKH,EAAe,GAAG,EAAE,CACvE,CAcO,SAASK,EAAiBC,EAAsC,CACrE,OAAOA,IAAY,SACf,CAAE,QAAAA,EAAS,SAAUP,CAAsB,EAC3C,CAAE,QAAAO,EAAS,SAAUX,CAAqB,CAChD,CAEO,SAASY,EAAmBD,EAAwB,CACzD,OAAOA,IAAY,SAAWR,EAAwBJ,CACxD,CAOA,IAAMc,EAAiE,CACrE,oBAAqB,iCACrB,UAAW,iCACX,UAAW,0BACX,iBAAkB,gCAClB,cAAe,gBACf,eAAgB,8BAChB,KAAM,gCACN,KAAM,gCACN,KAAM,gCACN,KAAM,+CACR,EAEO,SAASC,GAAcC,EAA0C,CACtE,OAAOF,EAAeE,CAAQ,CAChC",
|
|
6
|
-
"names": ["hostOf", "url", "HttpError", "message", "status", "handleFetch", "args", "response", "e", "textfetch", "jsonfetch", "timeout", "time", "signal", "resolve", "reject", "onAbort", "id", "isAbortError", "import_react", "readLocalStorage", "key", "initialValue", "item", "error", "useLocalStorage", "storedValue", "setStoredValue", "value", "pollLoop", "check", "intervalSeconds", "onCountdown", "signal", "i", "timeout", "EBI_BASE", "EBI_EMAIL_STORAGE_KEY", "DEFAULT_EBI_EMAIL", "getEbiEmail", "readLocalStorage", "FAILED_STATUSES", "submitEbiJob", "tool", "params", "signal", "textfetch", "STATUS_FAILURE_BUDGET_MS", "waitForEbiJob", "jobId", "intervalSeconds", "onCountdown", "failingSince", "pollLoop", "status", "e", "isAbortError", "runEbiJob", "label", "onProgress", "onRid", "s", "type", "BASE_BLAST_URL", "ebiMsaAlgorithms", "msaAlgorithms", "msaAlgorithmLabels", "blastDatabaseOptions", "defaultBlastDatabase", "searchPrograms", "searchProgramLabels", "phmmerDatabaseOptions", "defaultPhmmerDatabase", "blastHitCounts", "defaultMaxHits", "snapBlastHitCount", "maxHits", "n", "defaultSearchFor", "program", "databaseOptionsFor", "databaseLabels", "databaseLabel", "database"]
|
|
7
|
-
}
|