@sjcrh/proteinpaint-shared 2.187.0 → 2.188.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.
Files changed (117) hide show
  1. package/README.md +10 -2
  2. package/constants/AiHisto.ts +27 -0
  3. package/constants/README.md +11 -0
  4. package/devTs.ts +3 -0
  5. package/dist/constants/AiHisto.d.ts +23 -0
  6. package/dist/constants/AiHisto.js +31 -0
  7. package/dist/constants/AiHisto.js.map +7 -0
  8. package/dist/src/aiHisto.d.ts +5 -0
  9. package/dist/src/aiHisto.js +15 -0
  10. package/dist/src/aiHisto.js.map +7 -0
  11. package/dist/src/bulk.cnv.js +83 -0
  12. package/dist/src/bulk.cnv.js.map +7 -0
  13. package/dist/src/bulk.del.js +119 -0
  14. package/dist/src/bulk.del.js.map +7 -0
  15. package/dist/src/bulk.itd.js +119 -0
  16. package/dist/src/bulk.itd.js.map +7 -0
  17. package/dist/src/bulk.js +183 -0
  18. package/dist/src/bulk.js.map +7 -0
  19. package/dist/src/bulk.snv.js +175 -0
  20. package/dist/src/bulk.snv.js.map +7 -0
  21. package/dist/src/bulk.sv.js +266 -0
  22. package/dist/src/bulk.sv.js.map +7 -0
  23. package/dist/src/bulk.svjson.js +151 -0
  24. package/dist/src/bulk.svjson.js.map +7 -0
  25. package/dist/src/bulk.trunc.js +122 -0
  26. package/dist/src/bulk.trunc.js.map +7 -0
  27. package/dist/src/clustering.js +71 -0
  28. package/dist/src/clustering.js.map +7 -0
  29. package/dist/src/common.js +1302 -0
  30. package/dist/src/common.js.map +7 -0
  31. package/dist/src/compute.percentile.js +10 -0
  32. package/dist/src/compute.percentile.js.map +7 -0
  33. package/dist/src/doc.d.ts +7 -0
  34. package/dist/src/doc.js +10 -0
  35. package/dist/src/doc.js.map +7 -0
  36. package/dist/src/fetch-helpers.js +177 -0
  37. package/dist/src/fetch-helpers.js.map +7 -0
  38. package/dist/src/fileSize.js +10 -0
  39. package/dist/src/fileSize.js.map +7 -0
  40. package/dist/src/filter.d.ts +62 -0
  41. package/dist/src/filter.js +194 -0
  42. package/dist/src/filter.js.map +7 -0
  43. package/dist/src/hash.js +20 -0
  44. package/dist/src/hash.js.map +7 -0
  45. package/dist/src/helpers.js +66 -0
  46. package/dist/src/helpers.js.map +7 -0
  47. package/dist/src/index.d.ts +26 -0
  48. package/dist/src/index.js +27 -0
  49. package/dist/src/index.js.map +7 -0
  50. package/dist/src/joinUrl.d.ts +1 -0
  51. package/dist/src/joinUrl.js +17 -0
  52. package/dist/src/joinUrl.js.map +7 -0
  53. package/dist/src/mds3tk.js +64 -0
  54. package/dist/src/mds3tk.js.map +7 -0
  55. package/dist/src/roundValue.js +57 -0
  56. package/dist/src/roundValue.js.map +7 -0
  57. package/dist/src/termdb.bins.js +272 -0
  58. package/dist/src/termdb.bins.js.map +7 -0
  59. package/dist/src/termdb.initbinconfig.js +79 -0
  60. package/dist/src/termdb.initbinconfig.js.map +7 -0
  61. package/dist/src/termdb.usecase.js +239 -0
  62. package/dist/src/termdb.usecase.js.map +7 -0
  63. package/dist/src/terms.d.ts +83 -0
  64. package/dist/src/terms.js +327 -0
  65. package/dist/src/terms.js.map +7 -0
  66. package/dist/src/time.d.ts +9 -0
  67. package/dist/src/time.js +23 -0
  68. package/dist/src/time.js.map +7 -0
  69. package/dist/src/tree.js +82 -0
  70. package/dist/src/tree.js.map +7 -0
  71. package/dist/src/urljson.d.ts +8 -0
  72. package/dist/src/urljson.js +31 -0
  73. package/dist/src/urljson.js.map +7 -0
  74. package/dist/src/vcf.ann.js +56 -0
  75. package/dist/src/vcf.ann.js.map +7 -0
  76. package/dist/src/vcf.csq.js +82 -0
  77. package/dist/src/vcf.csq.js.map +7 -0
  78. package/dist/src/vcf.info.js +40 -0
  79. package/dist/src/vcf.info.js.map +7 -0
  80. package/dist/src/vcf.js +439 -0
  81. package/dist/src/vcf.js.map +7 -0
  82. package/dist/src/vcf.type.js +17 -0
  83. package/dist/src/vcf.type.js.map +7 -0
  84. package/package.json +20 -11
  85. package/src/bulk.cnv.js +0 -86
  86. package/src/bulk.del.js +0 -124
  87. package/src/bulk.itd.js +0 -123
  88. package/src/bulk.js +0 -197
  89. package/src/bulk.snv.js +0 -271
  90. package/src/bulk.sv.js +0 -276
  91. package/src/bulk.svjson.js +0 -164
  92. package/src/bulk.trunc.js +0 -132
  93. package/src/clustering.js +0 -66
  94. package/src/common.js +0 -1608
  95. package/src/compute.percentile.js +0 -11
  96. package/src/doc.js +0 -6
  97. package/src/fetch-helpers.js +0 -323
  98. package/src/fileSize.js +0 -6
  99. package/src/filter.js +0 -221
  100. package/src/hash.js +0 -21
  101. package/src/helpers.js +0 -88
  102. package/src/index.js +0 -26
  103. package/src/joinUrl.js +0 -14
  104. package/src/mds3tk.js +0 -100
  105. package/src/roundValue.js +0 -94
  106. package/src/termdb.bins.js +0 -456
  107. package/src/termdb.initbinconfig.js +0 -130
  108. package/src/termdb.usecase.js +0 -344
  109. package/src/terms.js +0 -341
  110. package/src/time.js +0 -22
  111. package/src/tree.js +0 -138
  112. package/src/urljson.js +0 -41
  113. package/src/vcf.ann.js +0 -62
  114. package/src/vcf.csq.js +0 -153
  115. package/src/vcf.info.js +0 -50
  116. package/src/vcf.js +0 -654
  117. package/src/vcf.type.js +0 -24
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/terms.ts"],
4
+ "sourcesContent": ["import type { Term } from '#types'\nimport {\n\tdtgeneexpression,\n\tdtssgsea,\n\tdtdnamethylation,\n\tdtmetaboliteintensity,\n\tdtproteomeabundance,\n\tTermTypeGroups,\n\tdtTerms\n} from './common.js'\n\n// moved TermTypeGroups to `server/src/common.js`, so now has to re-export\nexport { TermTypeGroups } from './common.js'\n\n/*\nFor datasets with multiple types of samples the ROOT_SAMPLE_TYPE is used to represent the root sample type, for example, \nthe type patient, that has one or more samples associated to it. This should be the id used as sample_type, when generating the db to identify the root samples\nin sampleidmap or the terms annotating root samples in the terms table.\nThe samples associated to a patient have annotations that are specific to a timepoint, for example, the age of the patient,\nthe doses of the drugs the patient was taking at the time of the data collection, etc. These annotations are associated to a sample.\n*/\nexport const ROOT_SAMPLE_TYPE = 1\n\n//For datasets with one sample type the DEFAULT_SAMPLE_TYPE is used to represent the sample type\nexport const DEFAULT_SAMPLE_TYPE = 2\n\nexport const NumericModes = {\n\tcontinuous: 'continuous',\n\tdiscrete: 'discrete'\n}\n\nexport const CATEGORICAL = 'categorical'\nexport const CONDITION = 'condition'\nexport const DATE = 'date'\nexport const DNA_METHYLATION = 'dnaMethylation'\nexport const FLOAT = 'float'\nexport const GENE_VARIANT = 'geneVariant'\nexport const GENE_EXPRESSION = 'geneExpression'\nexport const ISOFORM_EXPRESSION = 'isoformExpression'\nexport const INTEGER = 'integer'\nexport const METABOLITE_INTENSITY = 'metaboliteIntensity'\nexport const MULTIVALUE = 'multivalue'\nexport const SAMPLELST = 'samplelst'\nexport const SINGLECELL_CELLTYPE = 'singleCellCellType'\nexport const SINGLECELL_GENE_EXPRESSION = 'singleCellGeneExpression'\nexport const SNP = 'snp'\nexport const SNP_LIST = 'snplst'\nexport const SNP_LOCUS = 'snplocus'\nexport const SSGSEA = 'ssGSEA'\nexport const SURVIVAL = 'survival'\nexport const TERM_COLLECTION = 'termCollection'\nexport const PROTEOME_ABUNDANCE = 'proteomeAbundance'\nexport const PROTEOME_DAP = 'proteomeDAP'\n\n//Term types should be used gradually using these constants instead of hardcoding the values,\n// eg: type == CATEGORICAL instead of type == 'categorical'\nexport const TermTypes: { [key: string]: string } = {\n\tGENE_VARIANT,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tCATEGORICAL,\n\tINTEGER,\n\tFLOAT,\n\tSNP,\n\tSNP_LIST,\n\tSNP_LOCUS,\n\tCONDITION,\n\tSURVIVAL,\n\tSAMPLELST,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_CELLTYPE,\n\tSINGLECELL_GENE_EXPRESSION,\n\tMULTIVALUE,\n\tDATE,\n\tTERM_COLLECTION\n}\nexport const dtTermTypes: Set<string> = new Set(dtTerms.map((t: any) => t.type))\nfor (const dtTermType of dtTermTypes) {\n\tTermTypes[dtTermType.toUpperCase()] = dtTermType\n}\n\nexport const NUMERIC_DICTIONARY_TERM = 'numericDictTerm'\n\nexport const TermTypes2Dt = {\n\t[GENE_EXPRESSION]: dtgeneexpression,\n\t[SSGSEA]: dtssgsea,\n\t[DNA_METHYLATION]: dtdnamethylation,\n\t[METABOLITE_INTENSITY]: dtmetaboliteintensity,\n\t[PROTEOME_ABUNDANCE]: dtproteomeabundance\n}\n\n// maps term type to group (as is shown as toggles in search ui)\nexport const typeGroup = {\n\t[CATEGORICAL]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[CONDITION]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[FLOAT]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[INTEGER]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[SAMPLELST]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[SURVIVAL]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[DATE]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[MULTIVALUE]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[GENE_VARIANT]: TermTypeGroups.MUTATION_CNV_FUSION,\n\t[SNP]: TermTypeGroups.SNP,\n\t[SNP_LIST]: TermTypeGroups.SNP_LIST,\n\t[SNP_LOCUS]: TermTypeGroups.SNP_LOCUS,\n\t[GENE_EXPRESSION]: TermTypeGroups.GENE_EXPRESSION,\n\t[ISOFORM_EXPRESSION]: TermTypeGroups.ISOFORM_EXPRESSION,\n\t[SSGSEA]: TermTypeGroups.SSGSEA,\n\t[DNA_METHYLATION]: TermTypeGroups.DNA_METHYLATION,\n\t[METABOLITE_INTENSITY]: TermTypeGroups.METABOLITE_INTENSITY,\n\t[PROTEOME_ABUNDANCE]: TermTypeGroups.PROTEOME_ABUNDANCE,\n\t[TERM_COLLECTION]: TermTypeGroups.TERM_COLLECTION,\n\t[SINGLECELL_CELLTYPE]: TermTypeGroups.SINGLECELL_CELLTYPE,\n\t[SINGLECELL_GENE_EXPRESSION]: TermTypeGroups.SINGLECELL_GENE_EXPRESSION\n}\n\nconst nonDictTypes = new Set([\n\tSNP,\n\tSNP_LIST,\n\tSNP_LOCUS,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tGENE_VARIANT,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_CELLTYPE,\n\tSINGLECELL_GENE_EXPRESSION\n])\n\nfor (const dtTermType of dtTermTypes) {\n\tnonDictTypes.add(TermTypes[dtTermType.toUpperCase()])\n}\n\nexport const numericTypes = new Set([\n\tINTEGER,\n\tFLOAT,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_GENE_EXPRESSION,\n\tDATE\n])\n\n// available termdb numeric table names used as anno_<term.type>,\n// for example anno_integer, anno_float, anno_date\nexport const annoNumericTypes = new Set([INTEGER, FLOAT, DATE])\n\nconst categoricalTypes = new Set([CATEGORICAL, SNP])\n\nconst singleCellTerms = new Set([SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION])\n\nexport function isSingleCellTerm(term: any) {\n\tif (!term) return false\n\treturn singleCellTerms.has(term.type)\n}\nexport function isNumericTerm(term: Term) {\n\tif (!term) return false\n\treturn numericTypes.has(term.type)\n}\nexport function isCategoricalTerm(term: Term) {\n\tif (!term) return false\n\treturn categoricalTypes.has(term.type)\n}\n\nexport function isDictionaryType(type: string) {\n\treturn !isNonDictionaryType(type)\n}\n\nexport function isNonDictionaryType(type: string) {\n\tif (!type) throw new Error('Type is not defined')\n\treturn nonDictTypes.has(type)\n}\n\nexport function isNumTermCollection(term: Term) {\n\tif (!term || !term.type) throw new Error('Term or term type is not defined')\n\t//Enable this check when memberType is added to term collection\n\t// return term.type === TERM_COLLECTION && term.memberType == 'numeric'\n\treturn term.type === TERM_COLLECTION\n}\n\nexport function equals(t1: any, t2: any) {\n\tif (!t1) throw new Error('First term is not defined ')\n\tif (!t2) throw new Error('Second term is not defined ')\n\tif (t1.type !== t2.type) return false //term types are different\n\tif (isDictionaryType(t1.type) && isDictionaryType(t2.type) && t1.type != SAMPLELST) return t1.id === t2.id\n\tswitch (t1.type) {\n\t\tcase GENE_EXPRESSION:\n\t\t\treturn t1.gene == t2.gene\n\t\tcase ISOFORM_EXPRESSION:\n\t\t\treturn t1.isoform == t2.isoform\n\t\tcase SSGSEA:\n\t\t\treturn t1.id == t2.id\n\t\tcase DNA_METHYLATION:\n\t\t\treturn t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop\n\t\tcase METABOLITE_INTENSITY:\n\t\tcase PROTEOME_ABUNDANCE:\n\t\t\treturn t1.name == t2.name\n\t\tcase GENE_VARIANT:\n\t\t\treturn t1.gene == t2.gene || (t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop)\n\n\t\t// TO DO: Add more cases\n\t\t// case SNP_LIST:\n\t\t// case SNP_LOCUS:\n\t\t// case SAMPLELST:\n\n\t\tdefault:\n\t\t\treturn false\n\t}\n}\n\nexport function getBin(lst: any[], value: number) {\n\tlet bin = lst.findIndex(\n\t\tb => (b.startunbounded && value < b.stop) || (b.startunbounded && b.stopinclusive && value == b.stop)\n\t)\n\tif (bin == -1)\n\t\tbin = lst.findIndex(\n\t\t\tb => (b.stopunbounded && value > b.start) || (b.stopunbounded && b.startinclusive && value == b.start)\n\t\t)\n\tif (bin == -1)\n\t\tbin = lst.findIndex(\n\t\t\tb =>\n\t\t\t\t(value > b.start && value < b.stop) ||\n\t\t\t\t(b.startinclusive && value == b.start) ||\n\t\t\t\t(b.stopinclusive && value == b.stop)\n\t\t)\n\treturn bin\n}\n//Terms may have a sample type associated to them, in datasets with multiple types of samples.\n//For example the gender is associated to the patient while the age is associated to the type sample. This function is used\n//for example when calling getData or getFilter, to return either the parent or the child samples, depending on the use case.\nexport function getSampleType(term: any, ds: any) {\n\tif (!term) return null\n\t//non dict terms annotate only samples, eg: gene expression, metabolite intensity, gene variant.\n\t//Their sample type is the default sample type that may or may not have a parent type, depending on the dataset\n\tif (term.type && isNonDictionaryType(term.type)) return DEFAULT_SAMPLE_TYPE\n\t//dictionary terms may annotate different types of samples, eg: patient and sample or mouse and crop.\n\tif (term.id) return ds.cohort.termdb.term2SampleType.get(term.id)\n\tif (term.type == 'samplelst') {\n\t\tconst key = Object.keys(term.values)[0]\n\t\tconst sampleId = term.values[key].list[0]?.sampleId\n\t\tif (sampleId) return ds.sampleId2Type.get(Number(sampleId) || sampleId)\n\t\telse return DEFAULT_SAMPLE_TYPE\n\t}\n\t// samplelst or non dict terms\n\treturn DEFAULT_SAMPLE_TYPE //later own term needs to know what type annotates based on the samples\n}\n\nexport function getParentType(types: Set<string>, ds: any) {\n\tif (Object.keys(ds.cohort.termdb.sampleTypes).length == 0) return null //dataset only has one type of sample\n\tconst ids = Array.from(types)\n\tif (!ids || ids.length == 0) return null\n\tfor (const id of ids) {\n\t\tconst typeObj = ds.cohort.termdb.sampleTypes[id]\n\t\tif (!typeObj) continue\n\t\tif (typeObj.parent_id == null) return id //this is the root type\n\t\t//if my parent is in the list, then I am not the parent\n\t\tif (ids.includes(typeObj.parent_id)) continue\n\t\telse return typeObj.parent_id //my parent is not in the list, so I am the parent\n\t}\n\treturn null //no parent found\n}\n\n//Returns human readable label for each term type; label is just for printing and not computing\nconst typeMap: { [key: string]: string } = {\n\tcategorical: 'Categorical',\n\tcondition: 'Condition',\n\tfloat: 'Numerical',\n\tinteger: 'Numerical',\n\tgeneExpression: 'Gene Expression',\n\tisoformExpression: 'Isoform Expression',\n\tssGSEA: 'Geneset Expression',\n\tdnaMethylation: 'DNA Methylation',\n\tgeneVariant: 'Gene Variant',\n\tmetaboliteIntensity: 'Metabolite Intensity',\n\tproteomeAbundance: 'Proteome Abundance',\n\tproteomeDAP: 'Proteome DAP',\n\tmultivalue: 'Multi Value',\n\tsingleCellGeneExpression: 'Single Cell, Gene Expression',\n\tsingleCellCellType: 'Single Cell, Cell Type',\n\tsnplocus: 'SNP Locus',\n\tsnp: 'SNP',\n\tsnplst: 'SNP List',\n\tnumericDictTerm: 'Numeric Dictionary Term',\n\ttermCollection: 'Term Collection'\n}\n\nexport function termType2label(type: string) {\n\treturn typeMap[type] || 'Unknown term type'\n}\n\nexport function getDateFromNumber(value: number) {\n\tconst year = Math.floor(value)\n\tconst january1st = new Date(year, 0, 1)\n\tconst totalDays = getDaysInYear(year)\n\tconst time = Math.round((value - year) * totalDays) * oneDayTime\n\tconst date = new Date(january1st.getTime() + time)\n\treturn date\n}\n/*\nValue is a decimal year.\nA decimal year is a way of expressing a date or time period as a year with a decimal part, where the decimal portion \nrepresents the fraction of the year that has elapsed. \nExample:\n2025.0 represents the beginning of the year 2025. \n2025.5 represents the middle of the year 2025. \n */\nconst oneDayTime = 24 * 60 * 60 * 1000\n\nexport function getDateStrFromNumber(value: number) {\n\tconst date = getDateFromNumber(value)\n\n\t//Omit day to deidentify the patients\n\treturn date.toLocaleDateString('en-US', {\n\t\tyear: 'numeric',\n\t\tmonth: 'long'\n\t})\n}\n\n//The value returned is a decimal year\n//A decimal year is a way of expressing a date or time period as a year with a decimal part, where the decimal portion\n//represents the fraction of the year that has elapsed.\nexport function getNumberFromDateStr(str: string) {\n\tconst date = new Date(str)\n\treturn getNumberFromDate(date)\n}\n\nexport function getNumberFromDate(date: Date) {\n\tconst year = date.getFullYear()\n\tconst january1st: Date = new Date(year, 0, 1)\n\tconst diffDays = (date.getTime() - january1st.getTime()) / oneDayTime\n\tconst daysTotal = getDaysInYear(year)\n\tconst decimal = diffDays / daysTotal\n\treturn year + decimal\n}\n\nexport function getDaysInYear(year: number) {\n\tconst isLeap = new Date(year, 1, 29).getMonth() === 1\n\tconst days = isLeap ? 366 : 365\n\treturn days\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["TermTypeGroups"]
7
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Format elapsed time in milliseconds to a human-readable string
3
+ * Handles negative times (preserves sign) for defensive programming - useful when
4
+ * calculating time differences that might be in the wrong order (e.g., startTime - endTime)
5
+ * @param {number} ms - Time in milliseconds
6
+ * @param {number} [precision=2] - Number of decimal places for seconds (optional, defaults to 2)
7
+ * @returns {string} Formatted time string with units
8
+ */
9
+ export declare function formatElapsedTime(ms: number | unknown, precision?: number): string;
@@ -0,0 +1,23 @@
1
+ function formatElapsedTime(ms, precision = 2) {
2
+ if (typeof ms !== "number" || isNaN(ms)) {
3
+ return typeof ms !== "number" ? "Invalid time: not a number" : "Invalid time: NaN";
4
+ }
5
+ if (!isFinite(ms)) {
6
+ return ms > 0 ? "Infinite time" : "-Infinite time";
7
+ }
8
+ const absMs = Math.abs(ms);
9
+ const sign = ms < 0 ? "-" : "";
10
+ if (absMs < 1e3) {
11
+ return `${sign}${absMs}ms`;
12
+ }
13
+ if (absMs < 6e4) {
14
+ return `${sign}${(absMs / 1e3).toFixed(precision)}s`;
15
+ }
16
+ const minutes = Math.floor(absMs / 6e4);
17
+ const seconds = (absMs % 6e4 / 1e3).toFixed(precision);
18
+ return `${sign}${minutes}m ${seconds}s`;
19
+ }
20
+ export {
21
+ formatElapsedTime
22
+ };
23
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/time.ts"],
4
+ "sourcesContent": ["/**\n * Format elapsed time in milliseconds to a human-readable string\n * Handles negative times (preserves sign) for defensive programming - useful when\n * calculating time differences that might be in the wrong order (e.g., startTime - endTime)\n * @param {number} ms - Time in milliseconds\n * @param {number} [precision=2] - Number of decimal places for seconds (optional, defaults to 2)\n * @returns {string} Formatted time string with units\n */\nexport function formatElapsedTime(ms: number | unknown, precision: number = 2): string {\n\t// Handle all invalid cases\n\tif (typeof ms !== 'number' || isNaN(ms)) {\n\t\treturn typeof ms !== 'number' ? 'Invalid time: not a number' : 'Invalid time: NaN'\n\t}\n\tif (!isFinite(ms)) {\n\t\treturn ms > 0 ? 'Infinite time' : '-Infinite time'\n\t}\n\n\t// This additional logic is for handling negative times and preserving the sign in the output\n\tconst absMs = Math.abs(ms)\n\tconst sign = ms < 0 ? '-' : ''\n\n\tif (absMs < 1e3) {\n\t\treturn `${sign}${absMs}ms`\n\t}\n\tif (absMs < 6e4) {\n\t\treturn `${sign}${(absMs / 1e3).toFixed(precision)}s`\n\t}\n\tconst minutes = Math.floor(absMs / 6e4)\n\tconst seconds = ((absMs % 6e4) / 1e3).toFixed(precision)\n\treturn `${sign}${minutes}m ${seconds}s`\n}\n"],
5
+ "mappings": "AAQO,SAAS,kBAAkB,IAAsB,YAAoB,GAAW;AAEtF,MAAI,OAAO,OAAO,YAAY,MAAM,EAAE,GAAG;AACxC,WAAO,OAAO,OAAO,WAAW,+BAA+B;AAAA,EAChE;AACA,MAAI,CAAC,SAAS,EAAE,GAAG;AAClB,WAAO,KAAK,IAAI,kBAAkB;AAAA,EACnC;AAGA,QAAM,QAAQ,KAAK,IAAI,EAAE;AACzB,QAAM,OAAO,KAAK,IAAI,MAAM;AAE5B,MAAI,QAAQ,KAAK;AAChB,WAAO,GAAG,IAAI,GAAG,KAAK;AAAA,EACvB;AACA,MAAI,QAAQ,KAAK;AAChB,WAAO,GAAG,IAAI,IAAI,QAAQ,KAAK,QAAQ,SAAS,CAAC;AAAA,EAClD;AACA,QAAM,UAAU,KAAK,MAAM,QAAQ,GAAG;AACtC,QAAM,WAAY,QAAQ,MAAO,KAAK,QAAQ,SAAS;AACvD,SAAO,GAAG,IAAI,GAAG,OAAO,KAAK,OAAO;AACrC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,82 @@
1
+ const hardcode_root = "root";
2
+ const hierarchy_spacer = "...";
3
+ function stratinput(lst, levels) {
4
+ const lp = /* @__PURE__ */ Object.create(null);
5
+ const nodes = /* @__PURE__ */ Object.create(null);
6
+ const size = /* @__PURE__ */ Object.create(null);
7
+ for (const m of lst) {
8
+ for (const [i, lev] of levels.entries()) {
9
+ const thisv = getkey(m, i, levels);
10
+ const pav = getkey(m, i - 1, levels);
11
+ if (!m[lev.k]) {
12
+ if (i > 0) {
13
+ size[pav] += 1;
14
+ }
15
+ break;
16
+ }
17
+ lp[thisv] = pav;
18
+ if (!(thisv in size)) {
19
+ size[thisv] = 0;
20
+ }
21
+ if (!(thisv in nodes)) {
22
+ const n = {
23
+ lst: []
24
+ };
25
+ if (lev.full) {
26
+ n.full = m[lev.full];
27
+ }
28
+ n.id0 = levels[0].k;
29
+ n.v0 = m[levels[0].k];
30
+ if (i == 1) {
31
+ n.id1 = levels[1].k;
32
+ n.v1 = m[levels[1].k];
33
+ }
34
+ if (i == 2) {
35
+ n.id2 = levels[2].k;
36
+ n.v1 = m[levels[2].k];
37
+ }
38
+ nodes[thisv] = n;
39
+ }
40
+ nodes[thisv].lst.push(m);
41
+ if (i == levels.length - 1) {
42
+ size[thisv] += 1;
43
+ }
44
+ }
45
+ }
46
+ const nlst = [{ id: hardcode_root, name: hardcode_root }];
47
+ for (const chid in lp) {
48
+ const paid = lp[chid];
49
+ const n = nodes[chid];
50
+ const fields = chid.split(hierarchy_spacer);
51
+ nlst.push({
52
+ id: chid,
53
+ parentId: paid,
54
+ lst: n.lst,
55
+ value: size[chid],
56
+ name: fields[fields.length - 1],
57
+ // show this instead of chid
58
+ full: n.full,
59
+ id0: n.id0,
60
+ v0: n.v0,
61
+ id1: n.id1,
62
+ v1: n.v1,
63
+ id2: n.id2,
64
+ v2: n.v2
65
+ });
66
+ }
67
+ return nlst;
68
+ }
69
+ function getkey(m, i, levels) {
70
+ const klst = [hardcode_root];
71
+ for (let j = 0; j < i; j++) {
72
+ klst.push(m[levels[j].k]);
73
+ }
74
+ if (i >= 0) {
75
+ klst.push(m[levels[i].k]);
76
+ }
77
+ return klst.join(hierarchy_spacer);
78
+ }
79
+ export {
80
+ stratinput
81
+ };
82
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/tree.js"],
4
+ "sourcesContent": ["/*\ninput:\n1. list of leaf nodes, e.g. mutation cases, each with a set of key-value pairs\n2. levels of hierarchy in an ordered list\n each item: { k, full }\n \"k\" and \"full\" are two attribute keys\n\noutput:\na list of items, as input for d3-hierarchy.stratify\none item for each child-parent relationship in the hierarchy\n{\n\tid:\n\tparentId:\n\tlst:\n\tvalue:\n\tname:\n\tfull:\n\tid0:\n\tv0:\n\tid1:\n\tv1:\n\tid2:\n\tv2:\n}\n\nstrange issue: https://github.com/stjude/proteinpaint/commit/c36004d47d4374d2ade719c6ef9e2b848f0850dc\nusing Map for lp, nodes etc will cause memory issue, thus the use of simple objects\n\nto-do: verify this works after a reorg\n*/\n\nconst hardcode_root = 'root'\nconst hierarchy_spacer = '...'\n\nexport function stratinput(lst, levels) {\n\tconst lp = Object.create(null)\n\t// leaf to parent\n\t// k: HM...BALL...sub\n\t// v: HM...BALL\n\n\tconst nodes = Object.create(null)\n\t/*\n\tk: string id of node, e.g. HM...BALL\n\tv: node\n\t\t.full\n\t\t.lst[]\n\t\t\titems from input\n\t*/\n\n\tconst size = Object.create(null)\n\t// only increment size to leaf nodes, so that root.sum() will work\n\t// k: string id of a node, e.g. HM...BALL\n\t// v: number of items\n\n\tfor (const m of lst) {\n\t\tfor (const [i, lev] of levels.entries()) {\n\t\t\tconst thisv = getkey(m, i, levels)\n\t\t\tconst pav = getkey(m, i - 1, levels)\n\n\t\t\t// as mutations can come as {\"subtype\":\"\"}\n\t\t\t// in the sunburst chart at the subtype level, this mutation should not be counted\n\t\t\t// thus the test with !m[lev.k] rather than !(lev.k in m)\n\t\t\tif (!m[lev.k]) {\n\t\t\t\t// stop at this level\n\t\t\t\t// add count to prev level\n\t\t\t\tif (i > 0) {\n\t\t\t\t\tsize[pav] += 1\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tlp[thisv] = pav\n\t\t\tif (!(thisv in size)) {\n\t\t\t\tsize[thisv] = 0\n\t\t\t}\n\t\t\tif (!(thisv in nodes)) {\n\t\t\t\tconst n = {\n\t\t\t\t\tlst: []\n\t\t\t\t}\n\t\t\t\tif (lev.full) {\n\t\t\t\t\tn.full = m[lev.full]\n\t\t\t\t}\n\n\t\t\t\tn.id0 = levels[0].k\n\t\t\t\tn.v0 = m[levels[0].k]\n\t\t\t\tif (i == 1) {\n\t\t\t\t\tn.id1 = levels[1].k\n\t\t\t\t\tn.v1 = m[levels[1].k]\n\t\t\t\t}\n\t\t\t\tif (i == 2) {\n\t\t\t\t\tn.id2 = levels[2].k\n\t\t\t\t\tn.v1 = m[levels[2].k]\n\t\t\t\t}\n\n\t\t\t\tnodes[thisv] = n\n\t\t\t}\n\t\t\tnodes[thisv].lst.push(m)\n\t\t\tif (i == levels.length - 1) {\n\t\t\t\tsize[thisv] += 1\n\t\t\t}\n\t\t}\n\t}\n\n\tconst nlst = [{ id: hardcode_root, name: hardcode_root }]\n\n\tfor (const chid in lp) {\n\t\tconst paid = lp[chid]\n\t\tconst n = nodes[chid]\n\t\tconst fields = chid.split(hierarchy_spacer)\n\t\tnlst.push({\n\t\t\tid: chid,\n\t\t\tparentId: paid,\n\t\t\tlst: n.lst,\n\t\t\tvalue: size[chid],\n\t\t\tname: fields[fields.length - 1], // show this instead of chid\n\t\t\tfull: n.full,\n\t\t\tid0: n.id0,\n\t\t\tv0: n.v0,\n\t\t\tid1: n.id1,\n\t\t\tv1: n.v1,\n\t\t\tid2: n.id2,\n\t\t\tv2: n.v2\n\t\t})\n\t}\n\treturn nlst\n}\n\nfunction getkey(m, i, levels) {\n\t// if i is 0, return 'root'\n\tconst klst = [hardcode_root]\n\tfor (let j = 0; j < i; j++) {\n\t\tklst.push(m[levels[j].k])\n\t}\n\tif (i >= 0) {\n\t\tklst.push(m[levels[i].k])\n\t}\n\treturn klst.join(hierarchy_spacer)\n}\n"],
5
+ "mappings": "AA+BA,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;AAElB,SAAS,WAAW,KAAK,QAAQ;AACvC,QAAM,KAAK,uBAAO,OAAO,IAAI;AAK7B,QAAM,QAAQ,uBAAO,OAAO,IAAI;AAShC,QAAM,OAAO,uBAAO,OAAO,IAAI;AAK/B,aAAW,KAAK,KAAK;AACpB,eAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,GAAG;AACxC,YAAM,QAAQ,OAAO,GAAG,GAAG,MAAM;AACjC,YAAM,MAAM,OAAO,GAAG,IAAI,GAAG,MAAM;AAKnC,UAAI,CAAC,EAAE,IAAI,CAAC,GAAG;AAGd,YAAI,IAAI,GAAG;AACV,eAAK,GAAG,KAAK;AAAA,QACd;AACA;AAAA,MACD;AAEA,SAAG,KAAK,IAAI;AACZ,UAAI,EAAE,SAAS,OAAO;AACrB,aAAK,KAAK,IAAI;AAAA,MACf;AACA,UAAI,EAAE,SAAS,QAAQ;AACtB,cAAM,IAAI;AAAA,UACT,KAAK,CAAC;AAAA,QACP;AACA,YAAI,IAAI,MAAM;AACb,YAAE,OAAO,EAAE,IAAI,IAAI;AAAA,QACpB;AAEA,UAAE,MAAM,OAAO,CAAC,EAAE;AAClB,UAAE,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;AACpB,YAAI,KAAK,GAAG;AACX,YAAE,MAAM,OAAO,CAAC,EAAE;AAClB,YAAE,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;AAAA,QACrB;AACA,YAAI,KAAK,GAAG;AACX,YAAE,MAAM,OAAO,CAAC,EAAE;AAClB,YAAE,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;AAAA,QACrB;AAEA,cAAM,KAAK,IAAI;AAAA,MAChB;AACA,YAAM,KAAK,EAAE,IAAI,KAAK,CAAC;AACvB,UAAI,KAAK,OAAO,SAAS,GAAG;AAC3B,aAAK,KAAK,KAAK;AAAA,MAChB;AAAA,IACD;AAAA,EACD;AAEA,QAAM,OAAO,CAAC,EAAE,IAAI,eAAe,MAAM,cAAc,CAAC;AAExD,aAAW,QAAQ,IAAI;AACtB,UAAM,OAAO,GAAG,IAAI;AACpB,UAAM,IAAI,MAAM,IAAI;AACpB,UAAM,SAAS,KAAK,MAAM,gBAAgB;AAC1C,SAAK,KAAK;AAAA,MACT,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,KAAK,EAAE;AAAA,MACP,OAAO,KAAK,IAAI;AAAA,MAChB,MAAM,OAAO,OAAO,SAAS,CAAC;AAAA;AAAA,MAC9B,MAAM,EAAE;AAAA,MACR,KAAK,EAAE;AAAA,MACP,IAAI,EAAE;AAAA,MACN,KAAK,EAAE;AAAA,MACP,IAAI,EAAE;AAAA,MACN,KAAK,EAAE;AAAA,MACP,IAAI,EAAE;AAAA,IACP,CAAC;AAAA,EACF;AACA,SAAO;AACR;AAEA,SAAS,OAAO,GAAG,GAAG,QAAQ;AAE7B,QAAM,OAAO,CAAC,aAAa;AAC3B,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,SAAK,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,EACzB;AACA,MAAI,KAAK,GAAG;AACX,SAAK,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,EACzB;AACA,SAAO,KAAK,KAAK,gBAAgB;AAClC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,8 @@
1
+ export type UrlJsonRaw = {
2
+ [key: string]: any;
3
+ };
4
+ export type UrlJsonEncoded = {
5
+ [key: string]: string;
6
+ };
7
+ export declare function encode(rawObject: UrlJsonRaw): string;
8
+ export declare function decode(query: UrlJsonEncoded): UrlJsonEncoded;
@@ -0,0 +1,31 @@
1
+ import { isNumeric } from "./helpers.js";
2
+ const reserved = ["false", "true", "null", "undefined"];
3
+ const delimiters = ['"', "{", "["];
4
+ function encode(rawObject) {
5
+ const params = [];
6
+ for (const [key, value] of Object.entries(rawObject)) {
7
+ if (typeof value == "string" && !isNumeric(value) && !reserved.includes(value) && !delimiters.includes(value[0])) {
8
+ params.push(`${key}=${encodeURIComponent(value)}`);
9
+ } else if (value !== void 0) {
10
+ params.push(`${key}=${encodeURIComponent(JSON.stringify(value))}`);
11
+ }
12
+ }
13
+ return params.join("&");
14
+ }
15
+ function decode(query) {
16
+ const encoding = query.encoding;
17
+ for (const [key, value] of Object.entries(query)) {
18
+ if (encoding == "json" || value == "null" || // not new, always been
19
+ value == "true" || // NEED TO FIND-REPLACE CODE THAT USES value == 'true'
20
+ value == "false" || // NEED TO FIND-REPLACE CODE THAT USES value == 'false'
21
+ isNumeric(value) || // NEED TO check
22
+ typeof value == "string" && value.startsWith('"') && value.endsWith('"') || typeof value == "string" && value.startsWith("{") && value.endsWith("}") || typeof value == "string" && value.startsWith("[") && value.endsWith("]"))
23
+ query[key] = JSON.parse(value);
24
+ }
25
+ return query;
26
+ }
27
+ export {
28
+ decode,
29
+ encode
30
+ };
31
+ //# sourceMappingURL=urljson.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/urljson.ts"],
4
+ "sourcesContent": ["import { isNumeric } from './helpers.js'\n\n/*\n\tA custom encoder-decoder for URL query parameter values\n\n\tAll values are strings except for the following, which\n\twill are assumed to be json-encoded:\n\n\t- those that correspond to JSON reserved keywords: true, false, null\n\t- numeric values using the isNumeric() function below\n\t- values that are wrapped by \"\", {}, []\n\n\tIn addition, a URL-payload that includes an `encoding=urljson` parameter\n\twill cause all query parameter values to be processed by the decode()\n\tfunction below. This is not required, but may help remove ambiguity, especially\n\tto distinguish urljson-encoded params vs legacy URL params that have \n\tbeen manually coded in a way that doesn't conform to the expectations here.\n\n\tWhy not just encode every URL query parameter value as JSON?\n\n\t- That makes the URL harder to read, since more encoding characters have to\n\t\tbe URI (percent) encoded. In contrast, since most values are strings or numbers,\n\t the encoder below leaves those values alone for better readability of the URL. For\n\t example, unambiguous strings would not have to be wrapped with double-quotes\n\t that are then URI encoded.\n\n\t- The decoder will always accept and correctly process values that are JSON-encoded.\n\t So the encoding exceptions above do not prevent harder-to-read JSON-encoded string\n\t values. \n*/\n\n// a URL query parameters object with values to be encoded\nexport type UrlJsonRaw = {\n\t[key: string]: any //boolean | string | number | any[] | null | undefined //| { [key: string]: any }\n}\n\n// a URL query parameters object with values to be decoded\nexport type UrlJsonEncoded = {\n\t[key: string]: string\n}\n\nconst reserved = ['false', 'true', 'null', 'undefined']\nconst delimiters = ['\"', '{', '[']\n\nexport function encode(rawObject: UrlJsonRaw) {\n\tconst params: any[] = []\n\tfor (const [key, value] of Object.entries(rawObject)) {\n\t\tif (typeof value == 'string' && !isNumeric(value) && !reserved.includes(value) && !delimiters.includes(value[0])) {\n\t\t\t// no need to json-encode a string before percent encoding\n\t\t\t// if it doesn't contain reserved JSON keywords/wrapper characters\n\t\t\tparams.push(`${key}=${encodeURIComponent(value)}`)\n\t\t} else if (value !== undefined) {\n\t\t\tparams.push(`${key}=${encodeURIComponent(JSON.stringify(value))}`)\n\t\t}\n\t}\n\treturn params.join('&')\n}\n\nexport function decode(query: UrlJsonEncoded) {\n\tconst encoding = query.encoding\n\tfor (const [key, value] of Object.entries(query)) {\n\t\t//const value = query[key]\n\t\t// if (value == 'undefined') {\n\t\t// \t// maybe better to also detect this common error\n\t\t// \tconsole.warn(`${key}=\"undefined\" value as a string URL query parameter`)\n\t\t// \tquery[key] = undefined\n\t\t// \tcontinue\n\t\t// }\n\t\tif (\n\t\t\tencoding == 'json' ||\n\t\t\tvalue == 'null' || // not new, always been\n\t\t\tvalue == 'true' || // NEED TO FIND-REPLACE CODE THAT USES value == 'true'\n\t\t\tvalue == 'false' || // NEED TO FIND-REPLACE CODE THAT USES value == 'false'\n\t\t\tisNumeric(value) || // NEED TO check\n\t\t\t(typeof value == 'string' && value.startsWith('\"') && value.endsWith('\"')) ||\n\t\t\t(typeof value == 'string' && value.startsWith('{') && value.endsWith('}')) ||\n\t\t\t(typeof value == 'string' && value.startsWith('[') && value.endsWith(']'))\n\t\t)\n\t\t\tquery[key] = JSON.parse(value)\n\t\t// else the value is already a string\n\t}\n\treturn query\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAyC1B,MAAM,WAAW,CAAC,SAAS,QAAQ,QAAQ,WAAW;AACtD,MAAM,aAAa,CAAC,KAAK,KAAK,GAAG;AAE1B,SAAS,OAAO,WAAuB;AAC7C,QAAM,SAAgB,CAAC;AACvB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AACrD,QAAI,OAAO,SAAS,YAAY,CAAC,UAAU,KAAK,KAAK,CAAC,SAAS,SAAS,KAAK,KAAK,CAAC,WAAW,SAAS,MAAM,CAAC,CAAC,GAAG;AAGjH,aAAO,KAAK,GAAG,GAAG,IAAI,mBAAmB,KAAK,CAAC,EAAE;AAAA,IAClD,WAAW,UAAU,QAAW;AAC/B,aAAO,KAAK,GAAG,GAAG,IAAI,mBAAmB,KAAK,UAAU,KAAK,CAAC,CAAC,EAAE;AAAA,IAClE;AAAA,EACD;AACA,SAAO,OAAO,KAAK,GAAG;AACvB;AAEO,SAAS,OAAO,OAAuB;AAC7C,QAAM,WAAW,MAAM;AACvB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAQjD,QACC,YAAY,UACZ,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU,KAAK;AAAA,IACd,OAAO,SAAS,YAAY,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KACvE,OAAO,SAAS,YAAY,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KACvE,OAAO,SAAS,YAAY,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG;AAExE,YAAM,GAAG,IAAI,KAAK,MAAM,KAAK;AAAA,EAE/B;AACA,SAAO;AACR;",
6
+ "names": []
7
+ }
@@ -0,0 +1,56 @@
1
+ import { vepinfo } from "./common.js";
2
+ function parse_ANN(str, header, m) {
3
+ if (!header) {
4
+ return null;
5
+ }
6
+ for (const thisannotation of str.split(",")) {
7
+ const lst = thisannotation.replace(/&/g, ",").split("|");
8
+ const o = {};
9
+ for (let i = 0; i < header.length; i++) {
10
+ if (lst[i]) {
11
+ o[header[i].name] = lst[i];
12
+ }
13
+ }
14
+ if (!o.Allele) {
15
+ continue;
16
+ }
17
+ let allele = null;
18
+ for (const a of m.alleles) {
19
+ if (a.allele == o.Allele) {
20
+ allele = a;
21
+ break;
22
+ }
23
+ }
24
+ if (!allele) {
25
+ continue;
26
+ }
27
+ if (!allele.ann) {
28
+ allele.ann = [];
29
+ }
30
+ allele.ann.push(o);
31
+ o._gene = o.Gene_Name;
32
+ if (o.Feature_Type && o.Feature_Type == "transcript" && o.Feature_ID) {
33
+ o._isoform = o.Feature_ID.split(".")[0];
34
+ }
35
+ if (o.Annotation) {
36
+ const [dt, cls, rank] = vepinfo(o.Annotation);
37
+ o._dt = dt;
38
+ o._class = cls;
39
+ o._csqrank = rank;
40
+ } else {
41
+ o._dt = dtsnvindel;
42
+ o._class = mclassnonstandard;
43
+ }
44
+ if (o["HGVS.p"]) {
45
+ o._mname = o["HGVS.p"];
46
+ } else if (o["HGVS.c"]) {
47
+ o._mname = o["HGVS.c"];
48
+ } else {
49
+ }
50
+ }
51
+ return true;
52
+ }
53
+ export {
54
+ parse_ANN
55
+ };
56
+ //# sourceMappingURL=vcf.ann.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/vcf.ann.js"],
4
+ "sourcesContent": ["import { vepinfo } from './common.js'\n\nexport function parse_ANN(str, header, m) {\n\t// snpEff\n\tif (!header) {\n\t\treturn null\n\t}\n\tfor (const thisannotation of str.split(',')) {\n\t\tconst lst = thisannotation.replace(/&/g, ',').split('|')\n\n\t\tconst o = {}\n\n\t\tfor (let i = 0; i < header.length; i++) {\n\t\t\tif (lst[i]) {\n\t\t\t\to[header[i].name] = lst[i]\n\t\t\t}\n\t\t}\n\t\tif (!o.Allele) {\n\t\t\tcontinue\n\t\t}\n\t\tlet allele = null\n\t\tfor (const a of m.alleles) {\n\t\t\tif (a.allele == o.Allele) {\n\t\t\t\tallele = a\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (!allele) {\n\t\t\t// cannot match to allele!!!\n\t\t\tcontinue\n\t\t}\n\t\tif (!allele.ann) {\n\t\t\tallele.ann = []\n\t\t}\n\t\tallele.ann.push(o)\n\t\to._gene = o.Gene_Name\n\t\t// isoform\n\t\tif (o.Feature_Type && o.Feature_Type == 'transcript' && o.Feature_ID) {\n\t\t\to._isoform = o.Feature_ID.split('.')[0]\n\t\t}\n\t\t// class\n\t\tif (o.Annotation) {\n\t\t\tconst [dt, cls, rank] = vepinfo(o.Annotation)\n\t\t\to._dt = dt\n\t\t\to._class = cls\n\t\t\to._csqrank = rank\n\t\t} else {\n\t\t\t// FIXME\n\t\t\to._dt = dtsnvindel\n\t\t\to._class = mclassnonstandard\n\t\t}\n\t\t// mname\n\t\tif (o['HGVS.p']) {\n\t\t\t//o._mname=decodeURIComponent(o.HGVSp.substr(o.HGVSp.indexOf(':')+1))\n\t\t\to._mname = o['HGVS.p']\n\t\t} else if (o['HGVS.c']) {\n\t\t\to._mname = o['HGVS.c']\n\t\t} else {\n\t\t}\n\t}\n\treturn true\n}\n"],
5
+ "mappings": "AAAA,SAAS,eAAe;AAEjB,SAAS,UAAU,KAAK,QAAQ,GAAG;AAEzC,MAAI,CAAC,QAAQ;AACZ,WAAO;AAAA,EACR;AACA,aAAW,kBAAkB,IAAI,MAAM,GAAG,GAAG;AAC5C,UAAM,MAAM,eAAe,QAAQ,MAAM,GAAG,EAAE,MAAM,GAAG;AAEvD,UAAM,IAAI,CAAC;AAEX,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACvC,UAAI,IAAI,CAAC,GAAG;AACX,UAAE,OAAO,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;AAAA,MAC1B;AAAA,IACD;AACA,QAAI,CAAC,EAAE,QAAQ;AACd;AAAA,IACD;AACA,QAAI,SAAS;AACb,eAAW,KAAK,EAAE,SAAS;AAC1B,UAAI,EAAE,UAAU,EAAE,QAAQ;AACzB,iBAAS;AACT;AAAA,MACD;AAAA,IACD;AACA,QAAI,CAAC,QAAQ;AAEZ;AAAA,IACD;AACA,QAAI,CAAC,OAAO,KAAK;AAChB,aAAO,MAAM,CAAC;AAAA,IACf;AACA,WAAO,IAAI,KAAK,CAAC;AACjB,MAAE,QAAQ,EAAE;AAEZ,QAAI,EAAE,gBAAgB,EAAE,gBAAgB,gBAAgB,EAAE,YAAY;AACrE,QAAE,WAAW,EAAE,WAAW,MAAM,GAAG,EAAE,CAAC;AAAA,IACvC;AAEA,QAAI,EAAE,YAAY;AACjB,YAAM,CAAC,IAAI,KAAK,IAAI,IAAI,QAAQ,EAAE,UAAU;AAC5C,QAAE,MAAM;AACR,QAAE,SAAS;AACX,QAAE,WAAW;AAAA,IACd,OAAO;AAEN,QAAE,MAAM;AACR,QAAE,SAAS;AAAA,IACZ;AAEA,QAAI,EAAE,QAAQ,GAAG;AAEhB,QAAE,SAAS,EAAE,QAAQ;AAAA,IACtB,WAAW,EAAE,QAAQ,GAAG;AACvB,QAAE,SAAS,EAAE,QAAQ;AAAA,IACtB,OAAO;AAAA,IACP;AAAA,EACD;AACA,SAAO;AACR;",
6
+ "names": []
7
+ }
@@ -0,0 +1,82 @@
1
+ import { vepinfo } from "./common.js";
2
+ function parse_CSQ(str, header, m) {
3
+ if (!header) {
4
+ return null;
5
+ }
6
+ for (const thisannotation of str.split(",")) {
7
+ const lst = thisannotation.replace(/&/g, ",").split("|");
8
+ const o = {};
9
+ for (let i = 0; i < header.length; i++) {
10
+ if (lst[i]) {
11
+ o[header[i].name] = lst[i];
12
+ }
13
+ }
14
+ if (!o.Allele) {
15
+ continue;
16
+ }
17
+ let allele = null;
18
+ for (const a of m.mlst || m.alleles) {
19
+ if (a.allele_original == o.Allele) {
20
+ allele = a;
21
+ break;
22
+ }
23
+ }
24
+ if (!allele) {
25
+ if (o.Allele == "-") {
26
+ if (m.mlst) {
27
+ if (m.mlst.length == 1) {
28
+ allele = m.mlst[0];
29
+ }
30
+ } else if (m.alleles) {
31
+ if (m.alleles.length == 1) {
32
+ allele = m.alleles[0];
33
+ }
34
+ }
35
+ } else {
36
+ for (const a of m.mlst || m.alleles) {
37
+ if (a.allele_original.substr(1) == o.Allele) {
38
+ allele = a;
39
+ break;
40
+ }
41
+ }
42
+ }
43
+ if (!allele) {
44
+ continue;
45
+ }
46
+ }
47
+ if (!allele.csq) {
48
+ allele.csq = [];
49
+ }
50
+ allele.csq.push(o);
51
+ o._gene = o.SYMBOL || o.Gene;
52
+ if (o.Feature_type && o.Feature_type == "Transcript") {
53
+ o._isoform = o.Feature.split(".")[0];
54
+ } else {
55
+ o._isoform = o._gene;
56
+ }
57
+ if (o.Consequence) {
58
+ const [dt, cls, rank] = vepinfo(o.Consequence);
59
+ o._dt = dt;
60
+ o._class = cls;
61
+ o._csqrank = rank;
62
+ } else {
63
+ o._dt = dtsnvindel;
64
+ o._class = mclassnonstandard;
65
+ }
66
+ if (o.HGVSp) {
67
+ o._mname = decodeURIComponent(o.HGVSp.substr(o.HGVSp.indexOf(":") + 1));
68
+ } else if (o.Protein_position && o.Amino_acids) {
69
+ o._mname = decodeURIComponent(o.Protein_position + o.Amino_acids);
70
+ } else if (o.HGVSc) {
71
+ o._mname = o.HGVSc.substr(o.HGVSc.indexOf(":") + 1);
72
+ } else if (o.Existing_variation) {
73
+ o._name = o.Existing_variation;
74
+ } else {
75
+ }
76
+ }
77
+ return true;
78
+ }
79
+ export {
80
+ parse_CSQ
81
+ };
82
+ //# sourceMappingURL=vcf.csq.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/vcf.csq.js"],
4
+ "sourcesContent": ["import { vepinfo } from './common.js'\n/*\nparse csq field from a variant line, not header\nCSQ header must have already been parsed\n\nstr: the csq value for a vcf line\nheader: [ // something like this\n { name: 'Allele' },\n { name: 'Consequence' },\n { name: 'IMPACT' },\n { name: 'SYMBOL' },\n { name: 'Gene' },\n { name: 'Feature_type' },\n { name: 'Feature' },\n { name: 'BIOTYPE' },\n { name: 'EXON' },\n { name: 'INTRON' },\n { name: 'HGVSc' },\n { name: 'HGVSp' },\n { name: 'cDNA_position' },\n { name: 'CDS_position' },\n { name: 'Protein_position' },\n { name: 'Amino_acids' },\n { name: 'Codons' },\n { name: 'Existing_variation' },\n { name: 'DISTANCE' },\n { name: 'STRAND' },\n { name: 'FLAGS' },\n { name: 'SYMBOL_SOURCE' },\n { name: 'HGNC_ID' },\n { name: 'CANONICAL' },\n { name: 'REFSEQ_MATCH' },\n { name: 'GIVEN_REF' },\n { name: 'USED_REF' },\n { name: 'BAM_EDIT' },\n { name: 'HGVS_OFFSET' },\n { name: 'CLIN_SIG' },\n { name: 'SOMATIC' },\n { name: 'PHENO' }\n]\n\nm: {\n\tmlst[ {} ]\n\t\t.allele_original\n\t\t.csq[ {} ] // parse_CSQ will add this array to this allele\n\t\t\t._class\n\t\t\t._csqrank\n\t\t\t._dt\n\t\t\t._gene\n\t\t\t._isoform\n\t\t\t._mname\n}\n\n*/\n\nexport function parse_CSQ(str, header, m) {\n\tif (!header) {\n\t\treturn null\n\t}\n\tfor (const thisannotation of str.split(',')) {\n\t\tconst lst = thisannotation.replace(/&/g, ',').split('|')\n\n\t\tconst o = {}\n\n\t\tfor (let i = 0; i < header.length; i++) {\n\t\t\tif (lst[i]) {\n\t\t\t\to[header[i].name] = lst[i]\n\t\t\t}\n\t\t}\n\t\tif (!o.Allele) {\n\t\t\tcontinue\n\t\t}\n\t\tlet allele = null\n\n\t\t//////////////////////////////////////\n\t\t// NOTE\n\t\t// mds2delete\n\t\t// m.alleles[] is based on old vcf parsing and may delete?\n\t\t// latest spec is m.mlst[]\n\t\t//////////////////////////////////////\n\n\t\tfor (const a of m.mlst || m.alleles) {\n\t\t\tif (a.allele_original == o.Allele) {\n\t\t\t\tallele = a\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (!allele) {\n\t\t\tif (o.Allele == '-') {\n\t\t\t\t// deletion\n\t\t\t\tif (m.mlst) {\n\t\t\t\t\tif (m.mlst.length == 1) {\n\t\t\t\t\t\tallele = m.mlst[0]\n\t\t\t\t\t}\n\t\t\t\t} else if (m.alleles) {\n\t\t\t\t\tif (m.alleles.length == 1) {\n\t\t\t\t\t\tallele = m.alleles[0]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const a of m.mlst || m.alleles) {\n\t\t\t\t\tif (a.allele_original.substr(1) == o.Allele) {\n\t\t\t\t\t\t// insertion, without first padding base\n\t\t\t\t\t\tallele = a\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!allele) {\n\t\t\t\t// cannot match to allele!!!\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif (!allele.csq) {\n\t\t\tallele.csq = []\n\t\t}\n\t\tallele.csq.push(o)\n\n\t\t// gene\n\t\to._gene = o.SYMBOL || o.Gene\n\n\t\t// isoform\n\t\tif (o.Feature_type && o.Feature_type == 'Transcript') {\n\t\t\to._isoform = o.Feature.split('.')[0] // remove version\n\t\t} else {\n\t\t\to._isoform = o._gene\n\t\t}\n\n\t\t// class\n\t\tif (o.Consequence) {\n\t\t\tconst [dt, cls, rank] = vepinfo(o.Consequence)\n\t\t\to._dt = dt\n\t\t\to._class = cls\n\t\t\to._csqrank = rank\n\t\t} else {\n\t\t\t// FIXME\n\t\t\to._dt = dtsnvindel\n\t\t\to._class = mclassnonstandard\n\t\t}\n\t\t// mname\n\t\tif (o.HGVSp) {\n\t\t\to._mname = decodeURIComponent(o.HGVSp.substr(o.HGVSp.indexOf(':') + 1))\n\t\t} else if (o.Protein_position && o.Amino_acids) {\n\t\t\to._mname = decodeURIComponent(o.Protein_position + o.Amino_acids)\n\t\t} else if (o.HGVSc) {\n\t\t\to._mname = o.HGVSc.substr(o.HGVSc.indexOf(':') + 1)\n\t\t} else if (o.Existing_variation) {\n\t\t\to._name = o.Existing_variation\n\t\t} else {\n\t\t}\n\t}\n\treturn true\n}\n"],
5
+ "mappings": "AAAA,SAAS,eAAe;AAuDjB,SAAS,UAAU,KAAK,QAAQ,GAAG;AACzC,MAAI,CAAC,QAAQ;AACZ,WAAO;AAAA,EACR;AACA,aAAW,kBAAkB,IAAI,MAAM,GAAG,GAAG;AAC5C,UAAM,MAAM,eAAe,QAAQ,MAAM,GAAG,EAAE,MAAM,GAAG;AAEvD,UAAM,IAAI,CAAC;AAEX,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACvC,UAAI,IAAI,CAAC,GAAG;AACX,UAAE,OAAO,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;AAAA,MAC1B;AAAA,IACD;AACA,QAAI,CAAC,EAAE,QAAQ;AACd;AAAA,IACD;AACA,QAAI,SAAS;AASb,eAAW,KAAK,EAAE,QAAQ,EAAE,SAAS;AACpC,UAAI,EAAE,mBAAmB,EAAE,QAAQ;AAClC,iBAAS;AACT;AAAA,MACD;AAAA,IACD;AACA,QAAI,CAAC,QAAQ;AACZ,UAAI,EAAE,UAAU,KAAK;AAEpB,YAAI,EAAE,MAAM;AACX,cAAI,EAAE,KAAK,UAAU,GAAG;AACvB,qBAAS,EAAE,KAAK,CAAC;AAAA,UAClB;AAAA,QACD,WAAW,EAAE,SAAS;AACrB,cAAI,EAAE,QAAQ,UAAU,GAAG;AAC1B,qBAAS,EAAE,QAAQ,CAAC;AAAA,UACrB;AAAA,QACD;AAAA,MACD,OAAO;AACN,mBAAW,KAAK,EAAE,QAAQ,EAAE,SAAS;AACpC,cAAI,EAAE,gBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ;AAE5C,qBAAS;AACT;AAAA,UACD;AAAA,QACD;AAAA,MACD;AACA,UAAI,CAAC,QAAQ;AAEZ;AAAA,MACD;AAAA,IACD;AACA,QAAI,CAAC,OAAO,KAAK;AAChB,aAAO,MAAM,CAAC;AAAA,IACf;AACA,WAAO,IAAI,KAAK,CAAC;AAGjB,MAAE,QAAQ,EAAE,UAAU,EAAE;AAGxB,QAAI,EAAE,gBAAgB,EAAE,gBAAgB,cAAc;AACrD,QAAE,WAAW,EAAE,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,IACpC,OAAO;AACN,QAAE,WAAW,EAAE;AAAA,IAChB;AAGA,QAAI,EAAE,aAAa;AAClB,YAAM,CAAC,IAAI,KAAK,IAAI,IAAI,QAAQ,EAAE,WAAW;AAC7C,QAAE,MAAM;AACR,QAAE,SAAS;AACX,QAAE,WAAW;AAAA,IACd,OAAO;AAEN,QAAE,MAAM;AACR,QAAE,SAAS;AAAA,IACZ;AAEA,QAAI,EAAE,OAAO;AACZ,QAAE,SAAS,mBAAmB,EAAE,MAAM,OAAO,EAAE,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC;AAAA,IACvE,WAAW,EAAE,oBAAoB,EAAE,aAAa;AAC/C,QAAE,SAAS,mBAAmB,EAAE,mBAAmB,EAAE,WAAW;AAAA,IACjE,WAAW,EAAE,OAAO;AACnB,QAAE,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,QAAQ,GAAG,IAAI,CAAC;AAAA,IACnD,WAAW,EAAE,oBAAoB;AAChC,QAAE,QAAQ,EAAE;AAAA,IACb,OAAO;AAAA,IACP;AAAA,EACD;AACA,SAAO;AACR;",
6
+ "names": []
7
+ }
@@ -0,0 +1,40 @@
1
+ function dissect_INFO(str) {
2
+ let findsemicolon = false;
3
+ let findequalorsemicolon = true;
4
+ let i = 0;
5
+ let idx = 0;
6
+ const k2v = {};
7
+ let lastkey;
8
+ while (i < str.length) {
9
+ const c = str[i];
10
+ if (findequalorsemicolon) {
11
+ if (c == "=") {
12
+ findsemicolon = true;
13
+ findequalorsemicolon = false;
14
+ lastkey = str.substring(idx, i);
15
+ idx = i + 1;
16
+ } else if (c == ";") {
17
+ k2v[str.substring(idx, i)] = 1;
18
+ idx = i + 1;
19
+ }
20
+ } else if (findsemicolon && c == ";") {
21
+ findequalorsemicolon = true;
22
+ findsemicolon = false;
23
+ k2v[lastkey] = str.substring(idx, i);
24
+ lastkey = null;
25
+ idx = i + 1;
26
+ }
27
+ i++;
28
+ }
29
+ const remainstr = str.substr(idx, i);
30
+ if (lastkey) {
31
+ k2v[lastkey] = remainstr;
32
+ } else {
33
+ k2v[remainstr] = 1;
34
+ }
35
+ return k2v;
36
+ }
37
+ export {
38
+ dissect_INFO
39
+ };
40
+ //# sourceMappingURL=vcf.info.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/vcf.info.js"],
4
+ "sourcesContent": ["/*\nto parse a variant line, not header\n\ncannot simply slice by /[;=]/, but read char by char\ncase CLNVI=Breast_Cancer_Information_Core__(BRCA2):745-4&base_change=C_to_G;\ncase k1=v1;DB;k2=v2;\n*/\nexport function dissect_INFO(str) {\n\t//let findequal=true\n\tlet findsemicolon = false\n\tlet findequalorsemicolon = true\n\n\tlet i = 0\n\tlet idx = 0\n\n\tconst k2v = {}\n\tlet lastkey\n\n\twhile (i < str.length) {\n\t\tconst c = str[i]\n\t\tif (findequalorsemicolon) {\n\t\t\tif (c == '=') {\n\t\t\t\tfindsemicolon = true\n\t\t\t\tfindequalorsemicolon = false\n\t\t\t\tlastkey = str.substring(idx, i)\n\t\t\t\tidx = i + 1\n\t\t\t} else if (c == ';') {\n\t\t\t\t// should be a flag\n\t\t\t\tk2v[str.substring(idx, i)] = 1\n\t\t\t\tidx = i + 1\n\t\t\t}\n\t\t} else if (findsemicolon && c == ';') {\n\t\t\tfindequalorsemicolon = true\n\t\t\tfindsemicolon = false\n\t\t\tk2v[lastkey] = str.substring(idx, i)\n\t\t\tlastkey = null\n\t\t\tidx = i + 1\n\t\t}\n\t\ti++\n\t}\n\n\tconst remainstr = str.substr(idx, i)\n\tif (lastkey) {\n\t\tk2v[lastkey] = remainstr\n\t} else {\n\t\tk2v[remainstr] = 1\n\t}\n\n\treturn k2v\n}\n"],
5
+ "mappings": "AAOO,SAAS,aAAa,KAAK;AAEjC,MAAI,gBAAgB;AACpB,MAAI,uBAAuB;AAE3B,MAAI,IAAI;AACR,MAAI,MAAM;AAEV,QAAM,MAAM,CAAC;AACb,MAAI;AAEJ,SAAO,IAAI,IAAI,QAAQ;AACtB,UAAM,IAAI,IAAI,CAAC;AACf,QAAI,sBAAsB;AACzB,UAAI,KAAK,KAAK;AACb,wBAAgB;AAChB,+BAAuB;AACvB,kBAAU,IAAI,UAAU,KAAK,CAAC;AAC9B,cAAM,IAAI;AAAA,MACX,WAAW,KAAK,KAAK;AAEpB,YAAI,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI;AAC7B,cAAM,IAAI;AAAA,MACX;AAAA,IACD,WAAW,iBAAiB,KAAK,KAAK;AACrC,6BAAuB;AACvB,sBAAgB;AAChB,UAAI,OAAO,IAAI,IAAI,UAAU,KAAK,CAAC;AACnC,gBAAU;AACV,YAAM,IAAI;AAAA,IACX;AACA;AAAA,EACD;AAEA,QAAM,YAAY,IAAI,OAAO,KAAK,CAAC;AACnC,MAAI,SAAS;AACZ,QAAI,OAAO,IAAI;AAAA,EAChB,OAAO;AACN,QAAI,SAAS,IAAI;AAAA,EAClB;AAEA,SAAO;AACR;",
6
+ "names": []
7
+ }