@jbrowse/plugin-alignments 2.16.0 → 2.17.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 (221) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +2 -3
  2. package/dist/AlignmentsFeatureDetail/Flags.js +2 -2
  3. package/dist/AlignmentsFeatureDetail/LinkedPairedAlignments.js +2 -2
  4. package/dist/AlignmentsFeatureDetail/SupplementaryAlignments.js +2 -2
  5. package/dist/AlignmentsFeatureDetail/getSAFeatures.js +2 -2
  6. package/dist/AlignmentsFeatureDetail/stateModelFactory.d.ts +1 -1
  7. package/dist/BamAdapter/BamAdapter.d.ts +3 -2
  8. package/dist/BamAdapter/BamAdapter.js +34 -11
  9. package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +3 -17
  10. package/dist/BamAdapter/BamSlightlyLazyFeature.js +42 -72
  11. package/dist/CramAdapter/CramAdapter.d.ts +4 -3
  12. package/dist/CramAdapter/CramAdapter.js +24 -7
  13. package/dist/CramAdapter/CramSlightlyLazyFeature.d.ts +21 -27
  14. package/dist/CramAdapter/CramSlightlyLazyFeature.js +74 -73
  15. package/dist/CramAdapter/util.d.ts +1 -10
  16. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +1 -1
  17. package/dist/LinearAlignmentsDisplay/index.js +2 -2
  18. package/dist/LinearAlignmentsDisplay/{models/model.d.ts → model.d.ts} +6 -3
  19. package/dist/LinearAlignmentsDisplay/{models/model.js → model.js} +11 -7
  20. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +6 -27
  21. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +43 -21
  22. package/dist/LinearPileupDisplay/components/ColorByTagDialog.d.ts +5 -4
  23. package/dist/LinearPileupDisplay/components/ColorByTagDialog.js +3 -1
  24. package/dist/LinearPileupDisplay/components/GroupByDialog.js +8 -6
  25. package/dist/LinearPileupDisplay/components/SortByTagDialog.js +6 -4
  26. package/dist/LinearPileupDisplay/model.d.ts +41 -45
  27. package/dist/LinearPileupDisplay/model.js +118 -41
  28. package/dist/LinearReadArcsDisplay/components/ReactComponent.js +1 -1
  29. package/dist/LinearReadArcsDisplay/model.d.ts +22 -21
  30. package/dist/LinearReadArcsDisplay/model.js +13 -14
  31. package/dist/LinearReadCloudDisplay/components/ReactComponent.js +1 -1
  32. package/dist/LinearReadCloudDisplay/model.d.ts +14 -22
  33. package/dist/LinearReadCloudDisplay/model.js +12 -13
  34. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +49 -19
  35. package/dist/LinearSNPCoverageDisplay/index.js +3 -2
  36. package/dist/LinearSNPCoverageDisplay/{models/model.d.ts → model.d.ts} +3 -13
  37. package/dist/LinearSNPCoverageDisplay/{models/model.js → model.js} +71 -45
  38. package/dist/MismatchParser/cigarToMismatches.d.ts +3 -0
  39. package/dist/MismatchParser/cigarToMismatches.js +94 -0
  40. package/dist/MismatchParser/getNextRefPos.d.ts +4 -0
  41. package/dist/MismatchParser/getNextRefPos.js +40 -0
  42. package/dist/MismatchParser/index.d.ts +4 -29
  43. package/dist/MismatchParser/index.js +10 -321
  44. package/dist/MismatchParser/mdToMismatches.d.ts +3 -0
  45. package/dist/MismatchParser/mdToMismatches.js +80 -0
  46. package/dist/ModificationParser/index.d.ts +19 -0
  47. package/dist/ModificationParser/index.js +144 -0
  48. package/dist/PileupRPC/methods/GetGlobalValueForTag.js +1 -2
  49. package/dist/PileupRPC/methods/GetReducedFeatures.d.ts +1 -1
  50. package/dist/PileupRPC/methods/GetReducedFeatures.js +19 -16
  51. package/dist/PileupRPC/methods/GetVisibleModifications.d.ts +2 -1
  52. package/dist/PileupRPC/methods/GetVisibleModifications.js +9 -6
  53. package/dist/PileupRenderer/PileupLayoutSession.d.ts +8 -7
  54. package/dist/PileupRenderer/PileupRenderer.d.ts +6 -14
  55. package/dist/PileupRenderer/PileupRenderer.js +7 -5
  56. package/dist/PileupRenderer/renderAlignment.js +17 -4
  57. package/dist/PileupRenderer/renderAlignmentShape.js +102 -21
  58. package/dist/PileupRenderer/renderMethylation.d.ts +2 -1
  59. package/dist/PileupRenderer/renderMethylation.js +17 -9
  60. package/dist/PileupRenderer/renderMismatches.js +19 -19
  61. package/dist/PileupRenderer/renderModifications.d.ts +3 -2
  62. package/dist/PileupRenderer/renderModifications.js +31 -34
  63. package/dist/PileupRenderer/renderPerBaseLettering.d.ts +2 -1
  64. package/dist/PileupRenderer/renderPerBaseLettering.js +1 -3
  65. package/dist/PileupRenderer/renderPerBaseQuality.d.ts +2 -1
  66. package/dist/PileupRenderer/renderPerBaseQuality.js +1 -3
  67. package/dist/PileupRenderer/renderSoftClipping.js +6 -6
  68. package/dist/PileupRenderer/sortUtil.d.ts +2 -7
  69. package/dist/PileupRenderer/sortUtil.js +13 -13
  70. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +10 -5
  71. package/dist/SNPCoverageAdapter/generateCoverageBins.d.ts +13 -9
  72. package/dist/SNPCoverageAdapter/generateCoverageBins.js +269 -166
  73. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -1
  74. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +171 -54
  75. package/dist/shared/color.d.ts +0 -10
  76. package/dist/shared/color.js +1 -7
  77. package/{esm/shared → dist/shared/components}/BaseDisplayComponent.d.ts +2 -2
  78. package/{esm/shared → dist/shared/components}/FilterByTagDialog.d.ts +3 -3
  79. package/dist/shared/{FilterByTagDialog.js → components/FilterByTagDialog.js} +5 -1
  80. package/dist/shared/fetchChains.js +1 -2
  81. package/dist/shared/getMaximumModificationAtEachPosition.d.ts +8 -0
  82. package/dist/shared/getMaximumModificationAtEachPosition.js +42 -0
  83. package/dist/shared/getUniqueModifications.d.ts +14 -0
  84. package/dist/shared/getUniqueModifications.js +16 -0
  85. package/dist/shared/getUniqueTags.d.ts +15 -0
  86. package/dist/shared/getUniqueTags.js +18 -0
  87. package/dist/shared/types.d.ts +94 -0
  88. package/dist/shared/util.d.ts +8 -0
  89. package/dist/shared/util.js +26 -0
  90. package/dist/util.d.ts +7 -4
  91. package/dist/util.js +30 -30
  92. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +2 -3
  93. package/esm/AlignmentsFeatureDetail/Flags.js +1 -1
  94. package/esm/AlignmentsFeatureDetail/LinkedPairedAlignments.js +1 -1
  95. package/esm/AlignmentsFeatureDetail/SupplementaryAlignments.js +1 -1
  96. package/esm/AlignmentsFeatureDetail/getSAFeatures.js +2 -2
  97. package/esm/AlignmentsFeatureDetail/stateModelFactory.d.ts +1 -1
  98. package/esm/BamAdapter/BamAdapter.d.ts +3 -2
  99. package/esm/BamAdapter/BamAdapter.js +31 -8
  100. package/esm/BamAdapter/BamSlightlyLazyFeature.d.ts +3 -17
  101. package/esm/BamAdapter/BamSlightlyLazyFeature.js +43 -73
  102. package/esm/CramAdapter/CramAdapter.d.ts +4 -3
  103. package/esm/CramAdapter/CramAdapter.js +22 -5
  104. package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +21 -27
  105. package/esm/CramAdapter/CramSlightlyLazyFeature.js +74 -73
  106. package/esm/CramAdapter/util.d.ts +1 -10
  107. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +1 -1
  108. package/esm/LinearAlignmentsDisplay/index.js +2 -2
  109. package/esm/LinearAlignmentsDisplay/{models/model.d.ts → model.d.ts} +6 -3
  110. package/esm/LinearAlignmentsDisplay/{models/model.js → model.js} +11 -7
  111. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +6 -27
  112. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +45 -23
  113. package/esm/LinearPileupDisplay/components/ColorByTagDialog.d.ts +5 -4
  114. package/esm/LinearPileupDisplay/components/ColorByTagDialog.js +3 -1
  115. package/esm/LinearPileupDisplay/components/GroupByDialog.js +8 -6
  116. package/esm/LinearPileupDisplay/components/SortByTagDialog.js +6 -4
  117. package/esm/LinearPileupDisplay/model.d.ts +41 -45
  118. package/esm/LinearPileupDisplay/model.js +119 -42
  119. package/esm/LinearReadArcsDisplay/components/ReactComponent.js +1 -1
  120. package/esm/LinearReadArcsDisplay/model.d.ts +22 -21
  121. package/esm/LinearReadArcsDisplay/model.js +14 -15
  122. package/esm/LinearReadCloudDisplay/components/ReactComponent.js +1 -1
  123. package/esm/LinearReadCloudDisplay/model.d.ts +14 -22
  124. package/esm/LinearReadCloudDisplay/model.js +13 -14
  125. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +49 -19
  126. package/esm/LinearSNPCoverageDisplay/index.js +3 -2
  127. package/esm/LinearSNPCoverageDisplay/{models/model.d.ts → model.d.ts} +3 -13
  128. package/esm/LinearSNPCoverageDisplay/{models/model.js → model.js} +72 -46
  129. package/esm/MismatchParser/cigarToMismatches.d.ts +3 -0
  130. package/esm/MismatchParser/cigarToMismatches.js +91 -0
  131. package/esm/MismatchParser/getNextRefPos.d.ts +4 -0
  132. package/esm/MismatchParser/getNextRefPos.js +37 -0
  133. package/esm/MismatchParser/index.d.ts +4 -29
  134. package/esm/MismatchParser/index.js +5 -311
  135. package/esm/MismatchParser/mdToMismatches.d.ts +3 -0
  136. package/esm/MismatchParser/mdToMismatches.js +77 -0
  137. package/esm/ModificationParser/index.d.ts +19 -0
  138. package/esm/ModificationParser/index.js +138 -0
  139. package/esm/PileupRPC/methods/GetGlobalValueForTag.js +1 -2
  140. package/esm/PileupRPC/methods/GetReducedFeatures.d.ts +1 -1
  141. package/esm/PileupRPC/methods/GetReducedFeatures.js +19 -16
  142. package/esm/PileupRPC/methods/GetVisibleModifications.d.ts +2 -1
  143. package/esm/PileupRPC/methods/GetVisibleModifications.js +9 -6
  144. package/esm/PileupRenderer/PileupLayoutSession.d.ts +8 -7
  145. package/esm/PileupRenderer/PileupRenderer.d.ts +6 -14
  146. package/esm/PileupRenderer/PileupRenderer.js +8 -6
  147. package/esm/PileupRenderer/renderAlignment.js +17 -4
  148. package/esm/PileupRenderer/renderAlignmentShape.js +102 -21
  149. package/esm/PileupRenderer/renderMethylation.d.ts +2 -1
  150. package/esm/PileupRenderer/renderMethylation.js +17 -9
  151. package/esm/PileupRenderer/renderMismatches.js +19 -19
  152. package/esm/PileupRenderer/renderModifications.d.ts +3 -2
  153. package/esm/PileupRenderer/renderModifications.js +30 -33
  154. package/esm/PileupRenderer/renderPerBaseLettering.d.ts +2 -1
  155. package/esm/PileupRenderer/renderPerBaseLettering.js +1 -3
  156. package/esm/PileupRenderer/renderPerBaseQuality.d.ts +2 -1
  157. package/esm/PileupRenderer/renderPerBaseQuality.js +1 -3
  158. package/esm/PileupRenderer/renderSoftClipping.js +6 -6
  159. package/esm/PileupRenderer/sortUtil.d.ts +2 -7
  160. package/esm/PileupRenderer/sortUtil.js +13 -13
  161. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js +10 -5
  162. package/esm/SNPCoverageAdapter/generateCoverageBins.d.ts +13 -9
  163. package/esm/SNPCoverageAdapter/generateCoverageBins.js +269 -166
  164. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -1
  165. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +171 -54
  166. package/esm/shared/color.d.ts +0 -10
  167. package/esm/shared/color.js +0 -6
  168. package/{dist/shared → esm/shared/components}/BaseDisplayComponent.d.ts +2 -2
  169. package/{dist/shared → esm/shared/components}/FilterByTagDialog.d.ts +3 -3
  170. package/esm/shared/{FilterByTagDialog.js → components/FilterByTagDialog.js} +5 -1
  171. package/esm/shared/fetchChains.js +1 -2
  172. package/esm/shared/getMaximumModificationAtEachPosition.d.ts +8 -0
  173. package/esm/shared/getMaximumModificationAtEachPosition.js +39 -0
  174. package/esm/shared/getUniqueModifications.d.ts +14 -0
  175. package/esm/shared/getUniqueModifications.js +13 -0
  176. package/esm/shared/getUniqueTags.d.ts +15 -0
  177. package/esm/shared/getUniqueTags.js +15 -0
  178. package/esm/shared/types.d.ts +94 -0
  179. package/esm/shared/util.d.ts +8 -0
  180. package/esm/shared/util.js +23 -0
  181. package/esm/util.d.ts +7 -4
  182. package/esm/util.js +28 -27
  183. package/package.json +4 -4
  184. package/dist/LinearPileupDisplay/components/ColorByModificationsDialog.d.ts +0 -15
  185. package/dist/LinearPileupDisplay/components/ColorByModificationsDialog.js +0 -41
  186. package/dist/LinearPileupDisplay/components/ModificationsTable.d.ts +0 -4
  187. package/dist/LinearPileupDisplay/components/ModificationsTable.js +0 -28
  188. package/dist/SNPCoverageAdapter/util.d.ts +0 -25
  189. package/dist/shared/index.d.ts +0 -49
  190. package/dist/shared/index.js +0 -41
  191. package/esm/LinearPileupDisplay/components/ColorByModificationsDialog.d.ts +0 -15
  192. package/esm/LinearPileupDisplay/components/ColorByModificationsDialog.js +0 -36
  193. package/esm/LinearPileupDisplay/components/ModificationsTable.d.ts +0 -4
  194. package/esm/LinearPileupDisplay/components/ModificationsTable.js +0 -22
  195. package/esm/SNPCoverageAdapter/util.d.ts +0 -25
  196. package/esm/shared/index.d.ts +0 -49
  197. package/esm/shared/index.js +0 -36
  198. /package/dist/LinearAlignmentsDisplay/{models/alignmentsModel.d.ts → alignmentsModel.d.ts} +0 -0
  199. /package/dist/LinearAlignmentsDisplay/{models/alignmentsModel.js → alignmentsModel.js} +0 -0
  200. /package/dist/LinearAlignmentsDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  201. /package/dist/LinearAlignmentsDisplay/{models/configSchema.js → configSchema.js} +0 -0
  202. /package/dist/LinearAlignmentsDisplay/{models/util.d.ts → util.d.ts} +0 -0
  203. /package/dist/LinearAlignmentsDisplay/{models/util.js → util.js} +0 -0
  204. /package/dist/LinearSNPCoverageDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  205. /package/dist/LinearSNPCoverageDisplay/{models/configSchema.js → configSchema.js} +0 -0
  206. /package/dist/shared/{BaseDisplayComponent.js → components/BaseDisplayComponent.js} +0 -0
  207. /package/dist/shared/{renderSvg.d.ts → renderSvgUtil.d.ts} +0 -0
  208. /package/dist/shared/{renderSvg.js → renderSvgUtil.js} +0 -0
  209. /package/dist/{SNPCoverageAdapter/util.js → shared/types.js} +0 -0
  210. /package/esm/LinearAlignmentsDisplay/{models/alignmentsModel.d.ts → alignmentsModel.d.ts} +0 -0
  211. /package/esm/LinearAlignmentsDisplay/{models/alignmentsModel.js → alignmentsModel.js} +0 -0
  212. /package/esm/LinearAlignmentsDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  213. /package/esm/LinearAlignmentsDisplay/{models/configSchema.js → configSchema.js} +0 -0
  214. /package/esm/LinearAlignmentsDisplay/{models/util.d.ts → util.d.ts} +0 -0
  215. /package/esm/LinearAlignmentsDisplay/{models/util.js → util.js} +0 -0
  216. /package/esm/LinearSNPCoverageDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  217. /package/esm/LinearSNPCoverageDisplay/{models/configSchema.js → configSchema.js} +0 -0
  218. /package/esm/shared/{BaseDisplayComponent.js → components/BaseDisplayComponent.js} +0 -0
  219. /package/esm/shared/{renderSvg.d.ts → renderSvgUtil.d.ts} +0 -0
  220. /package/esm/shared/{renderSvg.js → renderSvgUtil.js} +0 -0
  221. /package/esm/{SNPCoverageAdapter/util.js → shared/types.js} +0 -0
@@ -2,12 +2,26 @@ import { createJBrowseTheme } from '@jbrowse/core/ui';
2
2
  import { featureSpanPx, bpSpanPx } from '@jbrowse/core/util';
3
3
  import { readConfObject } from '@jbrowse/core/configuration';
4
4
  import { getOrigin, getScale, WiggleBaseRenderer, YSCALEBAR_LABEL_OFFSET, } from '@jbrowse/plugin-wiggle';
5
+ import { alphaColor } from '../shared/util';
6
+ // width/height of the triangle above e.g. insertion indicators
7
+ const INTERBASE_INDICATOR_WIDTH = 7;
8
+ const INTERBASE_INDICATOR_HEIGHT = 4.5;
9
+ // minimum read depth to draw the insertion indicators, below this the
10
+ // 'statistical significance' is low
11
+ const MINIMUM_INTERBASE_INDICATOR_READ_DEPTH = 7;
12
+ const complementBase = {
13
+ C: 'G',
14
+ G: 'C',
15
+ A: 'T',
16
+ T: 'A',
17
+ };
5
18
  const fudgeFactor = 0.6;
6
19
  export default class SNPCoverageRenderer extends WiggleBaseRenderer {
7
20
  // note: the snps are drawn on linear scale even if the data is drawn in log
8
21
  // scape hence the two different scales being used
9
22
  async draw(ctx, props) {
10
- const { features, regions, bpPerPx, displayCrossHatches, modificationTagMap = {}, scaleOpts, height: unadjustedHeight, theme: configTheme, config: cfg, ticks, } = props;
23
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
24
+ const { features, regions, bpPerPx, colorBy, displayCrossHatches, visibleModifications = {}, scaleOpts, height: unadjustedHeight, theme: configTheme, config: cfg, ticks, } = props;
11
25
  const theme = createJBrowseTheme(configTheme);
12
26
  const region = regions[0];
13
27
  const width = (region.end - region.start) / bpPerPx;
@@ -46,16 +60,18 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
46
60
  softclip: 'blue',
47
61
  hardclip: 'red',
48
62
  total: readConfObject(cfg, 'color'),
49
- meth: 'red',
50
- unmeth: 'blue',
63
+ mod_NONE: 'blue',
64
+ cpg_meth: 'red',
65
+ cpg_unmeth: 'blue',
51
66
  };
52
67
  const feats = [...features.values()];
53
- const coverage = feats.filter(f => f.get('type') !== 'skip');
54
- const skips = feats.filter(f => f.get('type') === 'skip');
55
68
  // Use two pass rendering, which helps in visualizing the SNPs at higher
56
69
  // bpPerPx First pass: draw the gray background
57
70
  ctx.fillStyle = colorForBase.total;
58
- for (const feature of coverage) {
71
+ for (const feature of feats) {
72
+ if (feature.get('type') === 'skip') {
73
+ continue;
74
+ }
59
75
  const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
60
76
  const w = rightPx - leftPx + fudgeFactor;
61
77
  const score = feature.get('score');
@@ -63,45 +79,148 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
63
79
  }
64
80
  // Keep track of previous total which we will use it to draw the interbase
65
81
  // indicator (if there is a sudden clip, there will be no read coverage but
66
- // there will be "clip" coverage) at that position beyond the read. if the
67
- // clip is right at a block boundary then prevTotal will not be available,
68
- // so this is a best attempt to plot interbase indicator at the "cliffs"
82
+ // there will be "clip" coverage) at that position beyond the read.
83
+ //
84
+ // if the clip is right at a block boundary then prevTotal will not be
85
+ // available, so this is a best attempt to plot interbase indicator at the
86
+ // "cliffs"
69
87
  let prevTotal = 0;
70
88
  // extraHorizontallyFlippedOffset is used to draw interbase items, which
71
89
  // are located to the left when forward and right when reversed
72
90
  const extraHorizontallyFlippedOffset = region.reversed ? 1 / bpPerPx : 0;
91
+ // @ts-expect-error
92
+ const drawingModifications = (colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'modifications';
93
+ // @ts-expect-error
94
+ const drawingMethylation = (colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'methylation';
95
+ const isolatedModification =
96
+ // @ts-expect-error
97
+ (_a = colorBy === null || colorBy === void 0 ? void 0 : colorBy.modifications) === null || _a === void 0 ? void 0 : _a.isolatedModification;
73
98
  // Second pass: draw the SNP data, and add a minimum feature width of 1px
74
99
  // which can be wider than the actual bpPerPx This reduces overdrawing of
75
100
  // the grey background over the SNPs
76
- for (const feature of coverage) {
101
+ for (const feature of feats) {
102
+ if (feature.get('type') === 'skip') {
103
+ continue;
104
+ }
77
105
  const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx);
78
- const score = feature.get('score');
79
106
  const snpinfo = feature.get('snpinfo');
80
107
  const w = Math.max(rightPx - leftPx, 1);
81
- const totalScore = snpinfo.total;
82
- const keys = Object.keys(snpinfo.cov).sort();
83
- let curr = 0;
84
- for (const base of keys) {
85
- const { total } = snpinfo.cov[base];
86
- ctx.fillStyle =
87
- colorForBase[base] ||
88
- modificationTagMap[base.replace('mod_', '')] ||
89
- 'black';
90
- const height = toHeight(score);
91
- const bottom = toY(score) + height;
92
- ctx.fillRect(Math.round(leftPx), bottom - ((total + curr) / score) * height, w, (total / score) * height);
93
- curr += total;
108
+ const score0 = feature.get('score');
109
+ if (drawingModifications) {
110
+ let curr = 0;
111
+ const refbase = (_b = snpinfo.refbase) === null || _b === void 0 ? void 0 : _b.toUpperCase();
112
+ const { nonmods, mods, snps, ref } = snpinfo;
113
+ for (const m of Object.keys(nonmods).sort().reverse()) {
114
+ const mod = visibleModifications[m.replace('nonmod_', '')] ||
115
+ visibleModifications[m.replace('mod_', '')];
116
+ if (!mod) {
117
+ console.warn(`${m} not known yet`);
118
+ continue;
119
+ }
120
+ if (isolatedModification && mod.type !== isolatedModification) {
121
+ continue;
122
+ }
123
+ const cmp = complementBase[mod.base];
124
+ // this approach is inspired from the 'simplex' approach in igv
125
+ // https://github.com/igvteam/igv/blob/af07c3b1be8806cfd77343ee04982aeff17d2beb/src/main/java/org/broad/igv/sam/mods/BaseModificationCoverageRenderer.java#L51
126
+ const detectable = mod.base === 'N'
127
+ ? score0
128
+ : (((_c = snps[mod.base]) === null || _c === void 0 ? void 0 : _c.entryDepth) || 0) +
129
+ (((_d = snps[cmp]) === null || _d === void 0 ? void 0 : _d.entryDepth) || 0) +
130
+ (refbase === mod.base ? ref['1'] : 0) +
131
+ (refbase === cmp ? ref['-1'] : 0);
132
+ const modifiable = mod.base === 'N'
133
+ ? score0
134
+ : (((_e = snps[mod.base]) === null || _e === void 0 ? void 0 : _e.entryDepth) || 0) +
135
+ (((_f = snps[cmp]) === null || _f === void 0 ? void 0 : _f.entryDepth) || 0) +
136
+ (refbase === mod.base ? ref.entryDepth : 0) +
137
+ (refbase === cmp ? ref.entryDepth : 0);
138
+ const { entryDepth, avgProbability = 0 } = snpinfo.nonmods[m];
139
+ const modFraction = (modifiable / score0) * (entryDepth / detectable);
140
+ const nonModColor = 'blue';
141
+ const c = alphaColor(nonModColor, avgProbability);
142
+ const height = toHeight(score0);
143
+ const bottom = toY(score0) + height;
144
+ ctx.fillStyle = c;
145
+ ctx.fillRect(Math.round(leftPx), bottom - (curr + modFraction * height), w, modFraction * height);
146
+ curr += modFraction * height;
147
+ }
148
+ for (const m of Object.keys(mods).sort().reverse()) {
149
+ const mod = visibleModifications[m.replace('mod_', '')];
150
+ if (!mod) {
151
+ console.warn(`${m} not known yet`);
152
+ continue;
153
+ }
154
+ if (isolatedModification && mod.type !== isolatedModification) {
155
+ continue;
156
+ }
157
+ const cmp = complementBase[mod.base];
158
+ // this approach is inspired from the 'simplex' approach in igv
159
+ // https://github.com/igvteam/igv/blob/af07c3b1be8806cfd77343ee04982aeff17d2beb/src/main/java/org/broad/igv/sam/mods/BaseModificationCoverageRenderer.java#L51
160
+ const detectable = mod.base === 'N'
161
+ ? score0
162
+ : (((_g = snps[mod.base]) === null || _g === void 0 ? void 0 : _g.entryDepth) || 0) +
163
+ (((_h = snps[cmp]) === null || _h === void 0 ? void 0 : _h.entryDepth) || 0) +
164
+ (refbase === mod.base ? ref['1'] : 0) +
165
+ (refbase === cmp ? ref['-1'] : 0);
166
+ const modifiable = mod.base === 'N'
167
+ ? score0
168
+ : (((_j = snps[mod.base]) === null || _j === void 0 ? void 0 : _j.entryDepth) || 0) +
169
+ (((_k = snps[cmp]) === null || _k === void 0 ? void 0 : _k.entryDepth) || 0) +
170
+ (refbase === mod.base ? ref.entryDepth : 0) +
171
+ (refbase === cmp ? ref.entryDepth : 0);
172
+ const { entryDepth, avgProbability = 0 } = mods[m];
173
+ const modFraction = (modifiable / score0) * (entryDepth / detectable);
174
+ const baseColor = mod.color || 'black';
175
+ const c = alphaColor(baseColor, avgProbability);
176
+ const height = toHeight(score0);
177
+ const bottom = toY(score0) + height;
178
+ ctx.fillStyle = c;
179
+ ctx.fillRect(Math.round(leftPx), bottom - (curr + modFraction * height), w, modFraction * height);
180
+ curr += modFraction * height;
181
+ }
182
+ }
183
+ else if (drawingMethylation) {
184
+ const { depth, nonmods, mods } = snpinfo;
185
+ let curr = 0;
186
+ for (const base of Object.keys(mods).sort().reverse()) {
187
+ const { entryDepth } = mods[base];
188
+ const height = toHeight(score0);
189
+ const bottom = toY(score0) + height;
190
+ ctx.fillStyle = colorForBase[base] || 'black';
191
+ ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
192
+ curr += entryDepth;
193
+ }
194
+ for (const base of Object.keys(nonmods).sort().reverse()) {
195
+ const { entryDepth } = nonmods[base];
196
+ const height = toHeight(score0);
197
+ const bottom = toY(score0) + height;
198
+ ctx.fillStyle = colorForBase[base] || 'black';
199
+ ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
200
+ curr += entryDepth;
201
+ }
202
+ }
203
+ else {
204
+ const { depth, snps } = snpinfo;
205
+ let curr = 0;
206
+ for (const base of Object.keys(snps).sort().reverse()) {
207
+ const { entryDepth } = snps[base];
208
+ const height = toHeight(score0);
209
+ const bottom = toY(score0) + height;
210
+ ctx.fillStyle = colorForBase[base] || 'black';
211
+ ctx.fillRect(Math.round(leftPx), bottom - ((entryDepth + curr) / depth) * height, w, (entryDepth / depth) * height);
212
+ curr += entryDepth;
213
+ }
94
214
  }
95
215
  const interbaseEvents = Object.keys(snpinfo.noncov);
96
- const indicatorHeight = 4.5;
97
216
  if (drawInterbaseCounts) {
98
217
  let curr = 0;
99
218
  for (const base of interbaseEvents) {
100
- const { total } = snpinfo.noncov[base];
219
+ const { entryDepth } = snpinfo.noncov[base];
101
220
  const r = 0.6;
102
221
  ctx.fillStyle = colorForBase[base];
103
- ctx.fillRect(leftPx - r + extraHorizontallyFlippedOffset, indicatorHeight + toHeight2(curr), r * 2, toHeight2(total));
104
- curr += total;
222
+ ctx.fillRect(leftPx - r + extraHorizontallyFlippedOffset, INTERBASE_INDICATOR_HEIGHT + toHeight2(curr), r * 2, toHeight2(entryDepth));
223
+ curr += entryDepth;
105
224
  }
106
225
  }
107
226
  if (drawIndicators) {
@@ -109,48 +228,46 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
109
228
  let max = 0;
110
229
  let maxBase = '';
111
230
  for (const base of interbaseEvents) {
112
- const { total } = snpinfo.noncov[base];
113
- accum += total;
114
- if (total > max) {
115
- max = total;
231
+ const { entryDepth } = snpinfo.noncov[base];
232
+ accum += entryDepth;
233
+ if (entryDepth > max) {
234
+ max = entryDepth;
116
235
  maxBase = base;
117
236
  }
118
237
  }
119
- // avoid drawing a bunch of indicators if coverage is very low e.g.
120
- // less than 7, uses the prev total in the case of the "cliff"
121
- const indicatorComparatorScore = Math.max(totalScore, prevTotal);
238
+ // avoid drawing a bunch of indicators if coverage is very low. note:
239
+ // also uses the prev total in the case of the "cliff"
240
+ const indicatorComparatorScore = Math.max(score0, prevTotal);
122
241
  if (accum > indicatorComparatorScore * indicatorThreshold &&
123
- indicatorComparatorScore > 7) {
242
+ indicatorComparatorScore > MINIMUM_INTERBASE_INDICATOR_READ_DEPTH) {
124
243
  ctx.fillStyle = colorForBase[maxBase];
125
244
  ctx.beginPath();
126
245
  const l = leftPx + extraHorizontallyFlippedOffset;
127
- ctx.moveTo(l - 3.5, 0);
128
- ctx.lineTo(l + 3.5, 0);
129
- ctx.lineTo(l, indicatorHeight);
246
+ ctx.moveTo(l - INTERBASE_INDICATOR_WIDTH / 2, 0);
247
+ ctx.lineTo(l + INTERBASE_INDICATOR_WIDTH / 2, 0);
248
+ ctx.lineTo(l, INTERBASE_INDICATOR_HEIGHT);
130
249
  ctx.fill();
131
250
  }
132
251
  }
133
- prevTotal = totalScore;
252
+ prevTotal = score0;
134
253
  }
135
254
  if (drawArcs) {
136
- for (const f of skips) {
137
- const [left, right] = bpSpanPx(f.get('start'), f.get('end'), region, bpPerPx);
255
+ for (const f of feats) {
256
+ if (f.get('type') !== 'skip') {
257
+ continue;
258
+ }
259
+ const s = f.get('start');
260
+ const e = f.get('end');
261
+ const [left, right] = bpSpanPx(s, e, region, bpPerPx);
138
262
  ctx.beginPath();
139
- const str = f.get('strand');
140
- const xs = f.get('xs');
263
+ const effectiveStrand = f.get('effectiveStrand');
141
264
  const pos = 'rgba(255,200,200,0.7)';
142
265
  const neg = 'rgba(200,200,255,0.7)';
143
266
  const neutral = 'rgba(200,200,200,0.7)';
144
- if (xs === '+') {
267
+ if (effectiveStrand === 1) {
145
268
  ctx.strokeStyle = pos;
146
269
  }
147
- else if (xs === '-') {
148
- ctx.strokeStyle = neg;
149
- }
150
- else if (str === 1) {
151
- ctx.strokeStyle = pos;
152
- }
153
- else if (str === -1) {
270
+ else if (effectiveStrand === -1) {
154
271
  ctx.strokeStyle = neg;
155
272
  }
156
273
  else {
@@ -165,12 +282,12 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
165
282
  if (displayCrossHatches) {
166
283
  ctx.lineWidth = 1;
167
284
  ctx.strokeStyle = 'rgba(140,140,140,0.8)';
168
- ticks.values.forEach(tick => {
285
+ for (const tick of ticks.values) {
169
286
  ctx.beginPath();
170
287
  ctx.moveTo(0, Math.round(toY(tick)));
171
288
  ctx.lineTo(width, Math.round(toY(tick)));
172
289
  ctx.stroke();
173
- });
290
+ }
174
291
  }
175
292
  return undefined;
176
293
  }
@@ -1,4 +1,3 @@
1
- import { Instance } from 'mobx-state-tree';
2
1
  import { ChainStats } from './fetchChains';
3
2
  export declare const fillColor: {
4
3
  color_fwd_strand_not_proper: string;
@@ -57,12 +56,3 @@ export declare function getPairedOrientationColorOrDefault(f: {
57
56
  export declare function getPairedOrientationColor(f: {
58
57
  pair_orientation?: string;
59
58
  }): readonly [string, string];
60
- export interface ExtraColorBy {
61
- custom?: Record<string, string>;
62
- }
63
- export declare const ColorByModel: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
64
- type: import("mobx-state-tree").ISimpleType<string>;
65
- tag: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
66
- extra: import("mobx-state-tree").IType<any, any, any>;
67
- }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
68
- export type IColorByModel = Instance<typeof ColorByModel>;
@@ -1,4 +1,3 @@
1
- import { types } from 'mobx-state-tree';
2
1
  import { orientationTypes, pairMap } from '../util';
3
2
  export const fillColor = {
4
3
  color_fwd_strand_not_proper: '#ECC8C8',
@@ -79,8 +78,3 @@ export function getPairedOrientationColorOrDefault(f) {
79
78
  export function getPairedOrientationColor(f) {
80
79
  return getPairedOrientationColorOrDefault(f) || defaultColor;
81
80
  }
82
- export const ColorByModel = types.maybe(types.model({
83
- type: types.string,
84
- tag: types.maybe(types.string),
85
- extra: types.frozen(),
86
- }));
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { LinearReadCloudDisplayModel } from '../LinearReadCloudDisplay/model';
3
- import { LinearReadArcsDisplayModel } from '../LinearReadArcsDisplay/model';
2
+ import { LinearReadCloudDisplayModel } from '../../LinearReadCloudDisplay/model';
3
+ import { LinearReadArcsDisplayModel } from '../../LinearReadArcsDisplay/model';
4
4
  declare const BaseDisplayComponent: ({ model, children, }: {
5
5
  model: LinearReadArcsDisplayModel | LinearReadCloudDisplayModel;
6
6
  children?: React.ReactNode;
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
- import { IFilter } from '.';
2
+ import { FilterBy } from '../types';
3
3
  declare const FilterByTagDialog: (props: {
4
4
  model: {
5
- filterBy: IFilter;
6
- setFilterBy: (arg: IFilter) => void;
5
+ filterBy: FilterBy;
6
+ setFilterBy: (arg: FilterBy) => void;
7
7
  };
8
8
  handleClose: () => void;
9
9
  }) => React.JSX.Element;
@@ -78,7 +78,11 @@ const FilterByTagDialog = observer(function (props) {
78
78
  React.createElement(Typography, null, "Filter by tag name and value. Use * in the value field to get all reads containing any value for that tag. Example: filter tag name SA with value * to get all split/supplementary reads. Other examples include HP for haplotype, or RG for read group"),
79
79
  React.createElement(TextField, { className: classes.field, value: tag, onChange: event => {
80
80
  setTag(event.target.value);
81
- }, placeholder: "Enter tag name", inputProps: { maxLength: 2 }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '' }),
81
+ }, placeholder: "Enter tag name", error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '', slotProps: {
82
+ htmlInput: {
83
+ maxLength: 2,
84
+ },
85
+ } }),
82
86
  React.createElement(TextField, { className: classes.field, value: tagValue, onChange: event => {
83
87
  setTagValue(event.target.value);
84
88
  }, placeholder: "Enter tag value" })),
@@ -1,5 +1,4 @@
1
1
  import { getContainingTrack, getContainingView, getSession, } from '@jbrowse/core/util';
2
- import { getSnapshot } from 'mobx-state-tree';
3
2
  export async function fetchChains(self) {
4
3
  // @ts-expect-error
5
4
  const { rpcSessionId: sessionId } = getContainingTrack(self);
@@ -12,7 +11,7 @@ export async function fetchChains(self) {
12
11
  const ret = (await rpcManager.call(sessionId, 'PileupGetReducedFeatures', {
13
12
  sessionId,
14
13
  regions: view.staticBlocks.contentBlocks,
15
- filterBy: getSnapshot(self.filterBy),
14
+ filterBy: self.filterBy,
16
15
  adapterConfig: self.adapterConfig,
17
16
  }));
18
17
  self.setChainData(ret);
@@ -0,0 +1,8 @@
1
+ import { Feature } from '@jbrowse/core/util';
2
+ interface MaximumProbabilityMod {
3
+ type: string;
4
+ prob: number;
5
+ allProbs: number[];
6
+ }
7
+ export declare function getMaxProbModAtEachPosition(feature: Feature, cigarOps?: string[]): MaximumProbabilityMod[] | undefined;
8
+ export {};
@@ -0,0 +1,39 @@
1
+ // locals
2
+ import { getModPositions, getModProbabilities } from '../ModificationParser';
3
+ import { getNextRefPos, parseCigar } from '../MismatchParser';
4
+ import { getTagAlt } from '../util';
5
+ export function getMaxProbModAtEachPosition(feature, cigarOps) {
6
+ const fstrand = feature.get('strand');
7
+ const seq = feature.get('seq');
8
+ const mm = getTagAlt(feature, 'MM', 'Mm') || '';
9
+ const ops = cigarOps || parseCigar(feature.get('CIGAR'));
10
+ if (seq) {
11
+ const modifications = getModPositions(mm, seq, fstrand);
12
+ const probabilities = getModProbabilities(feature);
13
+ const maxProbModForPosition = [];
14
+ let probIndex = 0;
15
+ for (const { type, positions } of modifications) {
16
+ for (const { ref, idx } of getNextRefPos(ops, positions)) {
17
+ const prob = (probabilities === null || probabilities === void 0 ? void 0 : probabilities[probIndex + (fstrand === -1 ? positions.length - 1 - idx : idx)]) || 0;
18
+ if (!maxProbModForPosition[ref]) {
19
+ maxProbModForPosition[ref] = {
20
+ type,
21
+ prob,
22
+ allProbs: [prob],
23
+ };
24
+ }
25
+ else {
26
+ const old = maxProbModForPosition[ref];
27
+ maxProbModForPosition[ref] = {
28
+ allProbs: [...old.allProbs, prob],
29
+ prob: Math.max(old.prob, prob),
30
+ type: old.prob > prob ? old.type : type,
31
+ };
32
+ }
33
+ }
34
+ probIndex += positions.length;
35
+ }
36
+ return maxProbModForPosition;
37
+ }
38
+ return undefined;
39
+ }
@@ -0,0 +1,14 @@
1
+ import { IAnyStateTreeNode } from 'mobx-state-tree';
2
+ import { BlockSet } from '@jbrowse/core/util/blockTypes';
3
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
4
+ import { ModificationType } from './types';
5
+ export declare function getUniqueModifications({ self, adapterConfig, blocks, opts, }: {
6
+ self: IAnyStateTreeNode;
7
+ adapterConfig: AnyConfigurationModel;
8
+ blocks: BlockSet;
9
+ opts?: {
10
+ headers?: Record<string, string>;
11
+ signal?: AbortSignal;
12
+ filters: string[];
13
+ };
14
+ }): Promise<ModificationType[]>;
@@ -0,0 +1,13 @@
1
+ import { getSession } from '@jbrowse/core/util';
2
+ import { getRpcSessionId } from '@jbrowse/core/util/tracks';
3
+ export async function getUniqueModifications({ self, adapterConfig, blocks, opts, }) {
4
+ const { rpcManager } = getSession(self);
5
+ const sessionId = getRpcSessionId(self);
6
+ const values = await rpcManager.call(sessionId, 'PileupGetVisibleModifications', {
7
+ adapterConfig,
8
+ sessionId,
9
+ regions: blocks.contentBlocks,
10
+ ...opts,
11
+ });
12
+ return values;
13
+ }
@@ -0,0 +1,15 @@
1
+ import { IAnyStateTreeNode } from 'mobx-state-tree';
2
+ import { BlockSet } from '@jbrowse/core/util/blockTypes';
3
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
4
+ export declare function getUniqueTags({ self, tag, blocks, opts, }: {
5
+ self: IAnyStateTreeNode & {
6
+ adapterConfig: AnyConfigurationModel;
7
+ };
8
+ tag: string;
9
+ blocks: BlockSet;
10
+ opts?: {
11
+ headers?: Record<string, string>;
12
+ signal?: AbortSignal;
13
+ filters: string[];
14
+ };
15
+ }): Promise<string[]>;
@@ -0,0 +1,15 @@
1
+ import { getSession } from '@jbrowse/core/util';
2
+ import { getRpcSessionId } from '@jbrowse/core/util/tracks';
3
+ export async function getUniqueTags({ self, tag, blocks, opts, }) {
4
+ const { rpcManager } = getSession(self);
5
+ const { adapterConfig } = self;
6
+ const sessionId = getRpcSessionId(self);
7
+ const values = await rpcManager.call(getRpcSessionId(self), 'PileupGetGlobalValueForTag', {
8
+ adapterConfig,
9
+ tag,
10
+ sessionId,
11
+ regions: blocks.contentBlocks,
12
+ ...opts,
13
+ });
14
+ return values;
15
+ }
@@ -0,0 +1,94 @@
1
+ export type SkipMap = Record<string, {
2
+ score: number;
3
+ feature: unknown;
4
+ start: number;
5
+ end: number;
6
+ strand: number;
7
+ effectiveStrand: number;
8
+ }>;
9
+ export interface BinEntry {
10
+ entryDepth: number;
11
+ '-1': number;
12
+ '0': number;
13
+ '1': number;
14
+ avgProbability?: number;
15
+ }
16
+ type BinType = Record<string, BinEntry>;
17
+ export interface BaseCoverageBin {
18
+ refbase?: string;
19
+ depth: number;
20
+ readsCounted: number;
21
+ ref: BinEntry;
22
+ snps: BinType;
23
+ mods: BinType;
24
+ nonmods: BinType;
25
+ delskips: BinType;
26
+ noncov: BinType;
27
+ }
28
+ export interface PreBinEntry {
29
+ entryDepth: number;
30
+ '-1': number;
31
+ '0': number;
32
+ '1': number;
33
+ probabilities: number[];
34
+ }
35
+ type PreBinType = Record<string, PreBinEntry>;
36
+ export interface PreBaseCoverageBin extends PreBaseCoverageBinSubtypes {
37
+ refbase?: string;
38
+ depth: number;
39
+ readsCounted: number;
40
+ ref: PreBinEntry;
41
+ }
42
+ export interface PreBaseCoverageBinSubtypes {
43
+ snps: PreBinType;
44
+ mods: PreBinType;
45
+ nonmods: PreBinType;
46
+ delskips: PreBinType;
47
+ noncov: PreBinType;
48
+ }
49
+ export interface ModificationType {
50
+ type: string;
51
+ base: string;
52
+ strand: string;
53
+ }
54
+ export interface ModificationTypeWithColor {
55
+ color: string;
56
+ type: string;
57
+ base: string;
58
+ strand: string;
59
+ }
60
+ export interface ColorBy {
61
+ type: string;
62
+ tag?: string;
63
+ modifications?: {
64
+ twoColor?: boolean;
65
+ isolatedModification?: string;
66
+ };
67
+ }
68
+ export interface FilterBy {
69
+ flagExclude: number;
70
+ flagInclude: number;
71
+ readName?: string;
72
+ tagFilter?: {
73
+ tag: string;
74
+ value?: string;
75
+ };
76
+ }
77
+ export interface SortedBy {
78
+ type: string;
79
+ pos: number;
80
+ refName: string;
81
+ assemblyName: string;
82
+ tag?: string;
83
+ }
84
+ export interface Mismatch {
85
+ qual?: number;
86
+ start: number;
87
+ length: number;
88
+ type: string;
89
+ base: string;
90
+ altbase?: string;
91
+ seq?: string;
92
+ cliplen?: number;
93
+ }
94
+ export {};
@@ -1,2 +1,10 @@
1
1
  import { ChainData } from './fetchChains';
2
2
  export declare function hasPairedReads(features: ChainData): boolean;
3
+ export declare function alphaColor(baseColor: string, p: number): string;
4
+ export declare const defaultFilterFlags: {
5
+ flagInclude: number;
6
+ flagExclude: number;
7
+ };
8
+ export declare function cacheGetter<T>(ctor: {
9
+ prototype: T;
10
+ }, prop: keyof T): void;
@@ -1,3 +1,4 @@
1
+ import { colord } from '@jbrowse/core/util/colord';
1
2
  export function hasPairedReads(features) {
2
3
  for (const f of features.chains.values()) {
3
4
  if (f[0].flags & 1) {
@@ -6,3 +7,25 @@ export function hasPairedReads(features) {
6
7
  }
7
8
  return false;
8
9
  }
10
+ export function alphaColor(baseColor, p) {
11
+ return p !== 1
12
+ ? colord(baseColor)
13
+ .alpha(p * p)
14
+ .toHslString()
15
+ : baseColor;
16
+ }
17
+ export const defaultFilterFlags = {
18
+ flagInclude: 0,
19
+ flagExclude: 1540,
20
+ };
21
+ export function cacheGetter(ctor, prop) {
22
+ const desc = Object.getOwnPropertyDescriptor(ctor.prototype, prop);
23
+ const getter = desc.get;
24
+ Object.defineProperty(ctor.prototype, prop, {
25
+ get() {
26
+ const ret = getter.call(this);
27
+ Object.defineProperty(this, prop, { value: ret });
28
+ return ret;
29
+ },
30
+ });
31
+ }