@sjcrh/proteinpaint-client 2.220.0 → 2.221.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/2dmaf-7YU3SNKL.js +1362 -0
- package/dist/AggMatrixInput-73CDR5FS.js +402 -0
- package/dist/AggregateMatrix-NNULVFBM.js +37 -0
- package/dist/AppHeader-EZDDLLXU.js +826 -0
- package/dist/BoxPlot-463E7CRY.js +1229 -0
- package/dist/CorrelationVolcano-LHIIMBPP.js +613 -0
- package/dist/Cuminc-UL2TCIKV.js +1217 -0
- package/dist/DE-VRFSKFDW.js +85 -0
- package/dist/DEinput-FZTQRWVC.js +479 -0
- package/dist/DM-PO7CQZNT.js +86 -0
- package/dist/DifferentialAnalysis-WK6HE3YH.js +236 -0
- package/dist/Disco-YBNQJQFG.js +3384 -0
- package/dist/Disco.UI-HC5XYBFV.js +239 -0
- package/dist/DmrPlot-7VJ5C66D.js +361 -0
- package/dist/GB-VPFQRDRO.js +1388 -0
- package/dist/GSEA-ZEJB3QZQ.js +870 -0
- package/dist/GeneExpInput-SBDDIY6G.js +38 -0
- package/dist/Geomap-23AHGP2V.js +80 -0
- package/dist/HicApp-7AQQE4CM.js +2240 -0
- package/dist/IDCViewer-NO5Q6VOB.js +10808 -0
- package/dist/NumBinaryEditor-DSRP4OOU.js +274 -0
- package/dist/NumBinaryEditor.unit.spec-TT666YL4.js +308 -0
- package/dist/NumContEditor-6CURFOCH.js +100 -0
- package/dist/NumContEditor.unit.spec-MNVCFCMP.js +160 -0
- package/dist/NumCustomBinEditor-SQRR5EFL.js +29 -0
- package/dist/NumCustomBinEditor.unit.spec-F7BZWGGT.js +393 -0
- package/dist/NumDiscreteEditor-U7Z2QNYP.js +165 -0
- package/dist/NumDiscreteEditor.unit.spec-EIEBUZCX.js +229 -0
- package/dist/NumRegularBinEditor-CVZSWN6Y.js +29 -0
- package/dist/NumRegularBinEditor.unit.spec-ZMAJOIHL.js +274 -0
- package/dist/NumSplineEditor-U43D5NBJ.js +205 -0
- package/dist/NumSplineEditor.unit.spec-C52AADTS.js +220 -0
- package/dist/NumericDensity-PUKDZOVI.js +29 -0
- package/dist/NumericDensity.unit.spec-2347S76D.js +414 -0
- package/dist/NumericHandler-3RT32PTR.js +30 -0
- package/dist/NumericHandler.unit.spec-4PADL4KZ.js +225 -0
- package/dist/ProteomeInput-NFV4FW4U.js +610 -0
- package/dist/Regression-N7M7N6G4.js +1412 -0
- package/dist/RunChart2-UPQ7C6QE.js +744 -0
- package/dist/SC-KBW2NHUV.js +1290 -0
- package/dist/Violin-GWCOP3ZF.js +1092 -0
- package/dist/Volcano-X3HT32GQ.js +2661 -0
- package/dist/Wsi-NXAEOYIS.js +636 -0
- package/dist/aboutSunburst-5EKXZV2A.js +86 -0
- package/dist/adSandbox-RPEWEEW7.js +29 -0
- package/dist/animatedBubbleChart-ILDMZRBX.js +542 -0
- package/dist/app-LOUC4J47.js +28 -0
- package/dist/app-MRKXZ6AZ.js +38 -0
- package/dist/app.js +9 -9
- package/dist/bam-SQWPHCZZ.js +872 -0
- package/dist/bam-SQWPHCZZ.js.map +7 -0
- package/dist/barchart-CJR37234.js +38 -0
- package/dist/barchart2-QQYLTHWR.js +305 -0
- package/dist/block-GLF6QNKY.js +6203 -0
- package/dist/block.init-YJQTJIDO.js +29 -0
- package/dist/block.mds.expressionrank-GBMEI5KQ.js +350 -0
- package/dist/block.mds.geneboxplot-XWE3E5IW.js +819 -0
- package/dist/block.mds.junction-QLEHFVPE.js +1534 -0
- package/dist/block.mds.svcnv-53DTOPBC.js +6413 -0
- package/dist/block.svg-57T37ABS.js +155 -0
- package/dist/block.tk.aicheck-6DXJTS3H.js +274 -0
- package/dist/block.tk.bam-CJFFQDNX.js +1906 -0
- package/dist/block.tk.bam-CJFFQDNX.js.map +7 -0
- package/dist/block.tk.bigwig.ui-OYIVXE2L.js +202 -0
- package/dist/block.tk.hicstraw-UKTGEBWT.js +814 -0
- package/dist/block.tk.junction-ZU5KPFQ3.js +2353 -0
- package/dist/block.tk.junction.textmatrixui-P4WXTAZR.js +190 -0
- package/dist/block.tk.ld-3PQ4O2AE.js +90 -0
- package/dist/block.tk.menu-LLITB6UA.js +1050 -0
- package/dist/block.tk.pgv-Y3FBXUO3.js +934 -0
- package/dist/brainImaging-4B3WXLNP.js +550 -0
- package/dist/brainRegions-7VLONUWN.js +213 -0
- package/dist/bubbleHeatmap-DI6GJRR6.js +374 -0
- package/dist/cellTypeBubbleHeatmap-HJY53DB2.js +274 -0
- package/dist/chunk-226MNBZ2.js +240 -0
- package/dist/chunk-2CDFU4MQ.js +536 -0
- package/dist/chunk-2CNFGVHU.js +257 -0
- package/dist/chunk-2MC3RNKA.js +2685 -0
- package/dist/chunk-2SL4QWUS.js +50 -0
- package/dist/chunk-3KGBC5MK.js +692 -0
- package/dist/chunk-3PCRAPUV.js +56 -0
- package/dist/chunk-4DBOMSKP.js +102 -0
- package/dist/chunk-57BS6KNI.js +466 -0
- package/dist/chunk-5AXS5G4A.js +2334 -0
- package/dist/chunk-5HJG6ECV.js +237 -0
- package/dist/chunk-5ZYANHGX.js +550 -0
- package/dist/chunk-75MRUW2K.js +103 -0
- package/dist/chunk-7J3W3KCN.js +255 -0
- package/dist/chunk-AIZYAKIE.js +182 -0
- package/dist/chunk-AJNFI6GA.js +2008 -0
- package/dist/chunk-BJAWDZBL.js +2799 -0
- package/dist/chunk-C6PVZVIH.js +379 -0
- package/dist/chunk-C77X5ZUV.js +176 -0
- package/dist/chunk-CUCP2GMT.js +102 -0
- package/dist/chunk-DTGAMBRJ.js +134 -0
- package/dist/chunk-DXT7GDHY.js +55 -0
- package/dist/chunk-ENPMWVWG.js +5214 -0
- package/dist/chunk-FPMJJBLV.js +4389 -0
- package/dist/chunk-H7F6DMJA.js +70 -0
- package/dist/chunk-HH3NUAR2.js +96 -0
- package/dist/chunk-HRTPGNOG.js +159 -0
- package/dist/chunk-IFPRYTS7.js +848 -0
- package/dist/chunk-IJSFSUI4.js +302 -0
- package/dist/chunk-IRQKX6DL.js +263 -0
- package/dist/chunk-JNZL7HKB.js +1219 -0
- package/dist/chunk-K3G56J5R.js +299 -0
- package/dist/chunk-KKUCG2QE.js +516 -0
- package/dist/chunk-KPXCXBNU.js +626 -0
- package/dist/chunk-LF5WBI27.js +418 -0
- package/dist/chunk-LF5WBI27.js.map +7 -0
- package/dist/chunk-MSTYU3QO.js +14 -0
- package/dist/chunk-MWARRQT4.js +141 -0
- package/dist/chunk-MXKYPTZ7.js +203 -0
- package/dist/chunk-OZUF7O2S.js +133 -0
- package/dist/chunk-PRTLCJYF.js +2941 -0
- package/dist/chunk-PWYMHUXY.js +116 -0
- package/dist/chunk-PWYMHUXY.js.map +7 -0
- package/dist/chunk-QNCE6EOK.js +82 -0
- package/dist/chunk-RV335DF2.js +266 -0
- package/dist/chunk-SFPZUBPM.js +2102 -0
- package/dist/chunk-SFPZUBPM.js.map +7 -0
- package/dist/chunk-THAUD62Q.js +1253 -0
- package/dist/chunk-VBTBUXXX.js +6375 -0
- package/dist/chunk-VHWJK2MP.js +56 -0
- package/dist/chunk-VMK4RHV5.js +54 -0
- package/dist/chunk-WD7FZ5EE.js +26536 -0
- package/dist/chunk-WD7FZ5EE.js.map +7 -0
- package/dist/chunk-WKT7RF3C.js +468 -0
- package/dist/chunk-WXSMUSU7.js +184 -0
- package/dist/chunk-WXSX5OQJ.js +296 -0
- package/dist/chunk-WY3IORKG.js +194 -0
- package/dist/chunk-WYSOOKFJ.js +480 -0
- package/dist/chunk-XBBFFOLS.js +123 -0
- package/dist/chunk-XSRQGX5H.js +340 -0
- package/dist/chunk-YLL6CTBL.js +54 -0
- package/dist/chunk-YPBY37KD.js +1339 -0
- package/dist/chunk-YUNJBIK4.js +243 -0
- package/dist/chunk-ZAC34BZQ.js +35 -0
- package/dist/chunk-ZAC34BZQ.js.map +7 -0
- package/dist/cohort-5WL6UJOS.js +66 -0
- package/dist/cohortSunburst-R3Z5KJQL.js +402 -0
- package/dist/condition-2IILUMVB.js +323 -0
- package/dist/controls-G3JITZF5.js +30 -0
- package/dist/controls.config-BO7KPPET.js +30 -0
- package/dist/correlation-CZILLVEM.js +91 -0
- package/dist/customdata.inputui-BXFQAMTR.js +280 -0
- package/dist/dataDownload-QTWR4IW7.js +326 -0
- package/dist/databrowser.ui-V2NJQF3U.js +421 -0
- package/dist/dictionary-OVAQX6R3.js +109 -0
- package/dist/dnaMethylation-DHPFRXB2.js +29 -0
- package/dist/dnaMethylation.integration.spec-PJLIRGN5.js +194 -0
- package/dist/e2pca-O7SNMJGB.js +340 -0
- package/dist/ep-NIVLKG4S.js +1247 -0
- package/dist/expclust.gdc.spec-LVCD6C43.js +298 -0
- package/dist/facet-LB4SCXE4.js +556 -0
- package/dist/gb-3IJ4NCPO.js +77 -0
- package/dist/geneExpClustering-SIAC7CMA.js +240 -0
- package/dist/geneExpression-P2TTZXN2.js +29 -0
- package/dist/geneExpression.unit.spec-Q5D6XHUF.js +151 -0
- package/dist/geneORA-PKUIJKTL.js +269 -0
- package/dist/geneRanking-ZGT5MHBV.js +544 -0
- package/dist/geneVariant-24YNANTT.js +289 -0
- package/dist/geneVariant-CDGENHWQ.js +32 -0
- package/dist/geneVariant.integration.spec-7QW4C2WO.js +672 -0
- package/dist/genefusion.ui-NVXGSBXD.js +299 -0
- package/dist/geneset-7STL6UDD.js +199 -0
- package/dist/genomeBrowser.spec-OE2CIP7I.js +272 -0
- package/dist/grin2-2HXUIY5O.js +66 -0
- package/dist/grin2-32IIJR5E.js +945 -0
- package/dist/hierCluster-MDZEI2KB.js +51 -0
- package/dist/hierCluster-T3PZUGBI.js +55 -0
- package/dist/hierCluster.config-7UN6AYGB.js +32 -0
- package/dist/hierCluster.integration.spec-DWOYVK6T.js +479 -0
- package/dist/hierCluster.interactivity-5OM6XNFG.js +45 -0
- package/dist/imagePlot-KBRXDV5G.js +152 -0
- package/dist/importPlot-DJMIC22L.js +8 -0
- package/dist/isoformExpression-SWDWADRC.js +31 -0
- package/dist/isoformExpression.unit.spec-2U5KCYBP.js +233 -0
- package/dist/junction-NMXVVGRG.js +32 -0
- package/dist/junction.unit.spec-JTGBPPN7.js +178 -0
- package/dist/launch.adhoc-YB5SKMNY.js +33 -0
- package/dist/leftlabel.sample-QKXIODCS.js +253 -0
- package/dist/lollipop-TSZ62PBH.js +162 -0
- package/dist/maf-4L5YN4CG.js +451 -0
- package/dist/maftimeline-VOYB3NY3.js +583 -0
- package/dist/matrix-IWJECVTF.js +55 -0
- package/dist/matrix-MMJAJZA7.js +50 -0
- package/dist/matrix.config-DZGOZWJS.js +33 -0
- package/dist/matrix.integration.spec-2N237E7T.js +3156 -0
- package/dist/matrix.interactivity-FL33UUKR.js +33 -0
- package/dist/matrix.layout-7SYHV3KJ.js +35 -0
- package/dist/matrix.renderers-3SIBT2RP.js +30 -0
- package/dist/matrix.sort.unit.spec-L3H44T6I.js +464 -0
- package/dist/matrix.sorterUi.unit.spec-2NRU5UFH.js +334 -0
- package/dist/matrix.unit.spec-HRZIJB6T.js +146 -0
- package/dist/mavb-ZVRQSDPS.js +726 -0
- package/dist/mds.fimo-ZKETTET7.js +509 -0
- package/dist/mds.samplescatterplot-ZV3UNRLP.js +1545 -0
- package/dist/mds.survivalplot-OVXZRTU4.js +472 -0
- package/dist/multivalue-6BE5IA4F.js +79 -0
- package/dist/oncomatrix-XK62NEOO.js +286 -0
- package/dist/oncomatrix.spec-YVTCHOPS.js +439 -0
- package/dist/plot.2dvaf-NUOBWMNX.js +368 -0
- package/dist/plot.app-G6IQWXTV.js +32 -0
- package/dist/plot.barplot-6QJ6HEJR.js +93 -0
- package/dist/plot.boxplot-XKQJSW2O.js +142 -0
- package/dist/plot.brainImaging-UTHFJFXU.js +51 -0
- package/dist/plot.disco-3MSCX7TM.js +98 -0
- package/dist/plot.ssgq-4KBVHF42.js +130 -0
- package/dist/plot.vaf2cov-OGUQSSDS.js +249 -0
- package/dist/polar2-V7M56GTZ.js +228 -0
- package/dist/profileForms-TS3BJLHH.js +937 -0
- package/dist/profilePlot-DP5272HR.js +45 -0
- package/dist/proteinView-K4K4SP3L.js +1346 -0
- package/dist/proteomeCohortCompare-SFWVGLFK.js +866 -0
- package/dist/pseudbulk.unit.spec-NFOA7J2C.js +82 -0
- package/dist/pseudobulk-XKZQEZ4I.js +31 -0
- package/dist/qualitative-7OSFNVI5.js +241 -0
- package/dist/qualitative-OIIN6E4Y.js +34 -0
- package/dist/radar2-AHZJKX7S.js +323 -0
- package/dist/radarFacility2-OUW6D5E7.js +331 -0
- package/dist/render-7UZSGX3Q.js +29 -0
- package/dist/report-J7HKTXZ2.js +213 -0
- package/dist/sampleView-6547OUIM.js +39 -0
- package/dist/samplelst-UHF23UEB.js +114 -0
- package/dist/samplematrix-OOKS3TMR.js +2188 -0
- package/dist/sc-WF2BLGNG.js +77 -0
- package/dist/scatter-ABCVFGRV.js +84 -0
- package/dist/scatter-WF7XM3IA.js +919 -0
- package/dist/selectGenomeWithTklst-67HU5KRB.js +125 -0
- package/dist/singleCellCellType-3FZPJ25V.js +29 -0
- package/dist/singleCellCellType.unit.spec-TOMREHWK.js +150 -0
- package/dist/singleCellGeneExpression-NQTJ5KJQ.js +29 -0
- package/dist/singleCellGeneExpression.unit.spec-ZWUQTU2N.js +144 -0
- package/dist/singleCellNumericValue-VI7H722L.js +29 -0
- package/dist/singleCellNumericValue.unit.spec-QGLHES7H.js +412 -0
- package/dist/singleCellPlot-RU5T6SJK.js +44 -0
- package/dist/singlecell-C3CJVNXP.js +1562 -0
- package/dist/singlecell-NRQZ7KC6.js +77 -0
- package/dist/snp-X6XY65VS.js +29 -0
- package/dist/snp.unit.spec-6EENK7GQ.js +167 -0
- package/dist/snplocus-R4JA6TFT.js +200 -0
- package/dist/snplst-SOWVHSXH.js +36 -0
- package/dist/spliceevent.a53ss.diagram-IRLCCVQZ.js +142 -0
- package/dist/spliceevent.exonskip.diagram-4KG7LE5D.js +274 -0
- package/dist/spliceevent.noeventdiagram-OWXAJJX7.js +451 -0
- package/dist/ssGSEA-EMOKPLMP.js +29 -0
- package/dist/ssGSEA.unit.spec-KXQ7R5WH.js +79 -0
- package/dist/stattable-H2G7MOZG.js +112 -0
- package/dist/studyCatalog-3ITQXWFL.js +457 -0
- package/dist/summarizeCnvGeneexp-ZIPU6YDY.js +154 -0
- package/dist/summarizeGeneexpSurvival-3RYU226R.js +101 -0
- package/dist/summarizeMutationCnv-RGDBUB22.js +155 -0
- package/dist/summarizeMutationDiagnosis-Z4MZE6Y4.js +31 -0
- package/dist/summarizeMutationSurvival-Z5CNRH7E.js +95 -0
- package/dist/summary-6QQCNX3B.js +40 -0
- package/dist/summary.integration.spec-3ULXTZUP.js +405 -0
- package/dist/summaryInput-4QKR34QB.js +238 -0
- package/dist/sunburst-KB3BWC72.js +34 -0
- package/dist/sunburst-XTFBHZNH.js +274 -0
- package/dist/survival-7O6ZK63E.js +49 -0
- package/dist/survival-NNCY4K6C.js +1248 -0
- package/dist/survival.integration.spec-ZYZHZAXA.js +609 -0
- package/dist/svgraph-ZLSFFEAC.js +1377 -0
- package/dist/svmr-REBBDEYM.js +3834 -0
- package/dist/swimmer-NUBRIWLI.js +993 -0
- package/dist/table-CWIQQESJ.js +192 -0
- package/dist/termCollection-7TYJSQ45.js +29 -0
- package/dist/termCollection-7Z55QNL7.js +247 -0
- package/dist/termCollection.unit.spec-LQ5MIBDH.js +295 -0
- package/dist/termCollectionFractionSelection-24DZYVDU.js +38 -0
- package/dist/termCollectionFractionSelection.unit.spec-DCV2CFS5.js +184 -0
- package/dist/tk-2WZFPRCP.js +37 -0
- package/dist/tk-QTLEYIP7.js +1193 -0
- package/dist/tp.ui-HXQX2UH4.js +1453 -0
- package/dist/tvs.categorical-4D3JI2ER.js +28 -0
- package/dist/tvs.condition-62FXFHZ5.js +160 -0
- package/dist/tvs.density-IGO4I4T2.js +19 -0
- package/dist/tvs.dt-FZSVMJOO.js +34 -0
- package/dist/tvs.dtcnv.categorical-PPFQIC42.js +31 -0
- package/dist/tvs.dtcnv.continuous-TV2IGHY4.js +72 -0
- package/dist/tvs.dtfusion-ON4BA4XJ.js +31 -0
- package/dist/tvs.dtitd-VFNROOWQ.js +31 -0
- package/dist/tvs.dtsnvindel-ZXOP37T5.js +31 -0
- package/dist/tvs.dtsv-EUHPTW7J.js +31 -0
- package/dist/tvs.multivalue-NHVXZNDI.js +84 -0
- package/dist/tvs.numeric-FPWDPO3J.js +32 -0
- package/dist/tvs.samplelst-ZZHRNUP4.js +95 -0
- package/dist/tvs.survival-F3KSG3U6.js +110 -0
- package/dist/tvs.termCollection-B37DZLDY.js +118 -0
- package/dist/vocabulary-XNE5FFDK.js +32 -0
- package/dist/wsi.direct-3YH3QGQD.js +11514 -0
- package/package.json +3 -3
- package/dist/2dmaf-KRIX5DBS.js +0 -1362
- package/dist/AggMatrixInput-GBQD74NV.js +0 -402
- package/dist/AggregateMatrix-U2MOQOSZ.js +0 -37
- package/dist/AppHeader-OBZWUCOD.js +0 -826
- package/dist/BoxPlot-ZK6Q5JGE.js +0 -1229
- package/dist/CorrelationVolcano-WGR4JIGK.js +0 -613
- package/dist/Cuminc-I6D6YSIL.js +0 -1217
- package/dist/DE-HO7UBKPC.js +0 -85
- package/dist/DEinput-6LX4I65N.js +0 -479
- package/dist/DM-WYKLX4IC.js +0 -86
- package/dist/DifferentialAnalysis-L5VVBCVZ.js +0 -236
- package/dist/Disco-HLARIYXU.js +0 -3384
- package/dist/Disco.UI-W64WFVC3.js +0 -239
- package/dist/DmrPlot-BKQOT4JM.js +0 -361
- package/dist/GB-WKFGDJYW.js +0 -1388
- package/dist/GSEA-DCCJI5JE.js +0 -870
- package/dist/GeneExpInput-APLFNE6N.js +0 -38
- package/dist/Geomap-FTKWCV4J.js +0 -80
- package/dist/HicApp-ZGZKO4Y4.js +0 -2240
- package/dist/IDCViewer-MXB3OZUZ.js +0 -10808
- package/dist/NumBinaryEditor-S3MHUVZ5.js +0 -274
- package/dist/NumBinaryEditor.unit.spec-264X5ULG.js +0 -308
- package/dist/NumContEditor-MKEZCZMR.js +0 -100
- package/dist/NumContEditor.unit.spec-KBRAIU7M.js +0 -160
- package/dist/NumCustomBinEditor-OSF64BFC.js +0 -29
- package/dist/NumCustomBinEditor.unit.spec-T2SRBXTV.js +0 -393
- package/dist/NumDiscreteEditor-PVW5HRRQ.js +0 -165
- package/dist/NumDiscreteEditor.unit.spec-GUK7VWMR.js +0 -229
- package/dist/NumRegularBinEditor-757VRGFQ.js +0 -29
- package/dist/NumRegularBinEditor.unit.spec-JUIGEH3Z.js +0 -274
- package/dist/NumSplineEditor-U6MVFSCZ.js +0 -205
- package/dist/NumSplineEditor.unit.spec-PSH6YENX.js +0 -220
- package/dist/NumericDensity-YIP25Z4Y.js +0 -29
- package/dist/NumericDensity.unit.spec-3OSIZJHH.js +0 -414
- package/dist/NumericHandler-D2CO3FTS.js +0 -30
- package/dist/NumericHandler.unit.spec-RNFVGO2I.js +0 -225
- package/dist/ProteomeInput-ZOBJ2VU6.js +0 -610
- package/dist/Regression-ABKJOOMQ.js +0 -1412
- package/dist/RunChart2-D5CEEFEE.js +0 -744
- package/dist/SC-RLVEECU5.js +0 -1290
- package/dist/Violin-PCNX2CWV.js +0 -1092
- package/dist/Volcano-NVFNO7NE.js +0 -2661
- package/dist/Wsi-MAMCK5YZ.js +0 -636
- package/dist/aboutSunburst-VSQADTFD.js +0 -86
- package/dist/adSandbox-5YFAQZO6.js +0 -29
- package/dist/animatedBubbleChart-GM2GXDP3.js +0 -542
- package/dist/app-FNNCH37H.js +0 -28
- package/dist/app-ID5S5FUP.js +0 -38
- package/dist/bam-JZLYXHMF.js +0 -872
- package/dist/bam-JZLYXHMF.js.map +0 -7
- package/dist/barchart-EAXXILCH.js +0 -38
- package/dist/barchart2-E6A4UMUB.js +0 -305
- package/dist/block-VMVJH77F.js +0 -6203
- package/dist/block.init-TUCGKLXG.js +0 -29
- package/dist/block.mds.expressionrank-YVROHZVX.js +0 -350
- package/dist/block.mds.geneboxplot-TQNEWBJY.js +0 -819
- package/dist/block.mds.junction-ZOSTZQF5.js +0 -1534
- package/dist/block.mds.svcnv-XSTSJ4ZD.js +0 -6413
- package/dist/block.svg-D6HXL4SC.js +0 -155
- package/dist/block.tk.aicheck-7RNC4HRR.js +0 -274
- package/dist/block.tk.bam-L3U5YH3F.js +0 -1897
- package/dist/block.tk.bam-L3U5YH3F.js.map +0 -7
- package/dist/block.tk.bigwig.ui-UVSZ7LWQ.js +0 -202
- package/dist/block.tk.hicstraw-YFBJR5LO.js +0 -814
- package/dist/block.tk.junction-DNRK2JNQ.js +0 -2353
- package/dist/block.tk.junction.textmatrixui-EN4ADCAU.js +0 -190
- package/dist/block.tk.ld-I5CTAJ4K.js +0 -90
- package/dist/block.tk.menu-HUZBY7OM.js +0 -1050
- package/dist/block.tk.pgv-KA6BFYPY.js +0 -934
- package/dist/brainImaging-OQB2ZHCU.js +0 -550
- package/dist/brainRegions-2CRVMS24.js +0 -213
- package/dist/bubbleHeatmap-MANNFEG2.js +0 -374
- package/dist/cellTypeBubbleHeatmap-LRK4R4EC.js +0 -274
- package/dist/chunk-2NB5HVXB.js +0 -159
- package/dist/chunk-3E26ITYK.js +0 -55
- package/dist/chunk-3H4FCRAN.js +0 -266
- package/dist/chunk-4ENIOXIT.js +0 -133
- package/dist/chunk-4GKC43U3.js +0 -480
- package/dist/chunk-4NQS45KH.js +0 -302
- package/dist/chunk-4ZV6SE4B.js +0 -240
- package/dist/chunk-5TA5LHPW.js +0 -54
- package/dist/chunk-5YQXNW6Y.js +0 -1339
- package/dist/chunk-67MD4UES.js +0 -848
- package/dist/chunk-6BBUIRHA.js +0 -123
- package/dist/chunk-6DESNDD5.js +0 -468
- package/dist/chunk-6DRRN5XP.js +0 -243
- package/dist/chunk-6XKAOSQE.js +0 -116
- package/dist/chunk-6XKAOSQE.js.map +0 -7
- package/dist/chunk-7TLUQH7J.js +0 -82
- package/dist/chunk-7YMZSVWW.js +0 -1219
- package/dist/chunk-AENUJ7UO.js +0 -299
- package/dist/chunk-AZSWQWKL.js +0 -263
- package/dist/chunk-B5IJAQG4.js +0 -2054
- package/dist/chunk-B5IJAQG4.js.map +0 -7
- package/dist/chunk-BOCU6PXO.js +0 -257
- package/dist/chunk-C7ZPDNOJ.js +0 -70
- package/dist/chunk-DEQREL5P.js +0 -692
- package/dist/chunk-DXKZBSSD.js +0 -2799
- package/dist/chunk-DZBPF5QI.js +0 -550
- package/dist/chunk-DZDK64XY.js +0 -516
- package/dist/chunk-E6C2EWHU.js +0 -176
- package/dist/chunk-GK5QS5BR.js +0 -2685
- package/dist/chunk-GLAR6VNF.js +0 -626
- package/dist/chunk-H6YM4NKS.js +0 -134
- package/dist/chunk-HJKVYTYK.js +0 -379
- package/dist/chunk-HN67TOA7.js +0 -2008
- package/dist/chunk-IXV7FX5B.js +0 -255
- package/dist/chunk-IZ4IPYQY.js +0 -466
- package/dist/chunk-JPPNQVKA.js +0 -56
- package/dist/chunk-KCVBFXGO.js +0 -2941
- package/dist/chunk-LOX5GAVG.js +0 -103
- package/dist/chunk-M6OSJMVD.js +0 -536
- package/dist/chunk-PEKCVKJK.js +0 -26621
- package/dist/chunk-PEKCVKJK.js.map +0 -7
- package/dist/chunk-PIGTIWSK.js +0 -34
- package/dist/chunk-PIGTIWSK.js.map +0 -7
- package/dist/chunk-PIN5YUVJ.js +0 -6375
- package/dist/chunk-PV7AYYRZ.js +0 -50
- package/dist/chunk-QI7OWVFY.js +0 -54
- package/dist/chunk-QWBNQYIF.js +0 -182
- package/dist/chunk-S6WRMFWQ.js +0 -418
- package/dist/chunk-S6WRMFWQ.js.map +0 -7
- package/dist/chunk-SUOEFEJO.js +0 -96
- package/dist/chunk-TVSNHVWX.js +0 -194
- package/dist/chunk-U3CWWOHL.js +0 -340
- package/dist/chunk-VGC4STKW.js +0 -56
- package/dist/chunk-VHC4FDEJ.js +0 -141
- package/dist/chunk-VSDJEPDN.js +0 -5214
- package/dist/chunk-WTWHUZ4O.js +0 -203
- package/dist/chunk-XHZ723K4.js +0 -2334
- package/dist/chunk-XP4P55IC.js +0 -14
- package/dist/chunk-XVPPM25G.js +0 -1253
- package/dist/chunk-XYUERIZ6.js +0 -4389
- package/dist/chunk-YDIIKD7O.js +0 -102
- package/dist/chunk-YLGSRK75.js +0 -102
- package/dist/chunk-YR6EXI2K.js +0 -184
- package/dist/chunk-Z53VY5JV.js +0 -296
- package/dist/chunk-Z7Q2O5Y7.js +0 -237
- package/dist/cohort-ERDL7EJU.js +0 -66
- package/dist/cohortSunburst-KSTVS3OQ.js +0 -402
- package/dist/condition-CTJYHRJG.js +0 -323
- package/dist/controls-MMMRBTZL.js +0 -30
- package/dist/controls.config-ZKMQI27Q.js +0 -30
- package/dist/correlation-NEQNBQTT.js +0 -91
- package/dist/customdata.inputui-THUR7DF5.js +0 -280
- package/dist/dataDownload-ZMAJUKBX.js +0 -326
- package/dist/databrowser.ui-A6ZSIUG4.js +0 -421
- package/dist/dictionary-TQUVCHIN.js +0 -109
- package/dist/dnaMethylation-ZMJYY3ML.js +0 -29
- package/dist/dnaMethylation.integration.spec-5DTBGTYB.js +0 -194
- package/dist/e2pca-DNWBF545.js +0 -340
- package/dist/ep-JNH3HMY4.js +0 -1247
- package/dist/expclust.gdc.spec-2NJ7JVJW.js +0 -298
- package/dist/facet-RWQFAVVU.js +0 -556
- package/dist/gb-OT2Z3Y7J.js +0 -77
- package/dist/geneExpClustering-TPYGSTMO.js +0 -240
- package/dist/geneExpression-4K3OTXBZ.js +0 -29
- package/dist/geneExpression.unit.spec-26MCGRAP.js +0 -151
- package/dist/geneORA-GNXKCN45.js +0 -269
- package/dist/geneRanking-LV6W6TT7.js +0 -544
- package/dist/geneVariant-B2SYTHG6.js +0 -289
- package/dist/geneVariant-O4XG5VEM.js +0 -32
- package/dist/geneVariant.integration.spec-YYVPAFXT.js +0 -672
- package/dist/genefusion.ui-CVGGYVV3.js +0 -299
- package/dist/geneset-MBMCJNXT.js +0 -199
- package/dist/genomeBrowser.spec-OVXFKEIU.js +0 -272
- package/dist/grin2-OXRU465E.js +0 -945
- package/dist/grin2-YCJGBRFG.js +0 -66
- package/dist/hierCluster-KNPWL5KD.js +0 -51
- package/dist/hierCluster-L3LYQZQL.js +0 -55
- package/dist/hierCluster.config-VZBV5QIO.js +0 -32
- package/dist/hierCluster.integration.spec-ZM7K7WI4.js +0 -479
- package/dist/hierCluster.interactivity-EA7WVIQR.js +0 -45
- package/dist/imagePlot-OLVI26S5.js +0 -152
- package/dist/importPlot-3SSCNROC.js +0 -8
- package/dist/isoformExpression-BTMJNAAO.js +0 -31
- package/dist/isoformExpression.unit.spec-S2W5T42Z.js +0 -233
- package/dist/junction-GIS5OCRO.js +0 -32
- package/dist/junction.unit.spec-MSILW6QZ.js +0 -178
- package/dist/launch.adhoc-LLJY4LA5.js +0 -33
- package/dist/leftlabel.sample-P6DDVCOW.js +0 -253
- package/dist/lollipop-J34YCYIP.js +0 -162
- package/dist/maf-MFEEYT5P.js +0 -451
- package/dist/maftimeline-TGJ37QYA.js +0 -583
- package/dist/matrix-A6BNFCIH.js +0 -55
- package/dist/matrix-XTKRVPMQ.js +0 -50
- package/dist/matrix.config-RMDDMOZ5.js +0 -33
- package/dist/matrix.integration.spec-2DVRXVNH.js +0 -3156
- package/dist/matrix.interactivity-MGOYEKDN.js +0 -33
- package/dist/matrix.layout-T7EC5ZC2.js +0 -35
- package/dist/matrix.renderers-GR77V3RL.js +0 -30
- package/dist/matrix.sort.unit.spec-YUCV7G5L.js +0 -464
- package/dist/matrix.sorterUi.unit.spec-FESIQ2RC.js +0 -334
- package/dist/matrix.unit.spec-6QF3WKM7.js +0 -146
- package/dist/mavb-UXJBITZM.js +0 -726
- package/dist/mds.fimo-IPNWVBO4.js +0 -509
- package/dist/mds.samplescatterplot-KEG7RSN3.js +0 -1545
- package/dist/mds.survivalplot-LJF2CD33.js +0 -472
- package/dist/multivalue-YRQZ73DI.js +0 -79
- package/dist/oncomatrix-TIMH5JKS.js +0 -286
- package/dist/oncomatrix.spec-MUOKKCJN.js +0 -439
- package/dist/plot.2dvaf-3OL4S6QG.js +0 -368
- package/dist/plot.app-CMLHZV5F.js +0 -32
- package/dist/plot.barplot-NRYMIPK6.js +0 -93
- package/dist/plot.boxplot-ANGW3WUC.js +0 -142
- package/dist/plot.brainImaging-YUDBYKX5.js +0 -51
- package/dist/plot.disco-LV7RE3YO.js +0 -98
- package/dist/plot.ssgq-F2LOQFYD.js +0 -130
- package/dist/plot.vaf2cov-5OKC7X6D.js +0 -249
- package/dist/polar2-BGJA2GHZ.js +0 -228
- package/dist/profileForms-BKP3OBKV.js +0 -937
- package/dist/profilePlot-5PRRNUKD.js +0 -45
- package/dist/proteinView-VZIWIZZY.js +0 -1346
- package/dist/proteomeCohortCompare-XZI5OI4X.js +0 -866
- package/dist/pseudbulk.unit.spec-DXJQV7JQ.js +0 -82
- package/dist/pseudobulk-FCH3WW6O.js +0 -31
- package/dist/qualitative-ATX53V44.js +0 -34
- package/dist/qualitative-BRKLVRKW.js +0 -241
- package/dist/radar2-6BBT2FBT.js +0 -323
- package/dist/radarFacility2-76Q3IYP2.js +0 -331
- package/dist/render-KUC3QH36.js +0 -29
- package/dist/report-KB4K7ZXC.js +0 -213
- package/dist/sampleView-QD2JLZ4T.js +0 -39
- package/dist/samplelst-6R5RYHNV.js +0 -114
- package/dist/samplematrix-NGORNBTR.js +0 -2188
- package/dist/sc-27AHZZDK.js +0 -77
- package/dist/scatter-FXLZMWD6.js +0 -84
- package/dist/scatter-OWFYLMSJ.js +0 -919
- package/dist/selectGenomeWithTklst-ZTGABCXC.js +0 -125
- package/dist/singleCellCellType-7XXJ5NWC.js +0 -29
- package/dist/singleCellCellType.unit.spec-Y3TEYYCF.js +0 -150
- package/dist/singleCellGeneExpression-EUAIEIYJ.js +0 -29
- package/dist/singleCellGeneExpression.unit.spec-JVHPFLML.js +0 -144
- package/dist/singleCellNumericValue-FHIECJDK.js +0 -29
- package/dist/singleCellNumericValue.unit.spec-ZFG56MIO.js +0 -412
- package/dist/singleCellPlot-NDGIW32L.js +0 -44
- package/dist/singlecell-JPWVPZEF.js +0 -1562
- package/dist/singlecell-N7RJMWZ2.js +0 -77
- package/dist/snp-APUTOL2F.js +0 -29
- package/dist/snp.unit.spec-4AN7AJKO.js +0 -167
- package/dist/snplocus-WIMFAMBE.js +0 -200
- package/dist/snplst-SUJ5AK4E.js +0 -36
- package/dist/spliceevent.a53ss.diagram-4UBI7PFJ.js +0 -142
- package/dist/spliceevent.exonskip.diagram-NVEXVRIC.js +0 -274
- package/dist/spliceevent.noeventdiagram-CKEWNLVF.js +0 -451
- package/dist/ssGSEA-CJOVXTAW.js +0 -29
- package/dist/ssGSEA.unit.spec-A7VRVJSF.js +0 -79
- package/dist/stattable-JBJVVLQE.js +0 -112
- package/dist/studyCatalog-NEL7XSIP.js +0 -457
- package/dist/summarizeCnvGeneexp-BZSCTA5W.js +0 -154
- package/dist/summarizeGeneexpSurvival-743KXNV7.js +0 -101
- package/dist/summarizeMutationCnv-CALMSQGV.js +0 -155
- package/dist/summarizeMutationDiagnosis-OTE7O4AS.js +0 -31
- package/dist/summarizeMutationSurvival-VOZOFTFM.js +0 -95
- package/dist/summary-XJKCD35N.js +0 -40
- package/dist/summary.integration.spec-OOEU6WNB.js +0 -405
- package/dist/summaryInput-JSOXVSMY.js +0 -238
- package/dist/sunburst-J3QHMYKW.js +0 -34
- package/dist/sunburst-LZPP6NPV.js +0 -274
- package/dist/survival-5GWRVTQ6.js +0 -49
- package/dist/survival-FW7N3YXZ.js +0 -1248
- package/dist/survival.integration.spec-WN36VUHL.js +0 -609
- package/dist/svgraph-N35EMK3G.js +0 -1377
- package/dist/svmr-EWL5WDDD.js +0 -3834
- package/dist/swimmer-Z6FUH4CD.js +0 -993
- package/dist/table-EI2OIRGE.js +0 -192
- package/dist/termCollection-K3EX5P3F.js +0 -29
- package/dist/termCollection-TBTAHLVH.js +0 -247
- package/dist/termCollection.unit.spec-ZVNAIPHZ.js +0 -295
- package/dist/termCollectionFractionSelection-ATNIPWVX.js +0 -38
- package/dist/termCollectionFractionSelection.unit.spec-VBRWWBML.js +0 -184
- package/dist/tk-P3RPLUVH.js +0 -1193
- package/dist/tk-U6CYISBH.js +0 -37
- package/dist/tp.ui-KBFYUSWS.js +0 -1453
- package/dist/tvs.categorical-5USP772O.js +0 -28
- package/dist/tvs.condition-652MAA2Z.js +0 -160
- package/dist/tvs.density-CB24PXDE.js +0 -19
- package/dist/tvs.dt-7BTARQUS.js +0 -34
- package/dist/tvs.dtcnv.categorical-GAOO3DGO.js +0 -31
- package/dist/tvs.dtcnv.continuous-P2QRD45O.js +0 -72
- package/dist/tvs.dtfusion-L3I65W7L.js +0 -31
- package/dist/tvs.dtitd-B3JPW6OL.js +0 -31
- package/dist/tvs.dtsnvindel-6Y6CJBZV.js +0 -31
- package/dist/tvs.dtsv-GL7CPATL.js +0 -31
- package/dist/tvs.multivalue-75IM23FZ.js +0 -84
- package/dist/tvs.numeric-XB3GBPHE.js +0 -32
- package/dist/tvs.samplelst-QUA45UE7.js +0 -95
- package/dist/tvs.survival-EKSDZZIO.js +0 -110
- package/dist/tvs.termCollection-5ATMDC7O.js +0 -118
- package/dist/vocabulary-5QBBQAYC.js +0 -32
- package/dist/wsi.direct-BU6BL5UR.js +0 -11514
- /package/dist/{2dmaf-KRIX5DBS.js.map → 2dmaf-7YU3SNKL.js.map} +0 -0
- /package/dist/{AggMatrixInput-GBQD74NV.js.map → AggMatrixInput-73CDR5FS.js.map} +0 -0
- /package/dist/{AggregateMatrix-U2MOQOSZ.js.map → AggregateMatrix-NNULVFBM.js.map} +0 -0
- /package/dist/{AppHeader-OBZWUCOD.js.map → AppHeader-EZDDLLXU.js.map} +0 -0
- /package/dist/{BoxPlot-ZK6Q5JGE.js.map → BoxPlot-463E7CRY.js.map} +0 -0
- /package/dist/{CorrelationVolcano-WGR4JIGK.js.map → CorrelationVolcano-LHIIMBPP.js.map} +0 -0
- /package/dist/{Cuminc-I6D6YSIL.js.map → Cuminc-UL2TCIKV.js.map} +0 -0
- /package/dist/{DE-HO7UBKPC.js.map → DE-VRFSKFDW.js.map} +0 -0
- /package/dist/{DEinput-6LX4I65N.js.map → DEinput-FZTQRWVC.js.map} +0 -0
- /package/dist/{DM-WYKLX4IC.js.map → DM-PO7CQZNT.js.map} +0 -0
- /package/dist/{DifferentialAnalysis-L5VVBCVZ.js.map → DifferentialAnalysis-WK6HE3YH.js.map} +0 -0
- /package/dist/{Disco-HLARIYXU.js.map → Disco-YBNQJQFG.js.map} +0 -0
- /package/dist/{Disco.UI-W64WFVC3.js.map → Disco.UI-HC5XYBFV.js.map} +0 -0
- /package/dist/{DmrPlot-BKQOT4JM.js.map → DmrPlot-7VJ5C66D.js.map} +0 -0
- /package/dist/{GB-WKFGDJYW.js.map → GB-VPFQRDRO.js.map} +0 -0
- /package/dist/{GSEA-DCCJI5JE.js.map → GSEA-ZEJB3QZQ.js.map} +0 -0
- /package/dist/{GeneExpInput-APLFNE6N.js.map → GeneExpInput-SBDDIY6G.js.map} +0 -0
- /package/dist/{Geomap-FTKWCV4J.js.map → Geomap-23AHGP2V.js.map} +0 -0
- /package/dist/{HicApp-ZGZKO4Y4.js.map → HicApp-7AQQE4CM.js.map} +0 -0
- /package/dist/{IDCViewer-MXB3OZUZ.js.map → IDCViewer-NO5Q6VOB.js.map} +0 -0
- /package/dist/{NumBinaryEditor-S3MHUVZ5.js.map → NumBinaryEditor-DSRP4OOU.js.map} +0 -0
- /package/dist/{NumBinaryEditor.unit.spec-264X5ULG.js.map → NumBinaryEditor.unit.spec-TT666YL4.js.map} +0 -0
- /package/dist/{NumContEditor-MKEZCZMR.js.map → NumContEditor-6CURFOCH.js.map} +0 -0
- /package/dist/{NumContEditor.unit.spec-KBRAIU7M.js.map → NumContEditor.unit.spec-MNVCFCMP.js.map} +0 -0
- /package/dist/{NumCustomBinEditor-OSF64BFC.js.map → NumCustomBinEditor-SQRR5EFL.js.map} +0 -0
- /package/dist/{NumCustomBinEditor.unit.spec-T2SRBXTV.js.map → NumCustomBinEditor.unit.spec-F7BZWGGT.js.map} +0 -0
- /package/dist/{NumDiscreteEditor-PVW5HRRQ.js.map → NumDiscreteEditor-U7Z2QNYP.js.map} +0 -0
- /package/dist/{NumDiscreteEditor.unit.spec-GUK7VWMR.js.map → NumDiscreteEditor.unit.spec-EIEBUZCX.js.map} +0 -0
- /package/dist/{NumRegularBinEditor-757VRGFQ.js.map → NumRegularBinEditor-CVZSWN6Y.js.map} +0 -0
- /package/dist/{NumRegularBinEditor.unit.spec-JUIGEH3Z.js.map → NumRegularBinEditor.unit.spec-ZMAJOIHL.js.map} +0 -0
- /package/dist/{NumSplineEditor-U6MVFSCZ.js.map → NumSplineEditor-U43D5NBJ.js.map} +0 -0
- /package/dist/{NumSplineEditor.unit.spec-PSH6YENX.js.map → NumSplineEditor.unit.spec-C52AADTS.js.map} +0 -0
- /package/dist/{NumericDensity-YIP25Z4Y.js.map → NumericDensity-PUKDZOVI.js.map} +0 -0
- /package/dist/{NumericDensity.unit.spec-3OSIZJHH.js.map → NumericDensity.unit.spec-2347S76D.js.map} +0 -0
- /package/dist/{NumericHandler-D2CO3FTS.js.map → NumericHandler-3RT32PTR.js.map} +0 -0
- /package/dist/{NumericHandler.unit.spec-RNFVGO2I.js.map → NumericHandler.unit.spec-4PADL4KZ.js.map} +0 -0
- /package/dist/{ProteomeInput-ZOBJ2VU6.js.map → ProteomeInput-NFV4FW4U.js.map} +0 -0
- /package/dist/{Regression-ABKJOOMQ.js.map → Regression-N7M7N6G4.js.map} +0 -0
- /package/dist/{RunChart2-D5CEEFEE.js.map → RunChart2-UPQ7C6QE.js.map} +0 -0
- /package/dist/{SC-RLVEECU5.js.map → SC-KBW2NHUV.js.map} +0 -0
- /package/dist/{Violin-PCNX2CWV.js.map → Violin-GWCOP3ZF.js.map} +0 -0
- /package/dist/{Volcano-NVFNO7NE.js.map → Volcano-X3HT32GQ.js.map} +0 -0
- /package/dist/{Wsi-MAMCK5YZ.js.map → Wsi-NXAEOYIS.js.map} +0 -0
- /package/dist/{aboutSunburst-VSQADTFD.js.map → aboutSunburst-5EKXZV2A.js.map} +0 -0
- /package/dist/{adSandbox-5YFAQZO6.js.map → adSandbox-RPEWEEW7.js.map} +0 -0
- /package/dist/{animatedBubbleChart-GM2GXDP3.js.map → animatedBubbleChart-ILDMZRBX.js.map} +0 -0
- /package/dist/{app-FNNCH37H.js.map → app-LOUC4J47.js.map} +0 -0
- /package/dist/{app-ID5S5FUP.js.map → app-MRKXZ6AZ.js.map} +0 -0
- /package/dist/{barchart-EAXXILCH.js.map → barchart-CJR37234.js.map} +0 -0
- /package/dist/{barchart2-E6A4UMUB.js.map → barchart2-QQYLTHWR.js.map} +0 -0
- /package/dist/{block-VMVJH77F.js.map → block-GLF6QNKY.js.map} +0 -0
- /package/dist/{block.init-TUCGKLXG.js.map → block.init-YJQTJIDO.js.map} +0 -0
- /package/dist/{block.mds.expressionrank-YVROHZVX.js.map → block.mds.expressionrank-GBMEI5KQ.js.map} +0 -0
- /package/dist/{block.mds.geneboxplot-TQNEWBJY.js.map → block.mds.geneboxplot-XWE3E5IW.js.map} +0 -0
- /package/dist/{block.mds.junction-ZOSTZQF5.js.map → block.mds.junction-QLEHFVPE.js.map} +0 -0
- /package/dist/{block.mds.svcnv-XSTSJ4ZD.js.map → block.mds.svcnv-53DTOPBC.js.map} +0 -0
- /package/dist/{block.svg-D6HXL4SC.js.map → block.svg-57T37ABS.js.map} +0 -0
- /package/dist/{block.tk.aicheck-7RNC4HRR.js.map → block.tk.aicheck-6DXJTS3H.js.map} +0 -0
- /package/dist/{block.tk.bigwig.ui-UVSZ7LWQ.js.map → block.tk.bigwig.ui-OYIVXE2L.js.map} +0 -0
- /package/dist/{block.tk.hicstraw-YFBJR5LO.js.map → block.tk.hicstraw-UKTGEBWT.js.map} +0 -0
- /package/dist/{block.tk.junction-DNRK2JNQ.js.map → block.tk.junction-ZU5KPFQ3.js.map} +0 -0
- /package/dist/{block.tk.junction.textmatrixui-EN4ADCAU.js.map → block.tk.junction.textmatrixui-P4WXTAZR.js.map} +0 -0
- /package/dist/{block.tk.ld-I5CTAJ4K.js.map → block.tk.ld-3PQ4O2AE.js.map} +0 -0
- /package/dist/{block.tk.menu-HUZBY7OM.js.map → block.tk.menu-LLITB6UA.js.map} +0 -0
- /package/dist/{block.tk.pgv-KA6BFYPY.js.map → block.tk.pgv-Y3FBXUO3.js.map} +0 -0
- /package/dist/{brainImaging-OQB2ZHCU.js.map → brainImaging-4B3WXLNP.js.map} +0 -0
- /package/dist/{brainRegions-2CRVMS24.js.map → brainRegions-7VLONUWN.js.map} +0 -0
- /package/dist/{bubbleHeatmap-MANNFEG2.js.map → bubbleHeatmap-DI6GJRR6.js.map} +0 -0
- /package/dist/{cellTypeBubbleHeatmap-LRK4R4EC.js.map → cellTypeBubbleHeatmap-HJY53DB2.js.map} +0 -0
- /package/dist/{chunk-4ZV6SE4B.js.map → chunk-226MNBZ2.js.map} +0 -0
- /package/dist/{chunk-M6OSJMVD.js.map → chunk-2CDFU4MQ.js.map} +0 -0
- /package/dist/{chunk-BOCU6PXO.js.map → chunk-2CNFGVHU.js.map} +0 -0
- /package/dist/{chunk-GK5QS5BR.js.map → chunk-2MC3RNKA.js.map} +0 -0
- /package/dist/{chunk-PV7AYYRZ.js.map → chunk-2SL4QWUS.js.map} +0 -0
- /package/dist/{chunk-DEQREL5P.js.map → chunk-3KGBC5MK.js.map} +0 -0
- /package/dist/{chunk-VGC4STKW.js.map → chunk-3PCRAPUV.js.map} +0 -0
- /package/dist/{chunk-YLGSRK75.js.map → chunk-4DBOMSKP.js.map} +0 -0
- /package/dist/{chunk-IZ4IPYQY.js.map → chunk-57BS6KNI.js.map} +0 -0
- /package/dist/{chunk-XHZ723K4.js.map → chunk-5AXS5G4A.js.map} +0 -0
- /package/dist/{chunk-Z7Q2O5Y7.js.map → chunk-5HJG6ECV.js.map} +0 -0
- /package/dist/{chunk-DZBPF5QI.js.map → chunk-5ZYANHGX.js.map} +0 -0
- /package/dist/{chunk-LOX5GAVG.js.map → chunk-75MRUW2K.js.map} +0 -0
- /package/dist/{chunk-IXV7FX5B.js.map → chunk-7J3W3KCN.js.map} +0 -0
- /package/dist/{chunk-QWBNQYIF.js.map → chunk-AIZYAKIE.js.map} +0 -0
- /package/dist/{chunk-HN67TOA7.js.map → chunk-AJNFI6GA.js.map} +0 -0
- /package/dist/{chunk-DXKZBSSD.js.map → chunk-BJAWDZBL.js.map} +0 -0
- /package/dist/{chunk-HJKVYTYK.js.map → chunk-C6PVZVIH.js.map} +0 -0
- /package/dist/{chunk-E6C2EWHU.js.map → chunk-C77X5ZUV.js.map} +0 -0
- /package/dist/{chunk-YDIIKD7O.js.map → chunk-CUCP2GMT.js.map} +0 -0
- /package/dist/{chunk-H6YM4NKS.js.map → chunk-DTGAMBRJ.js.map} +0 -0
- /package/dist/{chunk-3E26ITYK.js.map → chunk-DXT7GDHY.js.map} +0 -0
- /package/dist/{chunk-VSDJEPDN.js.map → chunk-ENPMWVWG.js.map} +0 -0
- /package/dist/{chunk-XYUERIZ6.js.map → chunk-FPMJJBLV.js.map} +0 -0
- /package/dist/{chunk-C7ZPDNOJ.js.map → chunk-H7F6DMJA.js.map} +0 -0
- /package/dist/{chunk-SUOEFEJO.js.map → chunk-HH3NUAR2.js.map} +0 -0
- /package/dist/{chunk-2NB5HVXB.js.map → chunk-HRTPGNOG.js.map} +0 -0
- /package/dist/{chunk-67MD4UES.js.map → chunk-IFPRYTS7.js.map} +0 -0
- /package/dist/{chunk-4NQS45KH.js.map → chunk-IJSFSUI4.js.map} +0 -0
- /package/dist/{chunk-AZSWQWKL.js.map → chunk-IRQKX6DL.js.map} +0 -0
- /package/dist/{chunk-7YMZSVWW.js.map → chunk-JNZL7HKB.js.map} +0 -0
- /package/dist/{chunk-AENUJ7UO.js.map → chunk-K3G56J5R.js.map} +0 -0
- /package/dist/{chunk-DZDK64XY.js.map → chunk-KKUCG2QE.js.map} +0 -0
- /package/dist/{chunk-GLAR6VNF.js.map → chunk-KPXCXBNU.js.map} +0 -0
- /package/dist/{chunk-XP4P55IC.js.map → chunk-MSTYU3QO.js.map} +0 -0
- /package/dist/{chunk-VHC4FDEJ.js.map → chunk-MWARRQT4.js.map} +0 -0
- /package/dist/{chunk-WTWHUZ4O.js.map → chunk-MXKYPTZ7.js.map} +0 -0
- /package/dist/{chunk-4ENIOXIT.js.map → chunk-OZUF7O2S.js.map} +0 -0
- /package/dist/{chunk-KCVBFXGO.js.map → chunk-PRTLCJYF.js.map} +0 -0
- /package/dist/{chunk-7TLUQH7J.js.map → chunk-QNCE6EOK.js.map} +0 -0
- /package/dist/{chunk-3H4FCRAN.js.map → chunk-RV335DF2.js.map} +0 -0
- /package/dist/{chunk-XVPPM25G.js.map → chunk-THAUD62Q.js.map} +0 -0
- /package/dist/{chunk-PIN5YUVJ.js.map → chunk-VBTBUXXX.js.map} +0 -0
- /package/dist/{chunk-JPPNQVKA.js.map → chunk-VHWJK2MP.js.map} +0 -0
- /package/dist/{chunk-QI7OWVFY.js.map → chunk-VMK4RHV5.js.map} +0 -0
- /package/dist/{chunk-6DESNDD5.js.map → chunk-WKT7RF3C.js.map} +0 -0
- /package/dist/{chunk-YR6EXI2K.js.map → chunk-WXSMUSU7.js.map} +0 -0
- /package/dist/{chunk-Z53VY5JV.js.map → chunk-WXSX5OQJ.js.map} +0 -0
- /package/dist/{chunk-TVSNHVWX.js.map → chunk-WY3IORKG.js.map} +0 -0
- /package/dist/{chunk-4GKC43U3.js.map → chunk-WYSOOKFJ.js.map} +0 -0
- /package/dist/{chunk-6BBUIRHA.js.map → chunk-XBBFFOLS.js.map} +0 -0
- /package/dist/{chunk-U3CWWOHL.js.map → chunk-XSRQGX5H.js.map} +0 -0
- /package/dist/{chunk-5TA5LHPW.js.map → chunk-YLL6CTBL.js.map} +0 -0
- /package/dist/{chunk-5YQXNW6Y.js.map → chunk-YPBY37KD.js.map} +0 -0
- /package/dist/{chunk-6DRRN5XP.js.map → chunk-YUNJBIK4.js.map} +0 -0
- /package/dist/{cohort-ERDL7EJU.js.map → cohort-5WL6UJOS.js.map} +0 -0
- /package/dist/{cohortSunburst-KSTVS3OQ.js.map → cohortSunburst-R3Z5KJQL.js.map} +0 -0
- /package/dist/{condition-CTJYHRJG.js.map → condition-2IILUMVB.js.map} +0 -0
- /package/dist/{controls-MMMRBTZL.js.map → controls-G3JITZF5.js.map} +0 -0
- /package/dist/{controls.config-ZKMQI27Q.js.map → controls.config-BO7KPPET.js.map} +0 -0
- /package/dist/{correlation-NEQNBQTT.js.map → correlation-CZILLVEM.js.map} +0 -0
- /package/dist/{customdata.inputui-THUR7DF5.js.map → customdata.inputui-BXFQAMTR.js.map} +0 -0
- /package/dist/{dataDownload-ZMAJUKBX.js.map → dataDownload-QTWR4IW7.js.map} +0 -0
- /package/dist/{databrowser.ui-A6ZSIUG4.js.map → databrowser.ui-V2NJQF3U.js.map} +0 -0
- /package/dist/{dictionary-TQUVCHIN.js.map → dictionary-OVAQX6R3.js.map} +0 -0
- /package/dist/{dnaMethylation-ZMJYY3ML.js.map → dnaMethylation-DHPFRXB2.js.map} +0 -0
- /package/dist/{dnaMethylation.integration.spec-5DTBGTYB.js.map → dnaMethylation.integration.spec-PJLIRGN5.js.map} +0 -0
- /package/dist/{e2pca-DNWBF545.js.map → e2pca-O7SNMJGB.js.map} +0 -0
- /package/dist/{ep-JNH3HMY4.js.map → ep-NIVLKG4S.js.map} +0 -0
- /package/dist/{expclust.gdc.spec-2NJ7JVJW.js.map → expclust.gdc.spec-LVCD6C43.js.map} +0 -0
- /package/dist/{facet-RWQFAVVU.js.map → facet-LB4SCXE4.js.map} +0 -0
- /package/dist/{gb-OT2Z3Y7J.js.map → gb-3IJ4NCPO.js.map} +0 -0
- /package/dist/{geneExpClustering-TPYGSTMO.js.map → geneExpClustering-SIAC7CMA.js.map} +0 -0
- /package/dist/{geneExpression-4K3OTXBZ.js.map → geneExpression-P2TTZXN2.js.map} +0 -0
- /package/dist/{geneExpression.unit.spec-26MCGRAP.js.map → geneExpression.unit.spec-Q5D6XHUF.js.map} +0 -0
- /package/dist/{geneORA-GNXKCN45.js.map → geneORA-PKUIJKTL.js.map} +0 -0
- /package/dist/{geneRanking-LV6W6TT7.js.map → geneRanking-ZGT5MHBV.js.map} +0 -0
- /package/dist/{geneVariant-B2SYTHG6.js.map → geneVariant-24YNANTT.js.map} +0 -0
- /package/dist/{geneVariant-O4XG5VEM.js.map → geneVariant-CDGENHWQ.js.map} +0 -0
- /package/dist/{geneVariant.integration.spec-YYVPAFXT.js.map → geneVariant.integration.spec-7QW4C2WO.js.map} +0 -0
- /package/dist/{genefusion.ui-CVGGYVV3.js.map → genefusion.ui-NVXGSBXD.js.map} +0 -0
- /package/dist/{geneset-MBMCJNXT.js.map → geneset-7STL6UDD.js.map} +0 -0
- /package/dist/{genomeBrowser.spec-OVXFKEIU.js.map → genomeBrowser.spec-OE2CIP7I.js.map} +0 -0
- /package/dist/{grin2-YCJGBRFG.js.map → grin2-2HXUIY5O.js.map} +0 -0
- /package/dist/{grin2-OXRU465E.js.map → grin2-32IIJR5E.js.map} +0 -0
- /package/dist/{hierCluster-KNPWL5KD.js.map → hierCluster-MDZEI2KB.js.map} +0 -0
- /package/dist/{hierCluster-L3LYQZQL.js.map → hierCluster-T3PZUGBI.js.map} +0 -0
- /package/dist/{hierCluster.config-VZBV5QIO.js.map → hierCluster.config-7UN6AYGB.js.map} +0 -0
- /package/dist/{hierCluster.integration.spec-ZM7K7WI4.js.map → hierCluster.integration.spec-DWOYVK6T.js.map} +0 -0
- /package/dist/{hierCluster.interactivity-EA7WVIQR.js.map → hierCluster.interactivity-5OM6XNFG.js.map} +0 -0
- /package/dist/{imagePlot-OLVI26S5.js.map → imagePlot-KBRXDV5G.js.map} +0 -0
- /package/dist/{importPlot-3SSCNROC.js.map → importPlot-DJMIC22L.js.map} +0 -0
- /package/dist/{isoformExpression-BTMJNAAO.js.map → isoformExpression-SWDWADRC.js.map} +0 -0
- /package/dist/{isoformExpression.unit.spec-S2W5T42Z.js.map → isoformExpression.unit.spec-2U5KCYBP.js.map} +0 -0
- /package/dist/{junction-GIS5OCRO.js.map → junction-NMXVVGRG.js.map} +0 -0
- /package/dist/{junction.unit.spec-MSILW6QZ.js.map → junction.unit.spec-JTGBPPN7.js.map} +0 -0
- /package/dist/{launch.adhoc-LLJY4LA5.js.map → launch.adhoc-YB5SKMNY.js.map} +0 -0
- /package/dist/{leftlabel.sample-P6DDVCOW.js.map → leftlabel.sample-QKXIODCS.js.map} +0 -0
- /package/dist/{lollipop-J34YCYIP.js.map → lollipop-TSZ62PBH.js.map} +0 -0
- /package/dist/{maf-MFEEYT5P.js.map → maf-4L5YN4CG.js.map} +0 -0
- /package/dist/{maftimeline-TGJ37QYA.js.map → maftimeline-VOYB3NY3.js.map} +0 -0
- /package/dist/{matrix-A6BNFCIH.js.map → matrix-IWJECVTF.js.map} +0 -0
- /package/dist/{matrix-XTKRVPMQ.js.map → matrix-MMJAJZA7.js.map} +0 -0
- /package/dist/{matrix.config-RMDDMOZ5.js.map → matrix.config-DZGOZWJS.js.map} +0 -0
- /package/dist/{matrix.integration.spec-2DVRXVNH.js.map → matrix.integration.spec-2N237E7T.js.map} +0 -0
- /package/dist/{matrix.interactivity-MGOYEKDN.js.map → matrix.interactivity-FL33UUKR.js.map} +0 -0
- /package/dist/{matrix.layout-T7EC5ZC2.js.map → matrix.layout-7SYHV3KJ.js.map} +0 -0
- /package/dist/{matrix.renderers-GR77V3RL.js.map → matrix.renderers-3SIBT2RP.js.map} +0 -0
- /package/dist/{matrix.sort.unit.spec-YUCV7G5L.js.map → matrix.sort.unit.spec-L3H44T6I.js.map} +0 -0
- /package/dist/{matrix.sorterUi.unit.spec-FESIQ2RC.js.map → matrix.sorterUi.unit.spec-2NRU5UFH.js.map} +0 -0
- /package/dist/{matrix.unit.spec-6QF3WKM7.js.map → matrix.unit.spec-HRZIJB6T.js.map} +0 -0
- /package/dist/{mavb-UXJBITZM.js.map → mavb-ZVRQSDPS.js.map} +0 -0
- /package/dist/{mds.fimo-IPNWVBO4.js.map → mds.fimo-ZKETTET7.js.map} +0 -0
- /package/dist/{mds.samplescatterplot-KEG7RSN3.js.map → mds.samplescatterplot-ZV3UNRLP.js.map} +0 -0
- /package/dist/{mds.survivalplot-LJF2CD33.js.map → mds.survivalplot-OVXZRTU4.js.map} +0 -0
- /package/dist/{multivalue-YRQZ73DI.js.map → multivalue-6BE5IA4F.js.map} +0 -0
- /package/dist/{oncomatrix-TIMH5JKS.js.map → oncomatrix-XK62NEOO.js.map} +0 -0
- /package/dist/{oncomatrix.spec-MUOKKCJN.js.map → oncomatrix.spec-YVTCHOPS.js.map} +0 -0
- /package/dist/{plot.2dvaf-3OL4S6QG.js.map → plot.2dvaf-NUOBWMNX.js.map} +0 -0
- /package/dist/{plot.app-CMLHZV5F.js.map → plot.app-G6IQWXTV.js.map} +0 -0
- /package/dist/{plot.barplot-NRYMIPK6.js.map → plot.barplot-6QJ6HEJR.js.map} +0 -0
- /package/dist/{plot.boxplot-ANGW3WUC.js.map → plot.boxplot-XKQJSW2O.js.map} +0 -0
- /package/dist/{plot.brainImaging-YUDBYKX5.js.map → plot.brainImaging-UTHFJFXU.js.map} +0 -0
- /package/dist/{plot.disco-LV7RE3YO.js.map → plot.disco-3MSCX7TM.js.map} +0 -0
- /package/dist/{plot.ssgq-F2LOQFYD.js.map → plot.ssgq-4KBVHF42.js.map} +0 -0
- /package/dist/{plot.vaf2cov-5OKC7X6D.js.map → plot.vaf2cov-OGUQSSDS.js.map} +0 -0
- /package/dist/{polar2-BGJA2GHZ.js.map → polar2-V7M56GTZ.js.map} +0 -0
- /package/dist/{profileForms-BKP3OBKV.js.map → profileForms-TS3BJLHH.js.map} +0 -0
- /package/dist/{profilePlot-5PRRNUKD.js.map → profilePlot-DP5272HR.js.map} +0 -0
- /package/dist/{proteinView-VZIWIZZY.js.map → proteinView-K4K4SP3L.js.map} +0 -0
- /package/dist/{proteomeCohortCompare-XZI5OI4X.js.map → proteomeCohortCompare-SFWVGLFK.js.map} +0 -0
- /package/dist/{pseudbulk.unit.spec-DXJQV7JQ.js.map → pseudbulk.unit.spec-NFOA7J2C.js.map} +0 -0
- /package/dist/{pseudobulk-FCH3WW6O.js.map → pseudobulk-XKZQEZ4I.js.map} +0 -0
- /package/dist/{qualitative-BRKLVRKW.js.map → qualitative-7OSFNVI5.js.map} +0 -0
- /package/dist/{qualitative-ATX53V44.js.map → qualitative-OIIN6E4Y.js.map} +0 -0
- /package/dist/{radar2-6BBT2FBT.js.map → radar2-AHZJKX7S.js.map} +0 -0
- /package/dist/{radarFacility2-76Q3IYP2.js.map → radarFacility2-OUW6D5E7.js.map} +0 -0
- /package/dist/{render-KUC3QH36.js.map → render-7UZSGX3Q.js.map} +0 -0
- /package/dist/{report-KB4K7ZXC.js.map → report-J7HKTXZ2.js.map} +0 -0
- /package/dist/{sampleView-QD2JLZ4T.js.map → sampleView-6547OUIM.js.map} +0 -0
- /package/dist/{samplelst-6R5RYHNV.js.map → samplelst-UHF23UEB.js.map} +0 -0
- /package/dist/{samplematrix-NGORNBTR.js.map → samplematrix-OOKS3TMR.js.map} +0 -0
- /package/dist/{sc-27AHZZDK.js.map → sc-WF2BLGNG.js.map} +0 -0
- /package/dist/{scatter-FXLZMWD6.js.map → scatter-ABCVFGRV.js.map} +0 -0
- /package/dist/{scatter-OWFYLMSJ.js.map → scatter-WF7XM3IA.js.map} +0 -0
- /package/dist/{selectGenomeWithTklst-ZTGABCXC.js.map → selectGenomeWithTklst-67HU5KRB.js.map} +0 -0
- /package/dist/{singleCellCellType-7XXJ5NWC.js.map → singleCellCellType-3FZPJ25V.js.map} +0 -0
- /package/dist/{singleCellCellType.unit.spec-Y3TEYYCF.js.map → singleCellCellType.unit.spec-TOMREHWK.js.map} +0 -0
- /package/dist/{singleCellGeneExpression-EUAIEIYJ.js.map → singleCellGeneExpression-NQTJ5KJQ.js.map} +0 -0
- /package/dist/{singleCellGeneExpression.unit.spec-JVHPFLML.js.map → singleCellGeneExpression.unit.spec-ZWUQTU2N.js.map} +0 -0
- /package/dist/{singleCellNumericValue-FHIECJDK.js.map → singleCellNumericValue-VI7H722L.js.map} +0 -0
- /package/dist/{singleCellNumericValue.unit.spec-ZFG56MIO.js.map → singleCellNumericValue.unit.spec-QGLHES7H.js.map} +0 -0
- /package/dist/{singleCellPlot-NDGIW32L.js.map → singleCellPlot-RU5T6SJK.js.map} +0 -0
- /package/dist/{singlecell-JPWVPZEF.js.map → singlecell-C3CJVNXP.js.map} +0 -0
- /package/dist/{singlecell-N7RJMWZ2.js.map → singlecell-NRQZ7KC6.js.map} +0 -0
- /package/dist/{snp-APUTOL2F.js.map → snp-X6XY65VS.js.map} +0 -0
- /package/dist/{snp.unit.spec-4AN7AJKO.js.map → snp.unit.spec-6EENK7GQ.js.map} +0 -0
- /package/dist/{snplocus-WIMFAMBE.js.map → snplocus-R4JA6TFT.js.map} +0 -0
- /package/dist/{snplst-SUJ5AK4E.js.map → snplst-SOWVHSXH.js.map} +0 -0
- /package/dist/{spliceevent.a53ss.diagram-4UBI7PFJ.js.map → spliceevent.a53ss.diagram-IRLCCVQZ.js.map} +0 -0
- /package/dist/{spliceevent.exonskip.diagram-NVEXVRIC.js.map → spliceevent.exonskip.diagram-4KG7LE5D.js.map} +0 -0
- /package/dist/{spliceevent.noeventdiagram-CKEWNLVF.js.map → spliceevent.noeventdiagram-OWXAJJX7.js.map} +0 -0
- /package/dist/{ssGSEA-CJOVXTAW.js.map → ssGSEA-EMOKPLMP.js.map} +0 -0
- /package/dist/{ssGSEA.unit.spec-A7VRVJSF.js.map → ssGSEA.unit.spec-KXQ7R5WH.js.map} +0 -0
- /package/dist/{stattable-JBJVVLQE.js.map → stattable-H2G7MOZG.js.map} +0 -0
- /package/dist/{studyCatalog-NEL7XSIP.js.map → studyCatalog-3ITQXWFL.js.map} +0 -0
- /package/dist/{summarizeCnvGeneexp-BZSCTA5W.js.map → summarizeCnvGeneexp-ZIPU6YDY.js.map} +0 -0
- /package/dist/{summarizeGeneexpSurvival-743KXNV7.js.map → summarizeGeneexpSurvival-3RYU226R.js.map} +0 -0
- /package/dist/{summarizeMutationCnv-CALMSQGV.js.map → summarizeMutationCnv-RGDBUB22.js.map} +0 -0
- /package/dist/{summarizeMutationDiagnosis-OTE7O4AS.js.map → summarizeMutationDiagnosis-Z4MZE6Y4.js.map} +0 -0
- /package/dist/{summarizeMutationSurvival-VOZOFTFM.js.map → summarizeMutationSurvival-Z5CNRH7E.js.map} +0 -0
- /package/dist/{summary-XJKCD35N.js.map → summary-6QQCNX3B.js.map} +0 -0
- /package/dist/{summary.integration.spec-OOEU6WNB.js.map → summary.integration.spec-3ULXTZUP.js.map} +0 -0
- /package/dist/{summaryInput-JSOXVSMY.js.map → summaryInput-4QKR34QB.js.map} +0 -0
- /package/dist/{sunburst-J3QHMYKW.js.map → sunburst-KB3BWC72.js.map} +0 -0
- /package/dist/{sunburst-LZPP6NPV.js.map → sunburst-XTFBHZNH.js.map} +0 -0
- /package/dist/{survival-5GWRVTQ6.js.map → survival-7O6ZK63E.js.map} +0 -0
- /package/dist/{survival-FW7N3YXZ.js.map → survival-NNCY4K6C.js.map} +0 -0
- /package/dist/{survival.integration.spec-WN36VUHL.js.map → survival.integration.spec-ZYZHZAXA.js.map} +0 -0
- /package/dist/{svgraph-N35EMK3G.js.map → svgraph-ZLSFFEAC.js.map} +0 -0
- /package/dist/{svmr-EWL5WDDD.js.map → svmr-REBBDEYM.js.map} +0 -0
- /package/dist/{swimmer-Z6FUH4CD.js.map → swimmer-NUBRIWLI.js.map} +0 -0
- /package/dist/{table-EI2OIRGE.js.map → table-CWIQQESJ.js.map} +0 -0
- /package/dist/{termCollection-K3EX5P3F.js.map → termCollection-7TYJSQ45.js.map} +0 -0
- /package/dist/{termCollection-TBTAHLVH.js.map → termCollection-7Z55QNL7.js.map} +0 -0
- /package/dist/{termCollection.unit.spec-ZVNAIPHZ.js.map → termCollection.unit.spec-LQ5MIBDH.js.map} +0 -0
- /package/dist/{termCollectionFractionSelection-ATNIPWVX.js.map → termCollectionFractionSelection-24DZYVDU.js.map} +0 -0
- /package/dist/{termCollectionFractionSelection.unit.spec-VBRWWBML.js.map → termCollectionFractionSelection.unit.spec-DCV2CFS5.js.map} +0 -0
- /package/dist/{tk-U6CYISBH.js.map → tk-2WZFPRCP.js.map} +0 -0
- /package/dist/{tk-P3RPLUVH.js.map → tk-QTLEYIP7.js.map} +0 -0
- /package/dist/{tp.ui-KBFYUSWS.js.map → tp.ui-HXQX2UH4.js.map} +0 -0
- /package/dist/{tvs.categorical-5USP772O.js.map → tvs.categorical-4D3JI2ER.js.map} +0 -0
- /package/dist/{tvs.condition-652MAA2Z.js.map → tvs.condition-62FXFHZ5.js.map} +0 -0
- /package/dist/{tvs.density-CB24PXDE.js.map → tvs.density-IGO4I4T2.js.map} +0 -0
- /package/dist/{tvs.dt-7BTARQUS.js.map → tvs.dt-FZSVMJOO.js.map} +0 -0
- /package/dist/{tvs.dtcnv.categorical-GAOO3DGO.js.map → tvs.dtcnv.categorical-PPFQIC42.js.map} +0 -0
- /package/dist/{tvs.dtcnv.continuous-P2QRD45O.js.map → tvs.dtcnv.continuous-TV2IGHY4.js.map} +0 -0
- /package/dist/{tvs.dtfusion-L3I65W7L.js.map → tvs.dtfusion-ON4BA4XJ.js.map} +0 -0
- /package/dist/{tvs.dtitd-B3JPW6OL.js.map → tvs.dtitd-VFNROOWQ.js.map} +0 -0
- /package/dist/{tvs.dtsnvindel-6Y6CJBZV.js.map → tvs.dtsnvindel-ZXOP37T5.js.map} +0 -0
- /package/dist/{tvs.dtsv-GL7CPATL.js.map → tvs.dtsv-EUHPTW7J.js.map} +0 -0
- /package/dist/{tvs.multivalue-75IM23FZ.js.map → tvs.multivalue-NHVXZNDI.js.map} +0 -0
- /package/dist/{tvs.numeric-XB3GBPHE.js.map → tvs.numeric-FPWDPO3J.js.map} +0 -0
- /package/dist/{tvs.samplelst-QUA45UE7.js.map → tvs.samplelst-ZZHRNUP4.js.map} +0 -0
- /package/dist/{tvs.survival-EKSDZZIO.js.map → tvs.survival-F3KSG3U6.js.map} +0 -0
- /package/dist/{tvs.termCollection-5ATMDC7O.js.map → tvs.termCollection-B37DZLDY.js.map} +0 -0
- /package/dist/{vocabulary-5QBBQAYC.js.map → vocabulary-XNE5FFDK.js.map} +0 -0
- /package/dist/{wsi.direct-BU6BL5UR.js.map → wsi.direct-3YH3QGQD.js.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../mass/about.ts", "../mass/search.ts", "../mass/chat.ts", "../mass/user.ts", "../mass/nav.ts"],
|
|
4
|
+
"sourcesContent": ["import { getId } from './nav'\nimport { type AppApi, getCompInit } from '#rx'\nimport type { Elem, Div, H2 } from '../types/d3'\nimport type { SelectCohortEntry } from '#types'\nimport { renderTable, type TableRow, Menu } from '#dom'\nimport { importPlot } from '#plots/importPlot.js'\nimport { select } from 'd3-selection'\n\n/* \n\"about\" tab will display following contents inside this.subheader:\n- if ds uses subcohorts:\n\t- <h2> for selectCohort.title\n\t- description\n\t- radio button options\n- custom html via massNav.about.html (todo images and cartoon)\n- sunburst of the dataset's default rings, if massNav.about.showSunburst; in the custom html element\n that showSunburst.holderSelector selects, if given\n- active items to launch demo plots; in the custom html element that activeItems.holderSelector selects, if given\n- server info\n*/\n\nconst cohortTableActiveColor = 'yellow'\n\n// this type is fully defined in MassNav def in dataset.ts but not in a form that can extract \"about\" config to share. thus need to repeat here to avoid tsc err\ntype AboutObj = {\n\thtml: string\n\tactiveItems?: {\n\t\tlayout?: 'buttons' | 'cards'\n\t\tholderSelector?: string\n\t\ttitle?: string\n\t\tdescription?: string\n\t\titems: any\n\t}\n\tdisclaimer?: any\n\t/** when true, render the world map from termdbConfig.geomap directly on the landing tab */\n\tshowGeomap?: boolean\n\t/** render the sunburst of termdbConfig.sunburst.twLst on the landing tab; an object gives it a heading and\n\t * a holderSelector */\n\tshowSunburst?: boolean | { holderSelector?: string; title?: string; description?: string }\n}\n\ntype MassAboutOpts = {\n\t/** Optional. Set in the dataset file under .massNav.tabs.about. Otherwise null. */\n\taboutOverrides: AboutObj | null\n\t/** Required. Provided from nav component */\n\tapp: AppApi\n\t/** Required. Provided from nav component */\n\tinstanceNum: number\n\t/** Optional. Set in the dataset file under .termdb.selectCohort. Otherwise null. */\n\tselectCohort: SelectCohortEntry | null\n\t/** Required. .dom.subheader.about in nav component, assigned to this.subheader */\n\tsubheader: Elem\n}\n\ntype MassAboutDom = {\n\t/** Fine print dom shown between the cohort specific content and the server info */\n\tcohortAsterisk?: Div\n\t/** Displays description */\n\tcohortDescription: Div\n\t/** Div for cohort radio buttons */\n\tcohortOpts?: Div\n\t/** Text above radio cohort options */\n\tcohortPrompt?: Div\n\t/** */\n\tcohortTable?: Div\n\t/** Title above the cohort introduction/content */\n\tcohortTitle?: H2\n}\n//TODO: Make a validate opts fn\nexport class MassAbout {\n\tstatic type = 'about'\n\n\taboutOverrides: AboutObj | null\n\tapp: AppApi\n\tdom: MassAboutDom\n\tinstanceNum: number\n\tselectCohort: SelectCohortEntry | null\n\tsubheader: Elem // where all contents are rendered\n\ttype: string\n\topts: MassAboutOpts\n\tstate: any\n\t/** reused menu for openChartMenu() so repeated card clicks don't accumulate menu divs in the DOM */\n\tchartMenu?: Menu\n\t/** the sunburst on this tab, once its module is loaded (initSunburst) */\n\tsunburst?: Promise<any>\n\n\tconstructor(opts: MassAboutOpts) {\n\t\tthis.opts = opts\n\t\tthis.type = MassAbout.type\n\t\tthis.app = opts.app\n\t\tthis.subheader = opts.subheader\n\t\tthis.instanceNum = opts.instanceNum\n\t\tthis.aboutOverrides = opts.aboutOverrides\n\t\tthis.selectCohort = opts.selectCohort\n\t\tthis.dom = {\n\t\t\tcohortDescription: this.subheader\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-about-cohort-desc')\n\t\t\t\t.style('margin-left', '10px')\n\t\t}\n\n\t\tif (opts?.selectCohort?.title) {\n\t\t\tthis.dom.cohortTitle = opts.subheader\n\t\t\t\t.append('h2')\n\t\t\t\t.attr('data-testid', 'sjpp-about-cohort-title')\n\t\t\t\t.style('margin-left', '10px')\n\t\t\t\t.text(opts.selectCohort.title)\n\t\t}\n\n\t\tif (opts.selectCohort?.prompt) {\n\t\t\tthis.dom.cohortPrompt = this.subheader\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-about-cohort-prompt')\n\t\t\t\t.style('margin-left', '10px')\n\t\t\t\t.style('padding-top', '30px')\n\t\t\t\t.style('padding-bottom', '10px')\n\t\t\t\t.style('font-weight', 'bold')\n\t\t\t\t.style('font-size', '1.2em')\n\t\t\t\t.text(opts.selectCohort.prompt)\n\t\t}\n\n\t\tif (opts.selectCohort) {\n\t\t\tthis.dom.cohortOpts = this.subheader.append('div').style('margin-bottom', '30px').style('margin-left', '10px')\n\t\t}\n\t}\n\n\t/* render all contents into this.subheader\n\tdo it through init() means that contents are rendered just once on launching mass ui and won't be rerendered or updated\n\tsince there's no reason to update about tab contents while user is interacting with mass ui\n\t*/\n\tinit(appState) {\n\t\t/** If selectCohort available, options in the about html will not show */\n\t\tthis.initCohort(appState)\n\t\tthis.initCustomHtml()\n\t\tthis.initGeomap(appState)\n\t\tthis.initSunburst(appState)\n\t\tthis.initActiveItems()\n\t\tthis.initDisclaimer()\n\t\t//Always show the release version and server launch date at the bottom\n\t\tthis.showServerInfo()\n\t}\n\n\tasync main() {\n\t\t// do not render unless the cohort tab is active\n\t\tif (this.state.nav.activeTab !== 0) return\n\t\tawait this.renderCohortsTable()\n\t\t// the sunburst counts follow the global filter\n\t\tif (this.sunburst) await (await this.sunburst)?.update(this.state)\n\t\tif (this.opts.selectCohort) {\n\t\t\tif (this.opts.selectCohort.description) {\n\t\t\t\tthis.dom.cohortDescription.html(this.opts.selectCohort.description)\n\t\t\t} else if (this.opts.selectCohort.descriptionByCohort) {\n\t\t\t\tthis.dom.cohortDescription.html(\n\t\t\t\t\tthis.opts.selectCohort.descriptionByCohort[\n\t\t\t\t\t\tthis.state.termdbConfig.selectCohort.values[this.state.activeCohort].keys.join(',')\n\t\t\t\t\t]\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\tinitCohort = appState => {\n\t\tif (this.selectCohort == null) return\n\t\t//Move to validate opts fn\n\t\tif (!this.selectCohort.values) return\n\n\t\tconst instanceNum = this.instanceNum\n\t\tconst activeCohort = appState.activeCohort\n\t\tconst app = this.app\n\n\t\t//TODO: replace with make_radios\n\t\tthis.dom\n\t\t\t.cohortOpts!.append('table')\n\t\t\t.attr('data-testid', 'sjpp-about-cohort-options-table')\n\t\t\t.selectAll('tr')\n\t\t\t.data(this.selectCohort.values)\n\t\t\t.enter()\n\t\t\t.append('tr')\n\t\t\t.each(function (d, i, nodes) {\n\t\t\t\tconst tr = select(nodes[i])\n\t\t\t\tconst td0 = tr.append('td')\n\t\t\t\tconst radioName = 'sja-termdb-cohort-' + instanceNum\n\t\t\t\tconst radioId = radioName + '-' + i\n\t\t\t\ttd0\n\t\t\t\t\t.append('input')\n\t\t\t\t\t.style('scale', '1.2')\n\t\t\t\t\t.attr('type', 'radio')\n\t\t\t\t\t.attr('name', radioName)\n\t\t\t\t\t.attr('id', radioId)\n\t\t\t\t\t.attr('value', i)\n\t\t\t\t\t.property('checked', i === activeCohort)\n\t\t\t\t\t.style('margin-right', '5px')\n\t\t\t\t\t.style('margin-left', '0px')\n\t\t\t\t\t.on('click', async event => {\n\t\t\t\t\t\tconst state = app.getState()\n\t\t\t\t\t\tconst clearOnChange = state.termdbConfig.selectCohort.clearOnChange\n\t\t\t\t\t\tif (clearOnChange) {\n\t\t\t\t\t\t\tconst subactions: any[] = []\n\t\t\t\t\t\t\tconst toBeCleared: string[] = []\n\t\t\t\t\t\t\tconst plots = state.plots\n\t\t\t\t\t\t\tconst filter = state.termfilter.filter.lst.find(f => f.tag == 'filterUiRoot')?.lst\n\t\t\t\t\t\t\tconst groups = state.groups\n\n\t\t\t\t\t\t\tif (clearOnChange.plots && plots?.length) toBeCleared.push('plots')\n\t\t\t\t\t\t\tfor (const plot of plots) {\n\t\t\t\t\t\t\t\tsubactions.push({\n\t\t\t\t\t\t\t\t\ttype: 'plot_delete',\n\t\t\t\t\t\t\t\t\tid: plot.id\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (clearOnChange.filter && filter?.length) toBeCleared.push('filters')\n\t\t\t\t\t\t\tsubactions.push({\n\t\t\t\t\t\t\t\ttype: 'filter_replace',\n\t\t\t\t\t\t\t\tfilter: {\n\t\t\t\t\t\t\t\t\ttype: 'tvslst',\n\t\t\t\t\t\t\t\t\tin: true,\n\t\t\t\t\t\t\t\t\tjoin: '',\n\t\t\t\t\t\t\t\t\ttag: 'filterUiRoot',\n\t\t\t\t\t\t\t\t\tlst: []\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tif (clearOnChange.groups && groups?.length) {\n\t\t\t\t\t\t\t\ttoBeCleared.push('groups')\n\t\t\t\t\t\t\t\tfor (const group of groups) {\n\t\t\t\t\t\t\t\t\tsubactions.push({\n\t\t\t\t\t\t\t\t\t\ttype: 'delete_group',\n\t\t\t\t\t\t\t\t\t\tname: group.name\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfor (const term of state.customTerms) {\n\t\t\t\t\t\t\t\t\tsubactions.push({\n\t\t\t\t\t\t\t\t\t\ttype: 'delete_customTerm',\n\t\t\t\t\t\t\t\t\t\tname: term.name\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsubactions.push({ type: 'cohort_set', activeCohort: i })\n\t\t\t\t\t\t\tif (toBeCleared.length) {\n\t\t\t\t\t\t\t\tconst confirm = window.confirm(\n\t\t\t\t\t\t\t\t\t`Changing the cohort will clear all ${joinByComma(\n\t\t\t\t\t\t\t\t\t\ttoBeCleared\n\t\t\t\t\t\t\t\t\t)}. To proceed, click \"OK\". To save the session, click \"Cancel\" and then click the \"Session\" button at the top of the page.`\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tif (!confirm) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tapp.dispatch({\n\t\t\t\t\t\t\t\ttype: 'app_refresh',\n\t\t\t\t\t\t\t\tsubactions\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t} else app.dispatch({ type: 'cohort_set', activeCohort: i })\n\t\t\t\t\t})\n\n\t\t\t\ttd0\n\t\t\t\t\t.append('label')\n\t\t\t\t\t.style('font-size', '1.4em')\n\t\t\t\t\t.attr('for', radioId)\n\t\t\t\t\t.attr('colspan', 2)\n\t\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t\t.html((d: any) => d.label)\n\n\t\t\t\ttr.selectAll('td')\n\t\t\t\t\t.style('max-width', '600px')\n\t\t\t\t\t.style('padding-bottom', '10px')\n\t\t\t\t\t.style('padding-right', '20px')\n\t\t\t\t\t.style('vertical-align', 'top')\n\t\t\t})\n\n\t\tthis.dom.cohortTable = this.subheader\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-about-cohort-table')\n\t\t\t.style('margin-left', '12px')\n\n\t\tif (this.selectCohort.asterisk) {\n\t\t\tthis.dom.cohortAsterisk = this.subheader\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-about-cohort-asterisk')\n\t\t\t\t.style('margin', '10px')\n\t\t\t\t.style('font-size', '.8em')\n\t\t\t\t.text(this.selectCohort.asterisk)\n\t\t}\n\t}\n\n\trenderCohortsTable = async () => {\n\t\tif (!this.dom.cohortTable) return\n\t\tthis.dom.cohortTable.selectAll('*').remove()\n\t\tconst columns = [{ label: 'Feature' }]\n\t\tconst rows: TableRow[] = []\n\t\tconst result = await this.app.vocabApi.getCohortsData()\n\t\tif ('error' in result) throw result.error\n\t\tif (this.selectCohort?.values) {\n\t\t\t// selectCohort.values[] contains ordered set of cohorts\n\t\t\t// ensure cohorts in cohorts table follow this order\n\t\t\tconst values = this.selectCohort.values\n\t\t\tresult.cohorts.sort((a, b) => {\n\t\t\t\tconst aIndex = values.findIndex(v => v.keys.toString() == a.cohort)\n\t\t\t\tconst bIndex = values.findIndex(v => v.keys.toString() == b.cohort)\n\t\t\t\tif (aIndex < bIndex) return -1\n\t\t\t\tif (aIndex > bIndex) return 1\n\t\t\t\treturn 0\n\t\t\t})\n\t\t}\n\t\tif (!result.cfeatures.length) return\n\t\tfor (const feature of result.features) rows.push([{ value: feature.name }])\n\t\tfor (const cohort of result.cohorts) {\n\t\t\tif (cohort.subcohorts?.length) continue\n\t\t\tcolumns.push({ label: cohort.name })\n\t\t\tfor (const [i, feature] of result.features.entries()) {\n\t\t\t\tconst cf = result.cfeatures.find(cf => cf.idfeature === feature.idfeature && cf.cohort === cohort.cohort)\n\t\t\t\tif (cf) rows[i].push({ value: cf.value })\n\t\t\t}\n\t\t}\n\n\t\trenderTable({\n\t\t\trows,\n\t\t\tcolumns,\n\t\t\tdiv: this.dom.cohortTable,\n\t\t\tshowLines: false,\n\t\t\tmaxHeight: '60vh',\n\t\t\theader: { style: { 'font-size': '1.2em', 'font-weight': 'bold' } }\n\t\t})\n\n\t\tthis.dom.cohortTable.select('table').style('border-collapse', 'collapse')\n\t\tthis.dom.cohortTable.selectAll(`tbody > tr > td`).style('background-color', 'transparent').style('padding', '6px')\n\t\tconst state = this.app.getState()\n\t\tconst selectCohort = state.termdbConfig.selectCohort\n\t\tconst activeCohort = state.activeCohort\n\t\tconst keys = selectCohort.values[activeCohort].keys\n\t\tlet selector = `tbody > tr > td:nth-child(${activeCohort + 2})`\n\t\tconst combined = keys.length > 1\n\t\tif (combined) {\n\t\t\tselector = ''\n\t\t\tfor (const key of keys) {\n\t\t\t\tconst i = result.cohorts.map(c => c.cohort).indexOf(key)\n\t\t\t\tif (selector !== '') selector += ','\n\t\t\t\tselector += `tbody > tr > td:nth-child(${i + 2})`\n\t\t\t}\n\t\t}\n\t\tconst activeColumns = this.dom.cohortTable.selectAll(selector)\n\t\tconst color = state.termdbConfig.massNav?.activeColor || cohortTableActiveColor\n\t\tactiveColumns.style('background-color', color)\n\t}\n\n\tinitCustomHtml = () => {\n\t\tif (this.selectCohort != null) return\n\t\tif (!this.aboutOverrides?.html) return\n\t\tthis.subheader\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-custom-about-content')\n\t\t\t.style('padding', '10px')\n\t\t\t.html(this.aboutOverrides.html)\n\t}\n\n\t// render the world map (from termdbConfig.geomap) directly on the landing tab when the dataset opts in.\n\t// the renderer (and its ~170KB world.json basemap) is dynamically imported so it never loads for\n\t// datasets that don't enable the map.\n\tinitGeomap = async appState => {\n\t\tif (!this.aboutOverrides?.showGeomap) return\n\t\tconst geomap = appState.termdbConfig?.geomap\n\t\tif (!geomap?.sites?.length) return\n\t\tconst holder = this.subheader.append('div').attr('data-testid', 'sjpp-about-geomap').style('padding', '10px')\n\t\tconst { renderGeomap } = await import('#plots/geomap/render.ts')\n\t\trenderGeomap(holder, geomap)\n\t}\n\n\t// render the sunburst of the dataset's default rings when the dataset opts in. like the geomap,\n\t// its module is dynamically imported so it only loads for datasets that show it; main() draws it\n\tinitSunburst = appState => {\n\t\tif (!this.aboutOverrides?.showSunburst) return\n\t\tif (!appState.termdbConfig?.sunburst?.twLst?.length) return\n\t\tconst s = this.aboutOverrides.showSunburst\n\t\tconst placed = typeof s == 'object' ? this.getSectionHolder(s.holderSelector, 'showSunburst') : undefined\n\t\tconst section = (placed || this.subheader.append('div')).style('padding', '10px')\n\t\tif (typeof s == 'object') this.sectionHeading(section, s.title, s.description)\n\t\t// the chart is as wide as its columns, centered, with some space before the next section\n\t\tconst holder = section\n\t\t\t.append('div')\n\t\t\t.style('display', 'flex')\n\t\t\t.style('justify-content', 'center')\n\t\t\t.style('margin-bottom', '32px')\n\t\tconst onOpen = () => this.launchActiveItem({ plot: { chartType: 'sunburst' } }, holder.node())\n\t\tthis.sunburst = import('#plots/sunburst/aboutSunburst.ts')\n\t\t\t.then(_ => new _.AboutSunburst(holder, this.app, onOpen))\n\t\t\t.catch(e => {\n\t\t\t\tholder\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.attr('class', 'sja_errorbar')\n\t\t\t\t\t.text(e?.message || String(e))\n\t\t\t\tconsole.error(e)\n\t\t\t})\n\t}\n\n\tdestroy() {\n\t\tvoid this.sunburst?.then(sunburst => sunburst?.chart.destroy())\n\t}\n\n\t// the element of the custom html that a section's holderSelector (a css selector from the dataset)\n\t// selects; undefined without one, or when it selects nothing, and then the section follows the content above\n\tgetSectionHolder = (selector: string | undefined, section: string) => {\n\t\tif (!selector) return\n\t\tlet el\n\t\ttry {\n\t\t\tel = this.subheader.select(selector)\n\t\t} catch (_) {\n\t\t\t// not a valid selector\n\t\t}\n\t\tif (el && !el.empty()) return el\n\t\tconsole.error(`about tab: ${section}.holderSelector '${selector}' selects no element of the html; shown at the end`)\n\t}\n\n\t// a section's centered heading and text, from the dataset; nothing if neither is given\n\tsectionHeading = (holder, title?: string, description?: string) => {\n\t\tif (!title && !description) return\n\t\tconst div = holder.append('div').style('text-align', 'center').style('margin', '24px 0 12px 0')\n\t\tif (title)\n\t\t\tdiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-about-section-title')\n\t\t\t\t.style('font-size', '1.4em')\n\t\t\t\t.style('font-weight', '600')\n\t\t\t\t.style('color', '#243b53')\n\t\t\t\t.html(title)\n\t\tif (description)\n\t\t\tdiv\n\t\t\t\t.append('div')\n\t\t\t\t.style('margin-top', '6px')\n\t\t\t\t.style('font-size', '.95em')\n\t\t\t\t.style('color', '#4b5563')\n\t\t\t\t.html(description)\n\t}\n\n\tinitActiveItems = () => {\n\t\tif (!this.aboutOverrides?.activeItems) return\n\t\tconst placed = this.getSectionHolder(this.aboutOverrides.activeItems.holderSelector, 'activeItems')\n\t\tconst holder = placed || this.subheader\n\t\tconst { title, description } = this.aboutOverrides.activeItems\n\t\tthis.sectionHeading(holder, title, description)\n\t\tif (this.aboutOverrides.activeItems.layout == 'cards') {\n\t\t\tthis.initActiveItemCards(holder)\n\t\t\treturn\n\t\t}\n\n\t\t// todo: customize general holder by activeItems.holderStyle{}\n\t\tconst div = holder\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-custom-about-activeItems')\n\t\t\t// placed by the custom html, the buttons are not indented\n\t\t\t.style('padding', placed ? '0px 0px 10px 0px' : '0px 0px 10px 20px')\n\n\t\tfor (const item of this.aboutOverrides.activeItems.items) {\n\t\t\t// todo: by item.type, item.divStyle{}\n\t\t\tconst btn = div\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('margin', '5px')\n\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t.attr('data-testid', 'sjpp-custom-active-item-btn')\n\t\t\t\t.html(item.title)\n\t\t\tthis.makeActivatable(btn, () => this.launchActiveItem(item, btn.node()))\n\t\t}\n\t}\n\n\t// render activeItems as large square tiles (homepage style) that lift on hover\n\tinitActiveItemCards = parent => {\n\t\tconst items = this.aboutOverrides!.activeItems!.items\n\t\tconst holder = parent\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-custom-about-activeItems')\n\t\t\t.style('display', 'flex')\n\t\t\t.style('flex-wrap', 'wrap')\n\t\t\t.style('justify-content', 'center')\n\t\t\t.style('gap', '24px')\n\t\t\t.style('padding', '20px 20px 30px 20px')\n\n\t\tfor (const item of items) {\n\t\t\tconst card = holder\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sjpp-about-card')\n\t\t\t\t.attr('data-testid', 'sjpp-custom-active-item-card')\n\t\t\tif (item.icon) card.append('div').attr('class', 'sjpp-about-card-icon').html(item.icon)\n\t\t\tcard.append('div').attr('class', 'sjpp-about-card-title').html(item.title)\n\t\t\t// always render the subtitle div (even when empty) so its reserved height keeps every card the same size\n\t\t\tcard\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sjpp-about-card-subtitle')\n\t\t\t\t.text(item.subtitle || '')\n\t\t\tthis.makeActivatable(card, () => this.launchActiveItem(item, card.node()))\n\t\t}\n\t}\n\n\t// make a non-native clickable element (a styled <div>) operable like a button:\n\tmakeActivatable = (sel, onActivate) => {\n\t\tsel\n\t\t\t.attr('role', 'button')\n\t\t\t.attr('tabindex', 0)\n\t\t\t.on('click', () => onActivate())\n\t\t\t.on('keydown', (event: KeyboardEvent) => {\n\t\t\t\tif (event.key == 'Enter' || event.key == ' ') {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tonActivate()\n\t\t\t\t}\n\t\t\t})\n\t}\n\n\t// launch behavior shared by button and card layouts\n\tlaunchActiveItem = async (item, anchorEl) => {\n\t\t// an item grouping several launch items opens them as a menu under the item\n\t\tif (item.menu) {\n\t\t\tthis.openItemMenu(item.menu, anchorEl)\n\t\t\treturn\n\t\t}\n\t\t// some charts (e.g. proteinView) require user input before a plot can be created;\n\t\t// open their chart-specific menu instead of directly creating a plot\n\t\tif (item.openChartMenu) {\n\t\t\tawait this.openChartMenu(item.openChartMenu, anchorEl)\n\t\t\treturn\n\t\t}\n\t\tif (!item.plot) {\n\t\t\tconsole.error('about activeItem has neither .plot nor .openChartMenu', item)\n\t\t\treturn\n\t\t}\n\t\t/* First, set the active tab to toggle to the plots tab and wait for the tab to be set,\n\t\totherwise the plotDiv is hidden when rendering and may cause issues. */\n\t\tawait this.app.dispatch({\n\t\t\ttype: 'tab_set',\n\t\t\tactiveTab: 1\n\t\t})\n\t\t// after switching tab so plot div is shown, dispatch to create the plot\n\t\tthis.app.dispatch({\n\t\t\ttype: 'plot_create',\n\t\t\tid: getId(),\n\t\t\tconfig: structuredClone(item.plot)\n\t\t})\n\t}\n\n\t// menu of launch items in labelled groups, anchored to the tile. An entry with its own\n\t// chart menu (e.g. a gene search) replaces this menu's content in place; other entries\n\t// hide the menu and launch their plot.\n\topenItemMenu = (groups, anchorEl) => {\n\t\tconst menu = this.chartMenu || (this.chartMenu = new Menu({ padding: '0px' }))\n\t\tmenu.clear()\n\t\tconst holder = menu.d.append('div').style('padding', '6px 0').style('min-width', '260px')\n\t\tfor (const group of groups) {\n\t\t\tif (group.label) {\n\t\t\t\tholder\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.style('padding', '6px 14px 2px')\n\t\t\t\t\t.style('font-size', '0.75em')\n\t\t\t\t\t.style('font-weight', 'bold')\n\t\t\t\t\t.style('letter-spacing', '0.05em')\n\t\t\t\t\t.style('text-transform', 'uppercase')\n\t\t\t\t\t.style('color', '#777')\n\t\t\t\t\t.text(group.label)\n\t\t\t}\n\t\t\tfor (const entry of group.items || []) {\n\t\t\t\tconst row = holder.append('div').attr('class', 'sja_menuoption').style('padding', '6px 14px')\n\t\t\t\trow.append('div').style('font-weight', '600').html(entry.title)\n\t\t\t\tif (entry.subtitle) row.append('div').style('font-size', '0.8em').style('color', '#666').text(entry.subtitle)\n\t\t\t\tthis.makeActivatable(row, async () => {\n\t\t\t\t\tif (!entry.openChartMenu && !entry.menu) menu.hide()\n\t\t\t\t\tawait this.launchActiveItem(entry, anchorEl)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tmenu.showunder(anchorEl)\n\t}\n\n\t// open a chart-specific launch menu (e.g. gene search for proteinView) anchored to the tile.\n\t// the chart module is dynamically imported so its code only loads when the tile is clicked.\n\topenChartMenu = async (chartType, anchorEl) => {\n\t\t// reuse a single menu instance; Menu.hide() only hides (doesn't remove) the div\n\t\tconst menu = this.chartMenu || (this.chartMenu = new Menu({ padding: '0px' }))\n\t\tmenu.clear()\n\t\t// wrap dispatch so that creating a plot from the menu also switches to the plots tab\n\t\tconst shimApp = {\n\t\t\topts: this.app.opts,\n\t\t\tdispatch: async action => {\n\t\t\t\tif (action.type == 'plot_create') await this.app.dispatch({ type: 'tab_set', activeTab: 1 })\n\t\t\t\treturn this.app.dispatch(action)\n\t\t\t}\n\t\t}\n\t\tconst chartsInstanceShim = { app: shimApp, dom: { tip: menu } }\n\t\tconst _ = await importPlot(chartType)\n\t\tif (typeof _.makeChartBtnMenu != 'function')\n\t\t\tthrow `about activeItem openChartMenu: chart '${chartType}' has no makeChartBtnMenu`\n\t\t_.makeChartBtnMenu(menu.d.append('div'), chartsInstanceShim, chartType)\n\t\tmenu.showunder(anchorEl)\n\t}\n\n\tinitDisclaimer = () => {\n\t\tconst d = this.aboutOverrides?.disclaimer\n\t\tif (!d) return\n\t\t// customize styling from d{}\n\t\tconst div = this.subheader\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-custom-about-disclaimer')\n\t\t\t.style('margin', '10px 0 20px 10px')\n\t\t\t.style('opacity', 0.7)\n\t\t\t.style('padding', '10px')\n\t\t\t.style('background-color', '#f8f9fa')\n\t\t\t.style('border-left', '4px solid #6c757d')\n\t\t\t.style('font-size', '0.8em')\n\t\tdiv.append('div').style('margin-bottom', '8px').style('font-weight', 'bold').text('DISCLAIMER')\n\t\tdiv.append('div').text(d.text)\n\t}\n\n\tshowServerInfo = () => {\n\t\tconst state = this.app.getState()\n\t\tconst about = state.termdbConfig.massNav?.tabs?.about\n\t\tif (!about && !this.app.opts.pkgver && !this.app.opts.launchDate) return\n\t\tconst dataRelease = about?.dataRelease\n\t\tconst additionalInfo = about?.additionalInfo\n\t\tconst div = this.subheader\n\t\t\t.append('div')\n\t\t\t.attr('data-testid', 'sjpp-about-server-info')\n\t\t\t.style('margin', '10px')\n\t\t\t.style('font-size', '.8em')\n\n\t\tconst htmlArr: string[] = []\n\t\tif (dataRelease) {\n\t\t\thtmlArr.push(`Data Release: <a href=${dataRelease.link} target=_blank>${dataRelease.version}</a>`)\n\t\t}\n\t\tif (this.app.opts.pkgver) {\n\t\t\thtmlArr.push(\n\t\t\t\t`Software Release: <a href=https://github.com/stjude/proteinpaint/pkgs/container/ppfull target=_blank>${this.app.opts.pkgver}</a>`\n\t\t\t)\n\t\t}\n\t\tif (this.app.opts.launchDate) {\n\t\t\thtmlArr.push(`Server Launched: ${this.app.opts.launchDate}`)\n\t\t}\n\t\tif (additionalInfo) {\n\t\t\thtmlArr.push(additionalInfo)\n\t\t}\n\t\tdiv.append('div').html(htmlArr.join('; '))\n\t}\n}\n\nexport const aboutInit = getCompInit(MassAbout)\n\nfunction joinByComma(arr) {\n\tif (!arr.length) return ''\n\telse if (arr.length == 1) return arr[0]\n\telse if (arr.length == 2) return arr.join(' and ')\n\telse return `${arr.slice(0, -1).join(', ')}, and ${arr.slice(-1)}`\n}\n", "// Mass omnisearch (search-as-you-type): resolves a typed prompt to dictionary variables, genes, and a\n// genomic coordinate via one termdb/chat request, and renders the results as rows whose action buttons\n// launch plots. Extracted from chat.ts; the functions here operate on the MassAiChatBot instance (`self`),\n// which owns the DOM (self.dom), app api (self.app), and options (self.opts).\nimport { keyupEnter } from '#src/client'\nimport { dofetch3 } from '#common/dofetch'\nimport { type OmnisearchResult, DNA_METHYLATION } from '#types'\nimport { sayerror } from '../dom/sayerror.ts'\nimport { select } from 'd3-selection'\nimport { fillTermWrapper } from '#termsetting'\nimport { dtsnvindel, dtcnv, dtsv, dtfusionrna } from '#shared/common.js'\nimport { getDNAMethUnit } from '#tw/dnaMethylation'\nimport { first_genetrack_tolist } from '#common/1stGenetk'\nimport { getSampleFilter } from './groups.js'\nimport { escapeHtml } from '#dom'\n\n// Minimum prompt length per search family. Gene search runs from a single character; dictionary and\n// sample search require 3 (they match more loosely and, for samples, scan every sample name). Coordinate\n// search has no length gate (its regex decides). The dict/sample cutoff is sent to the server, which skips\n// those searches for short prompts so a 1\u20132 char keystroke never scans all samples on a large dataset.\nconst MIN_PROMPT_LENGTH_FOR_GENE_SEARCH = 1\nconst MIN_PROMPT_LENGTH_FOR_OTHER_SEARCH = 3\nconst MAX_PROMPT_LENGTH_FOR_OMNISEARCH = 20\n\n/** Build a region-based dnaMethylation term for the given coordinates. */\nfunction makeMethylationRegionTerm(opts: { chr: string; start: number; stop: number }, vocabApi: any) {\n\tconst { chr, start, stop } = opts\n\tif (!chr || !Number.isInteger(start) || !Number.isInteger(stop)) throw new Error('invalid coordinate')\n\treturn {\n\t\tchr,\n\t\tstart,\n\t\tstop,\n\t\ttype: DNA_METHYLATION,\n\t\tunit: getDNAMethUnit('region', vocabApi),\n\t\tgenomicFeatureType: 'region'\n\t}\n}\n\n/**\n * Embed a genome browser of a gene/region into `holder` with a \"Submit Region\" button. On submit,\n * builds a region-based dnaMethylation term from the region the user navigated to and passes it to\n * `callback`. Returns the Block instance. Used by the mass omnisearch to open a methylation region\n * picker for a gene. (The dnaMethylation search handler keeps its own equivalent inline logic.)\n */\nasync function embedMethylationRegionPicker(opts: {\n\tholder: any\n\tgenomeObj: any\n\tvocabApi: any\n\tchr: string\n\tstart: number\n\tstop: number\n\tcallback: (term: any) => void | Promise<void>\n\tdebug?: boolean\n}) {\n\tconst { holder, genomeObj, vocabApi, chr, start, stop, callback } = opts\n\tif (!chr || !Number.isInteger(start) || !Number.isInteger(stop)) throw new Error('unable to retrieve gene coordinate')\n\n\tholder.selectAll('*').remove()\n\tholder.style('display', 'block')\n\tholder.append('div').style('opacity', 0.6).text('Navigate genome browser to desired region')\n\n\tconst arg: any = {\n\t\tholder,\n\t\tgenome: genomeObj, // genome obj\n\t\tchr,\n\t\tstart,\n\t\tstop,\n\t\ttklst: [],\n\t\tnobox: true,\n\t\twidth: 500,\n\t\thidegenelegend: true,\n\t\tdebugmode: opts.debug\n\t}\n\tfirst_genetrack_tolist(genomeObj, arg.tklst)\n\tconst _ = await import('#src/block')\n\tconst blockInstance = new _.Block(arg)\n\n\tholder\n\t\t.append('div')\n\t\t.attr('data-testid', 'sjpp-dnaMethylation-submitDiv')\n\t\t.style('margin', '10px 0px')\n\t\t.append('button')\n\t\t.style('border', 'none')\n\t\t.style('border-radius', '20px')\n\t\t.style('padding', '10px 15px')\n\t\t.text('Submit Region')\n\t\t.on('click', async () => {\n\t\t\tconst { chr, start, stop } = blockInstance.rglst[0]\n\t\t\tawait callback(makeMethylationRegionTerm({ chr, start, stop }, vocabApi))\n\t\t})\n\n\treturn blockInstance\n}\n\n/** Genomic coordinate shape-filter + \"chr\" prefix toggling (moved from server chat/search.ts). Matches a\n * typed \"chr:start-stop\" range (e.g. \"chr7:100000-200000\" or, with the prefix omitted, \"7:100000-200000\")\n * and returns the candidate coordinate strings to try server-side \u2014 both the typed spelling and the\n * \"chr\"-toggled one, since only the server's genome object knows which chromosome name it uses. Returns\n * null when the prompt is not a coordinate range (a bare chr, a gene name, or partial typing), so no\n * coordinate is sent to the server. Chromosome existence and position validity are left to the server's\n * string2pos(); this is only a cheap shape/spelling step. */\nfunction parseCoordCandidates(prompt: string): string[] | null {\n\tconst m = /^\\s*(\\w+)\\s*:\\s*([\\d,]+)\\s*-\\s*([\\d,]+)\\s*$/.exec(prompt)\n\tif (!m) return null\n\tconst [, chrToken, start, stop] = m\n\tconst chrCandidates = /^chr/i.test(chrToken)\n\t\t? [chrToken, chrToken.replace(/^chr/i, '')] // \"chr7\" -> try \"chr7\", then \"7\"\n\t\t: [chrToken, 'chr' + chrToken] // \"7\" -> try \"7\", then \"chr7\"\n\treturn chrCandidates.map(chr => `${chr}:${start}-${stop}`)\n}\n\n/** keyup handler for the omnisearch input: run the omnisearch (doSearch) as the user types. A typed\n * genomic coordinate range triggers a search regardless of prompt length (no length cutoff \u2014 coordinate\n * strings can be long); any other prompt is gated by the length bounds. Otherwise clear the results popup.\n * Wired in chat.ts's initDom. `self` is the MassAiChatBot instance. */\nexport async function handleOmnisearchKeyup(self: any, event: KeyboardEvent) {\n\tif (keyupEnter(event)) return\n\tconst prompt = (event.target as HTMLInputElement).value.trim()\n\tif (!prompt) {\n\t\tself.dom.noMatchShown = false\n\t\tself.clear({ hide: true })\n\t\treturn\n\t}\n\t// A coordinate (regex passes) is searched regardless of length; only a coordinate triggers the\n\t// server's coordinate resolution (its candidates are passed to doSearch). Other prompts stay gated.\n\tconst coordCandidates = parseCoordCandidates(prompt)\n\tif (\n\t\tcoordCandidates ||\n\t\t(MIN_PROMPT_LENGTH_FOR_GENE_SEARCH <= prompt.length && prompt.length <= MAX_PROMPT_LENGTH_FOR_OMNISEARCH)\n\t) {\n\t\ttry {\n\t\t\tawait doSearch(self, prompt, coordCandidates) // Search as user types\n\t\t} catch (e: any) {\n\t\t\tif (e.stack) console.log(e.stack)\n\t\t\tsayerror(self.dom.resultDiv, 'Error: ' + (e.message || e))\n\t\t}\n\t} else {\n\t\tself.dom.noMatchShown = false\n\t\tself.clear({ hide: true })\n\t}\n}\n\n/** Server call for the mass omnisearch: POST the prompt (and, when the client's coordinate regex passed,\n * the \"chr:start-stop\" candidate spellings) to termdb/chat and return the OmnisearchResult. The server does\n * the gene/dictionary lookup and resolves the typed coordinate via string2pos (the genome object stays\n * server-side). Separated from the rendering (renderOmnisearchResults) and takes plain params (no DOM /\n * component instance) so it can be integration-tested against a running server on its own. */\nexport async function fetchOmnisearch(opts: {\n\tgenome: string\n\tdslabel: string\n\tprompt: string\n\tcohortStr?: string\n\tusecase?: any\n\ttreeFilter?: any\n\tcoordCandidates?: string[] | null\n}): Promise<OmnisearchResult> {\n\tconst data: OmnisearchResult = await dofetch3('termdb/chat', {\n\t\tbody: {\n\t\t\tgenome: opts.genome,\n\t\t\tdslabel: opts.dslabel,\n\t\t\tomnisearch: true,\n\t\t\tprompt: opts.prompt,\n\t\t\tcohortStr: opts.cohortStr,\n\t\t\tusecase: opts.usecase,\n\t\t\ttreeFilter: opts.treeFilter,\n\t\t\tcoordCandidates: opts.coordCandidates || undefined,\n\t\t\t// gene search runs from 1 char; dictionary + sample search only once the prompt reaches the\n\t\t\t// longer cutoff, so the server skips them (and their all-samples scan) for short prompts\n\t\t\tincludeDictAndSampleSearch: opts.prompt.trim().length >= MIN_PROMPT_LENGTH_FOR_OTHER_SEARCH\n\t\t}\n\t})\n\tif (data.error) throw data.error\n\treturn data\n}\n\n/** Build the result rows from an OmnisearchResult and render them into the results popup (or show the\n * \"No match\" message): one row per dictionary term, per gene (with the action buttons available for that\n * gene), and the typed genomic coordinate. Separated from the server call (fetchOmnisearch) so each can be\n * tested on its own. */\nfunction renderOmnisearchResults(self: any, data: OmnisearchResult) {\n\t// Genomic coordinate typed as the prompt (e.g. \"chr7:100000-200000\" or \"7:100000-200000\") is\n\t// treated as another searchable data type alongside dictionary terms and genes: the server returns\n\t// a parsed coordinate when the prompt is a valid range and the dataset supports the genomic view.\n\t// A coordinate result is added below whose \"Genome Browser\" button opens the genomic view.\n\tconst coord = data.coord || null\n\tconst dictItems: any[] = Array.isArray(data.dictionaryTerms) ? data.dictionaryTerms : []\n\t// Each gene match carries its own available data types (a gene may have e.g. SNV/indel while\n\t// another does not), so action buttons are decided per gene rather than dataset-wide.\n\tconst genes: { gene: string; dataTypes: any; coord?: any }[] = Array.isArray(data.genes) ? data.genes : []\n\n\t// Build one entry per gene, skipping any whose name already appears among the dictionary results.\n\t// Each gene renders as a single row whose buttons are the actions available for that gene, and\n\t// its own per-variant-type options (SNV/indel, CNV, SV/fusion) are attached for showTerm to use.\n\tconst dictNames = new Set(dictItems.map((t: any) => t.name?.toUpperCase()))\n\tconst geneMap = new Map<string, any>()\n\tfor (const g of genes) {\n\t\tconst gene = g?.gene\n\t\tif (!gene || dictNames.has(gene.toUpperCase())) continue\n\t\tconst dt = g.dataTypes || {}\n\t\t// per-gene variant sub-type buttons; svfusion maps to two dts (SV and fusion), tried in order\n\t\tconst geneVariantTypes: any[] = []\n\t\tif (dt.snvindel) geneVariantTypes.push({ label: 'SNV/indel', testid: 'snvindel', dtCandidates: [dtsnvindel] })\n\t\tif (dt.cnv) geneVariantTypes.push({ label: 'CNV', testid: 'cnv', dtCandidates: [dtcnv] })\n\t\tif (dt.svfusion)\n\t\t\tgeneVariantTypes.push({ label: 'SV/fusion', testid: 'svfusion', dtCandidates: [dtsv, dtfusionrna] })\n\t\tconst entry: any = { name: gene, gene, isGene: true }\n\t\tif (dt.geneExpression) entry.isGeneExpression = true\n\t\tif (geneVariantTypes.length) {\n\t\t\tentry.isGeneVariant = true\n\t\t\tentry.geneVariantTypes = geneVariantTypes\n\t\t}\n\t\t// genome browser is offered whenever any genomic-alteration data type (snvindel/cnv/svfusion)\n\t\t// is available for this gene; the browser's mds3 track renders all available types together\n\t\tif (dt.genomeBrowser) {\n\t\t\tentry.isGenomeBrowser = true\n\t\t\t// server-resolved default coordinate, used to seed the genome browser's genomic view\n\t\t\tentry.coord = g.coord\n\t\t}\n\t\tif (dt.dnaMethylation) {\n\t\t\tentry.isMethylation = true\n\t\t\t// server-resolved default coordinate, used to seed the genome browser region picker\n\t\t\tentry.coord = g.coord\n\t\t}\n\t\t// only list a gene if it has at least one available data type / action\n\t\tif (entry.isGeneExpression || entry.isGeneVariant || entry.isGenomeBrowser || entry.isMethylation) {\n\t\t\tgeneMap.set(gene.toUpperCase(), entry)\n\t\t}\n\t}\n\tconst geneItems = [...geneMap.values()]\n\t// Matched samples. The server only sends these when the dataset allows displaying sample ids\n\t// (authApi.canDisplaySampleIds), so no permission check is repeated here \u2014 an empty/absent list\n\t// means either no match or a dataset that does not permit it.\n\tconst sampleItems = (Array.isArray(data.samples) ? data.samples : [])\n\t\t.filter((s: any) => s?.name)\n\t\t.map((s: any) => ({\n\t\t\tisSample: true,\n\t\t\tname: s.name,\n\t\t\tsampleId: s.id,\n\t\t\tsingleCell: s.singleCell,\n\t\t\tfacetTracks: s.assays,\n\t\t\twsimages: s.wsimages\n\t\t}))\n\t// The genomic coordinate is its own result entry (like a gene entry), rendered by showTerm\n\tconst coordItems = coord\n\t\t? [{ isCoord: true, name: `${coord.chr}:${coord.start.toLocaleString()}-${coord.stop.toLocaleString()}`, coord }]\n\t\t: []\n\n\t// Per-type total match counts (server capped each type; totals report the full counts). A group's\n\t// results were truncated when its total exceeds the number the server returned for that type, in which\n\t// case a note is shown at the bottom of the group.\n\tconst totals = data.totals || ({} as any)\n\t// Group the results under headings so each result type is labeled (e.g. \"Dictionary\" above the matched\n\t// dictionary variables, then \"Genes\" above the matched genes). A heading row is inserted only for a\n\t// non-empty group; showTerm renders {isHeading:true} rows as the group label, {isNote:true} as the note.\n\tconst lst: any[] = []\n\tfor (const group of [\n\t\t{\n\t\t\tkey: 'dictionary',\n\t\t\theading: 'Dictionary',\n\t\t\tnoun: 'dictionary variable',\n\t\t\titems: dictItems,\n\t\t\treturned: dictItems.length,\n\t\t\ttotal: totals.dictionaryTerms\n\t\t},\n\t\t{\n\t\t\tkey: 'genes',\n\t\t\theading: 'Genes',\n\t\t\tnoun: 'gene',\n\t\t\titems: geneItems,\n\t\t\treturned: Array.isArray(data.genes) ? data.genes.length : 0,\n\t\t\ttotal: totals.genes\n\t\t},\n\t\t{\n\t\t\tkey: 'samples',\n\t\t\theading: 'Samples',\n\t\t\tnoun: 'sample',\n\t\t\titems: sampleItems,\n\t\t\treturned: sampleItems.length,\n\t\t\ttotal: totals.samples\n\t\t},\n\t\t{\n\t\t\tkey: 'coord',\n\t\t\theading: 'Genomic region',\n\t\t\tnoun: '',\n\t\t\titems: coordItems,\n\t\t\treturned: coordItems.length,\n\t\t\ttotal: undefined\n\t\t}\n\t]) {\n\t\tif (!group.items.length) continue\n\t\tlst.push({ isHeading: true, name: group.heading })\n\t\tfor (const item of group.items) lst.push(item)\n\t\t// truncation note: shown only when the server capped this type (total > what it returned)\n\t\tif (typeof group.total == 'number' && group.total > group.returned) {\n\t\t\tlst.push({\n\t\t\t\tisNote: true,\n\t\t\t\ttestid: `sjpp-mass-chat-note-${group.key}`,\n\t\t\t\tname: `Displaying ${group.items.length} out of a total of ${group.total} ${group.noun} matches`\n\t\t\t})\n\t\t}\n\t}\n\tif (!lst.length) {\n\t\t// Show the \"No match...\" message one time at the first miss\n\t\tif (!self.dom.noMatchShown) {\n\t\t\tself.dom.noMatchShown = true\n\t\t\tself.noResult()\n\t\t}\n\t} else {\n\t\tself.dom.noMatchShown = false\n\t\tself.showTerms({ lst })\n\t}\n}\n\n// Search method, adapted from MassSearch.doSearch. Thin orchestration: fetch results from the server\n// (fetchOmnisearch), then render them (renderOmnisearchResults). `coordCandidates` (when the prompt matched\n// the coordinate regex on the client) are the \"chr:start-stop\" spellings the server resolves via\n// string2pos; pass null/undefined for a normal gene/dictionary search.\nexport async function doSearch(self: any, prompt: string, coordCandidates?: string[] | null) {\n\tif (!prompt) {\n\t\tself.clear({ hide: true })\n\t\treturn\n\t}\n\t// search-as-you-type fires one doSearch per keystroke (\"PAX5\" -> P, PA, PAX, PAX5), and the fetches\n\t// are not ordered \u2014 a stale shorter-prompt response can arrive after the latest one and overwrite the\n\t// rendered rows. Tag each search and render only if it is still the most recent when the response lands.\n\tconst seq = (self.omnisearchSeq = (self.omnisearchSeq || 0) + 1)\n\tconst data = await fetchOmnisearch({\n\t\tgenome: self.app.vocabApi.vocab.genome,\n\t\tdslabel: self.app.vocabApi.vocab.dslabel,\n\t\tprompt,\n\t\tcohortStr: self.getState(self.app.getState()).cohortStr,\n\t\tusecase: self.opts.usecase,\n\t\ttreeFilter: self.app.vocabApi.state?.treeFilter,\n\t\tcoordCandidates\n\t})\n\tif (seq !== self.omnisearchSeq) return // a newer keystroke superseded this search; drop the stale result\n\trenderOmnisearchResults(self, data)\n}\n\n// Minimal renderers ported from MassSearch. Assigns the omnisearch renderers (noResult, showTerms,\n// launchPlot, the plot-launchers, showTerm, clear) onto the component instance `self`.\nexport function setSearchRenderers(self: any) {\n\tlet text = 'No match'\n\tif (self.isChat) {\n\t\ttext = 'No match. Using the chatbot...'\n\t}\n\tself.noResult = () => {\n\t\tself.clear()\n\t\tself.dom.resultDiv.append('div').text(text).style('padding', '3px 3px 3px 0px').style('opacity', 0.5)\n\n\t\t// Hide the popup after a delay. Track the timer so (a) successive no-match keystrokes don't stack\n\t\t// timers and (b) showTerms can cancel it \u2014 otherwise a stale hide from an earlier no-match keystroke\n\t\t// (e.g. a short gene-only prompt that matched nothing) fires later and wipes freshly-rendered results.\n\t\tclearTimeout(self.noResultTimer)\n\t\tself.noResultTimer = setTimeout(() => {\n\t\t\tself.clear({ hide: true })\n\t\t}, 1500)\n\t}\n\n\tself.showTerms = (data: any) => {\n\t\t// cancel any pending no-match hide so a stale timer can't wipe these results\n\t\tclearTimeout(self.noResultTimer)\n\t\tif (self.opts.disable_terms)\n\t\t\tdata.lst.forEach((t: any) => {\n\t\t\t\tif (t.disabled) self.opts.disable_terms.push(t)\n\t\t\t})\n\t\tself.clear({ hide: !data.lst.length })\n\t\tif (data.lst.length) {\n\t\t\tself.dom.resultDiv.append('table').selectAll().data(data.lst).enter().append('tr').each(self.showTerm)\n\t\t}\n\t}\n\n\t// dispatch a plot and reset the search box/popup\n\tself.launchPlot = async (config: any) => {\n\t\tif (self.state?.nav?.activeTab == 0) {\n\t\t\tawait self.app.dispatch({ type: 'tab_set', activeTab: 1 })\n\t\t}\n\t\tself.app.dispatch({ type: 'plot_create', config })\n\t\tself.dom.inputNode.value = '' // clear the search box\n\t\tself.clear({ hide: true })\n\t}\n\n\t// open a mutated-vs-wildtype barchart for one gene, restricted to a variant data type.\n\t// dtCandidates are tried in order (svfusion has two dts) until a matching predefined groupset\n\t// is found, since fillTermWrapper throws when the dataset lacks a groupset for a given dt.\n\tself.launchGeneVariantPlot = async (gene: string, dtCandidates: number[]) => {\n\t\tlet tw: any\n\t\tlet lastErr: any\n\t\tfor (const dt of dtCandidates) {\n\t\t\tconst candidate: any = {\n\t\t\t\tterm: {\n\t\t\t\t\tid: gene,\n\t\t\t\t\tname: gene,\n\t\t\t\t\tgenes: [{ kind: 'gene', id: gene, gene, name: gene, type: 'geneVariant' }],\n\t\t\t\t\ttype: 'geneVariant'\n\t\t\t\t},\n\t\t\t\tq: { type: 'predefined-groupset', dtLst: [dt] }\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait fillTermWrapper(candidate, self.app.vocabApi)\n\t\t\t\ttw = candidate\n\t\t\t\tbreak\n\t\t\t} catch (e) {\n\t\t\t\tlastErr = e\n\t\t\t}\n\t\t}\n\t\tif (!tw) throw lastErr\n\t\tawait self.launchPlot({ chartType: 'summary', term: tw })\n\t}\n\n\t// Open the genome browser as a separate mass chart (chartType 'genomeBrowser') with full plot state,\n\t// via launchPlot -> plot_create. The plot's mds3 track renders the dataset's SNV/indel, CNV and\n\t// SV/fusion data (whichever it has).\n\t// - 'protein': gene/protein view, seeded by gene symbol (blockIsProteinMode=true)\n\t// - 'genomic': genomic view over a region (chr/start/stop) from opts.coord (blockIsProteinMode=false)\n\t// \u2014 used both for a gene's locus and for a coordinate typed into the omnisearch box\n\t// blockIsProteinMode is set explicitly so each view opens as named regardless of the dataset's\n\t// default gbRestrictMode. launchPlot() dispatches plot_create and closes the search popup.\n\tself.launchGenomeBrowserView = async (\n\t\tmode: 'protein' | 'genomic',\n\t\topts: { gene?: string; coord?: { chr: string; start: number; stop: number } }\n\t) => {\n\t\tif (mode == 'protein') {\n\t\t\tif (!opts.gene) throw new Error('gene symbol required for protein view')\n\t\t\tawait self.launchPlot({\n\t\t\t\tchartType: 'genomeBrowser',\n\t\t\t\tgeneSearchResult: { geneSymbol: opts.gene },\n\t\t\t\tblockIsProteinMode: true\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tif (!opts.coord) throw new Error('coordinate required for genomic view')\n\t\tawait self.launchPlot({\n\t\t\tchartType: 'genomeBrowser',\n\t\t\tgeneSearchResult: { chr: opts.coord.chr, start: opts.coord.start, stop: opts.coord.stop },\n\t\t\tblockIsProteinMode: false\n\t\t})\n\t}\n\n\t// \"Genome Browser\": open a chooser popup offering protein vs genomic view of the gene; picking a view\n\t// opens the genome browser as a separate mass chart with plot state (see launchGenomeBrowserView).\n\t// The two buttons and the protein/genomic decision mirror the genome browser's\n\t// GeneSearchRenderer.renderGeneSearch (which shows the same \"Protein view of <gene>\" / \"Genomic view\n\t// of <gene>\" buttons on an interactive gene search); here they live in the omnisearch popup since the\n\t// omnisearch already resolved the gene. A mode-restricted dataset (gbRestrictMode) skips the chooser\n\t// and opens its one allowed view directly.\n\tself.launchGenomeBrowser = async (gene: string, coord?: { chr: string; start: number; stop: number }) => {\n\t\tconst gbRestrictMode = self.app.getState().termdbConfig?.queries?.gbRestrictMode\n\t\tif (gbRestrictMode == 'protein') {\n\t\t\tawait self.launchGenomeBrowserView('protein', { gene })\n\t\t\treturn\n\t\t}\n\t\tif (gbRestrictMode == 'genomic') {\n\t\t\t// genomic view requires the gene's locus (server-resolved in search.ts). Error out rather than\n\t\t\t// falling back to a dataset default region, which would open a locus unrelated to the gene.\n\t\t\tif (!coord) throw new Error(`Unable to resolve genomic coordinates for gene \"${gene}\".`)\n\t\t\tawait self.launchGenomeBrowserView('genomic', { coord })\n\t\t\treturn\n\t\t}\n\n\t\t// both views allowed: show the two view buttons; clicking opens the browser chart in that view\n\t\tself.dom.tip.clear()\n\t\tself.dom.tip.showunder(self.dom.inputNode)\n\t\tconst holder = self.dom.resultDiv.append('div').style('margin', '10px')\n\t\tholder.append('div').style('margin-bottom', '5px').text(gene)\n\t\tconst btndiv = holder.append('div')\n\t\tconst addViewBtn = (label: string, testid: string, mode: 'protein' | 'genomic') => {\n\t\t\tbtndiv\n\t\t\t\t.append('button')\n\t\t\t\t.attr('data-testid', testid)\n\t\t\t\t.style('margin-right', '10px')\n\t\t\t\t.text(label)\n\t\t\t\t.on(\n\t\t\t\t\t'click',\n\t\t\t\t\t() =>\n\t\t\t\t\t\tvoid self\n\t\t\t\t\t\t\t.launchGenomeBrowserView(mode, { gene, coord })\n\t\t\t\t\t\t\t.catch(e => sayerror(self.dom.resultDiv, 'Error: ' + (e?.message || e)))\n\t\t\t\t)\n\t\t}\n\t\taddViewBtn(`Protein view of ${gene}`, `sjpp-mass-chat-gb-protein-${gene}`, 'protein')\n\t\t// genomic view needs a coordinate; omit the button if the gene could not be resolved to one\n\t\tif (coord) addViewBtn(`Genomic view of ${gene}`, `sjpp-mass-chat-gb-genomic-${gene}`, 'genomic')\n\t}\n\n\t// DNA methylation: open a genome browser at the gene's default coordinates inline in the result\n\t// area with a \"Submit Region\" button (see embedMethylationRegionPicker above); on submit, open a\n\t// violin plot of the region-based dnaMethylation term's per-sample beta values.\n\tself.launchMethylationPlot = async (gene: string, coord: { chr: string; start: number; stop: number }) => {\n\t\t// coord is the gene's default genomic coordinate, resolved server-side by the omnisearch\n\t\t// (GeneMatch.coord) and used to seed the genome browser track \u2014 no genelookup request here.\n\t\tif (!coord) throw new Error(`Could not resolve coordinates for gene \"${gene}\"`)\n\n\t\t// render the region picker inline in the chat result area, replacing the result list\n\t\tself.dom.tip.clear()\n\t\tself.dom.tip.showunder(self.dom.inputNode)\n\t\tconst holder = self.dom.resultDiv.append('div').style('margin', '10px')\n\t\tholder.append('div').style('margin-bottom', '5px').text(gene)\n\n\t\tawait embedMethylationRegionPicker({\n\t\t\tholder: holder.append('div'),\n\t\t\tgenomeObj: self.app.opts.genome,\n\t\t\tvocabApi: self.app.vocabApi,\n\t\t\tchr: coord.chr,\n\t\t\tstart: coord.start,\n\t\t\tstop: coord.stop,\n\t\t\tcallback: async (term: any) => {\n\t\t\t\tawait self.launchPlot({ chartType: 'summary', term: { term } })\n\t\t\t}\n\t\t})\n\t}\n\n\t// Open the termdb tree to pick a survival outcome term, then dispatch a survival plot with\n\t// `covariateField` pre-set to `covariateTw` (e.g. term2 = the gene's expression/variant/methylation\n\t// term). survival's getPlotConfig() requires config.term to already be a resolved term wrapper, so\n\t// unlike launchPlot() this can't dispatch directly \u2014 it must collect the outcome term first, mirroring\n\t// charts.ts's showTree_select1term (which this component doesn't have access to, different class).\n\tself.launchSurvivalWithCovariate = async (covariateField: 'term2', covariateTw: any) => {\n\t\tself.dom.tip.clear()\n\t\tself.dom.tip.showunder(self.dom.inputNode)\n\t\tconst action: any = { type: 'plot_create', config: { chartType: 'survival', [covariateField]: covariateTw } }\n\t\tconst termdb = await import('../termdb/app')\n\t\ttermdb.appInit({\n\t\t\tvocabApi: self.app.vocabApi,\n\t\t\tholder: self.dom.tip.d.append('div'),\n\t\t\tstate: { nav: { header_mode: 'search_only' }, tree: { usecase: { target: 'survival', detail: 'term' } } },\n\t\t\ttree: {\n\t\t\t\tclick_term: (term: any) => {\n\t\t\t\t\taction.config.term = term.term ? term : { term }\n\t\t\t\t\tself.dom.tip.hide()\n\t\t\t\t\tself.app.dispatch(action)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\t// Render the category rows for a selected gene (Gene expression / SNV-indel-CNV-SV-fusion /\n\t// DNA methylation) into `holder` \u2014 one label + action button(s) per available category, reusing the\n\t// exact same launch calls the old inline row used. \"Survival\" buttons are gated on the dataset\n\t// allowing the survival term type at all; PSEUDO BULK is not yet implemented (needs server-side\n\t// per-gene pseudobulk detection first).\n\tself.renderGeneCategories = (holder: any, item: any) => {\n\t\tconst hasSurvival = self.app.vocabApi.termdbConfig?.allowedTermTypes?.includes('survival')\n\n\t\tconst addRow = (label: string) => {\n\t\t\tconst row = holder.append('div').style('margin', '4px 0')\n\t\t\trow\n\t\t\t\t.append('span')\n\t\t\t\t.style('font-weight', 'bold')\n\t\t\t\t.style('margin-right', '8px')\n\t\t\t\t.text(label + ':')\n\t\t\treturn row\n\t\t}\n\t\tconst addBtn = (row: any, label: string, testid: string, onClick: () => Promise<void>) => {\n\t\t\trow\n\t\t\t\t.append('span')\n\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t.attr('data-testid', testid)\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('margin', '0px 3px')\n\t\t\t\t.style('padding', '5px 10px')\n\t\t\t\t.style('border-radius', '5px')\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.text(label)\n\t\t\t\t.on('click', () => void onClick().catch(e => sayerror(self.dom.resultDiv, 'Error: ' + (e?.message || e))))\n\t\t}\n\n\t\tif (item.isGeneExpression) {\n\t\t\tconst row = addRow('Gene Expression')\n\t\t\taddBtn(row, 'Summary', `sjpp-mass-chat-gene-exp-${item.gene}`, async () => {\n\t\t\t\tawait self.launchPlot({\n\t\t\t\t\tchartType: 'summary',\n\t\t\t\t\tterm: { term: { gene: item.gene, name: item.name, type: 'geneExpression' } }\n\t\t\t\t})\n\t\t\t})\n\t\t\tif (hasSurvival) {\n\t\t\t\taddBtn(row, 'Survival', `sjpp-mass-chat-gene-exp-survival-${item.gene}`, async () => {\n\t\t\t\t\tawait self.launchSurvivalWithCovariate('term2', {\n\t\t\t\t\t\tterm: { gene: item.gene, name: item.name, type: 'geneExpression' }\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif (item.isGeneVariant) {\n\t\t\tconst label = (item.geneVariantTypes || []).map((vt: any) => vt.label).join('/')\n\t\t\tconst allDtCandidates = (item.geneVariantTypes || []).flatMap((vt: any) => vt.dtCandidates)\n\t\t\tconst row = addRow(label)\n\t\t\taddBtn(row, 'Summary', `sjpp-mass-chat-gene-variant-${item.gene}`, async () => {\n\t\t\t\tawait self.launchGeneVariantPlot(item.gene, allDtCandidates)\n\t\t\t})\n\t\t\taddBtn(row, 'Protein view', `sjpp-mass-chat-gene-protein-${item.gene}`, async () => {\n\t\t\t\tawait self.launchGenomeBrowserView('protein', { gene: item.gene })\n\t\t\t})\n\t\t\taddBtn(row, 'Genome view', `sjpp-mass-chat-gene-genomic-${item.gene}`, async () => {\n\t\t\t\tawait self.launchGenomeBrowserView('genomic', { coord: item.coord })\n\t\t\t})\n\t\t\t// TODO Survival for this category: needs the same fillTermWrapper resolution\n\t\t\t// launchGeneVariantPlot does, then launchSurvivalWithCovariate('term2', tw) instead of\n\t\t\t// launchPlot(). Not yet built/verified.\n\t\t}\n\n\t\tif (item.isMethylation) {\n\t\t\tconst row = addRow('DNA methylation')\n\t\t\taddBtn(row, 'Summary', `sjpp-mass-chat-gene-methylation-${item.gene}`, async () => {\n\t\t\t\tawait self.launchMethylationPlot(item.gene, item.coord)\n\t\t\t})\n\t\t\t// TODO Survival for this category: needs the region-picker's resolved term passed to\n\t\t\t// launchSurvivalWithCovariate('term2', {term}) instead of launchPlot(). Not yet built/verified.\n\t\t}\n\n\t\t// TODO PSEUDO BULK category: not implemented. Needs server-side work first \u2014 GeneDataTypeAvailability\n\t\t// (shared/types/src/routes/termdb.chat.ts) and getGeneDataTypes/getGeneDataTypesForEachGene\n\t\t// (server/src/chat/search.ts) don't know about ds.queries.singleCell.pseudobulk at all yet, and a\n\t\t// pseudobulk term needs assay+memberId+category (shared/types/src/terms/pseudobulk.ts), not a flat\n\t\t// per-gene boolean like the other categories.\n\t}\n\n\tself.showTerm = function (this: any, item: any) {\n\t\tconst tr = select(this)\n\n\t\tif (item.isHeading) {\n\t\t\t// group label row spanning both columns (name + action-button columns); not selectable\n\t\t\ttr.append('td')\n\t\t\t\t.attr('colspan', 2)\n\t\t\t\t.attr('data-testid', `sjpp-mass-chat-heading-${item.name.toLowerCase().replace(/\\s+/g, '-')}`)\n\t\t\t\t.text(item.name)\n\t\t\t\t.style('padding', '6px 10px 2px')\n\t\t\t\t.style('font-weight', 'bold')\n\t\t\t\t.style('font-size', '0.85em')\n\t\t\t\t.style('text-transform', 'uppercase')\n\t\t\t\t.style('opacity', 0.5)\n\t\t\treturn\n\t\t}\n\n\t\tif (item.isNote) {\n\t\t\t// \"Displaying N out of M ... matches\" note at the bottom of a truncated group; not selectable\n\t\t\ttr.append('td')\n\t\t\t\t.attr('colspan', 2)\n\t\t\t\t.attr('data-testid', item.testid || 'sjpp-mass-chat-note')\n\t\t\t\t.text(item.name)\n\t\t\t\t.style('padding', '2px 10px 6px')\n\t\t\t\t.style('font-size', '0.8em')\n\t\t\t\t.style('font-style', 'italic')\n\t\t\t\t.style('opacity', 0.6)\n\t\t\treturn\n\t\t}\n\n\t\tif (item.isCoord) {\n\t\t\t// Genomic coordinate row: region label + a \"Genome Browser\" button opening the genomic view as\n\t\t\t// a separate mass chart with plot state. No protein view \u2014 a bare region is not tied to one gene.\n\t\t\ttr.append('td').text(item.name).style('padding', '5px 10px')\n\t\t\ttr.append('td')\n\t\t\t\t.append('span')\n\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t.attr('data-testid', 'sjpp-mass-chat-coord-genomebrowser')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('margin', '0px 3px')\n\t\t\t\t.style('padding', '5px 10px')\n\t\t\t\t.style('border-radius', '5px')\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.text('Genome Browser')\n\t\t\t\t.on(\n\t\t\t\t\t'click',\n\t\t\t\t\t() =>\n\t\t\t\t\t\tvoid self\n\t\t\t\t\t\t\t.launchGenomeBrowserView('genomic', { coord: item.coord })\n\t\t\t\t\t\t\t.catch(e => sayerror(self.dom.resultDiv, 'Error: ' + (e?.message || e)))\n\t\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\tif (item.isSample) {\n\t\t\t// Sample row: sample name + available actions. The single-cell action is shown only when the\n\t\t\t// server confirmed that this particular sample has single-cell data.\n\t\t\t// Passes config.sample (singular), the same single-sample shape the scatter click handler\n\t\t\t// dispatches (scatterInteractivity.ts), which sampleView resolves to its related samples.\n\t\t\ttr.append('td').text(item.name).style('padding', '5px 10px')\n\t\t\ttr.append('td')\n\t\t\t\t.append('span')\n\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t.attr('data-testid', `sjpp-mass-chat-sample-view-${item.sampleId}`)\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('margin', '0px 3px')\n\t\t\t\t.style('padding', '5px 10px')\n\t\t\t\t.style('border-radius', '5px')\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.text('Sample View')\n\t\t\t\t.on(\n\t\t\t\t\t'click',\n\t\t\t\t\t() =>\n\t\t\t\t\t\tvoid self\n\t\t\t\t\t\t\t.launchPlot({\n\t\t\t\t\t\t\t\tchartType: 'sampleView',\n\t\t\t\t\t\t\t\tsample: { sampleId: item.sampleId, sampleName: item.name }\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch(e => sayerror(self.dom.resultDiv, 'Error: ' + (e?.message || e)))\n\t\t\t\t)\n\t\t\tif (item.singleCell) {\n\t\t\t\ttr.select('td:nth-child(2)')\n\t\t\t\t\t.append('button')\n\t\t\t\t\t.attr('type', 'button')\n\t\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t\t.attr('data-testid', `sjpp-mass-chat-single-cell-${item.sampleId}`)\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('margin', '0px 3px')\n\t\t\t\t\t.style('padding', '5px 10px')\n\t\t\t\t\t.style('border-radius', '5px')\n\t\t\t\t\t.style('border', '0')\n\t\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t\t.text('Single cell')\n\t\t\t\t\t.on(\n\t\t\t\t\t\t'click',\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tvoid self\n\t\t\t\t\t\t\t\t.launchPlot({\n\t\t\t\t\t\t\t\t\tchartType: 'sc',\n\t\t\t\t\t\t\t\t\tsettings: { sc: { item: item.singleCell } }\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.catch(e => sayerror(self.dom.resultDiv, 'Error: ' + (e?.message || e)))\n\t\t\t\t\t)\n\t\t\t}\n\t\t\tif (item.wsimages) {\n\t\t\t\t// shown only when the server confirmed this sample has plain\n\t\t\t\t// whole-slide images on disk; opens the wsi plot in fixed-sample\n\t\t\t\t// mode restricted to plain slides (imageType 'wsi')\n\t\t\t\ttr.select('td:nth-child(2)')\n\t\t\t\t\t.append('button')\n\t\t\t\t\t.attr('type', 'button')\n\t\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t\t.attr('data-testid', `sjpp-mass-chat-wsimages-${item.sampleId}`)\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('margin', '0px 3px')\n\t\t\t\t\t.style('padding', '5px 10px')\n\t\t\t\t\t.style('border-radius', '5px')\n\t\t\t\t\t.style('border', '0')\n\t\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t\t.text('Whole Slide Images')\n\t\t\t\t\t.on(\n\t\t\t\t\t\t'click',\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tvoid self\n\t\t\t\t\t\t\t\t.launchPlot({\n\t\t\t\t\t\t\t\t\tchartType: 'wsi',\n\t\t\t\t\t\t\t\t\tsample: { sID: item.name },\n\t\t\t\t\t\t\t\t\timageType: 'wsi'\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.catch(e => sayerror(self.dom.resultDiv, 'Error: ' + (e?.message || e)))\n\t\t\t\t\t)\n\t\t\t}\n\t\t\tif (item.facetTracks?.length) {\n\t\t\t\ttr.select('td:nth-child(2)')\n\t\t\t\t\t.append('button')\n\t\t\t\t\t.attr('type', 'button')\n\t\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t\t.attr('data-testid', `sjpp-mass-chat-assays-${item.sampleId}`)\n\t\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t\t.style('margin', '0px 3px')\n\t\t\t\t\t.style('padding', '5px 10px')\n\t\t\t\t\t.style('border-radius', '5px')\n\t\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t\t.text('Facet Table')\n\t\t\t\t\t.on(\n\t\t\t\t\t\t'click',\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tvoid self\n\t\t\t\t\t\t\t\t.launchPlot({\n\t\t\t\t\t\t\t\t\tchartType: 'genomeBrowser',\n\t\t\t\t\t\t\t\t\thidePlotFilter: true,\n\t\t\t\t\t\t\t\t\tfilter: getSampleFilter(item.sampleId)\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.catch(e => sayerror(self.dom.resultDiv, 'Error: ' + (e?.message || e)))\n\t\t\t\t\t)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (item.isGene) {\n\t\t\t// Gene row: clicking the name selects it \u2014 echoes into chat history as \"[ME] <name> (gene)\",\n\t\t\t// then renders the available data-type categories (renderGeneCategories) into a new bubble\n\t\t\t// right below it, each with the action button(s) to actually launch a plot.\n\t\t\ttr.append('td')\n\t\t\t\t.text(item.name)\n\t\t\t\t.style('padding', '5px 10px')\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t.attr('data-testid', `sjpp-mass-chat-gene-select-${item.gene}`)\n\t\t\t\t.on('click', () => {\n\t\t\t\t\tself.dom.inputNode.value = ''\n\t\t\t\t\tself.clear({ hide: true })\n\t\t\t\t\tself.addBubble({ msg: escapeHtml(item.name) + ' (gene)', me: 1 })\n\t\t\t\t\tconst holder = self.addBubble({ msg: '' })\n\t\t\t\t\tself.renderGeneCategories(holder, item)\n\t\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\t// Dictionary term row\n\t\tconst button = tr.append('td').text(item.name)\n\t\tif (item.type) {\n\t\t\tbutton\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t.attr('data-testid', `sjpp-mass-chat-term-${item.id}`)\n\t\t\t\t.on('click', async () => {\n\t\t\t\t\tself.addBubble({ msg: escapeHtml(item.name) + ' (dictionary variable)', me: 1 })\n\t\t\t\t\tawait self.launchPlot({\n\t\t\t\t\t\tchartType: item.type == 'survival' ? 'survival' : 'summary',\n\t\t\t\t\t\tterm: { term: item }\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t} else {\n\t\t\tbutton.style('padding', '5px 10px').style('opacity', 0.5)\n\t\t}\n\n\t\ttr.append('td')\n\t\t\t.text((item.__ancestorNames || []).join(' > '))\n\t\t\t.style('opacity', 0.5)\n\t\t\t.style('font-size', '.7em')\n\t}\n\n\tself.clear = (opts: any = {}) => {\n\t\tself.dom.tip.clear()\n\t\tif (opts.hide) self.dom.tip.hide()\n\t\telse self.dom.tip.showunder(self.dom.inputNode)\n\t}\n}\n", "import { escapeHtml } from '#dom'\nimport { getCompInit, type RxComponent } from '#rx'\nimport type { MassAppApi } from './types/mass'\nimport { Menu } from '#dom'\nimport { keyupEnter } from '#src/client'\nimport { dofetch3 } from '#common/dofetch'\nimport type { ChatRequest, ChatResponse } from '#types'\n// Mass omnisearch (search-as-you-type) lives in ./search.ts; this file owns the AI-chat path and the\n// shared DOM scaffold (the input + result popup + chat bubbles).\nimport { setSearchRenderers, handleOmnisearchKeyup } from './search.ts'\n\nconst MIN_PROMPT_LENGTH_FOR_CHAT = 5 // Set a minimum prompt length for chat submission\n\nclass MassAiChatBot implements RxComponent {\n\tstatic type = 'chat'\n\ttype: string\n\topts: any\n\tapp: MassAppApi\n\tdom!: any\n\tstate: any\n\tid!: string\n\tclear: any\n\tshowTerms: any\n\tnoResult: any\n\tisChat: any\n\n\tconstructor(opts: any) {\n\t\tthis.type = MassAiChatBot.type\n\t\tthis.opts = opts\n\t\tthis.app = opts.app\n\t\tthis.opts.usecase = this.opts.usecase || { target: 'dictionary', detail: 'term' }\n\t\tthis.opts.targetType = this.opts.targetType ? this.opts.targetType : 'Dictionary Variables'\n\t\tthis.isChat = this.app.getState().termdbConfig?.queries?.chat // Storing if chat is supported by the dataset for easy access in other methods\n\t\tsetSearchRenderers(this) // sets omnisearch renderers (showTerms, noResult, clear, showTerm, launchers) on this\n\t}\n\n\tgetState(appState: any) {\n\t\treturn {\n\t\t\tcohortStr:\n\t\t\t\tappState.activeCohort == -1 || !appState.termdbConfig.selectCohort\n\t\t\t\t\t? ''\n\t\t\t\t\t: appState.termdbConfig.selectCohort.values[appState.activeCohort].keys.slice().sort().join(','),\n\t\t\tsearch: appState.search,\n\t\t\tnav: appState.nav\n\t\t}\n\t}\n\n\tasync init() {\n\t\t// Note: no server-side request here \u2014 the omnisearch resolves dictionary terms, genes, and the\n\t\t// dataset's gene data types together in a single request per search (see doSearch in search.ts), so\n\t\t// nothing is fetched eagerly at component init.\n\t\tthis.initDom()\n\t}\n\n\tinitDom() {\n\t\t//const cohortStr = this.getState(appState).cohortStr\n\t\tlet text = 'Search an item'\n\t\tlet height = 'auto' // No white space needed for search only; grows to fit the selected gene's action buttons\n\t\tif (this.isChat) {\n\t\t\ttext = 'Ask a question'\n\t\t\theight = '200px'\n\t\t}\n\t\tthis.dom = {\n\t\t\ttip: new Menu({ padding: '5px' }),\n\t\t\tdiv: this.opts.subheader,\n\t\t\terror: this.opts.subheader.append('div').attr('id', 'sjpp-corrVolcano-error').style('opacity', 0.75),\n\t\t\tbubbleDiv: this.opts.subheader\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sjpp_show_scrollbar')\n\t\t\t\t.style('margin', '5px 20px 0px 20px')\n\t\t\t\t.style('height', height)\n\t\t\t\t.style('max-height', '200px')\n\t\t\t\t.style('overflow', 'auto')\n\t\t\t\t.style('scroll-behavior', 'smooth')\n\t\t}\n\n\t\tconst inputSel = this.dom.div\n\t\t\t.append('input')\n\t\t\t.attr('type', 'search')\n\t\t\t.attr('data-testid', 'sjpp-mass-omnisearch-input')\n\t\t\t.style('margin', '15px')\n\t\t\t.style('padding', '17px')\n\t\t\t.style('border-radius', '34px')\n\t\t\t.attr('size', 70)\n\t\t\t.attr('placeholder', text)\n\n\t\t// Store the input node so the search result tip can position under it\n\t\tthis.dom.inputNode = inputSel.node()\n\n\t\t// Result panel inside the tip, mirroring MassSearch.initUI\n\t\tthis.dom.resultDiv = this.dom.tip.d\n\t\t\t.style('border-left', 'solid 1px rgb(133,182,225)')\n\t\t\t.style('padding-left', '5px')\n\t\t\t.attr('tabindex', -1)\n\n\t\tinputSel\n\t\t\t// omnisearch (search-as-you-type) \u2014 handler lives in ./search.ts\n\t\t\t.on('keyup.search', (event: KeyboardEvent) => handleOmnisearchKeyup(this, event))\n\t\t\t.on('keyup.submit', async (event: any) => {\n\t\t\t\tif (!keyupEnter(event)) return\n\t\t\t\tif (!this.isChat) {\n\t\t\t\t\t// Prevents unnecessary server side call when chat not supported by ds\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst prompt = event.target.value.trim()\n\t\t\t\tif (!prompt) return\n\t\t\t\tthis.addBubble({ msg: escapeHtml(prompt), me: 1 })\n\t\t\t\tevent.target.value = ''\n\t\t\t\tconst serverBubble = this.addBubble({ msg: '...' }) // Keep server bubble always below prompt bubble so that responses are below the prompt always\n\t\t\t\tif (prompt.length <= MIN_PROMPT_LENGTH_FOR_CHAT) {\n\t\t\t\t\tserverBubble.text('Your prompt is too short. Enter a longer prompt.')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst body: ChatRequest = {\n\t\t\t\t\tgenome: this.app.vocabApi.vocab.genome,\n\t\t\t\t\tdslabel: this.app.vocabApi.vocab.dslabel,\n\t\t\t\t\tfilter: this.app.vocabApi.state.termfilter?.filter,\n\t\t\t\t\tprompt\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst data = await dofetch3('termdb/chat', { body })\n\t\t\t\t\tif (data.error) throw data.error\n\n\t\t\t\t\tconst result: ChatResponse = data\n\t\t\t\t\tif (result.type === 'text') {\n\t\t\t\t\t\tserverBubble.text(result.text)\n\t\t\t\t\t} else if (result.type === 'html') {\n\t\t\t\t\t\tserverBubble.html(result.html)\n\t\t\t\t\t} else if (result.type === 'plot') {\n\t\t\t\t\t\t// Determine if plot state is complete or not. A field whose value carries a\n\t\t\t\t\t\t// `possible_options` array means the server could not resolve that term and\n\t\t\t\t\t\t// is offering the user a choice. If found, show click boxes; otherwise the\n\t\t\t\t\t\t// plot state is complete and can be dispatched directly.\n\t\t\t\t\t\tconst optionField = findPossibleOptionsField(result.plot)\n\t\t\t\t\t\tif (optionField) {\n\t\t\t\t\t\t\tthis.showPossibleOptions(serverBubble, result.plot, optionField, result.msg)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.app.dispatch({\n\t\t\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\t\t\tconfig: result.plot\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tserverBubble.text(`${result.msg ? result.msg + '. ' : ''}Please refer to the plot generated below.`)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (e: any) {\n\t\t\t\t\tif (e.stack) console.log(e.stack)\n\t\t\t\t\tserverBubble.html(`Error: ${e.message || e}`)\n\t\t\t\t}\n\t\t\t})\n\t\t\t.node()\n\t\t\t.focus()\n\t}\n\n\taddBubble(arg: { msg: string; me?: number }) {\n\t\t/** {\nmsg: add a chat bubble for this msg; msg is html as it might contain hyperlinks\nme: if 1, is me; otherwise is ai\n}\nreturn the created bubble and allow to be modified\n*/\n\t\tconst bubble = this.dom.bubbleDiv\n\t\t\t.append('div')\n\t\t\t.style('padding', '10px')\n\t\t\t.html(`${arg.me ? '<span style=\"font-size:.7em\">[ME]</span> ' : ''}${arg.msg}`)\n\t\tif (arg.me) bubble.style('background', '#f1f1f1')\n\t\t// set this to scroll to bottom\n\t\tconst n = this.dom.bubbleDiv.node()\n\t\tn.scrollTop = n.scrollHeight\n\t\treturn bubble\n\t}\n\n\t// Render click boxes for an incomplete plot state. `fieldKey` is the field of `plot` whose\n\t// value holds `possible_options`. Clicking a box completes the plot state and dispatches plot_create.\n\t// Each option completes the plot in one of two ways:\n\t// - opt.config: a config patch merged into the plot (the incomplete field is dropped). Used when the\n\t// choice sets other fields, e.g. the genome browser view sets blockIsProteinMode: true|false.\n\t// - otherwise: the incomplete field is set to { id: opt.id }, e.g. survival term selection -> term:{id}.\n\tshowPossibleOptions(bubble: any, plot: any, fieldKey: string, msg?: string) {\n\t\tconst options = plot[fieldKey].possible_options || []\n\t\tbubble.text(`${msg ? msg + '. ' : ''}Multiple options are available. Please select one:`)\n\t\tconst boxDiv = bubble.append('div').style('margin-top', '5px')\n\t\tfor (const opt of options) {\n\t\t\tboxDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t.attr('data-testid', `sjpp-mass-chat-option-${opt.id}`)\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('margin', '3px')\n\t\t\t\t.style('padding', '5px 10px')\n\t\t\t\t.style('border-radius', '5px')\n\t\t\t\t.style('cursor', 'pointer')\n\t\t\t\t.text(opt.name)\n\t\t\t\t.on('click', () => {\n\t\t\t\t\t// Complete the plot state and dispatch the plot. An option may carry a `config` patch\n\t\t\t\t\t// (merged into the plot, dropping the incomplete field \u2014 e.g. the genome browser view sets\n\t\t\t\t\t// blockIsProteinMode); otherwise complete the incomplete field with the chosen option's id.\n\t\t\t\t\tconst config = JSON.parse(JSON.stringify(plot))\n\t\t\t\t\tif (opt.config) {\n\t\t\t\t\t\tdelete config[fieldKey]\n\t\t\t\t\t\tObject.assign(config, opt.config)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconfig[fieldKey] = { id: opt.id }\n\t\t\t\t\t}\n\t\t\t\t\tthis.app.dispatch({\n\t\t\t\t\t\ttype: 'plot_create',\n\t\t\t\t\t\tconfig\n\t\t\t\t\t})\n\t\t\t\t\tbubble.selectAll('*').remove()\n\t\t\t\t\tbubble.text(`Selected \"${opt.name}\". Please refer to the plot generated below.`)\n\t\t\t\t})\n\t\t}\n\t}\n\n\tmain() {\n\t\t// If the subheader is hidden, it means the chat component is not visible, so we skip focusing the input to avoid accidental typing into the search/chat bar. The user can click on the chat again to focus when they want to use it.\n\t\tif (this.opts.subheader.style('display') == 'none') {\n\t\t\tthis.dom.inputNode.blur()\n\t\t\t// dismiss the omnisearch results popup when leaving the tab so it doesn't linger over another tab's content\n\t\t\tthis.dom.tip.hide()\n\t\t\treturn\n\t\t}\n\t\tif (this.opts?.focus != 'off') this.dom.inputNode.focus()\n\t}\n}\n\nexport const chatInit = getCompInit(MassAiChatBot)\n\n// Prevents HTML/script injection in the chat UI (XSS) by entering markup in the prompt (Proposed fix by copilot)\n\n// Scan a plot state for a field whose value carries a `possible_options` array, indicating the\n// server could not resolve that term and is offering the user a list of choices. Returns the field\n// name (e.g. 'term') or null if the plot state is complete.\nfunction findPossibleOptionsField(plot: any): string | null {\n\tif (!plot || typeof plot !== 'object') return null\n\tfor (const key of Object.keys(plot)) {\n\t\tconst val = plot[key]\n\t\tif (val && typeof val === 'object' && Array.isArray(val.possible_options)) return key\n\t}\n\treturn null\n}\n", "import { getCompInit, type AppApi, type RxComponent } from '#rx'\nimport { Menu } from '#dom/menu'\nimport { sayerror } from '#dom/sayerror'\nimport { table2col } from '#dom/table2col'\nimport { to_textfile } from '#dom/downloadTextfile'\nimport { dofetch3 } from '#common/dofetch'\nimport { parentCorsMessage } from '#common/embedder-helpers'\nimport { select } from 'd3-selection'\nimport { importPlot } from '#plots/importPlot.js'\nimport { trimGvTermsForSave } from '#shared/terms.js'\nimport type { Elem } from '../types/d3'\nimport type { MassUserOpts, MassUserDom, SessionOption, SessionLocation } from './types/user'\nimport { markSavedState, getSavedStateRefusal } from './sessionForm.ts'\n\n/*\n\"user\" tab will display following contents inside this.subheader:\n- the user authorization information, if the dataset requires authorization: the status, and the msgs and list of\n termdbConfig.massNav.tabs.user, as computed by the optional ds hook massNav.tabs.user.getContent(), by the active\n cohort. the status, if any, replaces the default status\n- the session open/save/share/delete functionality, moved from the former session button. The options are always\n shown as buttons, and the selected option renders into dom.contentDiv\n\nThe nav tab label is always 'SESSION'. nav.ts sets it.\n*/\n\n/** A dataset requires authorization if the server sent a non-empty termdbConfig.requiredAuth[] */\nexport function datasetRequiresAuth(termdbConfig: any): boolean {\n\treturn !!termdbConfig?.requiredAuth?.length\n}\n\n/**\n * What the user tab shows for the active cohort. The server computes the content by cohort when the dataset has a\n * selectCohort, since the access of the user may differ by cohort, and sends it as byCohort, by the index of\n * the cohort. Otherwise the content is on the tab entry itself.\n */\nexport function getUserTabContent(userTab: any, activeCohort?: number): any {\n\treturn (activeCohort != null && userTab?.byCohort?.[activeCohort]) || userTab\n}\n\n/**\n * The sign-in status line.\n * isPublic: termdbConfig.massNav.tabs.user.isPublic, from the optional ds hook massNav.tabs.user.getContent(), true if the\n * signed-in user has only public access, such as a public role\n */\nexport function getAuthStatus(signedIn: boolean, isPublic?: boolean): string {\n\tif (!signedIn) return 'Requires sign-in'\n\treturn isPublic === true ? 'Public access' : 'You are signed in.'\n}\n\n/**\n * For a session opened from a `mass-session-id` URL, the days before the server removes it. The nav shows text in the\n * bottom row of the user tab, and tip as its tooltip. undefined if the number of days is not available\n */\nexport function getDaysLeft(days: unknown): { text: string; tip: string } | undefined {\n\tif (typeof days != 'number' || !Number.isFinite(days)) return\n\treturn {\n\t\ttext: `${days} ${days == 1 ? 'day' : 'days'} left`,\n\t\ttip: 'The server keeps a session opened from a link for a limited time, and removes it when the days run out. To keep your work, select \"Save\" in this tab to create a new session, then use \"Share\" to get its link.'\n\t}\n}\n\nexport class MassUser implements RxComponent {\n\tstatic type = 'user'\n\n\ttype: string\n\tapp: AppApi\n\tid!: string\n\topts: MassUserOpts\n\tdom: MassUserDom\n\tstate: any\n\tsubheader: Elem\n\t/** The termdb route that is checked for a required credential */\n\troute = 'termdb'\n\t/** Matching termdbConfig.requiredAuth[] entry, with type 'jwt'. Enables saving sessions to the server */\n\trequiredAuth?: any\n\tsessionOptions: SessionOption[]\n\tembedderOrigin: string\n\thostURL: string\n\tdslabel!: string\n\tsessionName!: string\n\t/** Sessions saved in this browser, by session name. Mirrors localStorage 'savedMassSessions' */\n\tsavedSessions: { [name: string]: any } = {}\n\t/** Ids of the sessions saved on the server. Undefined until first requested */\n\tserverCachedSessions?: string[]\n\t/** The lookup of serverCachedSessions that is in progress, shared by everything that needs the result */\n\tserverSessionsRequest?: Promise<void>\n\t/** Whether the user was signed in at the last check, to detect a sign-in after the launch */\n\tsignedIn = false\n\tconfirmationTimer?: ReturnType<typeof setTimeout>\n\t/** Hides the tip that confirms a copied link */\n\tcopyTipTimer?: ReturnType<typeof setTimeout>\n\n\tconstructor(opts: MassUserOpts) {\n\t\tthis.type = MassUser.type\n\t\tthis.opts = opts\n\t\tthis.app = opts.app\n\t\tthis.subheader = opts.subheader\n\t\tconst sessionDiv = this.subheader.append('div').attr('data-testid', 'sjpp-massnav-user-session')\n\t\tsessionDiv\n\t\t\t.append('span')\n\t\t\t.attr('data-testid', 'sjpp-massnav-user-session-label')\n\t\t\t.style('margin', '0 10px')\n\t\t\t.style('font-weight', 'bold')\n\t\t\t.style('opacity', 0.65)\n\t\t\t.text('SESSION')\n\t\tthis.dom = {\n\t\t\tauthDiv: this.subheader.append('div').attr('data-testid', 'sjpp-massnav-user-auth').style('margin', '10px'),\n\t\t\tsessionDiv,\n\t\t\t// inline-flex, to be on the same row as the label, with the same gap between the buttons\n\t\t\toptionsDiv: sessionDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-massnav-user-session-options')\n\t\t\t\t.style('display', 'inline-flex')\n\t\t\t\t.style('vertical-align', 'middle')\n\t\t\t\t.style('gap', '10px'),\n\t\t\t// aligned with the edge of the option buttons, which have a 10px margin\n\t\t\tcontentDiv: sessionDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('id', 'sjpp-massnav-user-session-menu')\n\t\t\t\t.attr('data-testid', 'sjpp-massnav-user-session-content')\n\t\t\t\t.style('margin', '0 10px'),\n\t\t\tcopytip: new Menu({ padding: '5px' })\n\t\t}\n\t\tthis.sessionOptions = [\n\t\t\t{ label: `Open`, icon: '⏏︎', title: 'Recover a saved session', callback: () => this.open() },\n\t\t\t{ label: `Save`, icon: '⬇︎', title: 'Save the current view', callback: () => this.save() },\n\t\t\t{\n\t\t\t\tlabel: `Share`,\n\t\t\t\ticon: '⛓︎',\n\t\t\t\ttitle: 'Share the current view',\n\t\t\t\tcallback: () => this.getSessionUrl()\n\t\t\t}\n\t\t]\n\t\tthis.embedderOrigin = window.location.origin\n\t\tthis.hostURL = sessionStorage.getItem('hostURL') || this.embedderOrigin\n\t}\n\n\t/**\n\t * By default, only what this component renders from. rx compares the returned object with the previous state\n\t * on every dispatch, so it must not include the whole termdbConfig, which can be very large.\n\t *\n\t * forSession=true: the parts of the app state that make up a saved session instead, copied so that the app\n\t * state, which is deeply frozen and shared, is not changed. app_refresh merges a reopened session into the\n\t * current state, so what is not saved, such as the dataset config that init() in mass/store.ts fetches\n\t * again, keeps its current value. The derived properties of a geneVariant term are re-filled by every path\n\t * that opens a session, see trimGvTermsForSave().\n\t */\n\tgetState(appState: any, forSession = false) {\n\t\tif (forSession) {\n\t\t\tconst { vocab, activeCohort, termfilter, plots, groups, customTerms, reuse, nav } = appState\n\t\t\tconst state = structuredClone({ vocab, activeCohort, termfilter, plots, groups, customTerms, reuse, nav })\n\t\t\treturn markSavedState(trimGvTermsForSave(state))\n\t\t}\n\t\treturn {\n\t\t\tactiveCohort: appState.activeCohort,\n\t\t\ttermdbConfig: {\n\t\t\t\trequiredAuth: appState.termdbConfig?.requiredAuth,\n\t\t\t\tmassNav: { tabs: { user: appState.termdbConfig?.massNav?.tabs?.user } }\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Adds the methods that nav.ts calls on the api, since only the api is available outside the component */\n\tpreApiFreeze(api: any) {\n\t\tapi.showDaysLeftTip = (e: HTMLElement) => {\n\t\t\tconst tip = getDaysLeft(this.opts.sessionDaysLeft)?.tip\n\t\t\tif (!tip) return\n\t\t\tthis.dom.copytip.clear().d.append('div').style('max-width', '300px').text(tip)\n\t\t\tconst p = e.getBoundingClientRect()\n\t\t\tthis.dom.copytip.show2(p.left, p.bottom + 5)\n\t\t}\n\t\tapi.hideDaysLeftTip = () => this.dom?.copytip?.hide()\n\t}\n\n\tasync init(appState: any) {\n\t\tthis.dslabel = appState.vocab.dslabel\n\t\tthis.savedSessions = JSON.parse(localStorage.getItem('savedMassSessions') || `{}`)\n\t\tthis.setRequiredAuth(appState.termdbConfig)\n\t\tthis.initSessionOptions()\n\t}\n\n\tasync main() {\n\t\tthis.setRequiredAuth(this.state.termdbConfig)\n\t\tthis.renderAuthInfo()\n\t\tthis.mayLookupAfterSignIn()\n\t}\n\n\t/**\n\t * The sessions on the server are not looked up while the user is not signed in. So when the user signs in\n\t * after the launch, look them up then. Only a change to signed in triggers this, so that a lookup that keeps\n\t * failing is not repeated on every update of the app.\n\t */\n\tmayLookupAfterSignIn() {\n\t\tconst signedIn = !!this.app.vocabApi.hasVerifiedToken()\n\t\tconst justSignedIn = signedIn && !this.signedIn\n\t\tthis.signedIn = signedIn\n\t\tif (justSignedIn && this.requiredAuth && !this.serverCachedSessions) {\n\t\t\tthis.setServerCachedSessions()\n\t\t}\n\t}\n\n\tsetRequiredAuth(termdbConfig: any) {\n\t\tthis.requiredAuth = termdbConfig?.requiredAuth?.find((a: any) => a.route == this.route && a.type == 'jwt')\n\t}\n\n\t/** Show the sign-in status when the dataset requires authorization. Hidden for a public dataset */\n\trenderAuthInfo() {\n\t\tconst div = this.dom.authDiv\n\t\tdiv.selectAll('*').remove()\n\t\tif (!datasetRequiresAuth(this.state.termdbConfig)) {\n\t\t\tdiv.style('display', 'none')\n\t\t\treturn\n\t\t}\n\t\tdiv.style('display', 'block')\n\t\tconst vocabApi: any = this.app.vocabApi\n\t\tconst signedIn = vocabApi.hasVerifiedToken()\n\t\t// computed by the optional ds hook massNav.tabs.user.getContent(), from the auth of the user\n\t\tconst userTab = getUserTabContent(this.state.termdbConfig.massNav?.tabs?.user, this.state.activeCohort)\n\t\t// same label style as SESSION, with the status on the same row\n\t\tconst row = div.append('div')\n\t\trow\n\t\t\t.append('span')\n\t\t\t.attr('data-testid', 'sjpp-massnav-user-auth-label')\n\t\t\t.style('font-weight', 'bold')\n\t\t\t.style('opacity', 0.65)\n\t\t\t.text('ACCESS')\n\t\trow\n\t\t\t.append('span')\n\t\t\t.attr('data-testid', 'sjpp-massnav-user-auth-status')\n\t\t\t.style('margin-left', '10px')\n\t\t\t.text(userTab?.status || getAuthStatus(signedIn, userTab?.isPublic))\n\t\t// reason for a failed sign-in, if any\n\t\tconst msg = vocabApi.tokenVerificationMessage\n\t\tif (!signedIn && msg) row.append('span').style('margin-left', '5px').style('opacity', 0.65).text(msg)\n\t\t// the messages under the row, as the rows of a table2col: the label, and the value as text, an email\n\t\t// or a link. a message with only text shows the text alone. by property, so that no sentence is split around\n\t\t// its target, which would not survive a change of the wording. text, not html, and the target is the value as\n\t\t// it is, so that nothing is parsed from the text\n\t\tif (userTab?.msgs?.length) {\n\t\t\t// same table2col style as the run stats of the GRIN2 results view: default cell padding, gray label, and\n\t\t\t// the value in the default text color\n\t\t\tconst table = table2col({ holder: div, margin: '2px 8px', testid: 'sjpp-massnav-user-auth-info' })\n\t\t\tfor (const m of userTab.msgs) {\n\t\t\t\tconst [td1, td2] = table.addRow(m.label)\n\t\t\t\tconst target = m.email ? `mailto:${m.email}` : m.link\n\t\t\t\tif (target) {\n\t\t\t\t\tconst a = td2\n\t\t\t\t\t\t.append('a')\n\t\t\t\t\t\t.attr('href', target)\n\t\t\t\t\t\t.text(m.email || m.link)\n\t\t\t\t\tif (m.link) a.attr('target', '_blank')\n\t\t\t\t} else if (m.label) {\n\t\t\t\t\ttd2.text(m.txt)\n\t\t\t\t} else {\n\t\t\t\t\t// text only, in a cell that spans both columns\n\t\t\t\t\ttd2.remove()\n\t\t\t\t\ttd1.attr('colspan', 2).style('color', null).text(m.txt)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// the list under the row, such as the sites of the user\n\t\tif (userTab?.list) {\n\t\t\tconst listDiv = div\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-massnav-user-auth-list')\n\t\t\t\t.style('margin', '5px 0 0 8px')\n\t\t\t\t.style('font-size', '0.95em')\n\t\t\tlistDiv.append('div').style('font-weight', 'bold').text(userTab.list.label)\n\t\t\tconst ul = listDiv.append('ul').style('margin', '3px 0')\n\t\t\tfor (const item of userTab.list.items) ul.append('li').text(item)\n\t\t}\n\t}\n\n\t/**\n\t * Renders the session options right away. The lookup of the sessions on the server is optional, so it\n\t * is not awaited, since it must not delay or block the launch of the mass ui. The options are\n\t * rendered again when any lookup is done, since Delete is only shown when there is a session to delete.\n\t */\n\tinitSessionOptions() {\n\t\tthis.signedIn = !!this.app.vocabApi.hasVerifiedToken()\n\t\tthis.renderSessionOptions()\n\t\tif (!this.serverCachedSessions) this.setServerCachedSessions()\n\t}\n\n\t/** The Open, Save, Share, Delete, and Download options. Delete is only available if there is something to delete */\n\tgetSessionOptions(): SessionOption[] {\n\t\tconst options = this.sessionOptions.slice()\n\t\tif (Object.keys(this.savedSessions).length || this.serverCachedSessions?.length) {\n\t\t\toptions.push({\n\t\t\t\tlabel: `Delete`,\n\t\t\t\ticon: '✕',\n\t\t\t\ttitle: 'Delete a saved session',\n\t\t\t\tcallback: () => this.delete()\n\t\t\t})\n\t\t}\n\t\t// only for a session opened from a `mass-session-id` URL\n\t\tif (this.opts.sessionDaysLeft != null && this.opts.sessionId) {\n\t\t\toptions.push({\n\t\t\t\tlabel: `Download`,\n\t\t\t\ticon: '⤓',\n\t\t\t\ttitle: 'Download this session as a file',\n\t\t\t\tcallback: () =>\n\t\t\t\t\tthis.download(this.opts.sessionId!.replace(/[^\\w-]/g, '_'), this.getState(this.app.getState(), true))\n\t\t\t})\n\t\t}\n\t\treturn options\n\t}\n\n\t/** Render the buttons of the session options */\n\trenderSessionOptions() {\n\t\t// a lookup of the sessions on the server may finish after the component is destroyed, which removes this.dom\n\t\tif (!this.dom?.optionsDiv) return\n\t\tconst options = this.getSessionOptions()\n\t\tthis.dom.optionsDiv.selectAll('*').remove()\n\t\tthis.dom.optionsDiv\n\t\t\t.selectAll('button')\n\t\t\t.data(options)\n\t\t\t.enter()\n\t\t\t.append('button')\n\t\t\t// same style as the chart buttons in charts.ts\n\t\t\t.style('margin', '10px 0')\n\t\t\t.style('padding', '10px 15px')\n\t\t\t.style('border-radius', '20px')\n\t\t\t.style('border-color', '#ededed')\n\t\t\t.attr(\n\t\t\t\t'data-testid',\n\t\t\t\t(d: SessionOption) => `sjpp-massnav-user-session-btn-${d.label.toLowerCase().replace(/\\s/g, '-')}`\n\t\t\t)\n\t\t\t.attr('aria-label', (d: SessionOption) => d.title)\n\t\t\t.attr('title', (d: SessionOption) => d.title)\n\t\t\t.html((d: SessionOption) => `${d.icon} ${d.label}`)\n\t\t\t.on('click', async (event: MouseEvent, d: SessionOption) => {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\tthis.clearContent()\n\t\t\t\tawait d.callback()\n\t\t\t\t// space what the option rendered from what is under it. not when nothing was rendered, so that the\n\t\t\t\t// days left message stays right under the options. the component may be destroyed during the callback\n\t\t\t\tif (this.dom?.contentDiv?.node()?.hasChildNodes()) this.dom.contentDiv.style('padding-bottom', '10px')\n\t\t\t})\n\t}\n\n\tclearContent() {\n\t\tclearTimeout(this.confirmationTimer)\n\t\tthis.confirmationTimer = undefined\n\t\tthis.dom.contentDiv.interrupt()\n\t\tthis.dom.contentDiv.selectAll('*').remove()\n\t\tthis.dom.contentDiv.style('opacity', 1).style('padding-bottom', null)\n\t}\n\n\t/**\n\t * Removes what is not under this.dom of the component, which ComponentApi.destroy() removes. The copytip\n\t * Menu is in the document body, with a listener on the body, so it must be destroyed here.\n\t */\n\tdestroy() {\n\t\tclearTimeout(this.copyTipTimer)\n\t\tthis.clearContent()\n\t\tthis.dom.copytip.destroy()\n\t}\n\n\tasync open() {\n\t\tconst radioName = `sjpp-massnav-user-session-open-radio-` + Math.random().toString().slice(-6)\n\t\tconst div = this.dom.contentDiv\n\t\t// always open in the current tab for now, to avoid the tricky part of the code\n\t\t// that involves parent-child window messaging\n\t\t// TODO: re-enable when the new tab option works reliably\n\t\tdiv.append('div').style('display', 'none').style('padding', '3px 9px').html(`\n\t\t\t\t\t<b>Open in</b>\n\t\t\t\t\t<label>\n\t\t\t\t\t\t<input type='radio' name='${radioName}' value='new' style='margin-right: 0; vertical-align: bottom'/>\n\t\t\t\t\t\t<span>a new tab</span>\n\t\t\t\t\t</label>\n\t\t\t\t\t<label style='margin-left: 5px'>\n\t\t\t\t\t\t<input type='radio' name='${radioName}' value='current' checked=checked style='margin-right: 0; vertical-align: bottom'/>\n\t\t\t\t\t\t<span>current tab</span>\n\t\t\t\t\t</label>\n\t\t\t\t`)\n\t\tconst getTargetWindow = () => (div.node()!.querySelector(`[name=\"${radioName}\"]:checked`) as HTMLInputElement).value\n\n\t\tconst t = await this.listSessions({\n\t\t\ttrClickHandler: async (_event: MouseEvent, d: { loc: SessionLocation; id: string }) => {\n\t\t\t\tconst { loc, id } = d\n\t\t\t\tif (!id) return\n\t\t\t\tif (loc == 'browser') {\n\t\t\t\t\tthis.sessionName = id\n\t\t\t\t\tconst state = structuredClone(this.savedSessions[id])\n\t\t\t\t\tif (this.refuses(state)) return\n\t\t\t\t\tawait preprocessState(state, this.app)\n\t\t\t\t\tconst targetWindow = getTargetWindow()\n\t\t\t\t\tif (targetWindow == 'current') {\n\t\t\t\t\t\tthis.app.dispatch({ type: 'app_refresh', state })\n\t\t\t\t\t} else if (window.location.origin == this.hostURL) {\n\t\t\t\t\t\twindow.open(`/?mass-session-id=${encodeURIComponent(id)}&src=browser`)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (state.embedder) parentCorsMessage({ state })\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tconst { protocol, host, search, origin, href } = window.location\n\t\t\t\t\t\t\tconst embedder = { protocol, host, search, origin, href }\n\t\t\t\t\t\t\tparentCorsMessage({ state: Object.assign({ embedder }, state) })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.clearContent()\n\t\t\t\t} else if (loc == 'server') {\n\t\t\t\t\tconst headers = await this.app.vocabApi.mayGetAuthHeaders(this.route)\n\t\t\t\t\tconst body = { id, route: this.route, dslabel: this.dslabel, embedder: window.location.hostname }\n\t\t\t\t\tconst res = await dofetch3(`/massSession?`, { headers, body })\n\t\t\t\t\tif (!res.state) throw res.error || 'unable to get the cached session from the server'\n\t\t\t\t\tif (this.refuses(res.state)) return\n\t\t\t\t\tawait preprocessState(res.state, this.app)\n\t\t\t\t\tthis.savedSessions[id] = res.state\n\n\t\t\t\t\tconst targetWindow = getTargetWindow()\n\t\t\t\t\tif (targetWindow == 'current') {\n\t\t\t\t\t\tthis.app.dispatch({ type: 'app_refresh', state: res.state })\n\t\t\t\t\t} else if (window.location.origin == this.hostURL) {\n\t\t\t\t\t\twindow.open(\n\t\t\t\t\t\t\t`/?mass-session-id=${encodeURIComponent(id)}&src=cred&dslabel=${encodeURIComponent(\n\t\t\t\t\t\t\t\tthis.dslabel\n\t\t\t\t\t\t\t)}&route=${encodeURIComponent(this.route)}`\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// server-cached sessions should have an state.embedder object, no need to check\n\t\t\t\t\t\tparentCorsMessage(res)\n\t\t\t\t\t}\n\t\t\t\t\tthis.clearContent()\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tt.headtr.select('th').text('Open from')\n\n\t\t// open session from a local file\n\t\tconst tr1 = t.tbody.insert('tr', 'tr')\n\t\ttr1.append('td').style('text-align', 'center').style('padding', '3px 9px').text('Local file')\n\t\tconst label = tr1.append('td').style('text-align', 'left').append('label')\n\t\tlabel\n\t\t\t.append('span')\n\t\t\t.style('padding', '3px 9px')\n\t\t\t.style('text-decoration', 'underline')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.text('Choose File')\n\t\tlabel\n\t\t\t.append('input')\n\t\t\t.attr('type', 'file')\n\t\t\t.attr('placeholder', 'file name')\n\t\t\t.style('opacity', 0)\n\t\t\t.style('width', '0.1px')\n\t\t\t.style('height', '0.1px')\n\t\t\t.style('position', 'absolute')\n\t\t\t.on('change', async (event: Event) => {\n\t\t\t\tconst file = (event.target as HTMLInputElement).files!.item(0)!\n\t\t\t\tconst json = await file.text()\n\t\t\t\tlet sessionName: string | null = file.name\n\t\t\t\tif (this.savedSessions[sessionName]) {\n\t\t\t\t\tsessionName = prompt(\n\t\t\t\t\t\t`Leave as-is to overwrite a session with the same name, or enter a different session name.`,\n\t\t\t\t\t\tsessionName\n\t\t\t\t\t)\n\t\t\t\t\t// the prompt was cancelled\n\t\t\t\t\tif (!sessionName) return\n\t\t\t\t}\n\t\t\t\tthis.sessionName = sessionName\n\t\t\t\tconst state = JSON.parse(json)\n\t\t\t\tif (this.refuses(state)) return\n\t\t\t\tawait preprocessState(state, this.app)\n\t\t\t\tthis.savedSessions[sessionName] = state\n\t\t\t\tlocalStorage.setItem('savedMassSessions', JSON.stringify(this.savedSessions))\n\t\t\t\tconst targetWindow = getTargetWindow()\n\t\t\t\tif (targetWindow == 'current') {\n\t\t\t\t\tthis.app.dispatch({ type: 'app_refresh', state })\n\t\t\t\t} else if (window.location.origin == this.hostURL) {\n\t\t\t\t\twindow.open(`/?mass-session-id=${encodeURIComponent(sessionName)}&src=browser`)\n\t\t\t\t} else {\n\t\t\t\t\tif (state.embedder) parentCorsMessage({ state })\n\t\t\t\t\telse {\n\t\t\t\t\t\tconst { protocol, host, search, origin, href } = window.location\n\t\t\t\t\t\tconst embedder = { protocol, host, search, origin, href }\n\t\t\t\t\t\tparentCorsMessage({ state: Object.assign({ embedder }, state) })\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.clearContent()\n\t\t\t})\n\t}\n\n\tasync listSessions(opts: { trClickHandler?: any } = {}) {\n\t\tconst table = this.dom.contentDiv.append('table').attr('class', 'sjpp-controls-table')\n\n\t\tconst headtr = table.append('thead').append('tr')\n\t\theadtr\n\t\t\t.selectAll('th')\n\t\t\t.data(['Cache Location', 'Session ID'])\n\t\t\t.enter()\n\t\t\t.append('th')\n\t\t\t.style('text-align', (_: string, i: number) => (i === 0 ? 'center' : 'left'))\n\t\t\t.style('padding', '3px 9px')\n\t\t\t.text((d: string) => d)\n\n\t\tconst sessionIds: { loc: SessionLocation; id: string }[] = Object.keys(this.savedSessions).map(id => ({\n\t\t\tloc: 'browser',\n\t\t\tid\n\t\t}))\n\t\tif (!this.serverCachedSessions) await this.setServerCachedSessions()\n\t\tsessionIds.push(...(this.serverCachedSessions || []).map(id => ({ loc: 'server' as SessionLocation, id })))\n\n\t\tconst tbody = table.append('tbody')\n\t\tconst trs = tbody\n\t\t\t.selectAll('tr')\n\t\t\t.data(sessionIds)\n\t\t\t.enter()\n\t\t\t.append('tr')\n\t\t\t.on('click', opts.trClickHandler || null)\n\n\t\ttrs\n\t\t\t.selectAll('td')\n\t\t\t.data((d: any) => [d, d])\n\t\t\t.enter()\n\t\t\t.append('td')\n\t\t\t.style('text-align', (_: any, i: number) => (i === 0 ? 'center' : 'left'))\n\t\t\t.style('padding', '3px 9px')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.text((d: any, i: number) => (i === 0 ? d.loc : d.id))\n\n\t\tif (!this.serverCachedSessions?.length && this.requiredAuth && !this.app.vocabApi.hasVerifiedToken()) {\n\t\t\ttable\n\t\t\t\t.append('tbody')\n\t\t\t\t.append('tr')\n\t\t\t\t.selectAll('td')\n\t\t\t\t.data(['server', 'requires sign-in'])\n\t\t\t\t.enter()\n\t\t\t\t.append('td')\n\t\t\t\t.style('text-align', (_: string, i: number) => (i === 0 ? 'center' : 'left'))\n\t\t\t\t.style('padding', '3px 9px')\n\t\t\t\t.text((d: string) => d)\n\t\t}\n\t\treturn { table, headtr, tbody, trs }\n\t}\n\n\t/**\n\t * Looks up the ids of the sessions that the user saved on the server. This never throws, since the\n\t * sessions on the server are optional: the sessions of the browser, and everything else in the mass ui,\n\t * must work when the lookup fails, for example from a network error or a failure to get a token.\n\t *\n\t * Only a successful lookup is kept in serverCachedSessions. It stays undefined when the lookup is not made\n\t * because the user is not signed in, or when it fails, so that it is tried again on the next use.\n\t * Callers that arrive while a lookup is in progress share it instead of sending another request.\n\t */\n\tsetServerCachedSessions(): Promise<void> {\n\t\tif (this.serverSessionsRequest) return this.serverSessionsRequest\n\t\t// a lookup that is skipped is not shared, since a user that signs in right after it must not reuse it\n\t\tif (!this.mayLookupSessions()) return Promise.resolve()\n\t\tthis.serverSessionsRequest = this.lookupServerSessions().finally(() => {\n\t\t\tthis.serverSessionsRequest = undefined\n\t\t\t// Delete is only shown when there is a session to delete, which the lookup may have changed\n\t\t\tthis.renderSessionOptions()\n\t\t})\n\t\treturn this.serverSessionsRequest\n\t}\n\n\t/**\n\t * Returns true when the sessions on the server should be looked up now. A dataset without a jwt\n\t * credential has none, and the lookup is not made, so serverCachedSessions is an empty list.\n\t * It is also not made before the user is signed in, when the server would reject the request.\n\t */\n\tmayLookupSessions(): boolean {\n\t\ttry {\n\t\t\tconst state: any = this.app.getState()\n\t\t\tthis.requiredAuth = state.termdbConfig?.requiredAuth?.find((a: any) => a.route == this.route && a.type == 'jwt')\n\t\t\tif (!this.requiredAuth) {\n\t\t\t\tthis.serverCachedSessions = []\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn !!this.app.vocabApi.hasVerifiedToken()\n\t\t} catch (e: any) {\n\t\t\tconsole.warn(`unable to get the sessions saved on the server: ${e?.message || e}`)\n\t\t\treturn false\n\t\t}\n\t}\n\n\tasync lookupServerSessions() {\n\t\ttry {\n\t\t\tconst headers = await this.app.vocabApi.mayGetAuthHeaders(this.route)\n\t\t\tconst body = { route: this.route, dslabel: this.dslabel, embedder: window.location.hostname }\n\t\t\tconst res = await dofetch3('/sessionIds', { headers, body })\n\t\t\t// an error response is not a list that is empty\n\t\t\tif (!Array.isArray(res?.sessionIds)) throw res?.error || 'unexpected response'\n\t\t\tthis.serverCachedSessions = res.sessionIds\n\t\t} catch (e: any) {\n\t\t\tconsole.warn(`unable to get the sessions saved on the server: ${e?.message || e}`)\n\t\t}\n\t}\n\n\tasync save() {\n\t\tconst div = this.dom.contentDiv\n\t\tconst inputDiv = div.append('div')\n\t\tinputDiv.append('span').text('Save as')\n\t\tconst sessionNames = Object.keys(this.savedSessions)\n\t\tif (!this.serverCachedSessions) await this.setServerCachedSessions()\n\t\tsessionNames.push(...(this.serverCachedSessions || []).filter(d => !sessionNames.includes(d)))\n\t\tconst placeholder = this.sessionName || 'unnamed-session'\n\t\tconst input = inputDiv\n\t\t\t.append('input')\n\t\t\t.attr('type', 'text')\n\t\t\t.attr('placeholder', placeholder)\n\t\t\t.style('width', '220px')\n\t\t\t.on('input', () => {\n\t\t\t\tsearchResultDiv.selectAll('*').remove()\n\t\t\t\tconst value = input.property('value')\n\t\t\t\tconst exactMatch = sessionNames.filter(s => s === value)\n\t\t\t\tconst startsWith = sessionNames.filter(s => s.startsWith(value))\n\t\t\t\tconst includes = sessionNames.filter(s => s.includes(value) && s !== value && !startsWith.includes(s))\n\t\t\t\tsearchResultDiv\n\t\t\t\t\t.selectAll('div')\n\t\t\t\t\t.data([...exactMatch, ...startsWith, ...includes])\n\t\t\t\t\t.enter()\n\t\t\t\t\t.append('div')\n\t\t\t\t\t.attr('class', 'sja_menuoption')\n\t\t\t\t\t.attr('data-testid', `sjpp-massnav-user-session-save-option`)\n\t\t\t\t\t.text((d: string) => d)\n\t\t\t\t\t.on('click', (_: MouseEvent, d: string) => {\n\t\t\t\t\t\tinput.property('value', d)\n\t\t\t\t\t\tsearchResultDiv.selectAll('*').remove()\n\t\t\t\t\t})\n\t\t\t})\n\n\t\tconst searchResultDiv = div.append('div')\n\t\tconst submitDiv = div.append('div')\n\t\tsubmitDiv.append('span').html('Save to ')\n\t\tsubmitDiv\n\t\t\t.append('button')\n\t\t\t.style('min-width', '80px')\n\t\t\t.text('Browser')\n\t\t\t.attr(\n\t\t\t\t'title',\n\t\t\t\t`Save the session in your current browser's cache. The session can be easily recovered, but not shared among your other devices`\n\t\t\t)\n\t\t\t.on('click', () => {\n\t\t\t\tthis.sessionName = input.property('value') || placeholder\n\t\t\t\tthis.savedSessions[this.sessionName] = this.getState(this.app.getState(), true)\n\t\t\t\tlocalStorage.setItem('savedMassSessions', JSON.stringify(this.savedSessions))\n\t\t\t\tthis.renderSessionOptions()\n\t\t\t\tthis.confirmAction(`Cached '${this.sessionName}' in browser`)\n\t\t\t})\n\n\t\tsubmitDiv\n\t\t\t.append('button')\n\t\t\t.style('min-width', '80px')\n\t\t\t.text('File')\n\t\t\t.attr(\n\t\t\t\t'title',\n\t\t\t\t`Save the session into a local file. The session can be easily recoved using the 'Open from local file' option.`\n\t\t\t)\n\t\t\t.on('click', () => {\n\t\t\t\tconst name = input.property('value') || placeholder\n\t\t\t\t// the file is the copy of the session, which is not kept in this.savedSessions, for the browser\n\t\t\t\tthis.download(name, this.getState(this.app.getState(), true))\n\t\t\t\tthis.confirmAction(`Downloaded '${name}'`)\n\t\t\t})\n\n\t\t// assume that a jwt-type credential will include the user email in the jwt payload,\n\t\t// which could be trusted for saving sessions under cachedir/termdbSessions/[embedderHostName]/[email]\n\t\tif (this.requiredAuth) {\n\t\t\tconst requiresSignIn = this.app.vocabApi.hasVerifiedToken() ? '' : 'Requires sign-in. '\n\t\t\tsubmitDiv\n\t\t\t\t.append('button')\n\t\t\t\t.style('min-width', '80px')\n\t\t\t\t.text('Server')\n\t\t\t\t.attr(\n\t\t\t\t\t'title',\n\t\t\t\t\t`${requiresSignIn}Save the session into a remote server. The session can be easily shared across your different devices and recovered using the 'Open from server' option.`\n\t\t\t\t)\n\t\t\t\t.property('disabled', !this.app.vocabApi.hasVerifiedToken())\n\t\t\t\t.on('click', async () => {\n\t\t\t\t\tif (!this.app.vocabApi.hasVerifiedToken()) {\n\t\t\t\t\t\talert('Requires sign-in')\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tconst name = input.property('value') || placeholder\n\t\t\t\t\t// the state is sent to the server, and is not kept in this.savedSessions, which is for the browser\n\t\t\t\t\tconst res = await this.getSessionUrl(name)\n\t\t\t\t\tif (res.error || res.id != name) {\n\t\t\t\t\t\tsayerror(submitDiv, `Unable to save '${name}' on the server: ${res.error || 'unexpected session id'}`)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t// if the lookup failed, the saved session is found by the next lookup\n\t\t\t\t\tif (this.serverCachedSessions && !this.serverCachedSessions.includes(name))\n\t\t\t\t\t\tthis.serverCachedSessions.push(name)\n\t\t\t\t\tthis.renderSessionOptions()\n\t\t\t\t\tthis.confirmAction(`Saved '${name}' on the server`)\n\t\t\t\t})\n\t\t}\n\t}\n\n\t// true when a saved state is not opened, see sessionForm.ts. the reason is shown\n\trefuses(state: any) {\n\t\tconst reason = getSavedStateRefusal(state)\n\t\tif (!reason) return false\n\t\tthis.clearContent()\n\t\tthis.app.printError(reason)\n\t\treturn true\n\t}\n\n\tdownload(name: string, state: any) {\n\t\tconst ext = name.endsWith('.txt') ? '' : '.txt'\n\t\tto_textfile(`${name}${ext}`, JSON.stringify(state))\n\t}\n\n\t/** With a filename, saves the session on the server under that name and returns the response.\n\tWithout one, creates a shareable link and renders it. */\n\tasync getSessionUrl(filename = ''): Promise<any> {\n\t\tconst headers = await this.app.vocabApi.mayGetAuthHeaders(this.route)\n\t\tconst state = this.getState(this.app.getState(), true)\n\t\tconst { protocol, host, search, origin, href } = window.location\n\t\tstate.embedder = { protocol, host, search, origin, href }\n\t\tif (filename) {\n\t\t\t// a non-empty filename value implies saving by email and having auth session,\n\t\t\t// since it's easy for different users to use the same non-random filename\n\t\t\tstate.__sessionFor__ = {\n\t\t\t\troute: this.route,\n\t\t\t\tfilename,\n\t\t\t\tdslabel: this.dslabel,\n\t\t\t\tembedder: window.location.hostname\n\t\t\t}\n\t\t}\n\t\tconst res = await dofetch3('/massSession', {\n\t\t\theaders,\n\t\t\tmethod: 'POST',\n\t\t\tbody: JSON.stringify(state)\n\t\t})\n\n\t\tif (filename) return res\n\n\t\tconst div = this.dom.contentDiv\n\t\tif (res.error || !res.id) {\n\t\t\t// for example, a session state that is too large, or a server that does not enable saved sessions\n\t\t\tsayerror(div.append('div'), `Unable to create a session link: ${res.error || 'missing session id'}`)\n\t\t\treturn\n\t\t}\n\t\tconst url = `${this.hostURL}/?mass-session-id=${encodeURIComponent(res.id)}&noheader=1`\n\t\tconst linkDiv = div.append('div').style('margin', '10px')\n\n\t\tconst a = linkDiv.append('a').style('display', 'none').attr('href', url).attr('target', '_blank').text(res.id)\n\n\t\t// open button\n\t\tlinkDiv\n\t\t\t.append('button')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.text('Open link')\n\t\t\t.on('click', () => {\n\t\t\t\ta.node()!.click()\n\t\t\t})\n\n\t\t// copy button\n\t\tlinkDiv\n\t\t\t.append('button')\n\t\t\t.style('cursor', 'pointer')\n\t\t\t.style('margin-left', '10px')\n\t\t\t.text('Copy link')\n\t\t\t.on('click', async (event: MouseEvent) => {\n\t\t\t\tawait navigator.clipboard.writeText(url)\n\t\t\t\t// the component may have been destroyed while the clipboard was written\n\t\t\t\tif (!this.dom?.copytip) return\n\t\t\t\tthis.dom.copytip.clear().showunder(event.target)\n\t\t\t\tthis.dom.copytip.d.append('div').html('✓')\n\t\t\t\tclearTimeout(this.copyTipTimer)\n\t\t\t\tthis.copyTipTimer = setTimeout(() => this.dom?.copytip?.hide(), 1000)\n\t\t\t})\n\n\t\tif (this.hostURL != window.location.origin) {\n\t\t\t// Avoid the multi-window/tab sequence to recover the session:\n\t\t\t// intercept the click on the URL link, so that the embedder URL is opened\n\t\t\t// instead of the hostURL with mass session id, and this window will post\n\t\t\t// a message to the child window with the link data instead\n\t\t\t//\n\t\t\t// NOTE: the multi-window/tab sequence is only necessary when the URL link\n\t\t\t// was not opened by the embedder window\n\t\t\t//\n\t\t\ta.on('click', (event: MouseEvent) => {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tparentCorsMessage({ state }, 'noredirect')\n\t\t\t\treturn false\n\t\t\t})\n\t\t}\n\n\t\tlinkDiv.append('div').html(`\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<div style=\"font-size: 1em; opacity:.6\">\n\t\t\t\t\t\t\t<span>NOTES</span>\n\t\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t<li>A recovered session may hide data or views to users that are not authorized to access the saved datasets or features.</li>\n\t\t\t\t\t\t\t<li>This session will be saved for ${this.opts.massSessionDuration} days.</li>\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t</div>`)\n\t}\n\n\tasync delete() {\n\t\tconst t = await this.listSessions({\n\t\t\ttrClickHandler: function (this: any, event: MouseEvent) {\n\t\t\t\tconst input = this.lastChild.querySelector('input')\n\t\t\t\tconst checked = event.target == input ? input.checked : !input.checked\n\t\t\t\tselect(this).style('text-decoration', checked ? 'line-through' : '')\n\t\t\t\tif (event.target != input) input.checked = checked\n\t\t\t\tconst checkedRows = t.table.node()!.querySelectorAll('input:checked')\n\t\t\t\tsubmitBtn.property('disabled', checkedRows.length ? false : true)\n\t\t\t}\n\t\t})\n\n\t\t// add a 3rd column for the checkboxes\n\t\tt.headtr.append('th').text('Delete')\n\t\tt.trs.each(function (this: any, d: any) {\n\t\t\tselect(this)\n\t\t\t\t.append('td')\n\t\t\t\t.style('text-align', 'center')\n\t\t\t\t.append('input')\n\t\t\t\t.attr('type', 'checkbox')\n\t\t\t\t.attr('value', d.id)\n\t\t})\n\n\t\t// left aligned with the table, the content is as wide as the tab\n\t\tconst submitBtn = this.dom.contentDiv\n\t\t\t.append('div')\n\t\t\t.style('margin-top', '10px')\n\t\t\t.append('button')\n\t\t\t.text('Delete selected sessions')\n\t\t\t.property('disabled', true)\n\t\t\t.on('click', async () => {\n\t\t\t\terrorDiv.selectAll('*').remove()\n\t\t\t\tconst inputs = t.table.node()!.querySelectorAll('input')\n\t\t\t\tconst sessionIdsDeletedFromServer: string[] = []\n\t\t\t\tfor (const input of inputs) {\n\t\t\t\t\tif (select(input).property('checked')) {\n\t\t\t\t\t\tconst d = (input.parentNode!.parentNode as any).__data__\n\t\t\t\t\t\tif (d.loc == 'browser') {\n\t\t\t\t\t\t\tdelete this.savedSessions[input.value]\n\t\t\t\t\t\t} else if (d.loc == 'server') {\n\t\t\t\t\t\t\tsessionIdsDeletedFromServer.push(input.value)\n\t\t\t\t\t\t} else throw `unknown cache location=${d.loc}`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlocalStorage.setItem('savedMassSessions', JSON.stringify(this.savedSessions))\n\t\t\t\tif (sessionIdsDeletedFromServer.length) {\n\t\t\t\t\tsubmitBtn.property('disabled', true)\n\t\t\t\t\tlet error: any, failedIds: string[] | undefined\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst headers = await this.app.vocabApi.mayGetAuthHeaders(this.route)\n\t\t\t\t\t\tconst errors: string[] = []\n\t\t\t\t\t\tfailedIds = []\n\t\t\t\t\t\tfor (const ids of getDeletionBatches(sessionIdsDeletedFromServer)) {\n\t\t\t\t\t\t\tconst body = { ids, route: this.route, dslabel: this.dslabel, embedder: window.location.hostname }\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst res = await dofetch3(`/massSession?`, { method: 'DELETE', headers, body })\n\t\t\t\t\t\t\t\tif (res.error) {\n\t\t\t\t\t\t\t\t\terrors.push(res.error)\n\t\t\t\t\t\t\t\t\t// without a list of failed ids, assume that none of the batch was deleted\n\t\t\t\t\t\t\t\t\tfailedIds.push(...(res.failedIds || ids))\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\t\terrors.push(e.message || e)\n\t\t\t\t\t\t\t\tfailedIds.push(...ids)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (errors.length) error = errors.join('; ')\n\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\terror = e.message || e\n\t\t\t\t\t\tfailedIds = sessionIdsDeletedFromServer\n\t\t\t\t\t}\n\t\t\t\t\tconst deletedIds = sessionIdsDeletedFromServer.filter(id => !failedIds?.includes(id))\n\t\t\t\t\tthis.serverCachedSessions = this.serverCachedSessions?.filter(id => !deletedIds.includes(id))\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\t// keep the content open so that the error is visible, and allow a retry of only the failed ids,\n\t\t\t\t\t\t// by removing the rows of deleted sessions while the failed rows remain checked\n\t\t\t\t\t\tt.trs\n\t\t\t\t\t\t\t.filter((d: any) => (d.loc == 'browser' ? !this.savedSessions[d.id] : deletedIds.includes(d.id)))\n\t\t\t\t\t\t\t.remove()\n\t\t\t\t\t\tconst checkedRows = t.table.node()!.querySelectorAll('input:checked')\n\t\t\t\t\t\tsubmitBtn.property('disabled', !checkedRows.length)\n\t\t\t\t\t\tsayerror(errorDiv, `Error deleting server session(s): ${error}`)\n\t\t\t\t\t\tthis.renderSessionOptions()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.renderSessionOptions()\n\t\t\t\tthis.clearContent()\n\t\t\t})\n\n\t\tconst errorDiv = this.dom.contentDiv.append('div')\n\t}\n\n\t/** Show a message that fades out, then clear the content */\n\tconfirmAction(message: string) {\n\t\tthis.clearContent()\n\t\tthis.dom.contentDiv.append('div').text(message)\n\t\tthis.dom.contentDiv.transition().delay(3000).duration(1000).style('opacity', 0)\n\t\tthis.confirmationTimer = setTimeout(() => this.clearContent(), 4000)\n\t}\n}\n\n/*\n\tids: session ids to delete from the server\n\n\treturns ids[] split into batches, so that each DELETE request URL\n\tstays below the length limit that dofetch3() allows for a non-GET request,\n\tsince the ids[] are URL-encoded as a request parameter\n*/\nexport function getDeletionBatches(ids: string[]): string[][] {\n\t// leave room in the URL for the host, path, and the other request parameters\n\tconst maxEncodedIdsLength = 1000\n\tconst batches: string[][] = []\n\tlet batch: string[] = []\n\tfor (const id of ids) {\n\t\tif (batch.length && encodeURIComponent(JSON.stringify([...batch, id])).length > maxEncodedIdsLength) {\n\t\t\tbatches.push(batch)\n\t\t\tbatch = []\n\t\t}\n\t\t// a single id that is too long will be sent alone, and dofetch3() will throw instead of converting to POST\n\t\tbatch.push(id)\n\t}\n\tif (batch.length) batches.push(batch)\n\treturn batches\n}\n\n// may need to edit state based on updated expectations,\n// such as new or deprecated plot settings keys/values\nasync function preprocessState(state: any, app: AppApi) {\n\tdelete state.termdbConfig\n\tif (state.plots) {\n\t\tconst promises: Promise<any>[] = []\n\t\tfor (const plot of state.plots) {\n\t\t\tpromises.push(\n\t\t\t\t(async () => {\n\t\t\t\t\tconst _ = await importPlot(plot.chartType)\n\t\t\t\t\treturn await _.getPlotConfig(plot, app)\n\t\t\t\t})()\n\t\t\t)\n\t\t}\n\t\ttry {\n\t\t\tawait Promise.all(promises)\n\t\t} catch (e: any) {\n\t\t\tconsole.error(e)\n\t\t\tapp.printError(e)\n\t\t}\n\t}\n}\n\nexport const userInit = getCompInit(MassUser)\n", "import { getCompInit, multiInit } from '#rx'\nimport { recoverInit } from '../rx/src/recover'\nimport { chartsInit } from './charts'\nimport { groupsInit } from './groups'\nimport { aboutInit } from './about.ts'\nimport { chatInit } from './chat.ts'\nimport { userInit, getDaysLeft } from './user'\nimport { Menu, icons as icon_functions } from '#dom'\nimport { getFilterItemByTag, filterRxCompInit } from '#filter/filter'\nimport type { NavTab, NavTabCell } from './types/nav'\n\n/*\ntodo: steps to add a new tab\n*/\n\nconst activeTabBgColor = '#ececec', // default bg color of active tab; inactive tab is transparent\n\tactiveTabBgColorHover = '#e0e0e0',\n\tactiveTabTextColor = 'black',\n\tinactiveTabBgColorHover = '#fcfced',\n\tinactiveTabTextColor = 'gray'\n\n// to be used for assigning unique\n// radio button names by object instance\n// otherwise termdp app popups\nlet instanceNum = 0\n\n// to distinguish from IDs assigned by other code or users\nconst idPrefix = '_MASS_AUTOID_' + Math.random().toString().slice(-6)\nlet id = Number((+new Date()).toString().slice(-8))\n\nconst headtip = new Menu({ padding: '0px', offsetX: 0, offsetY: 0 })\nheadtip.d.style('z-index', 5555)\n// headtip must get a crazy high z-index so it can stay on top of all, no matter if server config has base_zindex or not\n\n// data elements for navigation header tabs\nconst aboutTab = { top: 'ABOUT', mid: '', btm: '', subheader: 'about' }\nconst chartTab = { top: 'CHARTS', mid: 'NONE', btm: '', subheader: 'charts' }\nconst groupsTab = { top: 'GROUPS', mid: 'NONE', btm: '', subheader: 'groups' }\nconst filterTab = { top: 'FILTER', mid: 'NONE', btm: '', subheader: 'filter' }\n// const cartTab = { top: 'CART', mid: 'NONE', btm: '', subheader: 'cart' }\nconst userTab = { top: 'SESSION', mid: '', btm: '', subheader: 'user' }\n\n/**\n * The role of the user, for the middle row of the user tab. Only for a dataset that requires authorization.\n * Without a role for the dataset, the role is for the active cohort, keyed by a key of the cohort in\n * selectCohort.values[].keys, such as clientAuthResult.a.role for a cohort with keys ['a']\n */\nexport function getUserTabMid(termdbConfig: any, activeCohort = -1): string {\n\tif (!termdbConfig?.requiredAuth?.length) return ''\n\tconst auth = termdbConfig.clientAuthResult\n\tconst keys: string[] = termdbConfig.selectCohort?.values?.[activeCohort]?.keys || []\n\tconst role = [auth?.role, ...keys.map(k => auth?.[k]?.role)].find(r => typeof r === 'string' && r)\n\treturn role ? role.toUpperCase() : ''\n}\n\nexport function getId(): string {\n\treturn idPrefix + '_' + id++\n}\n\nclass TdbNav {\n\tstatic type = 'nav'\n\ttype: string\n\tinstanceNum: number\n\ttabs: NavTab[]\n\tactiveTab: number\n\tactiveCohort: number\n\tsamplecounts: Record<string, any>\n\tsearching: boolean\n\tmassSessionDuration: any\n\tpkgver: any\n\topts: any\n\tapp: any\n\tstate: any\n\tdom: any;\n\t[key: string]: any\n\n\tconstructor(opts: any) {\n\t\tthis.type = TdbNav.type\n\t\tthis.instanceNum = instanceNum++\n\t\tthis.tabs = [] // array of tab objects corresponding to what's shown on header, based on ds customization. hidden tabs are not in this array. filled in initUI()\n\t\tthis.activeTab = 0 // array index for .tabs[]; -1 for no active tabs and all closed\n\t\tthis.activeCohort = 0 // -1 = unselected, 0,1,2... = selected\n\t\tthis.samplecounts = {} // tracks sample count by .activeCohort value and stringified filter json\n\t\tthis.searching = false\n\t\tthis.massSessionDuration = opts.massSessionDuration\n\t\tthis.pkgver = opts.pkgver || null //Release version\n\t\tsetInteractivity(this)\n\t\tsetRenderers(this)\n\t}\n\n\tasync init(appState: any): Promise<void> {\n\t\t// try {\n\t\tthis.cohortFilter = getFilterItemByTag(appState.termfilter.filter, 'cohortFilter')\n\t\tthis.initUI(appState)\n\t\tif (appState?.termdbConfig?.selectCohort) {\n\t\t\tthis.dom.tds.filter(d => d.colNum === 0).style('display', '')\n\t\t\tthis.cohortNames = appState.termdbConfig.selectCohort.values.map(d => d.keys.slice().sort().join(','))\n\t\t}\n\n\t\tthis.components = await multiInit({\n\t\t\tfilter: filterRxCompInit({\n\t\t\t\tapp: this.app,\n\t\t\t\tvocabApi: this.app.vocabApi,\n\t\t\t\tholder: this.dom.subheader.filter.append('div').style('margin', '5px'),\n\t\t\t\thideLabel: this.opts.header_mode === 'with_tabs',\n\t\t\t\temptyLabel: '+Add new filter',\n\t\t\t\tcallback: (filter: any) => {\n\t\t\t\t\tthis.app.dispatch({\n\t\t\t\t\t\ttype: 'filter_replace',\n\t\t\t\t\t\tfilter\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}),\n\t\t\tcharts: chartsInit({\n\t\t\t\tapp: this.app,\n\t\t\t\tholder: this.dom.subheader.charts,\n\t\t\t\tvocab: this.opts.vocab\n\t\t\t}),\n\t\t\tgroups: groupsInit({\n\t\t\t\tapp: this.app,\n\t\t\t\tholder: this.dom.subheader.groups,\n\t\t\t\tvocab: this.opts.vocab\n\t\t\t}),\n\t\t\trecover: recoverInit({\n\t\t\t\tapp: this.app,\n\t\t\t\tholder: this.dom.recoverDiv,\n\t\t\t\t// TODO: ???? may limit the tracked state to only the filter, activeCohort ???\n\t\t\t\tgetState: (appState: any) => appState,\n\t\t\t\treactsTo: (action: any) => action.type != 'plot_edit',\n\t\t\t\tmaxHistoryLen: 5\n\t\t\t}),\n\t\t\tabout: aboutInit({\n\t\t\t\tapp: this.app,\n\t\t\t\tsubheader: this.dom.subheader.about,\n\t\t\t\tinstanceNum: this.instanceNum,\n\t\t\t\taboutOverrides: appState?.termdbConfig?.massNav?.tabs?.about || null,\n\t\t\t\tselectCohort: appState?.termdbConfig?.selectCohort || null\n\t\t\t}),\n\t\t\tchat: chatInit({\n\t\t\t\tapp: this.app,\n\t\t\t\tsubheader: this.dom.subheader.chat\n\t\t\t}),\n\t\t\tuser: userInit({\n\t\t\t\tapp: this.app,\n\t\t\t\tsubheader: this.dom.subheader.user,\n\t\t\t\tmassSessionDuration: this.opts.massSessionDuration,\n\t\t\t\tsessionDaysLeft: this.app.opts.sessionDaysLeft ?? null,\n\t\t\t\tsessionId: this.app.opts.sessionId || null\n\t\t\t})\n\t\t})\n\t\t// } catch (e) {\n\t\t// \tthrow e\n\t\t// }\n\t}\n\n\treactsTo(action: any): boolean | undefined {\n\t\tif (action.type.startsWith('filter')) return true\n\t\tif (action.type.startsWith('cohort')) return true\n\t\tif (action.type.startsWith('tab')) return true\n\n\t\t// do not use startsWith('plot_') to exclude 'plot_edit' as no need for nav to react to that\n\t\tif (action.type == 'plot_prep') return true\n\t\tif (action.type == 'plot_create') return true\n\t\tif (action.type == 'plot_delete') return true\n\n\t\tif (action.type == 'app_refresh') return true\n\t\tif (action.type.endsWith('_customTerm')) return true\n\t\tif (action.type.endsWith('_group')) return true\n\t}\n\n\tgetState(appState: any): any {\n\t\treturn {\n\t\t\tsearching: this.searching, // for detection of internal state change\n\t\t\tnav: appState.nav,\n\t\t\tactiveCohort: appState.activeCohort,\n\t\t\ttermdbConfig: appState.termdbConfig,\n\t\t\tfilter: appState.termfilter.filter,\n\t\t\tplots: appState.plots,\n\t\t\tgroups: appState.groups\n\t\t}\n\t}\n\n\tasync main(): Promise<void> {\n\t\tthis.dom.tabDiv.style('display', this.state.nav.header_mode === 'with_tabs' ? 'inline-block' : 'none')\n\t\tthis.dom.tip.hide()\n\t\tthis.activeTab = this.state.nav.activeTab\n\t\tthis.prevCohort = this.activeCohort\n\t\tthis.activeCohort = +this.state.activeCohort\n\t\tthis.filterUiRoot = getFilterItemByTag(this.state.filter, 'filterUiRoot')\n\t\tthis.cohortFilter = getFilterItemByTag(this.state.filter, 'cohortFilter')\n\t\tif (this.cohortNames) {\n\t\t\tthis.activeCohortName = this.cohortNames[this.activeCohort]\n\t\t\tif (this.activeCohort !== -1)\n\t\t\t\tthis.activeCohortLabel = this.state.termdbConfig.selectCohort.values[this.activeCohort].shortLabel\n\t\t}\n\t\tthis.filterJSON = JSON.stringify(this.state.filter)\n\n\t\tthis.cohortsData = await this.app.vocabApi.getCohortsData()\n\n\t\tif (this.state.nav.header_mode === 'with_tabs') {\n\t\t\tif (!(this.activeCohort in this.samplecounts)) {\n\t\t\t\tthis.samplecounts[this.activeCohort] = await this.app.vocabApi.getCohortSampleCount(this.activeCohortName)\n\t\t\t}\n\t\t\tif (!(this.filterJSON in this.samplecounts)) {\n\t\t\t\tif (!this.filterUiRoot || !this.filterUiRoot.lst.length) {\n\t\t\t\t\tthis.samplecounts[this.filterJSON] = this.samplecounts[this.activeCohort]\n\t\t\t\t} else {\n\t\t\t\t\tconst n = await this.app.vocabApi.getFilteredSampleCount(this.filterJSON)\n\t\t\t\t\tthis.samplecounts[this.filterJSON] = n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.updateUI()\n\t}\n}\n\nexport const navInit = getCompInit(TdbNav)\n\nfunction setRenderers(self: any): void {\n\tself.initUI = (appState: any) => {\n\t\tconst verifiedToken = self.app.vocabApi.verifiedToken\n\t\tconst invalidTokenErrorHandling = appState.termdbConfig.invalidTokenErrorHandling\n\t\t//Show error message if login failed and all charts require login. If the dataset does not require login verifiedToken is true\n\t\t//Currently only the profile and carereg always require a token.\n\t\t// Note that if the user did not login the public token was used. So only if the user did login and the token passed was invalid this error is shown\n\t\tif (!verifiedToken && invalidTokenErrorHandling?.affectedCharts?.includes('*'))\n\t\t\tthrow new Error(appState.termdbConfig.invalidTokenErrorHandling.errorMessage)\n\t\t// a flex row, so that the tabs stretch to the height of the controls, which may be taller than the tabs.\n\t\t// the active tab then reaches the border at the bottom of the header\n\t\tconst header = self.opts.holder\n\t\t\t.append('div')\n\t\t\t.style('white-space', 'nowrap')\n\t\t\t.style('display', 'flex')\n\t\t\t.style('align-items', 'stretch')\n\t\tconst massNav = appState.termdbConfig?.massNav || {}\n\t\tconst titleDiv = header\n\t\t\t.append('div')\n\t\t\t.style('order', '2') // rightmost\n\t\t\t.style('align-self', 'flex-start')\n\t\t\t.style('font-size', '1.1em')\n\t\t\t.style('margin', '50px 10px 0 0')\n\t\t\t.text(massNav?.title?.text) //this line will be executed in update UI to reflect cohort changes\n\n\t\tconst tabDiv = header.append('div').style('display', 'none').style('vertical-align', 'bottom')\n\t\tconst controlsDiv = header\n\t\t\t//Fix for adding message underneath the search bar and buttons\n\t\t\t.append('div')\n\t\t\t.style('order', '1') // right of the tabs, left of the title\n\t\t\t.style('margin', '10px 10px 10px auto')\n\t\t\t// the icons are at the right edge, beside the title\n\t\t\t.style('text-align', 'right')\n\n\t\tif (self.opts.header_mode === 'only_buttons') {\n\t\t\t// if header_mode is only_buttons, show only buttons\n\t\t\ttabDiv.style('display', 'none')\n\t\t\ttitleDiv.style('display', 'none')\n\t\t\tcontrolsDiv.style('display', 'none')\n\t\t}\n\t\tself.opts.holder.attr('class', 'sjpp-nav')\n\t\tself.dom = {\n\t\t\tholder: self.opts.holder,\n\t\t\theader,\n\t\t\ttabDiv,\n\t\t\tcontrolsDiv,\n\t\t\tsearchDiv: controlsDiv.append('div').style('margin', '10px'),\n\t\t\trecoverDiv: controlsDiv.append('div').style('display', 'inline-block'),\n\t\t\tpdfDiv: controlsDiv\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('padding', '4px')\n\t\t\t\t.style('vertical-align', 'middle'),\n\t\t\tdeleteAllDiv: controlsDiv\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('padding', '4px')\n\t\t\t\t.style('vertical-align', 'middle'),\n\n\t\t\thelpDiv: controlsDiv.append('div').style('display', 'none'),\n\t\t\tsubheaderDiv: self.opts.holder.append('div').style('display', 'block').style('border-bottom', '1px solid #000'),\n\t\t\tmessageDiv: self.opts.holder.append('div').style('margin', '30px').style('display', 'none'),\n\t\t\ttitleDiv,\n\t\t\ttip: new Menu({ padding: '5px' })\n\t\t}\n\t\ticon_functions['trash'](self.dom.deleteAllDiv, {\n\t\t\thandler: self.deletePlots,\n\t\t\ttitle: 'Delete all plots. To revert, click Undo button'\n\t\t})\n\n\t\ticon_functions['pdf'](self.dom.pdfDiv, {\n\t\t\thandler: self.opts.downloadPlots,\n\t\t\ttitle: 'Generate a PDF of all the plots opened'\n\t\t})\n\n\t\tif (self.opts.header_mode === 'with_cohortHtmlSelect') {\n\t\t\t// not part of filter div\n\t\t\tself.dom.cohortStandaloneDiv = header\n\t\t\t\t.append('div')\n\t\t\t\t.style('display', 'inline-block')\n\t\t\t\t.style('margin', '10px')\n\t\t\t\t.style('vertical-align', 'top')\n\n\t\t\tself.dom.cohortStandaloneDiv.append('label').html('Cohort: ')\n\t\t\tself.dom.cohortSelect = self.dom.cohortStandaloneDiv.append('select').on('change', async function (this: any) {\n\t\t\t\tself.app.dispatch({ type: 'cohort_set', activeCohort: +this.value })\n\t\t\t})\n\n\t\t\tself.dom.cohortSelect\n\t\t\t\t.selectAll('option')\n\t\t\t\t.data(appState.termdbConfig.selectCohort.values)\n\t\t\t\t.enter()\n\t\t\t\t.append('option')\n\t\t\t\t.attr('value', (d, i) => i)\n\t\t\t\t.property('selected', (d, i) => i === appState.activeCohort)\n\t\t\t\t.html(d => d.shortLabel)\n\t\t}\n\n\t\tself.dom.subheader = Object.freeze({\n\t\t\t// For either the COHORT or ABOUT tab\n\t\t\tabout: self.dom.subheaderDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-mass-nav-subheader-about')\n\t\t\t\t.style('display', 'none'),\n\t\t\tsearch: self.dom.subheaderDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-mass-nav-subheader-search')\n\t\t\t\t.style('display', 'none'),\n\t\t\tgroups: self.dom.subheaderDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-mass-nav-subheader-groups')\n\t\t\t\t.style('display', 'none'),\n\t\t\tcharts: self.dom.subheaderDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-mass-nav-subheader-charts')\n\t\t\t\t.style('display', 'none'),\n\t\t\tfilter: self.dom.subheaderDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-mass-nav-subheader-filter')\n\t\t\t\t.style('display', 'none'),\n\t\t\tchat: self.dom.subheaderDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-mass-nav-subheader-chat')\n\t\t\t\t.style('display', 'none'),\n\t\t\tuser: self.dom.subheaderDiv\n\t\t\t\t.append('div')\n\t\t\t\t.attr('data-testid', 'sjpp-mass-nav-subheader-user')\n\t\t\t\t.style('display', 'none')\n\t\t\t// cart: self.dom.subheaderDiv.append('div').style('display', 'none').html('<br/>Cart feature under construction - work in progress<br/> <br/>'),\n\t\t})\n\n\t\tif (!massNav.tabs?.about?.hide) {\n\t\t\t// about tab is not hidden\n\t\t\tself.tabs.push(aboutTab)\n\t\t\t// about tab contents are conditionally determined by 1) override 2) ds using or not using cohort.\n\t\t\t// furbish an override object with default properties based on conditions if those properties are missing\n\t\t\tconst override = Object.assign({}, massNav.tabs?.about)\n\t\t\tif (appState.termdbConfig?.selectCohort) {\n\t\t\t\t// ds has cohort selection and no customization to about tab\n\t\t\t\tif (!override.top) override.top = 'COHORT'\n\t\t\t\t// do not assign \"mid\" here as it will be dynamically assigned with active cohort name\n\t\t\t} else {\n\t\t\t\t// ds doesn't use cohort selection. if mid is missing, use dslabel\n\t\t\t\tif (!override.mid) override.mid = self.pickDatasetLabel(appState)\n\t\t\t}\n\t\t\tObject.assign(aboutTab, override) // apply ds customizations\n\t\t}\n\t\tif (!massNav.tabs?.charts?.hide) {\n\t\t\t// charts tab is not hidden\n\t\t\tself.tabs.push(chartTab)\n\t\t\tObject.assign(chartTab, massNav.tabs?.charts)\n\t\t}\n\t\tif (!massNav.tabs?.groups?.hide) {\n\t\t\t// group tab is not hidden\n\t\t\tself.tabs.push(groupsTab)\n\t\t\tObject.assign(groupsTab, massNav.tabs?.groups)\n\t\t}\n\t\tif (!massNav.tabs?.filter?.hide) {\n\t\t\t// filter tab is not hidden\n\t\t\tself.tabs.push(filterTab)\n\t\t\tObject.assign(filterTab, massNav.tabs?.filter)\n\t\t}\n\t\t/** When chat is enabled for a ds, show name as \"CHAT\". When not enabled, it should show \"SEARCH\" with ONLY omnisearch functionality\n\t\t **/\n\t\tif (!massNav.tabs?.chat?.hide) {\n\t\t\tif (appState.termdbConfig?.queries?.chat) {\n\t\t\t\tconst chatTab = { top: 'CHAT', mid: '', btm: '', subheader: 'chat' }\n\t\t\t\tObject.assign(chatTab, massNav.tabs?.chat)\n\t\t\t\tchatTab.top = 'CHAT' // Copilot mentioned that Object.assign may overwrite {chat/search}.top. Therefore this line has been added.\n\t\t\t\tself.tabs.push(chatTab)\n\t\t\t} else {\n\t\t\t\tconst searchTab = { top: 'SEARCH', mid: '', btm: '', subheader: 'chat' }\n\t\t\t\tObject.assign(searchTab, massNav.tabs?.chat)\n\t\t\t\tsearchTab.top = 'SEARCH' // Copilot mentioned that Object.assign may overwrite {chat/search}.top. Therefore this line has been added.\n\t\t\t\tself.tabs.push(searchTab)\n\t\t\t}\n\t\t}\n\t\tif (!massNav.tabs?.user?.hide) {\n\t\t\t//User tab is not hidden\n\t\t\tconst override = Object.assign({}, massNav.tabs?.user)\n\t\t\tif (!override.mid) override.mid = getUserTabMid(appState.termdbConfig, appState.activeCohort)\n\t\t\tself.tabs.push(Object.assign({}, userTab, override))\n\t\t}\n\n\t\tconst table = self.dom.tabDiv\n\t\t\t.append('table')\n\t\t\t.attr('data-testid', 'sjpp-nav-tabs-table')\n\t\t\t.style('border-collapse', 'collapse')\n\t\t\t.style('height', '100%')\n\n\t\t// using a table layout for tabs, iterate through each tab\n\t\t// once for each of [top, mid, btm] row\n\t\ttable\n\t\t\t.selectAll('tr')\n\t\t\t.data(['top', 'mid', 'btm'])\n\t\t\t.enter()\n\t\t\t.append('tr')\n\t\t\t.attr('class', (d, i) => `sjpp-nav-tabs-row-${i}`)\n\t\t\t.style('font-size', (d, i) => (i == 1 ? '20px' : '12px'))\n\t\t\t.selectAll('td')\n\t\t\t.data((key: 'top' | 'mid' | 'btm', i: number) =>\n\t\t\t\tself.tabs.map((row, colNum) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\trowNum: i,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tcolNum,\n\t\t\t\t\t\tlabel: row[key],\n\t\t\t\t\t\tsubheader: row.subheader,\n\t\t\t\t\t\tdisabled: row.disabled,\n\t\t\t\t\t\tdisabledMessage: row.disabledMessage\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t\t.enter()\n\t\t\t.append('td')\n\t\t\t.attr('class', d => `sjpp-nav-tab-col-${d.colNum}`)\n\t\t\t.attr('data-testid', d => `sjpp-nav-tab-col-${d.label}`)\n\t\t\t// hide the about (e.g. cohort tab) until there is termdbConfig.selectCohort or termdbCongfig.massNav.tabs.about\n\t\t\t.style('display', 'none') // d => (d.colNum === 0 || self.activeCohort !== -1 ? '' : 'none'))\n\t\t\t.style('width', '100px')\n\t\t\t.style('padding', d => (d.rowNum === 0 ? '12px 12px 3px 12px' : '3px 12px'))\n\t\t\t.style('text-align', 'center')\n\t\t\t.style('border-left', '1px solid #ccc')\n\t\t\t.style('border-right', '1px solid #ccc')\n\t\t\t.style('color', '#aaa')\n\t\t\t.style('opacity', d => (d.disabled ? 0.5 : 1))\n\t\t\t.style('cursor', d => (d.disabled ? 'not-allowed' : 'pointer'))\n\t\t\t.attr('title', d => d.disabledMessage || '')\n\t\t\t.html(d => d.label)\n\t\t\t.on('click', (event, d) => {\n\t\t\t\tself.setTab(event, d)\n\t\t\t})\n\t\t\t.on('mouseover', (event, d) => {\n\t\t\t\tself.mouseover(event, d)\n\t\t\t})\n\t\t\t.on('mouseout', (event, d) => {\n\t\t\t\tself.mouseout(d)\n\t\t\t})\n\n\t\tself.dom.trs = table.selectAll('tr')\n\t\tself.dom.tds = table.selectAll('td')\n\t\tself.subheaderKeys = self.tabs.map(d => d.subheader)\n\t}\n\n\tself.deletePlots = () => {\n\t\tconst state = self.app.getState()\n\t\tconst subactions: any[] = []\n\t\tfor (const plot of state.plots) subactions.push({ type: 'plot_delete', id: plot.id })\n\n\t\tself.app.dispatch({ type: 'app_refresh', subactions })\n\t}\n\n\tself.updateUI = async () => {\n\t\tif (!self.dom.subheaderDiv) return\n\t\t// the session controls of the user tab do not depend on a cohort, for example to open a saved session\n\t\t// that selects one, so that tab is shown even when no cohort is selected\n\t\tconst isUserTab = self.tabs[self.activeTab]?.subheader === 'user'\n\t\tif (self.activeTab && !isUserTab && self.state.termdbConfig.selectCohort && self.activeCohort == -1) {\n\t\t\t// showing charts or filter tab; cohort selection is enabled but no cohort is selected\n\t\t\tself.dom.subheaderDiv.style('display', 'none')\n\t\t\tself.dom.messageDiv.selectAll('text').remove()\n\t\t\tself.dom.messageDiv.style('display', '').text('No cohort selected. Please select a cohort in the \"COHORT\" tab.')\n\t\t} else {\n\t\t\tif (self.dom.subheaderDiv) self.dom.subheaderDiv.style('display', self.activeTab != -1 ? 'block' : 'none')\n\t\t\tif (self.dom.messageDiv) self.dom.messageDiv.style('display', 'none')\n\t\t}\n\t\tconst selectCohort = self.state.termdbConfig.selectCohort\n\t\tconst massNav = self.state.termdbConfig.massNav\n\t\tself.dom.searchDiv.style('display', selectCohort && self.activeCohort == -1 ? 'none' : 'inline-block')\n\t\t//self.dom.holder.style('margin-bottom', self.state.nav.header_mode === 'with_tabs' ? '20px' : '')//To be checked why it was needed\n\t\tself.dom.header.style('border-bottom', self.state.nav.header_mode === 'with_tabs' ? '1px solid #000' : '')\n\t\tself.dom.tds\n\t\t\t.style('display', '')\n\t\t\t//Only show black text when the tab is active and the subheader is displayed\n\t\t\t.style('color', d => (d.colNum == self.activeTab ? activeTabTextColor : inactiveTabTextColor))\n\t\t\t.style('background-color', d =>\n\t\t\t\td.colNum == self.activeTab && self.dom.subheaderDiv.style('display') != 'none'\n\t\t\t\t\t? self.state.termdbConfig.massNav?.activeColor || activeTabBgColor\n\t\t\t\t\t: 'transparent'\n\t\t\t)\n\t\t\t.html(function (this: any, d: NavTabCell /*, i: number */) {\n\t\t\t\tif (d.key == 'top') return this.innerHTML\n\n\t\t\t\tif (d.subheader == 'groups') {\n\t\t\t\t\tif (d.key == 'mid') return self.state.groups.length || 'NONE'\n\t\t\t\t\treturn ''\n\t\t\t\t}\n\n\t\t\t\tif (d.subheader === 'charts') {\n\t\t\t\t\t// only a plot in it's own sandbox will be counted; do not separately count child plots in the same sandbox\n\t\t\t\t\tconst n = self.state.plots.filter(p => !p.parentId).length\n\t\t\t\t\tif (d.key == 'mid') return !n ? 'NONE' : n\n\t\t\t\t\telse return ''\n\t\t\t\t} else if (d.subheader === 'about') {\n\t\t\t\t\tif (self.activeCohort != -1 && self.activeCohort in self.samplecounts) {\n\t\t\t\t\t\tconst aboutMap = {\n\t\t\t\t\t\t\ttop: this.innerHTML,\n\t\t\t\t\t\t\tmid: self.activeCohortLabel,\n\t\t\t\t\t\t\tbtm: self.samplecounts[self.activeCohort]\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn aboutMap[d.key] || ''\n\t\t\t\t\t} else if (!selectCohort) {\n\t\t\t\t\t\tconst aboutMap = {\n\t\t\t\t\t\t\ttop: massNav?.tabs?.about?.top || 'ABOUT',\n\t\t\t\t\t\t\tmid: massNav?.tabs?.about?.mid || this.innerHTML,\n\t\t\t\t\t\t\tbtm: massNav?.tabs?.about?.btm || self.samplecounts[self.activeCohort]\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn aboutMap[d.key] || ''\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn d.key === 'mid' ? 'NONE' : this.innerHTML\n\t\t\t\t\t}\n\t\t\t\t} else if (d.subheader === 'filter') {\n\t\t\t\t\tconst filter = self.filterUiRoot ? self.filterUiRoot : { lst: [] }\n\t\t\t\t\tif (filter.lst.length === 0) {\n\t\t\t\t\t\t// Do not show number of samples at bottom of FILTER tab when no filter applied\n\t\t\t\t\t\treturn d.key === 'mid' ? 'NONE' : ''\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst n = self.samplecounts[self.filterJSON] != undefined ? '' + self.samplecounts[self.filterJSON] : ''\n\t\t\t\t\t\treturn d.key === 'mid' ? filter.lst.length : n\n\t\t\t\t\t}\n\t\t\t\t} else if (d.subheader === 'user' && d.key == 'btm') {\n\t\t\t\t\treturn getDaysLeft(self.app.opts.sessionDaysLeft)?.text || ' '\n\t\t\t\t} else if (d.subheader === 'user' && d.key == 'mid' && !massNav?.tabs?.user?.mid) {\n\t\t\t\t\t// the role can differ by cohort, so it follows the active cohort\n\t\t\t\t\treturn getUserTabMid(self.state.termdbConfig, self.activeCohort)\n\t\t\t\t} else {\n\t\t\t\t\treturn d.key === 'mid' ? this.innerHTML : ' '\n\t\t\t\t}\n\t\t\t})\n\n\t\t// const visibleSubheaders = []\n\t\tfor (const key in self.dom.subheader) {\n\t\t\tself.dom.subheader[key].style(\n\t\t\t\t'display',\n\t\t\t\tself.activeTab == -1 ? 'none' : self.tabs[self.activeTab].subheader === key ? 'block' : 'none'\n\t\t\t)\n\t\t}\n\n\t\tif (self.opts.header_mode === 'with_cohortHtmlSelect') {\n\t\t\tself.dom.cohortSelect.selectAll('option').property('value', self.activeCohort)\n\t\t}\n\t}\n}\n\nfunction setInteractivity(self: any): void {\n\tself.setTab = async (event: any, d: NavTabCell): Promise<void> => {\n\t\t// a disabled tab is shown to advertise the capability but cannot be activated\n\t\tif (d.disabled) return\n\t\tif (d.colNum === self.activeTab && !self.searching) {\n\t\t\t// The about tab should not be hidden on double click with or without plots\n\t\t\tif (self.activeTab == 0) return\n\t\t\tself.prevCohort = self.activeCohort\n\t\t\tawait self.updateUI()\n\n\t\t\t// if the user double-clicks on the same tab, hide the subheader\n\t\t\tself.app.dispatch({ type: 'tab_set', activeTab: -1 })\n\t\t\treturn\n\t\t}\n\t\tself.activeTab = d.colNum\n\t\tself.searching = false\n\t\tself.app.dispatch({ type: 'tab_set', activeTab: self.activeTab })\n\t\tconst chartsIdx = self.subheaderKeys.indexOf('charts')\n\t\tif (self.activeTab == chartsIdx && self.activeCohort != -1 && !self.state.plots.length) {\n\t\t\t// show dictionary or default plot in charts tab if no other\n\t\t\t// plots have been created\n\t\t\tconst defaultChartType = self.state.termdbConfig.defaultChartType || 'dictionary'\n\t\t\tself.app.dispatch({\n\t\t\t\ttype: 'plot_create',\n\t\t\t\tid: getId(),\n\t\t\t\tconfig: { chartType: defaultChartType }\n\t\t\t})\n\t\t}\n\t}\n\n\tself.mouseover = (event: any, d: NavTabCell): void => {\n\t\tconst defaultActiveColor = self.state.termdbConfig.massNav?.activeColor || activeTabBgColor\n\t\tif (d.subheader == 'user' && d.key == 'btm') self.components.user?.showDaysLeftTip(event.currentTarget)\n\t\tself.dom.tds.style('background-color', t => {\n\t\t\t//light yellow for inactive tabs and grey-yellow for this active tab\n\t\t\tif (t.colNum === d.colNum)\n\t\t\t\treturn self.activeTab == t.colNum\n\t\t\t\t\t? self.state.termdbConfig.massNav?.activeColorHover || activeTabBgColorHover\n\t\t\t\t\t: inactiveTabBgColorHover\n\t\t\treturn self.activeTab == t.colNum ? defaultActiveColor : 'transparent'\n\t\t})\n\t}\n\n\tself.mouseout = (d: NavTabCell): void => {\n\t\tif (d.subheader == 'user' && d.key == 'btm') self.components.user?.hideDaysLeftTip()\n\t\tconst defaultActiveColor = self.state.termdbConfig.massNav?.activeColor || activeTabBgColor\n\t\tself.dom.tds.style('background-color', t => (self.activeTab == t.colNum ? defaultActiveColor : 'transparent'))\n\t}\n\n\tself.pickDatasetLabel = (appState: any): string => {\n\t\tconst dslabel = appState.vocab.dslabel.toUpperCase()\n\t\treturn dslabel.length > 10 ? `${dslabel.slice(0, 10)}...` : dslabel\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["instanceNum", "d", "cf", "chr", "start", "stop", "prompt", "prompt", "userTab", "id", "appState"]
|
|
7
|
+
}
|